From 7431163b522439108300d6746a852c683bdb65fc Mon Sep 17 00:00:00 2001 From: Jakub Zymelka Date: Tue, 20 Jan 2026 11:40:54 +0100 Subject: [PATCH 0001/6328] samples: ipc: icmsg: Extend support for nRF54LM20A Extends support and adds new overlays. Signed-off-by: Jakub Zymelka --- .../ipc/ipc_service/icmsg/CMakeLists.txt | 1 + .../ipc/ipc_service/icmsg/Kconfig.sysbuild | 1 + .../icmsg/boards/nrf54l_cpuapp_icbmsg.overlay | 11 +++++++ ... => nrf54lm20dk_nrf54lm20a_cpuapp.overlay} | 14 ++++---- .../boards/nrf54l_cpuflpr_icbmsg.overlay | 11 +++++++ ...=> nrf54lm20dk_nrf54lm20a_cpuflpr.overlay} | 14 ++++---- .../subsys/ipc/ipc_service/icmsg/sample.yaml | 33 +++++++++++-------- 7 files changed, 56 insertions(+), 29 deletions(-) create mode 100644 samples/subsys/ipc/ipc_service/icmsg/boards/nrf54l_cpuapp_icbmsg.overlay rename samples/subsys/ipc/ipc_service/icmsg/boards/{nrf54l15dk_nrf54l15_cpuapp_icbmsg.overlay => nrf54lm20dk_nrf54lm20a_cpuapp.overlay} (64%) create mode 100644 samples/subsys/ipc/ipc_service/icmsg/remote/boards/nrf54l_cpuflpr_icbmsg.overlay rename samples/subsys/ipc/ipc_service/icmsg/remote/boards/{nrf54l15dk_nrf54l15_cpuflpr_icbmsg.overlay => nrf54lm20dk_nrf54lm20a_cpuflpr.overlay} (67%) diff --git a/samples/subsys/ipc/ipc_service/icmsg/CMakeLists.txt b/samples/subsys/ipc/ipc_service/icmsg/CMakeLists.txt index fd88e8465fe1..b414551dd294 100644 --- a/samples/subsys/ipc/ipc_service/icmsg/CMakeLists.txt +++ b/samples/subsys/ipc/ipc_service/icmsg/CMakeLists.txt @@ -10,6 +10,7 @@ find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) if(NOT CONFIG_BOARD_NRF5340DK_NRF5340_CPUAPP AND NOT CONFIG_BOARD_NRF5340BSIM_NRF5340_CPUAPP AND + NOT CONFIG_BOARD_NRF54LM20DK_NRF54LM20A_CPUAPP AND NOT CONFIG_BOARD_STM32H747I_DISCO AND NOT CONFIG_BOARD_NRF54L15DK_NRF54L15_CPUAPP AND NOT CONFIG_BOARD_EK_RA8P1_R7KA8P1KFLCAC_CM85) diff --git a/samples/subsys/ipc/ipc_service/icmsg/Kconfig.sysbuild b/samples/subsys/ipc/ipc_service/icmsg/Kconfig.sysbuild index 58a434e2b6e9..11edd21c7540 100644 --- a/samples/subsys/ipc/ipc_service/icmsg/Kconfig.sysbuild +++ b/samples/subsys/ipc/ipc_service/icmsg/Kconfig.sysbuild @@ -9,5 +9,6 @@ string default "nrf5340dk/nrf5340/cpunet" if $(BOARD) = "nrf5340dk" default "nrf5340bsim/nrf5340/cpunet" if $(BOARD) = "nrf5340bsim" default "nrf54l15dk/nrf54l15/cpuflpr" if $(BOARD) = "nrf54l15dk" + default "nrf54lm20dk/nrf54lm20a/cpuflpr" if $(BOARD) = "nrf54lm20dk" default "stm32h747i_disco/stm32h747xx/m4" if $(BOARD) = "stm32h747i_disco" default "ek_ra8p1/r7ka8p1kflcac/cm33" if $(BOARD) = "ek_ra8p1" diff --git a/samples/subsys/ipc/ipc_service/icmsg/boards/nrf54l_cpuapp_icbmsg.overlay b/samples/subsys/ipc/ipc_service/icmsg/boards/nrf54l_cpuapp_icbmsg.overlay new file mode 100644 index 000000000000..68a36325c53d --- /dev/null +++ b/samples/subsys/ipc/ipc_service/icmsg/boards/nrf54l_cpuapp_icbmsg.overlay @@ -0,0 +1,11 @@ +/* + * Copyright (c) 2024 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +&ipc0 { + compatible = "zephyr,ipc-icbmsg"; + tx-blocks = <16>; + rx-blocks = <18>; +}; diff --git a/samples/subsys/ipc/ipc_service/icmsg/boards/nrf54l15dk_nrf54l15_cpuapp_icbmsg.overlay b/samples/subsys/ipc/ipc_service/icmsg/boards/nrf54lm20dk_nrf54lm20a_cpuapp.overlay similarity index 64% rename from samples/subsys/ipc/ipc_service/icmsg/boards/nrf54l15dk_nrf54l15_cpuapp_icbmsg.overlay rename to samples/subsys/ipc/ipc_service/icmsg/boards/nrf54lm20dk_nrf54lm20a_cpuapp.overlay index 639ad5e844b4..33afb300d789 100644 --- a/samples/subsys/ipc/ipc_service/icmsg/boards/nrf54l15dk_nrf54l15_cpuapp_icbmsg.overlay +++ b/samples/subsys/ipc/ipc_service/icmsg/boards/nrf54lm20dk_nrf54lm20a_cpuapp.overlay @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Nordic Semiconductor ASA + * Copyright (c) 2025 Nordic Semiconductor ASA * * SPDX-License-Identifier: Apache-2.0 */ @@ -10,24 +10,22 @@ #address-cells = <1>; #size-cells = <1>; - sram_rx: memory@20018000 { - reg = <0x20018000 0x0800>; + sram_rx: memory@20057c00 { + reg = <0x20057c00 0x8000>; }; - sram_tx: memory@20020000 { - reg = <0x20020000 0x0800>; + sram_tx: memory@2005fc00 { + reg = <0x2005fc00 0x8000>; }; }; }; ipc { ipc0: ipc0 { - compatible = "zephyr,ipc-icbmsg"; + compatible = "zephyr,ipc-icmsg"; dcache-alignment = <32>; tx-region = <&sram_tx>; rx-region = <&sram_rx>; - tx-blocks = <16>; - rx-blocks = <18>; mboxes = <&cpuapp_vevif_rx 20>, <&cpuapp_vevif_tx 21>; mbox-names = "rx", "tx"; status = "okay"; diff --git a/samples/subsys/ipc/ipc_service/icmsg/remote/boards/nrf54l_cpuflpr_icbmsg.overlay b/samples/subsys/ipc/ipc_service/icmsg/remote/boards/nrf54l_cpuflpr_icbmsg.overlay new file mode 100644 index 000000000000..e93358b71f22 --- /dev/null +++ b/samples/subsys/ipc/ipc_service/icmsg/remote/boards/nrf54l_cpuflpr_icbmsg.overlay @@ -0,0 +1,11 @@ +/* + * Copyright (c) 2024 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +&ipc0 { + compatible = "zephyr,ipc-icbmsg"; + tx-blocks = <18>; + rx-blocks = <16>; +}; diff --git a/samples/subsys/ipc/ipc_service/icmsg/remote/boards/nrf54l15dk_nrf54l15_cpuflpr_icbmsg.overlay b/samples/subsys/ipc/ipc_service/icmsg/remote/boards/nrf54lm20dk_nrf54lm20a_cpuflpr.overlay similarity index 67% rename from samples/subsys/ipc/ipc_service/icmsg/remote/boards/nrf54l15dk_nrf54l15_cpuflpr_icbmsg.overlay rename to samples/subsys/ipc/ipc_service/icmsg/remote/boards/nrf54lm20dk_nrf54lm20a_cpuflpr.overlay index 7fe78a716539..7aa2e5fa557b 100644 --- a/samples/subsys/ipc/ipc_service/icmsg/remote/boards/nrf54l15dk_nrf54l15_cpuflpr_icbmsg.overlay +++ b/samples/subsys/ipc/ipc_service/icmsg/remote/boards/nrf54lm20dk_nrf54lm20a_cpuflpr.overlay @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Nordic Semiconductor ASA + * Copyright (c) 2025 Nordic Semiconductor ASA * * SPDX-License-Identifier: Apache-2.0 */ @@ -10,24 +10,22 @@ #address-cells = <1>; #size-cells = <1>; - sram_tx: memory@20018000 { - reg = <0x20018000 0x0800>; + sram_tx: memory@20057c00 { + reg = <0x20057c00 0x8000>; }; - sram_rx: memory@20020000 { - reg = <0x20020000 0x0800>; + sram_rx: memory@2005fc00 { + reg = <0x2005fc00 0x8000>; }; }; }; ipc { ipc0: ipc0 { - compatible = "zephyr,ipc-icbmsg"; + compatible = "zephyr,ipc-icmsg"; dcache-alignment = <32>; tx-region = <&sram_tx>; rx-region = <&sram_rx>; - tx-blocks = <18>; - rx-blocks = <16>; mboxes = <&cpuflpr_vevif_rx 21>, <&cpuflpr_vevif_tx 20>; mbox-names = "rx", "tx"; status = "okay"; diff --git a/samples/subsys/ipc/ipc_service/icmsg/sample.yaml b/samples/subsys/ipc/ipc_service/icmsg/sample.yaml index d084434f7952..27ee7b5ad3bd 100644 --- a/samples/subsys/ipc/ipc_service/icmsg/sample.yaml +++ b/samples/subsys/ipc/ipc_service/icmsg/sample.yaml @@ -14,16 +14,18 @@ tests: - nrf5340dk/nrf5340/cpuapp - nrf5340bsim/nrf5340/cpuapp - sample.ipc.icmsg.nrf54l15: + sample.ipc.icmsg.nrf54l: platform_allow: - nrf54l15dk/nrf54l15/cpuapp + - nrf54lm20dk/nrf54lm20a/cpuapp integration_platforms: - nrf54l15dk/nrf54l15/cpuapp extra_args: icmsg_SNIPPET=nordic-flpr - sample.ipc.icmsg.nrf54l15_no_multithreading: + sample.ipc.icmsg.nrf54l_no_multithreading: platform_allow: - nrf54l15dk/nrf54l15/cpuapp + - nrf54lm20dk/nrf54lm20a/cpuapp integration_platforms: - nrf54l15dk/nrf54l15/cpuapp extra_args: @@ -33,9 +35,10 @@ tests: - remote_CONFIG_MULTITHREADING=n - remote_CONFIG_LOG_MODE_MINIMAL=y - sample.ipc.icmsg.nrf54l15_remote_no_multithreading: + sample.ipc.icmsg.nrf54l_remote_no_multithreading: platform_allow: - nrf54l15dk/nrf54l15/cpuapp + - nrf54lm20dk/nrf54lm20a/cpuapp integration_platforms: - nrf54l15dk/nrf54l15/cpuapp extra_args: @@ -43,43 +46,47 @@ tests: - remote_CONFIG_MULTITHREADING=n - remote_CONFIG_LOG_MODE_MINIMAL=y - sample.ipc.icbmsg.nrf54l15: - platform_allow: nrf54l15dk/nrf54l15/cpuapp + sample.ipc.icbmsg.nrf54l: + platform_allow: + - nrf54l15dk/nrf54l15/cpuapp + - nrf54lm20dk/nrf54lm20a/cpuapp integration_platforms: - nrf54l15dk/nrf54l15/cpuapp extra_args: - icmsg_SNIPPET=nordic-flpr - icmsg_CONFIG_IPC_SERVICE_BACKEND_ICBMSG_NUM_EP=1 - - icmsg_DTC_OVERLAY_FILE="boards/nrf54l15dk_nrf54l15_cpuapp_icbmsg.overlay" + - icmsg_EXTRA_DTC_OVERLAY_FILE="boards/nrf54l_cpuapp_icbmsg.overlay" - remote_CONFIG_IPC_SERVICE_BACKEND_ICBMSG_NUM_EP=1 - - remote_DTC_OVERLAY_FILE="boards/nrf54l15dk_nrf54l15_cpuflpr_icbmsg.overlay" + - remote_EXTRA_DTC_OVERLAY_FILE="boards/nrf54l_cpuflpr_icbmsg.overlay" - sample.ipc.icbmsg.nrf54l15_no_multithreading: + sample.ipc.icbmsg.nrf54l_no_multithreading: platform_allow: - nrf54l15dk/nrf54l15/cpuapp + - nrf54lm20dk/nrf54lm20a/cpuapp integration_platforms: - nrf54l15dk/nrf54l15/cpuapp extra_args: - icmsg_SNIPPET=nordic-flpr - icmsg_CONFIG_IPC_SERVICE_BACKEND_ICBMSG_NUM_EP=1 - - icmsg_DTC_OVERLAY_FILE="boards/nrf54l15dk_nrf54l15_cpuapp_icbmsg.overlay" + - icmsg_EXTRA_DTC_OVERLAY_FILE="boards/nrf54l_cpuapp_icbmsg.overlay" - icmsg_CONFIG_MULTITHREADING=n - icmsg_CONFIG_LOG_MODE_MINIMAL=y - remote_CONFIG_IPC_SERVICE_BACKEND_ICBMSG_NUM_EP=1 - - remote_DTC_OVERLAY_FILE="boards/nrf54l15dk_nrf54l15_cpuflpr_icbmsg.overlay" + - remote_EXTRA_DTC_OVERLAY_FILE="boards/nrf54l_cpuflpr_icbmsg.overlay" - remote_CONFIG_MULTITHREADING=n - remote_CONFIG_LOG_MODE_MINIMAL=y - sample.ipc.icbmsg.nrf54l15_remote_no_multithreading: + sample.ipc.icbmsg.nrf54l_remote_no_multithreading: platform_allow: - nrf54l15dk/nrf54l15/cpuapp + - nrf54lm20dk/nrf54lm20a/cpuapp integration_platforms: - nrf54l15dk/nrf54l15/cpuapp extra_args: - icmsg_SNIPPET=nordic-flpr - icmsg_CONFIG_IPC_SERVICE_BACKEND_ICBMSG_NUM_EP=1 - - icmsg_DTC_OVERLAY_FILE="boards/nrf54l15dk_nrf54l15_cpuapp_icbmsg.overlay" + - icmsg_EXTRA_DTC_OVERLAY_FILE="boards/nrf54l_cpuapp_icbmsg.overlay" - remote_CONFIG_IPC_SERVICE_BACKEND_ICBMSG_NUM_EP=1 - - remote_DTC_OVERLAY_FILE="boards/nrf54l15dk_nrf54l15_cpuflpr_icbmsg.overlay" + - remote_EXTRA_DTC_OVERLAY_FILE="boards/nrf54l_cpuflpr_icbmsg.overlay" - remote_CONFIG_MULTITHREADING=n - remote_CONFIG_LOG_MODE_MINIMAL=y From fdda5f5fad69bf8995622ed798917c90cc961229 Mon Sep 17 00:00:00 2001 From: Etienne Carriere Date: Mon, 15 Dec 2025 11:58:04 +0100 Subject: [PATCH 0002/6328] manifest: psa-arch-tests: build PSA arch tests from Zephyr Restore build of TF-M PSA-arch-tests using the Zephyr SDK toolchain. Signed-off-by: Etienne Carriere --- west.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/west.yml b/west.yml index f3a744910910..a51f8cf3962b 100644 --- a/west.yml +++ b/west.yml @@ -364,7 +364,7 @@ manifest: path: modules/lib/picolibc revision: ca8b6ebba5226a75545e57a140443168a26ba664 - name: psa-arch-tests - revision: 941cd8436a2e0f1da9d8584b83a403930826899d + revision: d70b2c7072cedf0f14724211d2122ef07b98720c path: modules/tee/tf-m/psa-arch-tests groups: - testing From 6f5e752187c0dfe6bff2874df28da05c932a2f96 Mon Sep 17 00:00:00 2001 From: Kate Wang Date: Mon, 22 Dec 2025 20:36:05 +0800 Subject: [PATCH 0003/6328] drivers: display: co5300: Fix pitch calculation in write function The previous implementation incorrectly calculated the source pointer advancement when pitch differs from width. The calculation was using `total_bytes_sent` which accumulated across iterations, leading to incorrect pointer arithmetic. Replace `total_bytes_sent` with `line_each_sent` to track lines written per iteration. Simplify the pointer advancement by: - Calculating complete lines written from bytes_written - Advancing by full pitch-sized lines - Adding any remaining partial line bytes This fixes the source pointer calculation when the buffer pitch is greater than the display width. Signed-off-by: Kate Wang --- drivers/display/display_co5300.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/drivers/display/display_co5300.c b/drivers/display/display_co5300.c index ee2bf3136410..bf1d7d688d21 100644 --- a/drivers/display/display_co5300.c +++ b/drivers/display/display_co5300.c @@ -154,7 +154,7 @@ static int co5300_write(const struct device *dev, uint16_t end_pos; uint8_t cmd_params[4]; struct mipi_dsi_msg msg = {0}; - uint32_t total_bytes_sent = 0U; + uint16_t line_each_sent = 0U; int bytes_written = 0; const uint8_t *src; uint32_t tx_size = 0U; @@ -247,10 +247,9 @@ static int co5300_write(const struct device *dev, /* Advance source pointer and decrement remaining */ if (local_desc.pitch > local_desc.width) { - total_bytes_sent += bytes_written; - src += bytes_written + total_bytes_sent / - (local_desc.width * data->bytes_per_pixel) * - ((local_desc.pitch - local_desc.width) * data->bytes_per_pixel); + line_each_sent = bytes_written / (local_desc.width * data->bytes_per_pixel); + src += line_each_sent * local_desc.pitch * data->bytes_per_pixel; + src += bytes_written % (local_desc.width * data->bytes_per_pixel); } else { src += bytes_written; } From 0bbe07bbc721546efad31d6c6e43a1cd551afc39 Mon Sep 17 00:00:00 2001 From: Ederson de Souza Date: Wed, 31 Dec 2025 16:11:50 -0800 Subject: [PATCH 0004/6328] drivers/i3c/mcux: Use size_t for buffer size Or a buffer whose size is 256 will become zero. Signed-off-by: Ederson de Souza --- drivers/i3c/i3c_mcux.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/i3c/i3c_mcux.c b/drivers/i3c/i3c_mcux.c index d955641f801e..d358890dd6ca 100644 --- a/drivers/i3c/i3c_mcux.c +++ b/drivers/i3c/i3c_mcux.c @@ -854,7 +854,7 @@ static int mcux_i3c_recover_bus(const struct device *dev) * @return Number of bytes read, or negative if error. */ static int mcux_i3c_do_one_xfer_read(I3C_Type *base, struct mcux_i3c_data *data, - uint8_t *buf, uint8_t buf_sz, bool ibi) + uint8_t *buf, size_t buf_sz, bool ibi) { int ret = 0; int offset = 0; From 3311d9734ca9b6ece26cc7089075bfc973c135b5 Mon Sep 17 00:00:00 2001 From: Ederson de Souza Date: Wed, 31 Dec 2025 16:14:44 -0800 Subject: [PATCH 0005/6328] drivers/i3c/mcux: Don't lose return value for function Return value for `mcux_i3c_do_one_xfer` was being lost due reuse of `ret` variable. Use another variable for timeout check. Signed-off-by: Ederson de Souza --- drivers/i3c/i3c_mcux.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/i3c/i3c_mcux.c b/drivers/i3c/i3c_mcux.c index d358890dd6ca..67f6a39fc726 100644 --- a/drivers/i3c/i3c_mcux.c +++ b/drivers/i3c/i3c_mcux.c @@ -1018,8 +1018,9 @@ static int mcux_i3c_do_one_xfer(I3C_Type *base, struct mcux_i3c_data *data, * Wait for controller to say the operation is done. * Save time by not clearing the bit. */ - ret = mcux_i3c_status_wait_timeout(base, I3C_MSTATUS_COMPLETE_MASK, 1000); - if (ret != 0) { + int ret2 = mcux_i3c_status_wait_timeout(base, I3C_MSTATUS_COMPLETE_MASK, 1000); + + if (ret2 != 0) { LOG_DBG("%s: timed out addr 0x%02x, buf_sz %u", __func__, addr, buf_sz); emit_stop = true; From 86f7962d2c263b20c2cb67f4320b7b9ef81bd03e Mon Sep 17 00:00:00 2001 From: Ederson de Souza Date: Wed, 31 Dec 2025 16:18:21 -0800 Subject: [PATCH 0006/6328] drivers/i3c/mcux: Handle short reads from target Sometimes, the size of a message coming from a target is not known in advance. In those cases, we must rely on the T-bit to get the end of message, which is signaled as the `COMPLETE` bit of `MSTATUS`. This patch verifies the COMPLETE bit before starting to wait for data, and if set, simply returns what was read so far. As a bonus, this simplifies the handling of IBI bytes: no need to rely on timeouts, if it's reading from IBI, etc. Signed-off-by: Ederson de Souza --- drivers/i3c/i3c_mcux.c | 38 ++++++++++++++++++++++---------------- 1 file changed, 22 insertions(+), 16 deletions(-) diff --git a/drivers/i3c/i3c_mcux.c b/drivers/i3c/i3c_mcux.c index 67f6a39fc726..02032da8966f 100644 --- a/drivers/i3c/i3c_mcux.c +++ b/drivers/i3c/i3c_mcux.c @@ -854,7 +854,7 @@ static int mcux_i3c_recover_bus(const struct device *dev) * @return Number of bytes read, or negative if error. */ static int mcux_i3c_do_one_xfer_read(I3C_Type *base, struct mcux_i3c_data *data, - uint8_t *buf, size_t buf_sz, bool ibi) + uint8_t *buf, size_t buf_sz) { int ret = 0; int offset = 0; @@ -866,7 +866,16 @@ static int mcux_i3c_do_one_xfer_read(I3C_Type *base, struct mcux_i3c_data *data, */ while (offset < buf_sz) { if (mcux_i3c_fifo_rx_count_get(base) == 0) { - /* Enable Receive pending interrupt */ + /* No more data - check if target marked message as complete */ + if (mcux_i3c_status_is_set(base, I3C_MSTATUS_COMPLETE_MASK)) { + /* All data received, move on */ + LOG_DBG("Target data complete, offset %d buf_sz %d", offset, + buf_sz); + ret = offset; + break; + } + + /* More data to come, enable Receive pending interrupt */ base->MINTSET = I3C_MSTATUS_RXPEND_MASK; /* Wait for data to arrive or an error */ @@ -881,28 +890,25 @@ static int mcux_i3c_do_one_xfer_read(I3C_Type *base, struct mcux_i3c_data *data, buf[offset++] = (uint8_t)base->MRDATAB; } } + + /* Done reading all data */ + if (ret > 0) { + break; + } + /* * If timed out, we abort the transaction. */ - if ((mcux_i3c_has_error(data) & I3C_MERRWARN_TIMEOUT_MASK) || ret) { + if ((mcux_i3c_has_error(data) & I3C_MERRWARN_TIMEOUT_MASK) || ret < 0) { ret = -ETIMEDOUT; - /* for ibi, ignore timeout err if any bytes were - * read, since the code doesn't know how many - * bytes will be sent by device. - */ - if (ibi && offset) { - ret = offset; - } else { - LOG_ERR("Timeout error"); - } + LOG_ERR("Timeout error"); break; } - } /* If no errors, then return the number of bytes read */ - if (ret > 0) { + if (ret >= 0) { ret = offset; } @@ -1003,7 +1009,7 @@ static int mcux_i3c_do_one_xfer(I3C_Type *base, struct mcux_i3c_data *data, } if (is_read) { - ret = mcux_i3c_do_one_xfer_read(base, data, buf, buf_sz, false); + ret = mcux_i3c_do_one_xfer_read(base, data, buf, buf_sz); } else { ret = mcux_i3c_do_one_xfer_write(base, data, buf, buf_sz, no_ending); } @@ -1509,7 +1515,7 @@ static void mcux_i3c_ibi_work(struct k_work *work) target = i3c_dev_list_i3c_addr_find(dev, (uint8_t)ibiaddr); if (target != NULL) { ret = mcux_i3c_do_one_xfer_read(base, data, &payload[0], - sizeof(payload), true); + sizeof(payload)); if (ret >= 0) { payload_sz = (size_t)ret; } else { From c1a356e5efaf697d370a7c2368d83c364e65fb11 Mon Sep 17 00:00:00 2001 From: Khai Cao Date: Tue, 13 Jan 2026 01:59:26 +0000 Subject: [PATCH 0007/6328] boards: renesas: Correct part number for mck_ra8t2 board Correct part number for mck_ra8t2 board by change r7ka8t2lfecac to r7ka8t2lflcac Signed-off-by: Khai Cao --- boards/renesas/mck_ra8t2/Kconfig.mck_ra8t2 | 4 ++-- boards/renesas/mck_ra8t2/board.cmake | 2 +- boards/renesas/mck_ra8t2/board.yml | 2 +- boards/renesas/mck_ra8t2/doc/index.rst | 8 ++++---- ...c_cm85.dts => mck_ra8t2_r7ka8t2lflcac_cm85.dts} | 2 +- ...cm85.yaml => mck_ra8t2_r7ka8t2lflcac_cm85.yaml} | 2 +- ...nfig => mck_ra8t2_r7ka8t2lflcac_cm85_defconfig} | 0 .../ra8/{r7ka8t2lfecac.dtsi => r7ka8t2lflcac.dtsi} | 0 ...8t2lfecac_cm85.dtsi => r7ka8t2lflcac_cm85.dtsi} | 2 +- ...verlay => mck_ra8t2_r7ka8t2lflcac_cm85.overlay} | 0 soc/renesas/ra/ra8t2/Kconfig | 12 ++++++------ soc/renesas/ra/ra8t2/Kconfig.defconfig | 4 ++-- soc/renesas/ra/ra8t2/Kconfig.soc | 14 +++++++------- soc/renesas/ra/soc.yml | 2 +- ...verlay => mck_ra8t2_r7ka8t2lflcac_cm85.overlay} | 0 ...verlay => mck_ra8t2_r7ka8t2lflcac_cm85.overlay} | 0 ...verlay => mck_ra8t2_r7ka8t2lflcac_cm85.overlay} | 0 ...verlay => mck_ra8t2_r7ka8t2lflcac_cm85.overlay} | 0 ...verlay => mck_ra8t2_r7ka8t2lflcac_cm85.overlay} | 0 ...cm85.conf => mck_ra8t2_r7ka8t2lflcac_cm85.conf} | 0 ...verlay => mck_ra8t2_r7ka8t2lflcac_cm85.overlay} | 0 ...=> mck_ra8t2_r7ka8t2lflcac_cm85_sci_b_i2c.conf} | 0 ...mck_ra8t2_r7ka8t2lflcac_cm85_sci_b_i2c.overlay} | 0 tests/drivers/i2c/i2c_api/testcase.yaml | 2 +- ...verlay => mck_ra8t2_r7ka8t2lflcac_cm85.overlay} | 0 ...verlay => mck_ra8t2_r7ka8t2lflcac_cm85.overlay} | 0 ...cm85.conf => mck_ra8t2_r7ka8t2lflcac_cm85.conf} | 0 ...verlay => mck_ra8t2_r7ka8t2lflcac_cm85.overlay} | 0 ...mck_ra8t2_r7ka8t2lflcac_cm85_sci_b_spi.overlay} | 0 tests/drivers/spi/spi_loopback/testcase.yaml | 4 ++-- ...verlay => mck_ra8t2_r7ka8t2lflcac_cm85.overlay} | 0 ...verlay => mck_ra8t2_r7ka8t2lflcac_cm85.overlay} | 0 ...verlay => mck_ra8t2_r7ka8t2lflcac_cm85.overlay} | 0 tests/subsys/fs/ext2/testcase.yaml | 4 ++-- ...cm85.conf => mck_ra8t2_r7ka8t2lflcac_cm85.conf} | 0 tests/subsys/pm/power_mgmt_soc/testcase.yaml | 2 +- 36 files changed, 33 insertions(+), 33 deletions(-) rename boards/renesas/mck_ra8t2/{mck_ra8t2_r7ka8t2lfecac_cm85.dts => mck_ra8t2_r7ka8t2lflcac_cm85.dts} (97%) rename boards/renesas/mck_ra8t2/{mck_ra8t2_r7ka8t2lfecac_cm85.yaml => mck_ra8t2_r7ka8t2lflcac_cm85.yaml} (78%) rename boards/renesas/mck_ra8t2/{mck_ra8t2_r7ka8t2lfecac_cm85_defconfig => mck_ra8t2_r7ka8t2lflcac_cm85_defconfig} (100%) rename dts/arm/renesas/ra/ra8/{r7ka8t2lfecac.dtsi => r7ka8t2lflcac.dtsi} (100%) rename dts/arm/renesas/ra/ra8/{r7ka8t2lfecac_cm85.dtsi => r7ka8t2lflcac_cm85.dtsi} (76%) rename samples/drivers/counter/alarm/boards/{mck_ra8t2_r7ka8t2lfecac_cm85.overlay => mck_ra8t2_r7ka8t2lflcac_cm85.overlay} (100%) rename tests/drivers/can/api/boards/{mck_ra8t2_r7ka8t2lfecac_cm85.overlay => mck_ra8t2_r7ka8t2lflcac_cm85.overlay} (100%) rename tests/drivers/can/timing/boards/{mck_ra8t2_r7ka8t2lfecac_cm85.overlay => mck_ra8t2_r7ka8t2lflcac_cm85.overlay} (100%) rename tests/drivers/clock_control/pwm_clock/boards/{mck_ra8t2_r7ka8t2lfecac_cm85.overlay => mck_ra8t2_r7ka8t2lflcac_cm85.overlay} (100%) rename tests/drivers/comparator/gpio_loopback/boards/{mck_ra8t2_r7ka8t2lfecac_cm85.overlay => mck_ra8t2_r7ka8t2lflcac_cm85.overlay} (100%) rename tests/drivers/counter/counter_basic_api/boards/{mck_ra8t2_r7ka8t2lfecac_cm85.overlay => mck_ra8t2_r7ka8t2lflcac_cm85.overlay} (100%) rename tests/drivers/i2c/i2c_api/boards/{mck_ra8t2_r7ka8t2lfecac_cm85.conf => mck_ra8t2_r7ka8t2lflcac_cm85.conf} (100%) rename tests/drivers/i2c/i2c_api/boards/{mck_ra8t2_r7ka8t2lfecac_cm85.overlay => mck_ra8t2_r7ka8t2lflcac_cm85.overlay} (100%) rename tests/drivers/i2c/i2c_api/boards/{mck_ra8t2_r7ka8t2lfecac_cm85_sci_b_i2c.conf => mck_ra8t2_r7ka8t2lflcac_cm85_sci_b_i2c.conf} (100%) rename tests/drivers/i2c/i2c_api/boards/{mck_ra8t2_r7ka8t2lfecac_cm85_sci_b_i2c.overlay => mck_ra8t2_r7ka8t2lflcac_cm85_sci_b_i2c.overlay} (100%) rename tests/drivers/pwm/pwm_api/boards/{mck_ra8t2_r7ka8t2lfecac_cm85.overlay => mck_ra8t2_r7ka8t2lflcac_cm85.overlay} (100%) rename tests/drivers/pwm/pwm_loopback/boards/{mck_ra8t2_r7ka8t2lfecac_cm85.overlay => mck_ra8t2_r7ka8t2lflcac_cm85.overlay} (100%) rename tests/drivers/spi/spi_loopback/boards/{mck_ra8t2_r7ka8t2lfecac_cm85.conf => mck_ra8t2_r7ka8t2lflcac_cm85.conf} (100%) rename tests/drivers/spi/spi_loopback/boards/{mck_ra8t2_r7ka8t2lfecac_cm85.overlay => mck_ra8t2_r7ka8t2lflcac_cm85.overlay} (100%) rename tests/drivers/spi/spi_loopback/boards/{mck_ra8t2_r7ka8t2lfecac_cm85_sci_b_spi.overlay => mck_ra8t2_r7ka8t2lflcac_cm85_sci_b_spi.overlay} (100%) rename tests/drivers/uart/uart_async_api/boards/{mck_ra8t2_r7ka8t2lfecac_cm85.overlay => mck_ra8t2_r7ka8t2lflcac_cm85.overlay} (100%) rename tests/subsys/canbus/isotp/conformance/boards/{mck_ra8t2_r7ka8t2lfecac_cm85.overlay => mck_ra8t2_r7ka8t2lflcac_cm85.overlay} (100%) rename tests/subsys/canbus/isotp/implementation/boards/{mck_ra8t2_r7ka8t2lfecac_cm85.overlay => mck_ra8t2_r7ka8t2lflcac_cm85.overlay} (100%) rename tests/subsys/fs/fat_fs_api/boards/{mck_ra8t2_r7ka8t2lfecac_cm85.conf => mck_ra8t2_r7ka8t2lflcac_cm85.conf} (100%) diff --git a/boards/renesas/mck_ra8t2/Kconfig.mck_ra8t2 b/boards/renesas/mck_ra8t2/Kconfig.mck_ra8t2 index ba0ca76b5d2f..28da044ae41e 100644 --- a/boards/renesas/mck_ra8t2/Kconfig.mck_ra8t2 +++ b/boards/renesas/mck_ra8t2/Kconfig.mck_ra8t2 @@ -2,5 +2,5 @@ # SPDX-License-Identifier: Apache-2.0 config BOARD_MCK_RA8T2 - select SOC_R7KA8T2LFECAC_CM85 if BOARD_MCK_RA8T2_R7KA8T2LFECAC_CM85 - select SOC_R7KA8T2LFECAC_CM33 if BOARD_MCK_RA8T2_R7KA8T2LFECAC_CM33 + select SOC_R7KA8T2LFLCAC_CM85 if BOARD_MCK_RA8T2_R7KA8T2LFLCAC_CM85 + select SOC_R7KA8T2LFLCAC_CM33 if BOARD_MCK_RA8T2_R7KA8T2LFLCAC_CM33 diff --git a/boards/renesas/mck_ra8t2/board.cmake b/boards/renesas/mck_ra8t2/board.cmake index 39712afe86e8..9430935aab35 100644 --- a/boards/renesas/mck_ra8t2/board.cmake +++ b/boards/renesas/mck_ra8t2/board.cmake @@ -1,7 +1,7 @@ # Copyright (c) 2025 Renesas Electronics Corporation # SPDX-License-Identifier: Apache-2.0 -if(CONFIG_SOC_R7KA8T2LFECAC_CM85) +if(CONFIG_SOC_R7KA8T2LFLCAC_CM85) board_runner_args(jlink "--device=R7KA8T2LF_CPU0" "--reset-after-load") endif() diff --git a/boards/renesas/mck_ra8t2/board.yml b/boards/renesas/mck_ra8t2/board.yml index 2981b49915b4..81358c562bab 100644 --- a/boards/renesas/mck_ra8t2/board.yml +++ b/boards/renesas/mck_ra8t2/board.yml @@ -3,4 +3,4 @@ board: full_name: RA8T2 Motor Control Kit vendor: renesas socs: - - name: r7ka8t2lfecac + - name: r7ka8t2lflcac diff --git a/boards/renesas/mck_ra8t2/doc/index.rst b/boards/renesas/mck_ra8t2/doc/index.rst index c3f9dd728894..dcbc8e323751 100644 --- a/boards/renesas/mck_ra8t2/doc/index.rst +++ b/boards/renesas/mck_ra8t2/doc/index.rst @@ -88,7 +88,7 @@ Here is an example for the :zephyr:code-sample:`hello_world` application on CM85 .. zephyr-app-commands:: :zephyr-app: samples/hello_world - :board: mck_ra8t2/r7ka8t2lfecac/cm85 + :board: mck_ra8t2/r7ka8t2lflcac/cm85 :goals: flash Open a serial terminal, reset the board (push the reset switch S1), and you should @@ -97,7 +97,7 @@ see the following message in the terminal: .. code-block:: console ***** Booting Zephyr OS v4.2.0-xxx-xxxxxxxxxxxxx ***** - Hello World! mck_ra8t2/r7ka8t2lfecac/cm85 + Hello World! mck_ra8t2/r7ka8t2lflcac/cm85 Flashing ======== @@ -128,7 +128,7 @@ To build the sample application using sysbuild use the command: .. zephyr-app-commands:: :tool: west :zephyr-app: samples/hello_world - :board: mck_ra8t2/r7ka8t2lfecac/cm85 + :board: mck_ra8t2/r7ka8t2lflcac/cm85 :goals: build flash :west-args: --sysbuild :gen-args: -DSB_CONFIG_BOOTLOADER_MCUBOOT=y @@ -188,7 +188,7 @@ You should see the following message in the terminal: I: Image version: v0.0.0 I: Jumping to the first image slot *** Booting Zephyr OS build v4.2.0-6156-ged85ac9ffda9 *** - Hello World! mck_ra8t2/r7ka8t2lfecac/cm85 + Hello World! mck_ra8t2/r7ka8t2lflcac/cm85 References ********** diff --git a/boards/renesas/mck_ra8t2/mck_ra8t2_r7ka8t2lfecac_cm85.dts b/boards/renesas/mck_ra8t2/mck_ra8t2_r7ka8t2lflcac_cm85.dts similarity index 97% rename from boards/renesas/mck_ra8t2/mck_ra8t2_r7ka8t2lfecac_cm85.dts rename to boards/renesas/mck_ra8t2/mck_ra8t2_r7ka8t2lflcac_cm85.dts index 2603cf3fb959..e88d85f6a234 100644 --- a/boards/renesas/mck_ra8t2/mck_ra8t2_r7ka8t2lfecac_cm85.dts +++ b/boards/renesas/mck_ra8t2/mck_ra8t2_r7ka8t2lflcac_cm85.dts @@ -5,7 +5,7 @@ /dts-v1/; -#include +#include #include "mck_ra8t2.dtsi" / { diff --git a/boards/renesas/mck_ra8t2/mck_ra8t2_r7ka8t2lfecac_cm85.yaml b/boards/renesas/mck_ra8t2/mck_ra8t2_r7ka8t2lflcac_cm85.yaml similarity index 78% rename from boards/renesas/mck_ra8t2/mck_ra8t2_r7ka8t2lfecac_cm85.yaml rename to boards/renesas/mck_ra8t2/mck_ra8t2_r7ka8t2lflcac_cm85.yaml index 94277f34b2c4..a1dbd0715dcf 100644 --- a/boards/renesas/mck_ra8t2/mck_ra8t2_r7ka8t2lfecac_cm85.yaml +++ b/boards/renesas/mck_ra8t2/mck_ra8t2_r7ka8t2lflcac_cm85.yaml @@ -1,4 +1,4 @@ -identifier: mck_ra8t2/r7ka8t2lfecac/cm85 +identifier: mck_ra8t2/r7ka8t2lflcac/cm85 name: Renesas MCK-RA8T2 type: mcu arch: arm diff --git a/boards/renesas/mck_ra8t2/mck_ra8t2_r7ka8t2lfecac_cm85_defconfig b/boards/renesas/mck_ra8t2/mck_ra8t2_r7ka8t2lflcac_cm85_defconfig similarity index 100% rename from boards/renesas/mck_ra8t2/mck_ra8t2_r7ka8t2lfecac_cm85_defconfig rename to boards/renesas/mck_ra8t2/mck_ra8t2_r7ka8t2lflcac_cm85_defconfig diff --git a/dts/arm/renesas/ra/ra8/r7ka8t2lfecac.dtsi b/dts/arm/renesas/ra/ra8/r7ka8t2lflcac.dtsi similarity index 100% rename from dts/arm/renesas/ra/ra8/r7ka8t2lfecac.dtsi rename to dts/arm/renesas/ra/ra8/r7ka8t2lflcac.dtsi diff --git a/dts/arm/renesas/ra/ra8/r7ka8t2lfecac_cm85.dtsi b/dts/arm/renesas/ra/ra8/r7ka8t2lflcac_cm85.dtsi similarity index 76% rename from dts/arm/renesas/ra/ra8/r7ka8t2lfecac_cm85.dtsi rename to dts/arm/renesas/ra/ra8/r7ka8t2lflcac_cm85.dtsi index bd47c88aa9d0..c6cebc406c59 100644 --- a/dts/arm/renesas/ra/ra8/r7ka8t2lfecac_cm85.dtsi +++ b/dts/arm/renesas/ra/ra8/r7ka8t2lflcac_cm85.dtsi @@ -5,6 +5,6 @@ */ #include -#include +#include /delete-node/ &cpu1; diff --git a/samples/drivers/counter/alarm/boards/mck_ra8t2_r7ka8t2lfecac_cm85.overlay b/samples/drivers/counter/alarm/boards/mck_ra8t2_r7ka8t2lflcac_cm85.overlay similarity index 100% rename from samples/drivers/counter/alarm/boards/mck_ra8t2_r7ka8t2lfecac_cm85.overlay rename to samples/drivers/counter/alarm/boards/mck_ra8t2_r7ka8t2lflcac_cm85.overlay diff --git a/soc/renesas/ra/ra8t2/Kconfig b/soc/renesas/ra/ra8t2/Kconfig index c41407520a1d..ae5d44d29a1a 100644 --- a/soc/renesas/ra/ra8t2/Kconfig +++ b/soc/renesas/ra/ra8t2/Kconfig @@ -16,11 +16,11 @@ config SOC_SERIES_RA8T2 select SOC_EARLY_INIT_HOOK select HAS_PM -config SOC_R7KA8T2LFECAC_CM85 +config SOC_R7KA8T2LFLCAC_CM85 select CPU_CORTEX_M85 select GPIO_RA_HAS_VBTICTLR -config SOC_R7KA8T2LFECAC_CM33 +config SOC_R7KA8T2LFLCAC_CM33 select CPU_CORTEX_M33 select SOC_RA_SECOND_CORE_BUILD @@ -28,14 +28,14 @@ if SOC_SERIES_RA8T2 config RENESAS_PN_ROM_SIZE hex - default 0x100000 if SOC_R7KA8T2LFECAC + default 0x100000 if SOC_R7KA8T2LFLCAC help Code MRAM and Flash size config RENESAS_PN_PACKAGE_TYPE int range 1 4 - default 2 if SOC_R7KA8T2LFECAC + default 2 if SOC_R7KA8T2LFLCAC help Package type: 1 -> AB: LFBGA 224 pins @@ -45,7 +45,7 @@ config RENESAS_PN_PACKAGE_TYPE config RENESAS_PN_FEATURE_SET hex - default 0x4c if SOC_R7KA8T2LFECAC + default 0x4c if SOC_R7KA8T2LFLCAC help Feature set (Convert the feature set character into its ASCII hex value): - A (0x41): Single Core (CM85 only), EtherCAT slave controller is not available @@ -55,7 +55,7 @@ config RENESAS_PN_FEATURE_SET config RENESAS_PN_NUMBER_OF_CORES int range 1 2 - default 2 if SOC_R7KA8T2LFECAC + default 2 if SOC_R7KA8T2LFLCAC help Number of SoC cores diff --git a/soc/renesas/ra/ra8t2/Kconfig.defconfig b/soc/renesas/ra/ra8t2/Kconfig.defconfig index 464f124c9213..438d992573b3 100644 --- a/soc/renesas/ra/ra8t2/Kconfig.defconfig +++ b/soc/renesas/ra/ra8t2/Kconfig.defconfig @@ -11,8 +11,8 @@ DT_CPUCLK1_PATH := $(dt_nodelabel_path,cpuclk1) DT_LOCO_PATH := $(dt_nodelabel_path,loco) config SYS_CLOCK_HW_CYCLES_PER_SEC - default $(dt_node_int_prop_int,$(DT_CPUCLK0_PATH),clock-frequency) if SOC_R7KA8T2LFECAC_CM85 && CORTEX_M_SYSTICK - default $(dt_node_int_prop_int,$(DT_CPUCLK1_PATH),clock-frequency) if SOC_R7KA8T2LFECAC_CM33 && CORTEX_M_SYSTICK + default $(dt_node_int_prop_int,$(DT_CPUCLK0_PATH),clock-frequency) if SOC_R7KA8T2LFLCAC_CM85 && CORTEX_M_SYSTICK + default $(dt_node_int_prop_int,$(DT_CPUCLK1_PATH),clock-frequency) if SOC_R7KA8T2LFLCAC_CM33 && CORTEX_M_SYSTICK default $(dt_node_int_prop_int,$(DT_LOCO_PATH),clock-frequency) if RENESAS_RA_ULPT_TIMER config CORTEX_M_SYSTICK diff --git a/soc/renesas/ra/ra8t2/Kconfig.soc b/soc/renesas/ra/ra8t2/Kconfig.soc index 0a68a17b393e..55ad88befb71 100644 --- a/soc/renesas/ra/ra8t2/Kconfig.soc +++ b/soc/renesas/ra/ra8t2/Kconfig.soc @@ -7,22 +7,22 @@ config SOC_SERIES_RA8T2 help Renesas RA8T2 series -config SOC_R7KA8T2LFECAC +config SOC_R7KA8T2LFLCAC bool select SOC_SERIES_RA8T2 help - R7KA8T2LFECAC + R7KA8T2LFLCAC -config SOC_R7KA8T2LFECAC_CM85 +config SOC_R7KA8T2LFLCAC_CM85 bool - select SOC_R7KA8T2LFECAC + select SOC_R7KA8T2LFLCAC -config SOC_R7KA8T2LFECAC_CM33 +config SOC_R7KA8T2LFLCAC_CM33 bool - select SOC_R7KA8T2LFECAC + select SOC_R7KA8T2LFLCAC config SOC_SERIES default "ra8t2" if SOC_SERIES_RA8T2 config SOC - default "r7ka8t2lfecac" if SOC_R7KA8T2LFECAC + default "r7ka8t2lflcac" if SOC_R7KA8T2LFLCAC diff --git a/soc/renesas/ra/soc.yml b/soc/renesas/ra/soc.yml index 1f8f49ee0efa..4c252cc39789 100644 --- a/soc/renesas/ra/soc.yml +++ b/soc/renesas/ra/soc.yml @@ -93,7 +93,7 @@ family: - name: cm33 - name: ra8t2 socs: - - name: r7ka8t2lfecac + - name: r7ka8t2lflcac cpuclusters: - name: cm85 - name: cm33 diff --git a/tests/drivers/can/api/boards/mck_ra8t2_r7ka8t2lfecac_cm85.overlay b/tests/drivers/can/api/boards/mck_ra8t2_r7ka8t2lflcac_cm85.overlay similarity index 100% rename from tests/drivers/can/api/boards/mck_ra8t2_r7ka8t2lfecac_cm85.overlay rename to tests/drivers/can/api/boards/mck_ra8t2_r7ka8t2lflcac_cm85.overlay diff --git a/tests/drivers/can/timing/boards/mck_ra8t2_r7ka8t2lfecac_cm85.overlay b/tests/drivers/can/timing/boards/mck_ra8t2_r7ka8t2lflcac_cm85.overlay similarity index 100% rename from tests/drivers/can/timing/boards/mck_ra8t2_r7ka8t2lfecac_cm85.overlay rename to tests/drivers/can/timing/boards/mck_ra8t2_r7ka8t2lflcac_cm85.overlay diff --git a/tests/drivers/clock_control/pwm_clock/boards/mck_ra8t2_r7ka8t2lfecac_cm85.overlay b/tests/drivers/clock_control/pwm_clock/boards/mck_ra8t2_r7ka8t2lflcac_cm85.overlay similarity index 100% rename from tests/drivers/clock_control/pwm_clock/boards/mck_ra8t2_r7ka8t2lfecac_cm85.overlay rename to tests/drivers/clock_control/pwm_clock/boards/mck_ra8t2_r7ka8t2lflcac_cm85.overlay diff --git a/tests/drivers/comparator/gpio_loopback/boards/mck_ra8t2_r7ka8t2lfecac_cm85.overlay b/tests/drivers/comparator/gpio_loopback/boards/mck_ra8t2_r7ka8t2lflcac_cm85.overlay similarity index 100% rename from tests/drivers/comparator/gpio_loopback/boards/mck_ra8t2_r7ka8t2lfecac_cm85.overlay rename to tests/drivers/comparator/gpio_loopback/boards/mck_ra8t2_r7ka8t2lflcac_cm85.overlay diff --git a/tests/drivers/counter/counter_basic_api/boards/mck_ra8t2_r7ka8t2lfecac_cm85.overlay b/tests/drivers/counter/counter_basic_api/boards/mck_ra8t2_r7ka8t2lflcac_cm85.overlay similarity index 100% rename from tests/drivers/counter/counter_basic_api/boards/mck_ra8t2_r7ka8t2lfecac_cm85.overlay rename to tests/drivers/counter/counter_basic_api/boards/mck_ra8t2_r7ka8t2lflcac_cm85.overlay diff --git a/tests/drivers/i2c/i2c_api/boards/mck_ra8t2_r7ka8t2lfecac_cm85.conf b/tests/drivers/i2c/i2c_api/boards/mck_ra8t2_r7ka8t2lflcac_cm85.conf similarity index 100% rename from tests/drivers/i2c/i2c_api/boards/mck_ra8t2_r7ka8t2lfecac_cm85.conf rename to tests/drivers/i2c/i2c_api/boards/mck_ra8t2_r7ka8t2lflcac_cm85.conf diff --git a/tests/drivers/i2c/i2c_api/boards/mck_ra8t2_r7ka8t2lfecac_cm85.overlay b/tests/drivers/i2c/i2c_api/boards/mck_ra8t2_r7ka8t2lflcac_cm85.overlay similarity index 100% rename from tests/drivers/i2c/i2c_api/boards/mck_ra8t2_r7ka8t2lfecac_cm85.overlay rename to tests/drivers/i2c/i2c_api/boards/mck_ra8t2_r7ka8t2lflcac_cm85.overlay diff --git a/tests/drivers/i2c/i2c_api/boards/mck_ra8t2_r7ka8t2lfecac_cm85_sci_b_i2c.conf b/tests/drivers/i2c/i2c_api/boards/mck_ra8t2_r7ka8t2lflcac_cm85_sci_b_i2c.conf similarity index 100% rename from tests/drivers/i2c/i2c_api/boards/mck_ra8t2_r7ka8t2lfecac_cm85_sci_b_i2c.conf rename to tests/drivers/i2c/i2c_api/boards/mck_ra8t2_r7ka8t2lflcac_cm85_sci_b_i2c.conf diff --git a/tests/drivers/i2c/i2c_api/boards/mck_ra8t2_r7ka8t2lfecac_cm85_sci_b_i2c.overlay b/tests/drivers/i2c/i2c_api/boards/mck_ra8t2_r7ka8t2lflcac_cm85_sci_b_i2c.overlay similarity index 100% rename from tests/drivers/i2c/i2c_api/boards/mck_ra8t2_r7ka8t2lfecac_cm85_sci_b_i2c.overlay rename to tests/drivers/i2c/i2c_api/boards/mck_ra8t2_r7ka8t2lflcac_cm85_sci_b_i2c.overlay diff --git a/tests/drivers/i2c/i2c_api/testcase.yaml b/tests/drivers/i2c/i2c_api/testcase.yaml index 81a2c1937239..c56a61649792 100644 --- a/tests/drivers/i2c/i2c_api/testcase.yaml +++ b/tests/drivers/i2c/i2c_api/testcase.yaml @@ -27,7 +27,7 @@ tests: platform_allow: - ek_ra8p1/r7ka8p1kflcac/cm85 - ek_ra8p1/r7ka8p1kflcac/cm33 - - mck_ra8t2/r7ka8t2lfecac/cm85 + - mck_ra8t2/r7ka8t2lflcac/cm85 - ek_ra8d2/r7ka8d2kflcac/cm85 - ek_ra8m2/r7ka8m2jflcac/cm85 extra_args: diff --git a/tests/drivers/pwm/pwm_api/boards/mck_ra8t2_r7ka8t2lfecac_cm85.overlay b/tests/drivers/pwm/pwm_api/boards/mck_ra8t2_r7ka8t2lflcac_cm85.overlay similarity index 100% rename from tests/drivers/pwm/pwm_api/boards/mck_ra8t2_r7ka8t2lfecac_cm85.overlay rename to tests/drivers/pwm/pwm_api/boards/mck_ra8t2_r7ka8t2lflcac_cm85.overlay diff --git a/tests/drivers/pwm/pwm_loopback/boards/mck_ra8t2_r7ka8t2lfecac_cm85.overlay b/tests/drivers/pwm/pwm_loopback/boards/mck_ra8t2_r7ka8t2lflcac_cm85.overlay similarity index 100% rename from tests/drivers/pwm/pwm_loopback/boards/mck_ra8t2_r7ka8t2lfecac_cm85.overlay rename to tests/drivers/pwm/pwm_loopback/boards/mck_ra8t2_r7ka8t2lflcac_cm85.overlay diff --git a/tests/drivers/spi/spi_loopback/boards/mck_ra8t2_r7ka8t2lfecac_cm85.conf b/tests/drivers/spi/spi_loopback/boards/mck_ra8t2_r7ka8t2lflcac_cm85.conf similarity index 100% rename from tests/drivers/spi/spi_loopback/boards/mck_ra8t2_r7ka8t2lfecac_cm85.conf rename to tests/drivers/spi/spi_loopback/boards/mck_ra8t2_r7ka8t2lflcac_cm85.conf diff --git a/tests/drivers/spi/spi_loopback/boards/mck_ra8t2_r7ka8t2lfecac_cm85.overlay b/tests/drivers/spi/spi_loopback/boards/mck_ra8t2_r7ka8t2lflcac_cm85.overlay similarity index 100% rename from tests/drivers/spi/spi_loopback/boards/mck_ra8t2_r7ka8t2lfecac_cm85.overlay rename to tests/drivers/spi/spi_loopback/boards/mck_ra8t2_r7ka8t2lflcac_cm85.overlay diff --git a/tests/drivers/spi/spi_loopback/boards/mck_ra8t2_r7ka8t2lfecac_cm85_sci_b_spi.overlay b/tests/drivers/spi/spi_loopback/boards/mck_ra8t2_r7ka8t2lflcac_cm85_sci_b_spi.overlay similarity index 100% rename from tests/drivers/spi/spi_loopback/boards/mck_ra8t2_r7ka8t2lfecac_cm85_sci_b_spi.overlay rename to tests/drivers/spi/spi_loopback/boards/mck_ra8t2_r7ka8t2lflcac_cm85_sci_b_spi.overlay diff --git a/tests/drivers/spi/spi_loopback/testcase.yaml b/tests/drivers/spi/spi_loopback/testcase.yaml index 55e47bbc7340..21f50ed49252 100644 --- a/tests/drivers/spi/spi_loopback/testcase.yaml +++ b/tests/drivers/spi/spi_loopback/testcase.yaml @@ -409,7 +409,7 @@ tests: - ek_ra8p1/r7ka8p1kflcac/cm85 platform_allow: - ek_ra8p1/r7ka8p1kflcac/cm85 - - mck_ra8t2/r7ka8t2lfecac/cm85 + - mck_ra8t2/r7ka8t2lflcac/cm85 extra_args: - DTC_OVERLAY_FILE="boards/${BOARD}${NORMALIZED_BOARD_QUALIFIERS}_sci_b_spi.overlay" - CONF_FILE="prj.conf" # to exclude "boards/${BOARD}${NORMALIZED_BOARD_QUALIFIERS}.overlay" @@ -419,7 +419,7 @@ tests: - ek_ra8p1/r7ka8p1kflcac/cm85 platform_allow: - ek_ra8p1/r7ka8p1kflcac/cm85 - - mck_ra8t2/r7ka8t2lfecac/cm85 + - mck_ra8t2/r7ka8t2lflcac/cm85 extra_configs: - CONFIG_SPI_ASYNC=n extra_args: diff --git a/tests/drivers/uart/uart_async_api/boards/mck_ra8t2_r7ka8t2lfecac_cm85.overlay b/tests/drivers/uart/uart_async_api/boards/mck_ra8t2_r7ka8t2lflcac_cm85.overlay similarity index 100% rename from tests/drivers/uart/uart_async_api/boards/mck_ra8t2_r7ka8t2lfecac_cm85.overlay rename to tests/drivers/uart/uart_async_api/boards/mck_ra8t2_r7ka8t2lflcac_cm85.overlay diff --git a/tests/subsys/canbus/isotp/conformance/boards/mck_ra8t2_r7ka8t2lfecac_cm85.overlay b/tests/subsys/canbus/isotp/conformance/boards/mck_ra8t2_r7ka8t2lflcac_cm85.overlay similarity index 100% rename from tests/subsys/canbus/isotp/conformance/boards/mck_ra8t2_r7ka8t2lfecac_cm85.overlay rename to tests/subsys/canbus/isotp/conformance/boards/mck_ra8t2_r7ka8t2lflcac_cm85.overlay diff --git a/tests/subsys/canbus/isotp/implementation/boards/mck_ra8t2_r7ka8t2lfecac_cm85.overlay b/tests/subsys/canbus/isotp/implementation/boards/mck_ra8t2_r7ka8t2lflcac_cm85.overlay similarity index 100% rename from tests/subsys/canbus/isotp/implementation/boards/mck_ra8t2_r7ka8t2lfecac_cm85.overlay rename to tests/subsys/canbus/isotp/implementation/boards/mck_ra8t2_r7ka8t2lflcac_cm85.overlay diff --git a/tests/subsys/fs/ext2/testcase.yaml b/tests/subsys/fs/ext2/testcase.yaml index 815ef4c424ed..d86efee51732 100644 --- a/tests/subsys/fs/ext2/testcase.yaml +++ b/tests/subsys/fs/ext2/testcase.yaml @@ -32,7 +32,7 @@ tests: - ek_ra8m1 - ek_ra8d1 - ek_ra8p1/r7ka8p1kflcac/cm85 - - mck_ra8t2/r7ka8t2lfecac/cm85 + - mck_ra8t2/r7ka8t2lflcac/cm85 - ek_ra8p1/r7ka8p1kflcac/cm33 - ek_ra8d2/r7ka8d2kflcac/cm85 - ek_ra8m2/r7ka8m2jflcac/cm85 @@ -50,7 +50,7 @@ tests: - platform:ek_ra8d2/r7ka8d2kflcac/cm85:CONFIG_EXT2_DISK_STARTING_SECTOR=0 - platform:ek_ra8m2/r7ka8m2jflcac/cm85:CONFIG_EXT2_DISK_STARTING_SECTOR=0 - platform:mck_ra8t1/r7fa8t1ahecbd:CONFIG_EXT2_DISK_STARTING_SECTOR=0 - - platform:mck_ra8t2/r7ka8t2lfecac/cm85:CONFIG_EXT2_DISK_STARTING_SECTOR=0 + - platform:mck_ra8t2/r7ka8t2lflcac/cm85:CONFIG_EXT2_DISK_STARTING_SECTOR=0 filesystem.ext2.flash: platform_allow: diff --git a/tests/subsys/fs/fat_fs_api/boards/mck_ra8t2_r7ka8t2lfecac_cm85.conf b/tests/subsys/fs/fat_fs_api/boards/mck_ra8t2_r7ka8t2lflcac_cm85.conf similarity index 100% rename from tests/subsys/fs/fat_fs_api/boards/mck_ra8t2_r7ka8t2lfecac_cm85.conf rename to tests/subsys/fs/fat_fs_api/boards/mck_ra8t2_r7ka8t2lflcac_cm85.conf diff --git a/tests/subsys/pm/power_mgmt_soc/testcase.yaml b/tests/subsys/pm/power_mgmt_soc/testcase.yaml index 7e0bc1dc345b..f5b87c53291b 100644 --- a/tests/subsys/pm/power_mgmt_soc/testcase.yaml +++ b/tests/subsys/pm/power_mgmt_soc/testcase.yaml @@ -26,7 +26,7 @@ tests: - ek_ra8d1 - mck_ra8t1 - ek_ra8p1/r7ka8p1kflcac/cm85 - - mck_ra8t2/r7ka8t2lfecac/cm85 + - mck_ra8t2/r7ka8t2lflcac/cm85 - ek_ra8d2/r7ka8d2kflcac/cm85 - ek_ra8m2/r7ka8m2jflcac/cm85 - frdm_mcxn236 From 71389b3dd535567dd2f11102609a8a28d1c24ab0 Mon Sep 17 00:00:00 2001 From: Khai Cao Date: Tue, 13 Jan 2026 06:37:01 +0000 Subject: [PATCH 0008/6328] doc: releases: document ek_ra8t2/r7ka8t2lfecac rename Document the board rename from ek_ra8t2/r7ka8t2lfecac/cm85 to ek_ra8t2/r7ka8t2lflcac/cm85 in the Zephyr v4.4.0 migration guide. Signed-off-by: Khai Cao --- doc/releases/migration-guide-4.4.rst | 2 ++ 1 file changed, 2 insertions(+) diff --git a/doc/releases/migration-guide-4.4.rst b/doc/releases/migration-guide-4.4.rst index 11498e15a83c..bc576bc5d726 100644 --- a/doc/releases/migration-guide-4.4.rst +++ b/doc/releases/migration-guide-4.4.rst @@ -46,6 +46,8 @@ Boards in the respective board CMakeLists.txt files. Applications that depended on these definitions being globally available may need to be updated. (:github:`101322`) +* Renesas ``ek_ra8t2/r7ka8t2lfecac/cm85`` is renamed to ``ek_ra8t2/r7ka8t2lflcac/cm85``. + * NXP has changed the scope of some in-tree compile flags to limit their visibility to only where they are needed. Out-of-tree applications or boards that depended on these flags being globally available may need to add them to their own CMakeLists.txt files to ensure they continue to build From 917404f5d7a069a6086d734d19519199822b4abd Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Tue, 13 Jan 2026 16:41:40 +0000 Subject: [PATCH 0009/6328] mgmt: mcumgr: transport: uart: Change Kconfig to depends on Changes CONFIG_MCUMGR_TRANSPORT_UART from selecting CONFIG_UART_MCUMGR to instead of depending upon it, as it should never have selected a driver Kconfig and instead always depended upon it, and is needed for supporting different UART transports Signed-off-by: Jamie McCrae --- samples/subsys/mgmt/mcumgr/smp_svr/cdc.conf | 1 + samples/subsys/mgmt/mcumgr/smp_svr/serial.conf | 1 + subsys/mgmt/mcumgr/transport/Kconfig.uart | 2 +- tests/subsys/mgmt/mcumgr/all_options/other-options.conf | 1 + 4 files changed, 4 insertions(+), 1 deletion(-) diff --git a/samples/subsys/mgmt/mcumgr/smp_svr/cdc.conf b/samples/subsys/mgmt/mcumgr/smp_svr/cdc.conf index 436ff459dcc4..3110440fc0b4 100644 --- a/samples/subsys/mgmt/mcumgr/smp_svr/cdc.conf +++ b/samples/subsys/mgmt/mcumgr/smp_svr/cdc.conf @@ -2,6 +2,7 @@ CONFIG_SERIAL=y CONFIG_UART_LINE_CTRL=y CONFIG_CONSOLE=y +CONFIG_UART_MCUMGR=y CONFIG_USB_DEVICE_STACK_NEXT=y CONFIG_CDC_ACM_SERIAL_INITIALIZE_AT_BOOT=y # USB backend is serial device diff --git a/samples/subsys/mgmt/mcumgr/smp_svr/serial.conf b/samples/subsys/mgmt/mcumgr/smp_svr/serial.conf index 47d4e8d0b853..0800da1ff366 100644 --- a/samples/subsys/mgmt/mcumgr/smp_svr/serial.conf +++ b/samples/subsys/mgmt/mcumgr/smp_svr/serial.conf @@ -1,5 +1,6 @@ # Enable the serial MCUmgr transport. CONFIG_BASE64=y CONFIG_CRC=y +CONFIG_UART_MCUMGR=y CONFIG_MCUMGR_TRANSPORT_UART=y CONFIG_CONSOLE=y diff --git a/subsys/mgmt/mcumgr/transport/Kconfig.uart b/subsys/mgmt/mcumgr/transport/Kconfig.uart index 096819b0c20e..32c65c5a5ca7 100644 --- a/subsys/mgmt/mcumgr/transport/Kconfig.uart +++ b/subsys/mgmt/mcumgr/transport/Kconfig.uart @@ -14,7 +14,7 @@ menuconfig MCUMGR_TRANSPORT_UART depends on CONSOLE depends on BASE64 depends on CRC - select UART_MCUMGR + depends on UART_MCUMGR help Enables handling of SMP commands received over UART. This is a lightweight alternative to MCUMGR_TRANSPORT_SHELL. It allows MCUmgr commands to be received over UART without diff --git a/tests/subsys/mgmt/mcumgr/all_options/other-options.conf b/tests/subsys/mgmt/mcumgr/all_options/other-options.conf index 01a9979b2cbc..74ce1790e678 100644 --- a/tests/subsys/mgmt/mcumgr/all_options/other-options.conf +++ b/tests/subsys/mgmt/mcumgr/all_options/other-options.conf @@ -15,6 +15,7 @@ CONFIG_MCUMGR_GRP_OS_INFO_BUILD_DATE_TIME=y CONFIG_MCUMGR_GRP_SHELL_LEGACY_RC_RETURN_CODE=y CONFIG_MCUMGR_GRP_SETTINGS_BUFFER_TYPE_HEAP=y CONFIG_COMMON_LIBC_MALLOC_ARENA_SIZE=2048 +CONFIG_UART_MCUMGR=y CONFIG_MCUMGR_TRANSPORT_SHELL=n CONFIG_MCUMGR_TRANSPORT_UART=y CONFIG_MCUMGR_TRANSPORT_SHELL_INPUT_TIMEOUT=n From b0467a0313521b310326f25109ea685a7bb74140 Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Wed, 14 Jan 2026 10:35:38 +0000 Subject: [PATCH 0010/6328] doc: release: migration_guide: 4.4: Add MCUmgr change Adds a note on a required change for MCUmgr if using the UART transport Signed-off-by: Jamie McCrae --- doc/releases/migration-guide-4.4.rst | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/doc/releases/migration-guide-4.4.rst b/doc/releases/migration-guide-4.4.rst index bc576bc5d726..bfd40de5598a 100644 --- a/doc/releases/migration-guide-4.4.rst +++ b/doc/releases/migration-guide-4.4.rst @@ -755,6 +755,15 @@ Libsbc * Libsbc (sbc.c and sbc.h) is moved under the Bluetooth subsystem. The sbc.h is in include/zephyr/bluetooth now. +Management +========== + +* MCUmgr + + * If using :kconfig:option:`CONFIG_MCUMGR_TRANSPORT_UART` then + :kconfig:option:`CONFIG_UART_MCUMGR` must now also be selected, this has changed to be + ``depends on`` rather than ``select``. + Tracing ======== From 4edfd97621241b9ba4f8eead5f913c1d2129db62 Mon Sep 17 00:00:00 2001 From: Jiafei Pan Date: Thu, 15 Jan 2026 18:25:25 +0800 Subject: [PATCH 0011/6328] dts: arm64: mimx943; add MSI device ID for ENET3 port ENET3 port is internal port for switch, add MSI device ID to enable interrupt for it. Signed-off-by: Jiafei Pan --- dts/arm64/nxp/nxp_mimx943_a55.dtsi | 1 + 1 file changed, 1 insertion(+) diff --git a/dts/arm64/nxp/nxp_mimx943_a55.dtsi b/dts/arm64/nxp/nxp_mimx943_a55.dtsi index 72a9e103bef8..e67eb8c106e4 100644 --- a/dts/arm64/nxp/nxp_mimx943_a55.dtsi +++ b/dts/arm64/nxp/nxp_mimx943_a55.dtsi @@ -526,6 +526,7 @@ reg = <0x4cd40000 0x40000>, <0x4ca00000 0x1000>; reg-names = "port", "pfconfig"; + msi-device-id = <0x68>; mac-index = <3>; si-index = <3>; phy-connection-type = "internal"; From b1946cba2a06f93a5cbd8360d680ce6f4ca838e8 Mon Sep 17 00:00:00 2001 From: Jiafei Pan Date: Thu, 15 Jan 2026 18:23:16 +0800 Subject: [PATCH 0012/6328] boards: imx943_evk: use 100M PHY for net switch port Currently the PHY for 2.5G SGMII is not enabled, so could only use 100M PHY for two switch ports on the board. Signed-off-by: Jiafei Pan --- boards/nxp/imx943_evk/doc/index.rst | 4 ++++ boards/nxp/imx943_evk/imx943_evk_mimx94398_a55.dts | 4 ++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/boards/nxp/imx943_evk/doc/index.rst b/boards/nxp/imx943_evk/doc/index.rst index 1f76384616ec..c7e44253915d 100644 --- a/boards/nxp/imx943_evk/doc/index.rst +++ b/boards/nxp/imx943_evk/doc/index.rst @@ -73,6 +73,10 @@ For A55 Core, ENET0, ENETC1, ENETC2 ports are enabled by default, so no overlay needed, but NETC depends on GIC ITS, so need to make sure to allocate heap memory to be larger than 851968 byes by setting CONFIG_HEAP_MEM_POOL_SIZE. +On the EVK board, switch port0 and port2 are connected to both SGMII port (SGMII-swp0 +and SGMII-swp1) and 100M port (swp0 and swp1), currently only 100M port (swp0 and swp1) +is enabled, so could connect to 100M port for verify two switch ports. + The two switch ports could be verified via :zephyr:code-sample:`dsa` on M33 core or on A55 Core, for example for A55 Core: diff --git a/boards/nxp/imx943_evk/imx943_evk_mimx94398_a55.dts b/boards/nxp/imx943_evk/imx943_evk_mimx94398_a55.dts index 31a696846253..c76b046ded5d 100644 --- a/boards/nxp/imx943_evk/imx943_evk_mimx94398_a55.dts +++ b/boards/nxp/imx943_evk/imx943_evk_mimx94398_a55.dts @@ -57,13 +57,13 @@ phy0: phy@2 { compatible = "ethernet-phy"; - reg = <0xf>; + reg = <0x2>; status = "disabled"; }; phy1: phy@3 { compatible = "ethernet-phy"; - reg = <0x10>; + reg = <0x3>; status = "disabled"; }; From 1a12292846613e7742efb6d890696f0ac355979a Mon Sep 17 00:00:00 2001 From: Gaetan Perrot Date: Thu, 15 Jan 2026 22:30:58 +0900 Subject: [PATCH 0013/6328] tests: drivers: flash: negative_tests: fix write/fill alignment tests The negative flash write and fill tests assumed that unaligned offsets are always invalid. This is not true for flash drivers reporting a write_block_size of 1, where all offsets and sizes are naturally aligned. Condition the unaligned offset and size tests on the actual write_block_size reported by the driver to avoid false failures and ensure the tests follow the flash API contract. No functional change for drivers with write_block_size > 1. Signed-off-by: Gaetan Perrot --- tests/drivers/flash/negative_tests/src/main.c | 58 +++++++++++++++---- 1 file changed, 48 insertions(+), 10 deletions(-) diff --git a/tests/drivers/flash/negative_tests/src/main.c b/tests/drivers/flash/negative_tests/src/main.c index fa3723b52312..a07dff5c6a60 100644 --- a/tests/drivers/flash/negative_tests/src/main.c +++ b/tests/drivers/flash/negative_tests/src/main.c @@ -133,17 +133,37 @@ ZTEST(flash_driver_negative, test_negative_flash_fill) rc = flash_fill(flash_dev, fill_val, (TEST_FLASH_START + TEST_FLASH_SIZE), page_info.size); zassert_true(rc < 0, "Invalid use of flash_fill returned %d", rc); - /* Check error returned when filling unaligned memory */ - rc = flash_fill(flash_dev, fill_val, (TEST_AREA_OFFSET + 1), page_info.size); - zassert_true(rc < 0, "Invalid use of flash_fill returned %d", rc); - rc = flash_fill(flash_dev, fill_val, TEST_AREA_OFFSET, (page_info.size + 1)); - zassert_true(rc < 0, "Invalid use of flash_fill returned %d", rc); - /* Filling 0 bytes shall succeed */ rc = flash_fill(flash_dev, fill_val, TEST_AREA_OFFSET, 0); zassert_true(rc == 0, "flash_fill 0 bytes returned %d", rc); } +ZTEST(flash_driver_negative, test_negative_flash_fill_unaligned) +{ + int rc; + uint8_t fill_val = 0xA; /* Dummy value */ + size_t write_block_size; + +#if !defined(TEST_AREA) + /* Flash memory boundaries are correctly calculated + * only for storage_partition. + */ + ztest_test_skip(); +#endif + + write_block_size = flash_get_write_block_size(flash_dev); + + if (write_block_size <= 1) { + ztest_test_skip(); + } + /* Check error returned when filling unaligned memory */ + rc = flash_fill(flash_dev, fill_val, TEST_AREA_OFFSET + 1, page_info.size); + zassert_true(rc < 0, "Invalid use of flash_fill returned %d", rc); + + rc = flash_fill(flash_dev, fill_val, TEST_AREA_OFFSET, page_info.size + 1); + zassert_true(rc < 0, "Invalid use of flash_fill returned %d", rc); +} + ZTEST(flash_driver_negative, test_negative_flash_flatten) { int rc; @@ -234,10 +254,6 @@ ZTEST(flash_driver_negative, test_negative_flash_write) rc = flash_write(flash_dev, (TEST_FLASH_START + TEST_FLASH_SIZE), expected, page_info.size); zassert_true(rc < 0, "Invalid use of flash_write returned %d", rc); - /* Check error returned when writing at unaligned memory */ - rc = flash_write(flash_dev, (TEST_AREA_OFFSET + 1), expected, page_info.size); - zassert_true(rc < 0, "Invalid use of flash_write returned %d", rc); - /* Check error returned when writing too large chunk of memory */ rc = flash_write(flash_dev, TEST_AREA_OFFSET, expected, (TEST_FLASH_SIZE + 1)); zassert_true(rc < 0, "Invalid use of flash_write returned %d", rc); @@ -247,4 +263,26 @@ ZTEST(flash_driver_negative, test_negative_flash_write) zassert_true(rc == 0, "flash_write 0 bytes returned %d", rc); } +ZTEST(flash_driver_negative, test_negative_flash_write_unaligned) +{ + int rc; + size_t write_block_size; + +#if !defined(TEST_AREA) + /* Flash memory boundaries are correctly calculated + * only for storage_partition. + */ + ztest_test_skip(); +#endif + + write_block_size = flash_get_write_block_size(flash_dev); + + if (write_block_size <= 1) { + ztest_test_skip(); + } + /* Check error returned when writing at unaligned memory */ + rc = flash_write(flash_dev, (TEST_AREA_OFFSET + 1), expected, page_info.size); + zassert_true(rc < 0, "Invalid use of flash_write returned %d", rc); +} + ZTEST_SUITE(flash_driver_negative, NULL, flash_driver_setup, NULL, NULL, NULL); From fd8188a408240090498bac31597148f41cdc160e Mon Sep 17 00:00:00 2001 From: Adrian Warecki Date: Thu, 15 Jan 2026 16:53:44 +0100 Subject: [PATCH 0014/6328] xtensa: Remove saving EXCCAUSE in BSA from _Level1Vector Remove saving EXCCAUSE register in BSA through the _Level1Vector handler. These value are later overwritten by the ODD_REG_SAVE macro called by EXCINT_HANDLER, so saving it here is pointless. Signed-off-by: Adrian Warecki --- arch/xtensa/include/xtensa_asm2.inc.S | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/arch/xtensa/include/xtensa_asm2.inc.S b/arch/xtensa/include/xtensa_asm2.inc.S index 9d8ce2bf7b8a..6a173eb0edab 100644 --- a/arch/xtensa/include/xtensa_asm2.inc.S +++ b/arch/xtensa/include/xtensa_asm2.inc.S @@ -726,13 +726,10 @@ _not_triple_fault: s32i a2, a1, ___xtensa_irq_bsa_t_a2_OFFSET s32i a3, a1, ___xtensa_irq_bsa_t_a3_OFFSET - /* Save registers needed for handling the exception as - * these registers can be overwritten during nested + /* Save register needed for handling the exception as + * this register can be overwritten during nested * exceptions. */ - rsr.exccause a0 - s32i a0, a1, ___xtensa_irq_bsa_t_exccause_OFFSET - rsr.excvaddr a0 s32i a0, a1, ___xtensa_irq_bsa_t_excvaddr_OFFSET From c1a2b3be459d4f34d31ae54774fd57e96438d237 Mon Sep 17 00:00:00 2001 From: Adrian Warecki Date: Thu, 15 Jan 2026 16:50:25 +0100 Subject: [PATCH 0015/6328] xtensa: Restore the EXCCAUSE register when returning from Double Exception Preserve EXCCAUSE and EXCVADDR values on entry to _Level1Vector. Restore EXCCAUSE when exiting TLB miss exception handling in the double exception handler. During first-level exception handling, a LoadStoreTLBMissException may occur during the initial register dump to BSA. It modifies EXCCAUSE and EXCVADDR registers before they are saved in BSA. Therefore, these values must be captured as early as possible. Signed-off-by: Adrian Warecki --- arch/xtensa/core/gen_zsr.py | 2 +- arch/xtensa/core/xtensa_asm2_util.S | 4 +++ arch/xtensa/include/xtensa_asm2.inc.S | 35 ++++++++++++++++++++++----- 3 files changed, 34 insertions(+), 7 deletions(-) diff --git a/arch/xtensa/core/gen_zsr.py b/arch/xtensa/core/gen_zsr.py index cc2f243d3468..69537d08f1ee 100755 --- a/arch/xtensa/core/gen_zsr.py +++ b/arch/xtensa/core/gen_zsr.py @@ -36,7 +36,7 @@ def parse_args(): NEEDED = ["A0SAVE", "CPU"] if args.mmu: - NEEDED += ["DBLEXC", "DEPC_SAVE"] + NEEDED += ["DBLEXC", "DEPC_SAVE", "EXCCAUSE_SAVE"] if args.flush_reg: NEEDED += ["FLUSH"] diff --git a/arch/xtensa/core/xtensa_asm2_util.S b/arch/xtensa/core/xtensa_asm2_util.S index 24893db692dc..00e7b1bcd3fd 100644 --- a/arch/xtensa/core/xtensa_asm2_util.S +++ b/arch/xtensa/core/xtensa_asm2_util.S @@ -580,6 +580,10 @@ _handle_tlb_miss_dblexc: rsr.ptevaddr a0 l32i a0, a0, 0 + /* Restore EXCCAUSE and a0 values */ + rsr a0, ZSR_EXCCAUSE_SAVE + wsr.exccause a0 + rsr a0, ZSR_DBLEXC rfde #endif diff --git a/arch/xtensa/include/xtensa_asm2.inc.S b/arch/xtensa/include/xtensa_asm2.inc.S index 6a173eb0edab..89582d1abb88 100644 --- a/arch/xtensa/include/xtensa_asm2.inc.S +++ b/arch/xtensa/include/xtensa_asm2.inc.S @@ -677,17 +677,20 @@ _Level\LVL\()Vector: .if \LVL == 1 /* If there are any TLB misses during interrupt handling, * the user/kernel/double exception vector will be triggered - * to handle these misses. This results in DEPC and EXCCAUSE - * being overwritten, and then execution returned back to - * this site of TLB misses. When it gets to the C handler, - * it will not see the original cause. So stash - * the EXCCAUSE here so C handler can see the original cause. + * to handle these misses. This results in DEPC, EXCCAUSE + * and EXCVADDR being overwritten, and then execution returned + * back to this site of TLB misses. When it gets to the C handler, + * it will not see the original cause. So stash the EXCCAUSE + * and EXCVADDR here so C handler can see the original cause. * * For double exception, DEPC in saved in earlier vector * code. */ wsr a0, ZSR_A0SAVE + rsr.exccause a0 + wsr a0, ZSR_EXCCAUSE_SAVE + esync rsr a0, ZSR_DEPC_SAVE @@ -717,21 +720,41 @@ _Level\LVL\()Vector: j _TripleFault _not_triple_fault: - rsr a0, ZSR_A0SAVE .endif #endif addi a1, a1, -___xtensa_irq_bsa_t_SIZEOF + +#ifdef CONFIG_XTENSA_MMU +.if \LVL == 1 + /* Save EXCVADDR register needed for handling the exception + * as this register can be overwritten during nested + * exceptions. It has to be saved first, because + * executing the store instruction may trigger a + * TLB miss, which will modify its value. + */ + rsr.excvaddr a0 + s32i a0, a1, ___xtensa_irq_bsa_t_excvaddr_OFFSET + rsr a0, ZSR_A0SAVE +.endif +#endif + s32i a0, a1, ___xtensa_irq_bsa_t_a0_OFFSET s32i a2, a1, ___xtensa_irq_bsa_t_a2_OFFSET s32i a3, a1, ___xtensa_irq_bsa_t_a3_OFFSET +#ifdef CONFIG_XTENSA_MMU +.if \LVL != 1 +#endif /* Save register needed for handling the exception as * this register can be overwritten during nested * exceptions. */ rsr.excvaddr a0 s32i a0, a1, ___xtensa_irq_bsa_t_excvaddr_OFFSET +#ifdef CONFIG_XTENSA_MMU +.endif +#endif /* Level "1" is the exception handler, which uses a different * calling convention. No special register holds the From 0cafc3e4f69cc7199ce2c5553b0f3398695c1244 Mon Sep 17 00:00:00 2001 From: Hui Bai Date: Fri, 16 Jan 2026 14:34:20 +0800 Subject: [PATCH 0016/6328] modules: hostap: Add new APIs to set operating mode for SoftAP Add new APIs to set operating mode 11n, 11ac and 11ax for SoftAP. Currently, the 11n, 11ac and 11ax are enabled by default. Theses APIs can be used to configure operating modes enable/disable for SoftAP. Signed-off-by: Hui Bai --- modules/hostap/src/hapd_api.c | 97 +++++++++++++++++++++++++++++++++++ modules/hostap/src/hapd_api.h | 31 +++++++++++ 2 files changed, 128 insertions(+) diff --git a/modules/hostap/src/hapd_api.c b/modules/hostap/src/hapd_api.c index 699a151e4eb4..3a12826afc3c 100644 --- a/modules/hostap/src/hapd_api.c +++ b/modules/hostap/src/hapd_api.c @@ -785,6 +785,103 @@ int hostapd_ap_status(const struct device *dev, struct wifi_iface_status *status return ret; } +int hostapd_11n_cfg(const struct device *dev, uint8_t enable) +{ + int ret = 0; + struct hostapd_iface *iface; + + k_mutex_lock(&hostapd_mutex, K_FOREVER); + + iface = get_hostapd_handle(dev); + if (!iface) { + wpa_printf(MSG_ERROR, "Interface %s not found", dev->name); + ret = -ENODEV; + goto out; + } + + if (iface->state == HAPD_IFACE_ENABLED) { + wpa_printf(MSG_ERROR, "Interface %s is operational and in SAP mode", dev->name); + ret = -EACCES; + goto out; + } + + if (!hostapd_cli_cmd_v("set ieee80211n %d", enable)) { + wpa_printf(MSG_ERROR, "Failed to set ieee80211n"); + ret = -EINVAL; + goto out; + } + +out: + k_mutex_unlock(&hostapd_mutex); + return ret; +} + +#if CONFIG_WIFI_NM_WPA_SUPPLICANT_11AC +int hostapd_11ac_cfg(const struct device *dev, uint8_t enable) +{ + int ret = 0; + struct hostapd_iface *iface; + + k_mutex_lock(&hostapd_mutex, K_FOREVER); + + iface = get_hostapd_handle(dev); + if (!iface) { + wpa_printf(MSG_ERROR, "Interface %s not found", dev->name); + ret = -ENODEV; + goto out; + } + + if (iface->state == HAPD_IFACE_ENABLED) { + wpa_printf(MSG_ERROR, "Interface %s is operational and in SAP mode", dev->name); + ret = -EACCES; + goto out; + } + + if (!hostapd_cli_cmd_v("set ieee80211ac %d", enable)) { + wpa_printf(MSG_ERROR, "Failed to set ieee80211ac"); + ret = -EINVAL; + goto out; + } + +out: + k_mutex_unlock(&hostapd_mutex); + return ret; +} +#endif + +#if CONFIG_WIFI_NM_WPA_SUPPLICANT_11AX +int hostapd_11ax_cfg(const struct device *dev, uint8_t enable) +{ + int ret = 0; + struct hostapd_iface *iface; + + k_mutex_lock(&hostapd_mutex, K_FOREVER); + + iface = get_hostapd_handle(dev); + if (!iface) { + wpa_printf(MSG_ERROR, "Interface %s not found", dev->name); + ret = -ENODEV; + goto out; + } + + if (iface->state == HAPD_IFACE_ENABLED) { + wpa_printf(MSG_ERROR, "Interface %s is operational and in SAP mode", dev->name); + ret = -EACCES; + goto out; + } + + if (!hostapd_cli_cmd_v("set ieee80211ax %d", enable)) { + wpa_printf(MSG_ERROR, "Failed to set ieee80211ax"); + ret = -EINVAL; + goto out; + } + +out: + k_mutex_unlock(&hostapd_mutex); + return ret; +} +#endif + #ifdef CONFIG_WIFI_NM_HOSTAPD_WPS static int hapd_ap_wps_pbc(const struct device *dev) { diff --git a/modules/hostap/src/hapd_api.h b/modules/hostap/src/hapd_api.h index aa95a5582320..7f09d602579c 100644 --- a/modules/hostap/src/hapd_api.h +++ b/modules/hostap/src/hapd_api.h @@ -90,4 +90,35 @@ int hostapd_dpp_dispatch(const struct device *dev, struct wifi_dpp_params *param #endif /* CONFIG_WIFI_NM_HOSTAPD_AP */ #endif /* CONFIG_WIFI_NM_WPA_SUPPLICANT_DPP */ +/** + * @brief Enable or disable 11N for AP + * + * @param dev Wi-Fi interface name to use + * @param enable Enable or disable + * @return 0 for OK; -1 for ERROR + */ +int hostapd_11n_cfg(const struct device *dev, uint8_t enable); + +#if CONFIG_WIFI_NM_WPA_SUPPLICANT_11AC +/** + * @brief Enable or disable 11AC for AP + * + * @param dev Wi-Fi interface name to use + * @param enable Enable or disable + * @return 0 for OK; -1 for ERROR + */ +int hostapd_11ac_cfg(const struct device *dev, uint8_t enable); +#endif + +#if CONFIG_WIFI_NM_WPA_SUPPLICANT_11AX +/** + * @brief Enable or disable 11AX for AP + * + * @param dev Wi-Fi interface name to use + * @param enable Enable or disable + * @return 0 for OK; -1 for ERROR + */ +int hostapd_11ax_cfg(const struct device *dev, uint8_t enable); +#endif + #endif /* __HAPD_API_H_ */ From bdcb5c6b4b9a319a6165219e8acf96cd2865c09f Mon Sep 17 00:00:00 2001 From: Waqar Tahir Date: Fri, 16 Jan 2026 12:25:02 +0100 Subject: [PATCH 0017/6328] boards: nxp: mcxn947: updated partitions - Updated partitions in non-secure device tree files as tfm now supports Bl2. - Flash_base address updated for ns-app as tfm apps are now using bl2 by default. Signed-off-by: Waqar Tahir --- .../frdm_mcxn947_mcxn947_cpu0_ns.dts | 55 +++++++++++++++++-- .../frdm_mcxn947_mcxn947_cpu0_ns_defconfig | 6 +- 2 files changed, 54 insertions(+), 7 deletions(-) diff --git a/boards/nxp/frdm_mcxn947/frdm_mcxn947_mcxn947_cpu0_ns.dts b/boards/nxp/frdm_mcxn947/frdm_mcxn947_mcxn947_cpu0_ns.dts index 71cb3a93dc9c..7e4ac87cb46a 100644 --- a/boards/nxp/frdm_mcxn947/frdm_mcxn947_mcxn947_cpu0_ns.dts +++ b/boards/nxp/frdm_mcxn947/frdm_mcxn947_mcxn947_cpu0_ns.dts @@ -56,12 +56,59 @@ #size-cells = <1>; /* - * Partition sizes must be aligned - * to the flash memory sector size of 8KB. + * All partition sizes must be aligned to the flash memory sector size (8 KB). + * + * This flash layout must exactly match the upstream TF-M layout defined in + * the platform-specific `flash_layout.h`. Any modification to the layout + * must be applied consistently in both `flash_layout.h` and this file. + * + * BL2 / MCUBoot */ - slot0_ns_partition: partition@80000 { + boot_partition: partition@0 { + label = "mcuboot"; + reg = <0x00000000 DT_SIZE_K(64)>; /* 64 KB */ + }; + + /* Secure image - primary */ + slot0_partition: partition@10000 { + label = "image-0"; + reg = <0x00010000 DT_SIZE_K(288)>; /* 288 KB */ + }; + + /* Non-secure image - primary */ + slot0_ns_partition: partition@58000 { label = "image-0-nonsecure"; - reg = <0x00080000 DT_SIZE_K(512)>; + reg = <0x00058000 DT_SIZE_K(256)>; /* 256 KB */ + }; + + /* Secure image - secondary */ + slot1_partition: partition@98000 { + label = "image-1-secondary"; + reg = <0x00098000 DT_SIZE_K(288)>; /* 288 KB */ + }; + + /* Non-secure image - secondary */ + slot1_ns_partition: partition@E0000 { + label = "image-1-non-secure"; + reg = <0x000E0000 DT_SIZE_K(256)>; /* 256 KB */ + }; + + /* Protected Storage (PS) */ + tfm_ps_partition: partition@120000 { + label = "tfm-ps"; + reg = <0x00120000 DT_SIZE_K(16)>; /* 16 KB */ + }; + + /* Internal Trusted Storage (ITS) */ + tfm_its_partition: partition@124000 { + label = "tfm-its"; + reg = <0x00124000 DT_SIZE_K(16)>; /* 16 KB */ + }; + + /* OTP / NV counters */ + tfm_otp_partition: partition@128000 { + label = "tfm-otp"; + reg = <0x00128000 DT_SIZE_K(8)>; /* 8 KB */ }; }; }; diff --git a/boards/nxp/frdm_mcxn947/frdm_mcxn947_mcxn947_cpu0_ns_defconfig b/boards/nxp/frdm_mcxn947/frdm_mcxn947_mcxn947_cpu0_ns_defconfig index 9f421c6b50bb..66adee8f206b 100644 --- a/boards/nxp/frdm_mcxn947/frdm_mcxn947_mcxn947_cpu0_ns_defconfig +++ b/boards/nxp/frdm_mcxn947/frdm_mcxn947_mcxn947_cpu0_ns_defconfig @@ -1,5 +1,5 @@ # -# Copyright 2025 NXP +# Copyright 2025-2026 NXP # # SPDX-License-Identifier: Apache-2.0 # @@ -14,6 +14,6 @@ CONFIG_ARM_MPU=y CONFIG_HW_STACK_PROTECTION=y CONFIG_TRUSTED_EXECUTION_NONSECURE=y -CONFIG_TFM_BL2=n +CONFIG_TFM_BL2=y CONFIG_BUILD_WITH_TFM=y -CONFIG_FLASH_BASE_ADDRESS=0x80000 +CONFIG_FLASH_BASE_ADDRESS=0x58000 From 07384efb72bd2e9f51d4ffa8f65cc2d0fb013ca5 Mon Sep 17 00:00:00 2001 From: Waqar Tahir Date: Sun, 18 Jan 2026 22:25:31 +0100 Subject: [PATCH 0018/6328] samples: tfm_ipc: update mcxn947 board support As the board now supports TF-M with bl2, spport from sample.tfm_ipc.no_bl2 is removed and added in sample.tfm_ipc test. Signed-off-by: Waqar Tahir --- samples/tfm_integration/tfm_ipc/sample.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/samples/tfm_integration/tfm_ipc/sample.yaml b/samples/tfm_integration/tfm_ipc/sample.yaml index b049f7a82a16..a2f26c2bca30 100644 --- a/samples/tfm_integration/tfm_ipc/sample.yaml +++ b/samples/tfm_integration/tfm_ipc/sample.yaml @@ -18,6 +18,7 @@ tests: - bl5340_dvk/nrf5340/cpuapp/ns - b_u585i_iot02a/stm32u585xx/ns - stm32h573i_dk/stm32h573xx/ns + - frdm_mcxn947/mcxn947/cpu0/ns integration_platforms: - mps2/an521/cpu0/ns harness: console @@ -37,7 +38,6 @@ tests: - nrf54l15dk/nrf54l15/cpuapp/ns - nrf54l15dk/nrf54l10/cpuapp/ns - nrf54lm20dk/nrf54lm20a/cpuapp/ns - - frdm_mcxn947/mcxn947/cpu0/ns extra_configs: - CONFIG_TFM_BL2=n harness: console From 8e7198392a2abb5e977f33a60dd91222080da2f7 Mon Sep 17 00:00:00 2001 From: Waqar Tahir Date: Fri, 16 Jan 2026 12:26:58 +0100 Subject: [PATCH 0019/6328] manifest: tf-m: BL2 support mcxn947 Updated TF-M repo for BL2 support in mcxn947 Signed-off-by: Waqar Tahir --- west.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/west.yml b/west.yml index a51f8cf3962b..55b322fa978b 100644 --- a/west.yml +++ b/west.yml @@ -386,7 +386,7 @@ manifest: groups: - tee - name: trusted-firmware-m - revision: 677e0565e030cbe4946ac0cbde5603eae7d6392f + revision: 6788687e013733d12f015b5d45b214019dea58f7 path: modules/tee/tf-m/trusted-firmware-m groups: - tee From 2c911b1b8a83a07b4396ff88209b14162d23c3f0 Mon Sep 17 00:00:00 2001 From: Daniel Leung Date: Tue, 13 Jan 2026 14:17:42 -0800 Subject: [PATCH 0020/6328] soc: snps: vpx5: no -Hccm compiler option for userspace With -Hccm, the linker automatically moves stuff in RODATA section into DATA section. Our current kobject related scripts cannot accommodate this, resulting in space not being reserved correctly. So for now, disable -Hccm compiler option if userspace is enabled. Signed-off-by: Daniel Leung --- soc/snps/nsim/arc_classic/vpx5/CMakeLists.txt | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/soc/snps/nsim/arc_classic/vpx5/CMakeLists.txt b/soc/snps/nsim/arc_classic/vpx5/CMakeLists.txt index 26f43b967936..240ca1209077 100644 --- a/soc/snps/nsim/arc_classic/vpx5/CMakeLists.txt +++ b/soc/snps/nsim/arc_classic/vpx5/CMakeLists.txt @@ -8,10 +8,21 @@ if(COMPILER STREQUAL gcc) else() # MWDT compiler options + # With -Hccm, the linker automatically moves stuff in RODATA + # section into DATA section. Our current kobject related + # scripts cannot accommodate this, resulting in space not + # being reserved correctly. So for now, disable -Hccm + # compiler option if userspace is enabled. + if(CONFIG_USERSPACE) + set(USE_CCM "") + else() + set(USE_CCM "-Hccm") + endif() + zephyr_compile_options_ifdef(CONFIG_SOC_NSIM_VPX5 -arcv2hs -core4 -uarch_rev=1:4 -Xcode_density -HL -Xatomic -Xll64 -Xunaligned -Xdiv_rem=radix4 -Xswap -Xbitscan -Xmpy_option=qmpyh -Xshift_assist -Xbarrel_shifter -Xtimer0 -Xtimer1 -Xrtc -dcache=32768,64,2,a - -Hld_cycles=1 -DDCCM_SYSTEM_BASE_CORE0=0x80000000 -Hccm + -Hld_cycles=1 -DDCCM_SYSTEM_BASE_CORE0=0x80000000 ${USE_CCM} -DICCM0_SYSTEM_BASE_CORE0=0x0000000 -Xstu=4 -Xvdsp4 -Xvec_unit_rev_minor=1 -Xvec_width=512 -Xvec_mem_size=256k -Xvec_mem_bank_width=16 -Xvec_max_fetch_size=16 -Xvec_num_slots=3 -Xvec_super_with_scalar -Xvec_regs=40 -Xvec_num_rd_ports=6 @@ -20,4 +31,6 @@ else() zephyr_ld_option_ifdef(CONFIG_SOC_NSIM_VPX5 -Hlib=vpx5_integer_full) + unset(USE_CCM) + endif() From ee8f9915a45692a46d25febac1b16dc4c3e179fe Mon Sep 17 00:00:00 2001 From: Daniel Leung Date: Wed, 7 Jan 2026 13:11:59 -0800 Subject: [PATCH 0021/6328] soc: arc: mark nsim_vpx5 as supporting MPU This selects CONFIG_CPU_HAS_MPU for nsim_vpx5 series SoC as it supports ARC MPUv3. Signed-off-by: Daniel Leung --- soc/snps/nsim/arc_classic/vpx5/Kconfig | 1 + soc/snps/nsim/arc_classic/vpx5/Kconfig.defconfig | 3 +++ 2 files changed, 4 insertions(+) diff --git a/soc/snps/nsim/arc_classic/vpx5/Kconfig b/soc/snps/nsim/arc_classic/vpx5/Kconfig index af6f944ab6ad..94579c6b573b 100644 --- a/soc/snps/nsim/arc_classic/vpx5/Kconfig +++ b/soc/snps/nsim/arc_classic/vpx5/Kconfig @@ -3,3 +3,4 @@ config SOC_SERIES_NSIM_VPX5 select ARC + select CPU_HAS_MPU diff --git a/soc/snps/nsim/arc_classic/vpx5/Kconfig.defconfig b/soc/snps/nsim/arc_classic/vpx5/Kconfig.defconfig index 24a2a38c4a05..ad41e14a0a89 100644 --- a/soc/snps/nsim/arc_classic/vpx5/Kconfig.defconfig +++ b/soc/snps/nsim/arc_classic/vpx5/Kconfig.defconfig @@ -30,4 +30,7 @@ config ARC_FIRQ config CACHE_MANAGEMENT default y +config ARC_MPU_VER + default 3 if ARC_MPU_ENABLE + endif # SOC_NSIM_VPX5 From 231e72af8ed0426d28cab8915e83188d7231974f Mon Sep 17 00:00:00 2001 From: Daniel Leung Date: Wed, 7 Jan 2026 13:13:34 -0800 Subject: [PATCH 0022/6328] boards: snps/arc: add nsim_vpx5/mpuv3 board This adds the nsim_vpx5/mpuv3 board for MPU. The files are based on nsim_vpx5 board files. Signed-off-by: Daniel Leung --- boards/snps/nsim/arc_classic/Kconfig.nsim | 1 + boards/snps/nsim/arc_classic/board.yml | 2 + .../nsim/arc_classic/nsim_nsim_vpx5_mpuv3.dts | 31 +++++ .../arc_classic/nsim_nsim_vpx5_mpuv3.yaml | 14 +++ .../nsim_nsim_vpx5_mpuv3_defconfig | 10 ++ .../arc_classic/support/mdb_vpx5_mpuv3.args | 98 ++++++++++++++++ .../arc_classic/support/nsim_vpx5_mpuv3.props | 107 ++++++++++++++++++ 7 files changed, 263 insertions(+) create mode 100644 boards/snps/nsim/arc_classic/nsim_nsim_vpx5_mpuv3.dts create mode 100644 boards/snps/nsim/arc_classic/nsim_nsim_vpx5_mpuv3.yaml create mode 100644 boards/snps/nsim/arc_classic/nsim_nsim_vpx5_mpuv3_defconfig create mode 100644 boards/snps/nsim/arc_classic/support/mdb_vpx5_mpuv3.args create mode 100644 boards/snps/nsim/arc_classic/support/nsim_vpx5_mpuv3.props diff --git a/boards/snps/nsim/arc_classic/Kconfig.nsim b/boards/snps/nsim/arc_classic/Kconfig.nsim index 33be7632e732..e0b5740b8dbf 100644 --- a/boards/snps/nsim/arc_classic/Kconfig.nsim +++ b/boards/snps/nsim/arc_classic/Kconfig.nsim @@ -22,3 +22,4 @@ config BOARD_NSIM select SOC_NSIM_SEM if BOARD_NSIM_NSIM_SEM select SOC_NSIM_SEM if BOARD_NSIM_NSIM_SEM_MPU_STACK_GUARD select SOC_NSIM_VPX5 if BOARD_NSIM_NSIM_VPX5 + select SOC_NSIM_VPX5 if BOARD_NSIM_NSIM_VPX5_MPUV3 diff --git a/boards/snps/nsim/arc_classic/board.yml b/boards/snps/nsim/arc_classic/board.yml index 20bbd3071ec5..905c83a244e4 100644 --- a/boards/snps/nsim/arc_classic/board.yml +++ b/boards/snps/nsim/arc_classic/board.yml @@ -27,3 +27,5 @@ board: variants: - name: mpu_stack_guard - name: nsim_vpx5 + variants: + - name: mpuv3 diff --git a/boards/snps/nsim/arc_classic/nsim_nsim_vpx5_mpuv3.dts b/boards/snps/nsim/arc_classic/nsim_nsim_vpx5_mpuv3.dts new file mode 100644 index 000000000000..291a136195d2 --- /dev/null +++ b/boards/snps/nsim/arc_classic/nsim_nsim_vpx5_mpuv3.dts @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2023, Synopsys, Inc. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; + +#define ICCM_SIZE DT_SIZE_K(256) +#define DCCM_SIZE DT_SIZE_K(256) +#define UART0_IRQ_NUM 23 + +#include "nsim.dtsi" +#include "nsim-ccm-mem.dtsi" +#include "nsim-uart-ns16550.dtsi" + +/ { + model = "snps,nsim_hs"; + compatible = "snps,nsim_hs"; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpu@0 { + device_type = "cpu"; + compatible = "snps,archs"; + reg = <0>; + }; + }; +}; diff --git a/boards/snps/nsim/arc_classic/nsim_nsim_vpx5_mpuv3.yaml b/boards/snps/nsim/arc_classic/nsim_nsim_vpx5_mpuv3.yaml new file mode 100644 index 000000000000..e1564aff63c6 --- /dev/null +++ b/boards/snps/nsim/arc_classic/nsim_nsim_vpx5_mpuv3.yaml @@ -0,0 +1,14 @@ +identifier: nsim/nsim_vpx5/mpuv3 +name: VPX5 nSIM simulator (with MPUv3) +type: sim +simulation: + - name: nsim + exec: nsimdrv +arch: arc +toolchain: + - arcmwdt +testing: + ignore_tags: + - net + - bluetooth +vendor: snps diff --git a/boards/snps/nsim/arc_classic/nsim_nsim_vpx5_mpuv3_defconfig b/boards/snps/nsim/arc_classic/nsim_nsim_vpx5_mpuv3_defconfig new file mode 100644 index 000000000000..37f49899a89b --- /dev/null +++ b/boards/snps/nsim/arc_classic/nsim_nsim_vpx5_mpuv3_defconfig @@ -0,0 +1,10 @@ +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_SYS_CLOCK_TICKS_PER_SEC=100 +CONFIG_BUILD_OUTPUT_BIN=n +CONFIG_ARCV2_INTERRUPT_UNIT=y +CONFIG_ARCV2_TIMER=y +CONFIG_ARC_MPU_ENABLE=y +CONFIG_CONSOLE=y +CONFIG_UART_CONSOLE=y +CONFIG_SERIAL=y diff --git a/boards/snps/nsim/arc_classic/support/mdb_vpx5_mpuv3.args b/boards/snps/nsim/arc_classic/support/mdb_vpx5_mpuv3.args new file mode 100644 index 000000000000..c3a8594a7427 --- /dev/null +++ b/boards/snps/nsim/arc_classic/support/mdb_vpx5_mpuv3.args @@ -0,0 +1,98 @@ + -arcv2hs + -core4 + -uarch_rev=1:4 + -Xcode_density + -rgf_num_banks=1 + -rgf_num_wr_ports=2 + -Xatomic + -Xll64 + -Xunaligned + -Xdiv_rem=radix4 + -Xswap + -Xbitscan + -Xmpy_option=qmpyh + -Xshift_assist + -Xbarrel_shifter + -Xtimer0 + -Xtimer0_level=0 + -Xtimer1 + -Xtimer1_level=0 + -Xrtc + -action_points=8 + -ap_feature=1 + -Xstack_check + -dmp_per0_base=14 + -dmp_per0_limit=15 + -volatile_base=12 + -volatile_limit=0 + -volatile_strict_ordering + -bpu_bc_entries=1024 + -bpu_pt_entries=8192 + -bpu_rs_entries=8 + -bpu_bc_full_tag=1 + -bpu_tosq_entries=5 + -bpu_fb_entries=2 + -interrupts=24 + -interrupt_priorities=4 + -ext_interrupts=8 + -interrupt_base=0x0 + -intvbase_ext + -dcache=32768,64,2,a + -dcache_version=5 + -dcache_feature=2 + -dcache_mem_cycles=1 + -icache=32768,128,4,a + -icache_version=4 + -icache_feature=2 + -dccm_size=0x40000 + -dccm_base=0x80000000 + -dccm_mem_cycles=1 + -iccm0_size=0x40000 + -iccm0_base=0x00000000 + -Xpct_counters=16 + -Xpct_interrupt + -arconnect + -connect_asi=2 + -connect_ici=3 + -connect_icd=2 + -connect_gfrc=4 + -connect_idu=2 + -connect_idu_cirqnum=4 + -connect_ivc=1 + -stu=4 + -stu_initiator_num=1 + -stu_initiator_dbw=128 + -stu_phy_ch_num=1 + -stu_req_fifo_depth=32 + -stu_buffer_size=32 + -stu_perf + -Xvdsp4 + -Xvec_unit_rev_minor=1 + -Xvec_width=512 + -Xvec_mem_size=256k + -Xvec_mem_banks=32 + -Xvec_mem_bank_width=16 + -Xvec_max_fetch_size=16 + -Xvec_num_slots=3 + -Xvec_super_with_scalar + -Xvec_regs=40 + -Xvec_fast=0 + -Xvec_num_rd_ports=6 + -Xvec_num_acc=8 + -Xvec_num_mpy=2 + -Xvec_mpy32 + -Xvec_num_alu=3 + -Xvec_guard_bit_option=2 + -Xvec_mem_topology=0 + -Xvec_stack_check + -Xvec_mem_base=0x90000000 + -cluster_version=5 + -scu + -scu_stb_entries=8 + -scu_coherent_io=1 + -cluster_peripheral_interfaces=1 + -clock_gating + -mpuv3 + -mpu_regions=16 + -prop=nsim_mem-dev=uart0,kind=dwuart,base=0xf0000000,irq=24 + -noprofile diff --git a/boards/snps/nsim/arc_classic/support/nsim_vpx5_mpuv3.props b/boards/snps/nsim/arc_classic/support/nsim_vpx5_mpuv3.props new file mode 100644 index 000000000000..279048676b0d --- /dev/null +++ b/boards/snps/nsim/arc_classic/support/nsim_vpx5_mpuv3.props @@ -0,0 +1,107 @@ + nsim_isa_family=av2hs + nsim_isa_core=4 + arcver=0x54 + nsim_isa_uarch_rev_major=1 + nsim_isa_uarch_rev_minor=4 + nsim_isa_code_density_option=2 + nsim_isa_rgf_num_banks=1 + nsim_isa_rgf_num_regs=32 + nsim_isa_rgf_num_wr_ports=2 + nsim_isa_big_endian=0 + nsim_isa_lpc_size=32 + nsim_isa_pc_size=32 + nsim_isa_addr_size=32 + nsim_isa_atomic_option=1 + nsim_isa_ll64_option=1 + nsim_isa_unaligned_option=1 + nsim_isa_div_rem_option=2 + nsim_isa_swap_option=1 + nsim_isa_bitscan_option=1 + nsim_isa_mpy_option=9 + nsim_isa_shift_option=3 + nsim_isa_enable_timer_0=1 + nsim_isa_timer_0_int_level=0 + nsim_isa_enable_timer_1=1 + nsim_isa_timer_1_int_level=0 + nsim_isa_rtc_option=1 + nsim_isa_num_actionpoints=8 + nsim_isa_aps_feature=1 + nsim_isa_stack_checking=1 + nsim_isa_has_dmp_peripheral=1 + nsim_isa_dmp_peripheral_version=2 + nsim_isa_dmp_peripheral_count=1 + nsim_isa_dmp_peripheral_base0=14 + nsim_isa_dmp_peripheral_limit0=15 + nsim_isa_volatile_base=12 + nsim_isa_volatile_limit=0 + nsim_isa_volatile_disable=0 + nsim_isa_volatile_strict_ordering=1 + nsim_bpu_bc_entries=1024 + nsim_bpu_pt_entries=8192 + nsim_bpu_rs_entries=8 + nsim_bpu_bc_full_tag=1 + nsim_bpu_tosq_entries=5 + nsim_bpu_fb_entries=2 + nsim_isa_number_of_interrupts=24 + nsim_isa_number_of_levels=4 + nsim_isa_number_of_external_interrupts=8 + nsim_isa_intvbase_preset=0x0 + nsim_isa_intvbase_ext=1 + dcache=32768,64,2,a + nsim_isa_dc_version=5 + nsim_isa_dc_feature_level=2 + nsim_isa_dc_mem_cycles=1 + icache=32768,128,4,a + nsim_isa_ic_version=4 + nsim_isa_ic_feature_level=2 + dccm_size=0x40000 + dccm_base=0x80000000 + nsim_isa_dccm_mem_cycles=1 + iccm0_size=0x40000 + iccm0_base=0x00000000 + nsim_isa_pct_counters=16 + nsim_isa_pct_interrupt=1 + nsim_connect=2 + nsim_connect_asi=2 + nsim_connect_ici=3 + nsim_connect_icd=2 + nsim_connect_gfrc=4 + nsim_connect_idu=2 + nsim_connect_idu_cirqnum=4 + nsim_connect_ivc=1 + nsim_stu=4 + nsim_stu_initiator_num=1 + nsim_stu_initiator_dbw=128 + nsim_stu_phy_ch_num=1 + nsim_stu_req_fifo_depth=32 + nsim_stu_buffer_size=32 + nsim_stu_perf=1 + nsim_isa_vec_unit=4 + nsim_isa_vec_unit_rev_minor=1 + nsim_isa_vec_width=512 + vec_mem_size=256k + nsim_isa_vec_mem_banks=32 + nsim_isa_vec_mem_bank_width=16 + nsim_isa_vec_max_fetch_size=16 + nsim_isa_vec_num_slots=3 + nsim_isa_vec_super_with_scalar=1 + nsim_isa_vec_regs=40 + nsim_isa_vec_fast=0 + nsim_isa_vec_num_rd_ports=6 + nsim_isa_vec_num_acc=8 + nsim_isa_vec_num_mpy=2 + nsim_isa_vec_mpy32=1 + nsim_isa_vec_num_alu=3 + nsim_isa_vec_guard_bit_option=2 + nsim_isa_vec_mem_topology=0 + nsim_isa_vec_stack_check=1 + vec_mem_base=0x90000000 + nsim_cluster_version=5 + nsim_isa_has_scu=1 + nsim_isa_scu_stb_entries=8 + nsim_isa_scu_coherent_io=1 + nsim_cluster_peripheral_interfaces=1 + nsim_isa_clock_gating=1 + nsim_mem-dev=uart0,kind=dwuart,base=0xf0000000,irq=23 + mpu_regions=16 + mpu_version=3 From 3d5a3ae075d6f61a76136758c7b18783e89dfc12 Mon Sep 17 00:00:00 2001 From: Flavio Ceolin Date: Sun, 18 Jan 2026 18:52:30 -0800 Subject: [PATCH 0023/6328] entropy: mcux_rng: Do not ignore possible error Propagate the HAL error otherwise it may return success even when it fails causing invalid entropy and compromising security. Signed-off-by: Flavio Ceolin --- drivers/entropy/entropy_mcux_rng.c | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/drivers/entropy/entropy_mcux_rng.c b/drivers/entropy/entropy_mcux_rng.c index 74d78ee2735e..56195e617760 100644 --- a/drivers/entropy/entropy_mcux_rng.c +++ b/drivers/entropy/entropy_mcux_rng.c @@ -23,11 +23,26 @@ static int entropy_mcux_rng_get_entropy(const struct device *dev, { const struct mcux_entropy_config *config = dev->config; status_t status; + int ret; status = RNG_GetRandomData(config->base, buffer, length); - __ASSERT_NO_MSG(!status); - return 0; + /* It seems that this function returns either success or + * invalid argument. + */ + switch (status) { + case kStatus_InvalidArgument: + ret = -EINVAL; + break; + case kStatus_Success: + ret = 0; + break; + default: + ret = -ENODATA; + break; + } + + return ret; } static DEVICE_API(entropy, entropy_mcux_rng_api_funcs) = { From a2b64c933585293c7293dbe1350734c5042c3839 Mon Sep 17 00:00:00 2001 From: Aksel Skauge Mellbye Date: Mon, 19 Jan 2026 10:06:46 +0100 Subject: [PATCH 0024/6328] dts: arm: silabs: Clean up radio feature selection Sort ble radio feature properties alphabetically according to the coding standard. Certain features on xg22 and xg28 depend on the specific SoC selected, move the properties from the generic .dtsi file to the SoC specific one. Signed-off-by: Aksel Skauge Mellbye --- dts/arm/silabs/xg21/efr32xg21.dtsi | 4 ++-- dts/arm/silabs/xg22/bgm220pc22hna.dtsi | 4 ++++ dts/arm/silabs/xg22/bgm220pc22wga.dtsi | 2 ++ dts/arm/silabs/xg22/bgm220sc22hna.dtsi | 4 ++++ dts/arm/silabs/xg22/efr32bg22c222f352gm32.dtsi | 5 +++++ dts/arm/silabs/xg22/efr32bg22c222f352gm40.dtsi | 5 +++++ dts/arm/silabs/xg22/efr32bg22c222f352gn32.dtsi | 5 +++++ dts/arm/silabs/xg22/efr32bg22c224f512gm32.dtsi | 7 +++++++ dts/arm/silabs/xg22/efr32bg22c224f512gm40.dtsi | 7 +++++++ dts/arm/silabs/xg22/efr32bg22c224f512gn32.dtsi | 7 +++++++ dts/arm/silabs/xg22/efr32bg22c224f512im32.dtsi | 7 +++++++ dts/arm/silabs/xg22/efr32bg22c224f512im40.dtsi | 7 +++++++ dts/arm/silabs/xg22/efr32mg22c224f512gn32.dtsi | 7 +++++++ dts/arm/silabs/xg22/efr32mg22c224f512im32.dtsi | 7 +++++++ dts/arm/silabs/xg22/efr32mg22c224f512im40.dtsi | 7 +++++++ dts/arm/silabs/xg22/efr32xg22.dtsi | 4 ---- dts/arm/silabs/xg23/efr32xg23.dtsi | 1 + dts/arm/silabs/xg24/efr32xg24.dtsi | 10 +++++----- dts/arm/silabs/xg26/efr32xg26.dtsi | 5 +++++ dts/arm/silabs/xg27/efr32xg27.dtsi | 6 +++--- dts/arm/silabs/xg28/efr32xg28.dtsi | 1 + dts/arm/silabs/xg28/efr32zg28b322f1024im68.dtsi | 4 ++++ dts/arm/silabs/xg29/efr32xg29.dtsi | 6 +++--- 23 files changed, 105 insertions(+), 17 deletions(-) diff --git a/dts/arm/silabs/xg21/efr32xg21.dtsi b/dts/arm/silabs/xg21/efr32xg21.dtsi index fc928cac9af3..0ceaa57ff709 100644 --- a/dts/arm/silabs/xg21/efr32xg21.dtsi +++ b/dts/arm/silabs/xg21/efr32xg21.dtsi @@ -11,6 +11,8 @@ radio: radio@b0000000 { compatible = "silabs,series2-radio"; reg = <0xb0000000 0x01000000>; + ble-2mbps-supported; + ble-coded-phy-supported; interrupt-names = "agc", "bufc", "frc_pri", "frc", "modem", "protimer", "rac_rsm", "rac_seq", "prortc", "synth"; interrupts = <31 1>, <32 1>, <33 1>, <34 1>, <35 1>, <36 1>, <37 1>, @@ -19,8 +21,6 @@ pa-initial-power-dbm = <10>; pa-ramp-time-us = <10>; pa-voltage-mv = <3300>; - ble-2mbps-supported; - ble-coded-phy-supported; radio-tx-high-power-supported; bt_hci_silabs: bt_hci_silabs { diff --git a/dts/arm/silabs/xg22/bgm220pc22hna.dtsi b/dts/arm/silabs/xg22/bgm220pc22hna.dtsi index 8ab760fcda44..d2ea0131d755 100644 --- a/dts/arm/silabs/xg22/bgm220pc22hna.dtsi +++ b/dts/arm/silabs/xg22/bgm220pc22hna.dtsi @@ -43,6 +43,10 @@ }; &radio { + ble-2mbps-supported; + ble-coded-phy-supported; + ble-cte-rx-supported; + ble-cte-tx-supported; pa-voltage-mv = <1800>; }; diff --git a/dts/arm/silabs/xg22/bgm220pc22wga.dtsi b/dts/arm/silabs/xg22/bgm220pc22wga.dtsi index bce9701e0a0f..f90927466d30 100644 --- a/dts/arm/silabs/xg22/bgm220pc22wga.dtsi +++ b/dts/arm/silabs/xg22/bgm220pc22wga.dtsi @@ -29,6 +29,8 @@ }; &radio { + ble-2mbps-supported; + ble-cte-tx-supported; pa-voltage-mv = <1800>; }; diff --git a/dts/arm/silabs/xg22/bgm220sc22hna.dtsi b/dts/arm/silabs/xg22/bgm220sc22hna.dtsi index 70215e0793c8..282e31b1fe1e 100644 --- a/dts/arm/silabs/xg22/bgm220sc22hna.dtsi +++ b/dts/arm/silabs/xg22/bgm220sc22hna.dtsi @@ -31,6 +31,10 @@ }; &radio { + ble-2mbps-supported; + ble-coded-phy-supported; + ble-cte-rx-supported; + ble-cte-tx-supported; pa-voltage-mv = <1800>; }; diff --git a/dts/arm/silabs/xg22/efr32bg22c222f352gm32.dtsi b/dts/arm/silabs/xg22/efr32bg22c222f352gm32.dtsi index 3289ea2b2254..6aa2a17220fb 100644 --- a/dts/arm/silabs/xg22/efr32bg22c222f352gm32.dtsi +++ b/dts/arm/silabs/xg22/efr32bg22c222f352gm32.dtsi @@ -19,6 +19,11 @@ reg = <0x00000000 DT_SIZE_K(352)>; }; +&radio { + ble-2mbps-supported; + ble-cte-tx-supported; +}; + &sram0 { reg = <0x20000000 DT_SIZE_K(32)>; }; diff --git a/dts/arm/silabs/xg22/efr32bg22c222f352gm40.dtsi b/dts/arm/silabs/xg22/efr32bg22c222f352gm40.dtsi index 4dd5ead08e3f..d7485b55fce3 100644 --- a/dts/arm/silabs/xg22/efr32bg22c222f352gm40.dtsi +++ b/dts/arm/silabs/xg22/efr32bg22c222f352gm40.dtsi @@ -19,6 +19,11 @@ reg = <0x00000000 DT_SIZE_K(352)>; }; +&radio { + ble-2mbps-supported; + ble-cte-tx-supported; +}; + &sram0 { reg = <0x20000000 DT_SIZE_K(32)>; }; diff --git a/dts/arm/silabs/xg22/efr32bg22c222f352gn32.dtsi b/dts/arm/silabs/xg22/efr32bg22c222f352gn32.dtsi index 5ee05b65efd7..3fb801264de1 100644 --- a/dts/arm/silabs/xg22/efr32bg22c222f352gn32.dtsi +++ b/dts/arm/silabs/xg22/efr32bg22c222f352gn32.dtsi @@ -19,6 +19,11 @@ reg = <0x00000000 DT_SIZE_K(352)>; }; +&radio { + ble-2mbps-supported; + ble-cte-tx-supported; +}; + &sram0 { reg = <0x20000000 DT_SIZE_K(32)>; }; diff --git a/dts/arm/silabs/xg22/efr32bg22c224f512gm32.dtsi b/dts/arm/silabs/xg22/efr32bg22c224f512gm32.dtsi index 6e264464f0ff..1842e7eaf805 100644 --- a/dts/arm/silabs/xg22/efr32bg22c224f512gm32.dtsi +++ b/dts/arm/silabs/xg22/efr32bg22c224f512gm32.dtsi @@ -19,6 +19,13 @@ reg = <0x00000000 DT_SIZE_K(512)>; }; +&radio { + ble-2mbps-supported; + ble-coded-phy-supported; + ble-cte-rx-supported; + ble-cte-tx-supported; +}; + &sram0 { reg = <0x20000000 DT_SIZE_K(32)>; }; diff --git a/dts/arm/silabs/xg22/efr32bg22c224f512gm40.dtsi b/dts/arm/silabs/xg22/efr32bg22c224f512gm40.dtsi index 5d31e5361489..5f2d4a278029 100644 --- a/dts/arm/silabs/xg22/efr32bg22c224f512gm40.dtsi +++ b/dts/arm/silabs/xg22/efr32bg22c224f512gm40.dtsi @@ -19,6 +19,13 @@ reg = <0x00000000 DT_SIZE_K(512)>; }; +&radio { + ble-2mbps-supported; + ble-coded-phy-supported; + ble-cte-rx-supported; + ble-cte-tx-supported; +}; + &sram0 { reg = <0x20000000 DT_SIZE_K(32)>; }; diff --git a/dts/arm/silabs/xg22/efr32bg22c224f512gn32.dtsi b/dts/arm/silabs/xg22/efr32bg22c224f512gn32.dtsi index 9eedd872378b..3614d8327406 100644 --- a/dts/arm/silabs/xg22/efr32bg22c224f512gn32.dtsi +++ b/dts/arm/silabs/xg22/efr32bg22c224f512gn32.dtsi @@ -19,6 +19,13 @@ reg = <0x00000000 DT_SIZE_K(512)>; }; +&radio { + ble-2mbps-supported; + ble-coded-phy-supported; + ble-cte-rx-supported; + ble-cte-tx-supported; +}; + &sram0 { reg = <0x20000000 DT_SIZE_K(32)>; }; diff --git a/dts/arm/silabs/xg22/efr32bg22c224f512im32.dtsi b/dts/arm/silabs/xg22/efr32bg22c224f512im32.dtsi index 11f88d44e250..cbb4e0e7f764 100644 --- a/dts/arm/silabs/xg22/efr32bg22c224f512im32.dtsi +++ b/dts/arm/silabs/xg22/efr32bg22c224f512im32.dtsi @@ -19,6 +19,13 @@ reg = <0x00000000 DT_SIZE_K(512)>; }; +&radio { + ble-2mbps-supported; + ble-coded-phy-supported; + ble-cte-rx-supported; + ble-cte-tx-supported; +}; + &sram0 { reg = <0x20000000 DT_SIZE_K(32)>; }; diff --git a/dts/arm/silabs/xg22/efr32bg22c224f512im40.dtsi b/dts/arm/silabs/xg22/efr32bg22c224f512im40.dtsi index b85a4096d7d5..0202eb2c3d38 100644 --- a/dts/arm/silabs/xg22/efr32bg22c224f512im40.dtsi +++ b/dts/arm/silabs/xg22/efr32bg22c224f512im40.dtsi @@ -19,6 +19,13 @@ reg = <0x00000000 DT_SIZE_K(512)>; }; +&radio { + ble-2mbps-supported; + ble-coded-phy-supported; + ble-cte-rx-supported; + ble-cte-tx-supported; +}; + &sram0 { reg = <0x20000000 DT_SIZE_K(32)>; }; diff --git a/dts/arm/silabs/xg22/efr32mg22c224f512gn32.dtsi b/dts/arm/silabs/xg22/efr32mg22c224f512gn32.dtsi index 12618cdcda25..298b4b26895d 100644 --- a/dts/arm/silabs/xg22/efr32mg22c224f512gn32.dtsi +++ b/dts/arm/silabs/xg22/efr32mg22c224f512gn32.dtsi @@ -19,6 +19,13 @@ reg = <0x00000000 DT_SIZE_K(512)>; }; +&radio { + ble-2mbps-supported; + ble-coded-phy-supported; + ble-cte-rx-supported; + ble-cte-tx-supported; +}; + &sram0 { reg = <0x20000000 DT_SIZE_K(32)>; }; diff --git a/dts/arm/silabs/xg22/efr32mg22c224f512im32.dtsi b/dts/arm/silabs/xg22/efr32mg22c224f512im32.dtsi index 39f0416342d1..2141623f0eea 100644 --- a/dts/arm/silabs/xg22/efr32mg22c224f512im32.dtsi +++ b/dts/arm/silabs/xg22/efr32mg22c224f512im32.dtsi @@ -19,6 +19,13 @@ reg = <0x00000000 DT_SIZE_K(512)>; }; +&radio { + ble-2mbps-supported; + ble-coded-phy-supported; + ble-cte-rx-supported; + ble-cte-tx-supported; +}; + &sram0 { reg = <0x20000000 DT_SIZE_K(32)>; }; diff --git a/dts/arm/silabs/xg22/efr32mg22c224f512im40.dtsi b/dts/arm/silabs/xg22/efr32mg22c224f512im40.dtsi index 66f0ea88b856..82d6122ecba3 100644 --- a/dts/arm/silabs/xg22/efr32mg22c224f512im40.dtsi +++ b/dts/arm/silabs/xg22/efr32mg22c224f512im40.dtsi @@ -19,6 +19,13 @@ reg = <0x00000000 DT_SIZE_K(512)>; }; +&radio { + ble-2mbps-supported; + ble-coded-phy-supported; + ble-cte-rx-supported; + ble-cte-tx-supported; +}; + &sram0 { reg = <0x20000000 DT_SIZE_K(32)>; }; diff --git a/dts/arm/silabs/xg22/efr32xg22.dtsi b/dts/arm/silabs/xg22/efr32xg22.dtsi index 99417981627a..12eb99f565b6 100644 --- a/dts/arm/silabs/xg22/efr32xg22.dtsi +++ b/dts/arm/silabs/xg22/efr32xg22.dtsi @@ -20,10 +20,6 @@ pa-initial-power-dbm = <10>; pa-ramp-time-us = <2>; pa-voltage-mv = <3300>; - ble-2mbps-supported; - ble-coded-phy-supported; - ble-cte-tx-supported; - ble-cte-rx-supported; radio-tx-high-power-supported; pti: pti { diff --git a/dts/arm/silabs/xg23/efr32xg23.dtsi b/dts/arm/silabs/xg23/efr32xg23.dtsi index 3e94bc1d4b06..d7b9c3042a5c 100644 --- a/dts/arm/silabs/xg23/efr32xg23.dtsi +++ b/dts/arm/silabs/xg23/efr32xg23.dtsi @@ -20,6 +20,7 @@ pa-ramp-time-us = <10>; pa-subghz = "highest"; pa-voltage-mv = <3300>; + radio-tx-high-power-supported; pti: pti { compatible = "silabs,pti"; diff --git a/dts/arm/silabs/xg24/efr32xg24.dtsi b/dts/arm/silabs/xg24/efr32xg24.dtsi index 8c9a32edb39e..44dcc1c196a3 100644 --- a/dts/arm/silabs/xg24/efr32xg24.dtsi +++ b/dts/arm/silabs/xg24/efr32xg24.dtsi @@ -11,6 +11,11 @@ radio: radio@b0000000 { compatible = "silabs,series2-radio"; reg = <0xb0000000 0x01000000>; + ble-2mbps-supported; + ble-coded-phy-supported; + ble-cs-supported; + ble-cte-rx-supported; + ble-cte-tx-supported; interrupt-names = "agc", "bufc", "frc_pri", "frc", "modem", "protimer", "rac_rsm", "rac_seq", "hostmailbox", "synth", "rfeca0", "rfeca1"; @@ -20,11 +25,6 @@ pa-initial-power-dbm = <10>; pa-ramp-time-us = <10>; pa-voltage-mv = <3300>; - ble-2mbps-supported; - ble-coded-phy-supported; - ble-cte-tx-supported; - ble-cte-rx-supported; - ble-cs-supported; radio-tx-high-power-supported; bt_hci_silabs: bt_hci_silabs { diff --git a/dts/arm/silabs/xg26/efr32xg26.dtsi b/dts/arm/silabs/xg26/efr32xg26.dtsi index 61dea61507c5..471a8d184dd1 100644 --- a/dts/arm/silabs/xg26/efr32xg26.dtsi +++ b/dts/arm/silabs/xg26/efr32xg26.dtsi @@ -11,6 +11,10 @@ radio: radio@b0000000 { compatible = "silabs,series2-radio"; reg = <0xb0000000 0x01000000>; + ble-2mbps-supported; + ble-coded-phy-supported; + ble-cte-rx-supported; + ble-cte-tx-supported; interrupt-names = "agc", "bufc", "frc_pri", "frc", "modem", "protimer", "rac_rsm", "rac_seq", "hostmailbox", "synth", "rfeca0", "rfeca1"; @@ -20,6 +24,7 @@ pa-initial-power-dbm = <10>; pa-ramp-time-us = <10>; pa-voltage-mv = <3300>; + radio-tx-high-power-supported; pti: pti { compatible = "silabs,pti"; diff --git a/dts/arm/silabs/xg27/efr32xg27.dtsi b/dts/arm/silabs/xg27/efr32xg27.dtsi index a06f5e1c4d0c..584fa2f515c9 100644 --- a/dts/arm/silabs/xg27/efr32xg27.dtsi +++ b/dts/arm/silabs/xg27/efr32xg27.dtsi @@ -11,6 +11,9 @@ radio: radio@b0000000 { compatible = "silabs,series2-radio"; reg = <0xb0000000 0x01000000>; + ble-2mbps-supported; + ble-coded-phy-supported; + ble-cte-tx-supported; interrupt-names = "agc", "bufc", "frc_pri", "frc", "modem", "protimer", "rac_rsm", "rac_seq", "rdmailbox", "rfsense", "synth", "prortc"; @@ -20,9 +23,6 @@ pa-initial-power-dbm = <10>; pa-ramp-time-us = <2>; pa-voltage-mv = <3300>; - ble-2mbps-supported; - ble-coded-phy-supported; - ble-cte-tx-supported; radio-tx-high-power-supported; bt_hci_silabs: bt_hci_silabs { diff --git a/dts/arm/silabs/xg28/efr32xg28.dtsi b/dts/arm/silabs/xg28/efr32xg28.dtsi index b1e7f049a401..6b315da62286 100644 --- a/dts/arm/silabs/xg28/efr32xg28.dtsi +++ b/dts/arm/silabs/xg28/efr32xg28.dtsi @@ -21,6 +21,7 @@ pa-ramp-time-us = <10>; pa-subghz = "highest"; pa-voltage-mv = <3300>; + radio-tx-high-power-supported; pti: pti { compatible = "silabs,pti"; diff --git a/dts/arm/silabs/xg28/efr32zg28b322f1024im68.dtsi b/dts/arm/silabs/xg28/efr32zg28b322f1024im68.dtsi index cd0390ebd036..6de0fcf5d828 100644 --- a/dts/arm/silabs/xg28/efr32zg28b322f1024im68.dtsi +++ b/dts/arm/silabs/xg28/efr32zg28b322f1024im68.dtsi @@ -19,6 +19,10 @@ reg = <0x08000000 DT_SIZE_K(1024)>; }; +&radio { + ble-2mbps-supported; +}; + &sram0 { reg = <0x20000000 DT_SIZE_K(256)>; }; diff --git a/dts/arm/silabs/xg29/efr32xg29.dtsi b/dts/arm/silabs/xg29/efr32xg29.dtsi index cec52dc2cf17..505ebc75244e 100644 --- a/dts/arm/silabs/xg29/efr32xg29.dtsi +++ b/dts/arm/silabs/xg29/efr32xg29.dtsi @@ -11,6 +11,9 @@ radio: radio@b0000000 { compatible = "silabs,series2-radio"; reg = <0xb0000000 0x01000000>; + ble-2mbps-supported; + ble-coded-phy-supported; + ble-cte-tx-supported; interrupt-names = "agc", "bufc", "frc_pri", "frc", "modem", "protimer", "rac_rsm", "rac_seq", "rdmailbox", "rfsense", "synth", "prortc"; @@ -20,9 +23,6 @@ pa-initial-power-dbm = <10>; pa-ramp-time-us = <2>; pa-voltage-mv = <3300>; - ble-2mbps-supported; - ble-coded-phy-supported; - ble-cte-tx-supported; radio-tx-high-power-supported; bt_hci_silabs: bt_hci_silabs { From c7425884d648d329c3f6607d7c369d1dde83f626 Mon Sep 17 00:00:00 2001 From: Felix Wang Date: Mon, 19 Jan 2026 14:55:02 +0530 Subject: [PATCH 0025/6328] MAINTAINERS: add FelixWang47831 as PWM collaborator Add FelixWang47831 as a collaborator for the PWM driver. Signed-off-by: Felix Wang --- MAINTAINERS.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/MAINTAINERS.yml b/MAINTAINERS.yml index 0aff172eb1e8..6b231468d6ba 100644 --- a/MAINTAINERS.yml +++ b/MAINTAINERS.yml @@ -2230,6 +2230,7 @@ Documentation Infrastructure: collaborators: - anangl - henrikbrixandersen + - FelixWang47831 files: - drivers/pwm/ - dts/bindings/pwm/ From 699da43045268a8102705b6da37f6c65638486f8 Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Mon, 19 Jan 2026 10:42:37 +0100 Subject: [PATCH 0026/6328] samples: net: sockets: http_get: Fix addrinfo dump The debug code for dumping resolved addresses was modifying the addrinfo res pointer (effectively setting it to NULL), causing crash later in the sample. Fix this, by using a temporary pointer copy for iterating over resolved addresses. Signed-off-by: Robert Lubos --- samples/net/sockets/http_get/src/http_get.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/samples/net/sockets/http_get/src/http_get.c b/samples/net/sockets/http_get/src/http_get.c index 32e79c434830..9ac506007f72 100644 --- a/samples/net/sockets/http_get/src/http_get.c +++ b/samples/net/sockets/http_get/src/http_get.c @@ -89,8 +89,10 @@ int main(void) } #if 0 - for (; res; res = res->ai_next) { - dump_addrinfo(res); + struct addrinfo *temp_res = res; + + for (; temp_res; temp_res = temp_res->ai_next) { + dump_addrinfo(temp_res); } #endif From 4e314b4aecc8f39a79ffdbb69c57c174637c99cb Mon Sep 17 00:00:00 2001 From: Braeden Lane Date: Tue, 20 Jan 2026 14:44:49 -0800 Subject: [PATCH 0027/6328] boards: infineon: standardize pinctrl in supported list Update board YAML files to use 'pinctrl' instead of 'pin_ctrl' in the supported features list for consistency with Zephyr naming conventions. Affected boards: - cy8cproto_041tp - kit_pse84_ai - kit_pse84_eval Signed-off-by: Braeden Lane --- boards/infineon/cy8cproto_041tp/cy8cproto_041tp.yaml | 2 +- boards/infineon/kit_pse84_ai/kit_pse84_ai_m33.yaml | 2 +- boards/infineon/kit_pse84_ai/kit_pse84_ai_m55.yaml | 2 +- boards/infineon/kit_pse84_eval/kit_pse84_eval_m33.yaml | 2 +- boards/infineon/kit_pse84_eval/kit_pse84_eval_m55.yaml | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/boards/infineon/cy8cproto_041tp/cy8cproto_041tp.yaml b/boards/infineon/cy8cproto_041tp/cy8cproto_041tp.yaml index 7053a2254b9c..780adc3f3b34 100644 --- a/boards/infineon/cy8cproto_041tp/cy8cproto_041tp.yaml +++ b/boards/infineon/cy8cproto_041tp/cy8cproto_041tp.yaml @@ -15,5 +15,5 @@ toolchain: supported: - uart - clock_control - - pin_ctrl + - pinctrl vendor: infineon diff --git a/boards/infineon/kit_pse84_ai/kit_pse84_ai_m33.yaml b/boards/infineon/kit_pse84_ai/kit_pse84_ai_m33.yaml index ca3e4c9f1b2d..20eda5e05f7c 100644 --- a/boards/infineon/kit_pse84_ai/kit_pse84_ai_m33.yaml +++ b/boards/infineon/kit_pse84_ai/kit_pse84_ai_m33.yaml @@ -14,5 +14,5 @@ toolchain: supported: - clock_control - gpio - - pin_ctrl + - pinctrl - uart diff --git a/boards/infineon/kit_pse84_ai/kit_pse84_ai_m55.yaml b/boards/infineon/kit_pse84_ai/kit_pse84_ai_m55.yaml index bc8cd3dc9471..19125395d788 100644 --- a/boards/infineon/kit_pse84_ai/kit_pse84_ai_m55.yaml +++ b/boards/infineon/kit_pse84_ai/kit_pse84_ai_m55.yaml @@ -14,5 +14,5 @@ toolchain: supported: - clock_control - gpio - - pin_ctrl + - pinctrl - uart diff --git a/boards/infineon/kit_pse84_eval/kit_pse84_eval_m33.yaml b/boards/infineon/kit_pse84_eval/kit_pse84_eval_m33.yaml index 29daa46ec3f2..8005f3b38d7c 100644 --- a/boards/infineon/kit_pse84_eval/kit_pse84_eval_m33.yaml +++ b/boards/infineon/kit_pse84_eval/kit_pse84_eval_m33.yaml @@ -15,6 +15,6 @@ supported: - clock_control - dma - gpio - - pin_ctrl + - pinctrl - uart - spi diff --git a/boards/infineon/kit_pse84_eval/kit_pse84_eval_m55.yaml b/boards/infineon/kit_pse84_eval/kit_pse84_eval_m55.yaml index 9ed20693cc0d..ee241e89804b 100644 --- a/boards/infineon/kit_pse84_eval/kit_pse84_eval_m55.yaml +++ b/boards/infineon/kit_pse84_eval/kit_pse84_eval_m55.yaml @@ -15,6 +15,6 @@ supported: - clock_control - dma - gpio - - pin_ctrl + - pinctrl - uart - spi From bf747b8e037eef1a873c998fc6642ba32a28d84b Mon Sep 17 00:00:00 2001 From: Laurentiu Mihalcea Date: Wed, 21 Jan 2026 00:47:23 +0200 Subject: [PATCH 0028/6328] bindings: scmi: modify description format Modify the description format of all SCMI-related bindings such that the SCMI/SHMEM acronym is spelled out in between parentheses and not the other way around. This will make the generated documentation more compact. Signed-off-by: Laurentiu Mihalcea --- dts/bindings/firmware/arm,scmi-clock.yaml | 2 +- dts/bindings/firmware/arm,scmi-pinctrl.yaml | 2 +- dts/bindings/firmware/arm,scmi-power.yaml | 2 +- dts/bindings/firmware/arm,scmi-shmem.yaml | 2 +- dts/bindings/firmware/arm,scmi-system.yaml | 2 +- dts/bindings/firmware/arm,scmi.yaml | 4 ++-- dts/bindings/firmware/nxp,scmi-cpu.yaml | 2 +- dts/bindings/power-domain/arm,scmi-power-domain.yaml | 2 +- 8 files changed, 9 insertions(+), 9 deletions(-) diff --git a/dts/bindings/firmware/arm,scmi-clock.yaml b/dts/bindings/firmware/arm,scmi-clock.yaml index 5f0aa160d3fc..943f3015fb70 100644 --- a/dts/bindings/firmware/arm,scmi-clock.yaml +++ b/dts/bindings/firmware/arm,scmi-clock.yaml @@ -1,7 +1,7 @@ # Copyright 2024 NXP # SPDX-License-Identifier: Apache-2.0 -description: System Control and Management Interface (SCMI) clock protocol +description: SCMI (System Control and Management Interface) clock protocol compatible: "arm,scmi-clock" diff --git a/dts/bindings/firmware/arm,scmi-pinctrl.yaml b/dts/bindings/firmware/arm,scmi-pinctrl.yaml index f1e52b0fd209..74b3b55831a9 100644 --- a/dts/bindings/firmware/arm,scmi-pinctrl.yaml +++ b/dts/bindings/firmware/arm,scmi-pinctrl.yaml @@ -1,7 +1,7 @@ # Copyright 2024 NXP # SPDX-License-Identifier: Apache-2.0 -description: System Control and Management Interface (SCMI) pinctrl protocol +description: SCMI (System Control and Management Interface) pinctrl protocol compatible: "arm,scmi-pinctrl" diff --git a/dts/bindings/firmware/arm,scmi-power.yaml b/dts/bindings/firmware/arm,scmi-power.yaml index 41ad234681d0..2b5c5281a518 100644 --- a/dts/bindings/firmware/arm,scmi-power.yaml +++ b/dts/bindings/firmware/arm,scmi-power.yaml @@ -1,7 +1,7 @@ # Copyright 2024 NXP # SPDX-License-Identifier: Apache-2.0 -description: System Control and Management Interface (SCMI) power domain protocol +description: SCMI (System Control and Management Interface) power domain protocol compatible: "arm,scmi-power" diff --git a/dts/bindings/firmware/arm,scmi-shmem.yaml b/dts/bindings/firmware/arm,scmi-shmem.yaml index aa968a3e4e5f..4fe7453e9301 100644 --- a/dts/bindings/firmware/arm,scmi-shmem.yaml +++ b/dts/bindings/firmware/arm,scmi-shmem.yaml @@ -1,7 +1,7 @@ # Copyright 2024 NXP # SPDX-License-Identifier: Apache-2.0 -description: System Control and Management Interface (SCMI) shared memory (SHMEM) +description: SCMI (System Control and Management Interface) SHMEM (shared memory) compatible: "arm,scmi-shmem" diff --git a/dts/bindings/firmware/arm,scmi-system.yaml b/dts/bindings/firmware/arm,scmi-system.yaml index 77aba5abf176..f8b79a8fefd5 100644 --- a/dts/bindings/firmware/arm,scmi-system.yaml +++ b/dts/bindings/firmware/arm,scmi-system.yaml @@ -1,7 +1,7 @@ # Copyright 2025 NXP # SPDX-License-Identifier: Apache-2.0 -description: System Control and Management Interface (SCMI) system power protocol +description: SCMI (System Control and Management Interface) system power protocol compatible: "arm,scmi-system" diff --git a/dts/bindings/firmware/arm,scmi.yaml b/dts/bindings/firmware/arm,scmi.yaml index 5ece8e59201d..22766cb815df 100644 --- a/dts/bindings/firmware/arm,scmi.yaml +++ b/dts/bindings/firmware/arm,scmi.yaml @@ -2,8 +2,8 @@ # SPDX-License-Identifier: Apache-2.0 description: | - System Control and Management Interface (SCMI) with doorbell - and shared memory (SHMEM) transport. + SCMI (System Control and Management Interface) with doorbell + and SHMEM (shared memory) transport. Devicetree example: #include diff --git a/dts/bindings/firmware/nxp,scmi-cpu.yaml b/dts/bindings/firmware/nxp,scmi-cpu.yaml index 7032df08d982..d435eb47bfee 100644 --- a/dts/bindings/firmware/nxp,scmi-cpu.yaml +++ b/dts/bindings/firmware/nxp,scmi-cpu.yaml @@ -1,7 +1,7 @@ # Copyright 2025 NXP # SPDX-License-Identifier: Apache-2.0 -description: System Control and Management Interface (SCMI) cpu domain protocol +description: SCMI (System Control and Management Interface) cpu domain protocol compatible: "nxp,scmi-cpu" diff --git a/dts/bindings/power-domain/arm,scmi-power-domain.yaml b/dts/bindings/power-domain/arm,scmi-power-domain.yaml index 66a732af25e7..588d0c041e5a 100644 --- a/dts/bindings/power-domain/arm,scmi-power-domain.yaml +++ b/dts/bindings/power-domain/arm,scmi-power-domain.yaml @@ -1,7 +1,7 @@ # Copyright 2026 NXP # SPDX-License-Identifier: Apache-2.0 -description: ARM SCMI Power Domain +description: SCMI (System Control and Management Interface) power domain compatible: "arm,scmi-power-domain" From 7deab5e3347abbf539356f969a0859c55af83456 Mon Sep 17 00:00:00 2001 From: Evgenii Kosenko Date: Wed, 7 Jan 2026 16:23:18 +0200 Subject: [PATCH 0029/6328] Bluetooth: Shell: Add per-bearer pool for GATT operations The original implementation used a single global parameter structure for GATT operations, preventing concurrent operations on different bearers. By introducing a per-bearer context pool, each bearer can maintain its own operation state, enabling simultaneous GATT operations. Signed-off-by: Evgenii Kosenko --- subsys/bluetooth/host/shell/gatt.c | 204 ++++++++++++++++++----------- 1 file changed, 129 insertions(+), 75 deletions(-) diff --git a/subsys/bluetooth/host/shell/gatt.c b/subsys/bluetooth/host/shell/gatt.c index 013b878a6af3..335cc0f91cc6 100644 --- a/subsys/bluetooth/host/shell/gatt.c +++ b/subsys/bluetooth/host/shell/gatt.c @@ -141,9 +141,49 @@ static int cmd_exchange_mtu(const struct shell *sh, return err; } -static struct bt_gatt_discover_params discover_params; +#define GATT_OP_POOL_SIZE (1U + COND_CODE_1(IS_ENABLED(CONFIG_BT_EATT), (CONFIG_BT_EATT_MAX), (0U))) +#define GATT_READ_MAX_HANDLES 8 + +static struct gatt_op_context { + struct bt_gatt_discover_params discover; + struct bt_gatt_read_params read; + uint16_t read_handles[GATT_READ_MAX_HANDLES]; + struct bt_gatt_write_params write; + uint8_t write_buf[BT_ATT_MAX_ATTRIBUTE_LEN]; +} gatt_ctx[GATT_OP_POOL_SIZE]; + static struct bt_uuid_16 uuid = BT_UUID_INIT_16(0); +static struct gatt_op_context *gatt_ctx_discover_alloc(void) +{ + for (size_t i = 0U; i < ARRAY_SIZE(gatt_ctx); i++) { + if (gatt_ctx[i].discover.func == NULL) { + return &gatt_ctx[i]; + } + } + return NULL; +} + +static struct gatt_op_context *gatt_ctx_read_alloc(void) +{ + for (size_t i = 0U; i < ARRAY_SIZE(gatt_ctx); i++) { + if (gatt_ctx[i].read.func == NULL) { + return &gatt_ctx[i]; + } + } + return NULL; +} + +static struct gatt_op_context *gatt_ctx_write_alloc(void) +{ + for (size_t i = 0U; i < ARRAY_SIZE(gatt_ctx); i++) { + if (gatt_ctx[i].write.func == NULL) { + return &gatt_ctx[i]; + } + } + return NULL; +} + static void print_chrc_props(uint8_t properties) { bt_shell_print("Properties: "); @@ -226,6 +266,7 @@ static uint8_t discover_func(struct bt_conn *conn, static int cmd_discover(const struct shell *sh, size_t argc, char *argv[]) { + struct gatt_op_context *ctx; int err; if (!default_conn) { @@ -233,47 +274,49 @@ static int cmd_discover(const struct shell *sh, size_t argc, char *argv[]) return -ENOEXEC; } - if (discover_params.func) { - shell_print(sh, "Discover ongoing"); + ctx = gatt_ctx_discover_alloc(); + if (ctx == NULL) { + shell_error(sh, "No available operation slots"); return -ENOEXEC; } - discover_params.func = discover_func; - discover_params.start_handle = BT_ATT_FIRST_ATTRIBUTE_HANDLE; - discover_params.end_handle = BT_ATT_LAST_ATTRIBUTE_HANDLE; - SET_CHAN_OPT_ANY(discover_params); + ctx->discover.func = discover_func; + ctx->discover.start_handle = BT_ATT_FIRST_ATTRIBUTE_HANDLE; + ctx->discover.end_handle = BT_ATT_LAST_ATTRIBUTE_HANDLE; + SET_CHAN_OPT_ANY(ctx->discover); if (argc > 1) { /* Only set the UUID if the value is valid (non zero) */ uuid.val = strtoul(argv[1], NULL, 16); if (uuid.val) { - discover_params.uuid = &uuid.uuid; + ctx->discover.uuid = &uuid.uuid; } } if (argc > 2) { - discover_params.start_handle = strtoul(argv[2], NULL, 16); + ctx->discover.start_handle = strtoul(argv[2], NULL, 16); if (argc > 3) { - discover_params.end_handle = strtoul(argv[3], NULL, 16); + ctx->discover.end_handle = strtoul(argv[3], NULL, 16); } } if (!strcmp(argv[0], "discover")) { - discover_params.type = BT_GATT_DISCOVER_ATTRIBUTE; + ctx->discover.type = BT_GATT_DISCOVER_ATTRIBUTE; } else if (!strcmp(argv[0], "discover-secondary")) { - discover_params.type = BT_GATT_DISCOVER_SECONDARY; + ctx->discover.type = BT_GATT_DISCOVER_SECONDARY; } else if (!strcmp(argv[0], "discover-include")) { - discover_params.type = BT_GATT_DISCOVER_INCLUDE; + ctx->discover.type = BT_GATT_DISCOVER_INCLUDE; } else if (!strcmp(argv[0], "discover-characteristic")) { - discover_params.type = BT_GATT_DISCOVER_CHARACTERISTIC; + ctx->discover.type = BT_GATT_DISCOVER_CHARACTERISTIC; } else if (!strcmp(argv[0], "discover-descriptor")) { - discover_params.type = BT_GATT_DISCOVER_DESCRIPTOR; + ctx->discover.type = BT_GATT_DISCOVER_DESCRIPTOR; } else { - discover_params.type = BT_GATT_DISCOVER_PRIMARY; + ctx->discover.type = BT_GATT_DISCOVER_PRIMARY; } - err = bt_gatt_discover(default_conn, &discover_params); + err = bt_gatt_discover(default_conn, &ctx->discover); if (err) { + (void)memset(&ctx->discover, 0, sizeof(ctx->discover)); shell_error(sh, "Discover failed (err %d)", err); } else { shell_print(sh, "Discover pending"); @@ -282,8 +325,6 @@ static int cmd_discover(const struct shell *sh, size_t argc, char *argv[]) return err; } -static struct bt_gatt_read_params read_params; - static uint8_t read_func(struct bt_conn *conn, uint8_t err, struct bt_gatt_read_params *params, const void *data, uint16_t length) @@ -302,6 +343,7 @@ static uint8_t read_func(struct bt_conn *conn, uint8_t err, static int cmd_read(const struct shell *sh, size_t argc, char *argv[]) { + struct gatt_op_context *ctx; int err; if (!default_conn) { @@ -309,23 +351,25 @@ static int cmd_read(const struct shell *sh, size_t argc, char *argv[]) return -ENOEXEC; } - if (read_params.func) { - shell_print(sh, "Read ongoing"); - return -ENOEXEC; + ctx = gatt_ctx_read_alloc(); + if (ctx == NULL) { + shell_error(sh, "No available operation slots"); + return -EBUSY; } - read_params.func = read_func; - read_params.handle_count = 1; - read_params.single.handle = strtoul(argv[1], NULL, 16); - read_params.single.offset = 0U; - SET_CHAN_OPT_ANY(read_params); + ctx->read.func = read_func; + ctx->read.handle_count = 1; + ctx->read.single.handle = strtoul(argv[1], NULL, 16); + ctx->read.single.offset = 0U; + SET_CHAN_OPT_ANY(ctx->read); if (argc > 2) { - read_params.single.offset = strtoul(argv[2], NULL, 16); + ctx->read.single.offset = strtoul(argv[2], NULL, 16); } - err = bt_gatt_read(default_conn, &read_params); + err = bt_gatt_read(default_conn, &ctx->read); if (err) { + (void)memset(&ctx->read, 0, sizeof(ctx->read)); shell_error(sh, "Read failed (err %d)", err); } else { shell_print(sh, "Read pending"); @@ -336,7 +380,7 @@ static int cmd_read(const struct shell *sh, size_t argc, char *argv[]) static int cmd_mread(const struct shell *sh, size_t argc, char *argv[]) { - uint16_t h[8]; + struct gatt_op_context *ctx; size_t i; int err; @@ -345,29 +389,34 @@ static int cmd_mread(const struct shell *sh, size_t argc, char *argv[]) return -ENOEXEC; } - if (read_params.func) { - shell_print(sh, "Read ongoing"); - return -ENOEXEC; + ctx = gatt_ctx_read_alloc(); + if (ctx == NULL) { + shell_error(sh, "No available operation slots"); + return -EBUSY; } - if ((argc - 1) > ARRAY_SIZE(h)) { - shell_print(sh, "Enter max %zu handle items to read", ARRAY_SIZE(h)); + if ((argc - 1) > ARRAY_SIZE(ctx->read_handles)) { + shell_print(sh, "Enter max %zu handle items to read", + ARRAY_SIZE(ctx->read_handles)); return -EINVAL; } for (i = 0; i < argc - 1; i++) { - h[i] = strtoul(argv[i + 1], NULL, 16); + ctx->read_handles[i] = strtoul(argv[i + 1], NULL, 16); } - read_params.func = read_func; - read_params.handle_count = i; - read_params.multiple.handles = h; - read_params.multiple.variable = true; - SET_CHAN_OPT_ANY(read_params); + ctx->read.func = read_func; + ctx->read.handle_count = i; + ctx->read.multiple.handles = ctx->read_handles; + ctx->read.multiple.variable = true; + SET_CHAN_OPT_ANY(ctx->read); - err = bt_gatt_read(default_conn, &read_params); + err = bt_gatt_read(default_conn, &ctx->read); if (err) { + (void)memset(&ctx->read, 0, sizeof(ctx->read)); shell_error(sh, "GATT multiple read request failed (err %d)", err); + } else { + shell_print(sh, "Read pending"); } return err; @@ -375,6 +424,7 @@ static int cmd_mread(const struct shell *sh, size_t argc, char *argv[]) static int cmd_read_uuid(const struct shell *sh, size_t argc, char *argv[]) { + struct gatt_op_context *ctx; int err; if (!default_conn) { @@ -382,33 +432,35 @@ static int cmd_read_uuid(const struct shell *sh, size_t argc, char *argv[]) return -ENOEXEC; } - if (read_params.func) { - shell_print(sh, "Read ongoing"); - return -ENOEXEC; + ctx = gatt_ctx_read_alloc(); + if (ctx == NULL) { + shell_error(sh, "No available operation slots"); + return -EBUSY; } - read_params.func = read_func; - read_params.handle_count = 0; - read_params.by_uuid.start_handle = BT_ATT_FIRST_ATTRIBUTE_HANDLE; - read_params.by_uuid.end_handle = BT_ATT_LAST_ATTRIBUTE_HANDLE; - SET_CHAN_OPT_ANY(read_params); + ctx->read.func = read_func; + ctx->read.handle_count = 0; + ctx->read.by_uuid.start_handle = BT_ATT_FIRST_ATTRIBUTE_HANDLE; + ctx->read.by_uuid.end_handle = BT_ATT_LAST_ATTRIBUTE_HANDLE; + SET_CHAN_OPT_ANY(ctx->read); if (argc > 1) { uuid.val = strtoul(argv[1], NULL, 16); if (uuid.val) { - read_params.by_uuid.uuid = &uuid.uuid; + ctx->read.by_uuid.uuid = &uuid.uuid; } } if (argc > 2) { - read_params.by_uuid.start_handle = strtoul(argv[2], NULL, 16); + ctx->read.by_uuid.start_handle = strtoul(argv[2], NULL, 16); if (argc > 3) { - read_params.by_uuid.end_handle = strtoul(argv[3], NULL, 16); + ctx->read.by_uuid.end_handle = strtoul(argv[3], NULL, 16); } } - err = bt_gatt_read(default_conn, &read_params); + err = bt_gatt_read(default_conn, &ctx->read); if (err) { + (void)memset(&ctx->read, 0, sizeof(ctx->read)); shell_error(sh, "Read failed (err %d)", err); } else { shell_print(sh, "Read pending"); @@ -417,19 +469,17 @@ static int cmd_read_uuid(const struct shell *sh, size_t argc, char *argv[]) return err; } -static struct bt_gatt_write_params write_params; -static uint8_t gatt_write_buf[BT_ATT_MAX_ATTRIBUTE_LEN]; - static void write_func(struct bt_conn *conn, uint8_t err, struct bt_gatt_write_params *params) { bt_shell_print("Write complete: err 0x%02x", err); - (void)memset(&write_params, 0, sizeof(write_params)); + (void)memset(params, 0, sizeof(*params)); } static int cmd_write(const struct shell *sh, size_t argc, char *argv[]) { + struct gatt_op_context *ctx; int err; uint16_t handle, offset; @@ -438,30 +488,31 @@ static int cmd_write(const struct shell *sh, size_t argc, char *argv[]) return -ENOEXEC; } - if (write_params.func) { - shell_error(sh, "Write ongoing"); - return -ENOEXEC; + ctx = gatt_ctx_write_alloc(); + if (ctx == NULL) { + shell_error(sh, "No available operation slots"); + return -EBUSY; } handle = strtoul(argv[1], NULL, 16); offset = strtoul(argv[2], NULL, 16); - write_params.length = hex2bin(argv[3], strlen(argv[3]), - gatt_write_buf, sizeof(gatt_write_buf)); - if (write_params.length == 0) { + ctx->write.length = hex2bin(argv[3], strlen(argv[3]), + ctx->write_buf, sizeof(ctx->write_buf)); + if (ctx->write.length == 0) { shell_error(sh, "No data set"); return -ENOEXEC; } - write_params.data = gatt_write_buf; - write_params.handle = handle; - write_params.offset = offset; - write_params.func = write_func; - SET_CHAN_OPT_ANY(write_params); + ctx->write.data = ctx->write_buf; + ctx->write.handle = handle; + ctx->write.offset = offset; + ctx->write.func = write_func; + SET_CHAN_OPT_ANY(ctx->write); - err = bt_gatt_write(default_conn, &write_params); + err = bt_gatt_write(default_conn, &ctx->write); if (err) { - write_params.func = NULL; + (void)memset(&ctx->write, 0, sizeof(ctx->write)); shell_error(sh, "Write failed (err %d)", err); } else { shell_print(sh, "Write pending"); @@ -479,6 +530,9 @@ static void write_without_rsp_cb(struct bt_conn *conn, void *user_data) print_write_stats(); } +/* Separate buffer for write-without-response (doesn't use async params) */ +static uint8_t gatt_write_without_rsp_buf[BT_ATT_MAX_ATTRIBUTE_LEN]; + static int cmd_write_without_rsp(const struct shell *sh, size_t argc, char *argv[]) { @@ -503,16 +557,16 @@ static int cmd_write_without_rsp(const struct shell *sh, } handle = strtoul(argv[1], NULL, 16); - gatt_write_buf[0] = strtoul(argv[2], NULL, 16); + gatt_write_without_rsp_buf[0] = strtoul(argv[2], NULL, 16); len = 1U; if (argc > 3) { int i; - len = MIN(strtoul(argv[3], NULL, 16), sizeof(gatt_write_buf)); + len = MIN(strtoul(argv[3], NULL, 16), sizeof(gatt_write_without_rsp_buf)); for (i = 1; i < len; i++) { - gatt_write_buf[i] = gatt_write_buf[0]; + gatt_write_without_rsp_buf[i] = gatt_write_without_rsp_buf[0]; } } @@ -529,7 +583,7 @@ static int cmd_write_without_rsp(const struct shell *sh, while (repeat--) { err = bt_gatt_write_without_response_cb(default_conn, handle, - gatt_write_buf, len, + gatt_write_without_rsp_buf, len, sign, func, UINT_TO_POINTER(len)); if (err) { From 8bf8eeb3383d5e2c6eb3495bd3886ce851d3dd70 Mon Sep 17 00:00:00 2001 From: Stephan Linz Date: Sat, 28 Dec 2024 08:03:02 +0100 Subject: [PATCH 0030/6328] drivers: display: rm67162: avoid uninitialized variable MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Warning as error was: .../drivers/display/display_rm67162.c: In function ‘rm67162_write_fb’: .../drivers/display/display_rm67162.c:383:9: error: ‘wlen’ may be used uninitialized in this function [-Werror=maybe-uninitialized] 383 | return wlen; | ^~~~ cc1: all warnings being treated as errors Signed-off-by: Stephan Linz --- drivers/display/display_rm67162.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/display/display_rm67162.c b/drivers/display/display_rm67162.c index fc6c6f4dd9bd..d1fef43d97f9 100644 --- a/drivers/display/display_rm67162.c +++ b/drivers/display/display_rm67162.c @@ -355,7 +355,7 @@ static int rm67162_write_fb(const struct device *dev, bool first_write, { const struct rm67162_config *config = dev->config; struct rm67162_data *data = dev->data; - ssize_t wlen; + ssize_t wlen = 0; struct mipi_dsi_msg msg = {0}; uint8_t *local_src = (uint8_t *)src; uint32_t len = desc->height * desc->width * data->bytes_per_pixel; From 2d6aa4739886a923d650cb4403e623d89422aa28 Mon Sep 17 00:00:00 2001 From: Tom Hughes Date: Fri, 16 Jan 2026 16:44:33 -0800 Subject: [PATCH 0031/6328] tests: mcumgr: Re-enable clang warning by using variables When removing TOOLCHAIN_DISABLE_CLANG_WARNING, building the settings.mgmt test with clang fails with: tests/subsys/mgmt/mcumgr/settings_mgmt/src/main.c:87:22: error: variable 'test_response_read_data_start' is not needed and will not be emitted [-Werror,-Wunneeded-internal-declaration] 87 | static const uint8_t test_response_read_data_start[5] = { | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~ tests/subsys/mgmt/mcumgr/settings_mgmt/src/main.c:91:22: error: variable 'test_response_read_data_end' is not needed and will not be emitted [-Werror,-Wunneeded-internal-declaration] 91 | static const uint8_t test_response_read_data_end[1] = { Add additional asserts to use these variables in the test. Signed-off-by: Tom Hughes --- .../mgmt/mcumgr/settings_mgmt/src/main.c | 63 ++++++++++++++++--- 1 file changed, 56 insertions(+), 7 deletions(-) diff --git a/tests/subsys/mgmt/mcumgr/settings_mgmt/src/main.c b/tests/subsys/mgmt/mcumgr/settings_mgmt/src/main.c index 86443ccace86..25f13ba007d7 100644 --- a/tests/subsys/mgmt/mcumgr/settings_mgmt/src/main.c +++ b/tests/subsys/mgmt/mcumgr/settings_mgmt/src/main.c @@ -79,12 +79,6 @@ static const uint8_t test_response_error_data[8] = { 0xbf, 0x62, 0x72, 0x63, 0x19, 0x01, 0x00, 0xff }; -/* - * TODO: The contents of these structs are not used, which is why clang complains. - * The test should be updated to use these values. See discussion in - * https://github.com/zephyrproject-rtos/zephyr/pull/87592. - */ -TOOLCHAIN_DISABLE_CLANG_WARNING(TOOLCHAIN_WARNING_UNNEEDED_INTERNAL_DECLARATION) static const uint8_t test_response_read_data_start[5] = { 0xbf, 0x63, 0x76, 0x61, 0x6c }; @@ -92,7 +86,6 @@ static const uint8_t test_response_read_data_start[5] = { static const uint8_t test_response_read_data_end[1] = { 0xff }; -TOOLCHAIN_ENABLE_CLANG_WARNING(TOOLCHAIN_WARNING_UNNEEDED_INTERNAL_DECLARATION) static void cleanup_test(void *p) { @@ -525,6 +518,14 @@ ZTEST(settings_mgmt, test_set_read) zassert_true(smp_header->nh_len > sys_cpu_to_be16(TEST_RESPONSE_READ_DATA_LENGTH), "SMP header length mismatch"); + zassert_mem_equal(nb->data, test_response_read_data_start, + sizeof(test_response_read_data_start), + "SMP response start mismatch"); + zassert_mem_equal(&nb->data[nb->len - sizeof(test_response_read_data_end)], + test_response_read_data_end, + sizeof(test_response_read_data_end), + "SMP response end mismatch"); + zassert_equal(smp_header->nh_flags, 0, "SMP header flags mismatch"); zassert_equal(smp_header->nh_op, MGMT_OP_READ_RSP, "SMP header operation mismatch"); @@ -629,6 +630,14 @@ ZTEST(settings_mgmt, test_read_max_size) zassert_true(smp_header->nh_len > sys_cpu_to_be16(TEST_RESPONSE_READ_DATA_LENGTH), "SMP header length mismatch"); + zassert_mem_equal(nb->data, test_response_read_data_start, + sizeof(test_response_read_data_start), + "SMP response start mismatch"); + zassert_mem_equal(&nb->data[nb->len - sizeof(test_response_read_data_end)], + test_response_read_data_end, + sizeof(test_response_read_data_end), + "SMP response end mismatch"); + zassert_equal(smp_header->nh_flags, 0, "SMP header flags mismatch"); zassert_equal(smp_header->nh_op, MGMT_OP_READ_RSP, "SMP header operation mismatch"); zassert_equal(smp_header->nh_group, sys_cpu_to_be16(MGMT_GROUP_ID_SETTINGS), @@ -784,6 +793,14 @@ ZTEST(settings_mgmt, test_set_disallowed) zassert_true(smp_header->nh_len > sys_cpu_to_be16(TEST_RESPONSE_READ_DATA_LENGTH), "SMP header length mismatch"); + zassert_mem_equal(nb->data, test_response_read_data_start, + sizeof(test_response_read_data_start), + "SMP response start mismatch"); + zassert_mem_equal(&nb->data[nb->len - sizeof(test_response_read_data_end)], + test_response_read_data_end, + sizeof(test_response_read_data_end), + "SMP response end mismatch"); + zassert_equal(smp_header->nh_flags, 0, "SMP header flags mismatch"); zassert_equal(smp_header->nh_op, MGMT_OP_READ_RSP, "SMP header operation mismatch"); zassert_equal(smp_header->nh_group, sys_cpu_to_be16(MGMT_GROUP_ID_SETTINGS), @@ -914,6 +931,14 @@ ZTEST(settings_mgmt, test_set_disallowed) zassert_true(smp_header->nh_len > sys_cpu_to_be16(TEST_RESPONSE_READ_DATA_LENGTH), "SMP header length mismatch"); + zassert_mem_equal(nb->data, test_response_read_data_start, + sizeof(test_response_read_data_start), + "SMP response start mismatch"); + zassert_mem_equal(&nb->data[nb->len - sizeof(test_response_read_data_end)], + test_response_read_data_end, + sizeof(test_response_read_data_end), + "SMP response end mismatch"); + zassert_equal(smp_header->nh_flags, 0, "SMP header flags mismatch"); zassert_equal(smp_header->nh_op, MGMT_OP_READ_RSP, "SMP header operation mismatch"); zassert_equal(smp_header->nh_group, sys_cpu_to_be16(MGMT_GROUP_ID_SETTINGS), @@ -1186,6 +1211,14 @@ ZTEST(settings_mgmt, test_delete) zassert_true(smp_header->nh_len > sys_cpu_to_be16(TEST_RESPONSE_READ_DATA_LENGTH), "SMP header length mismatch"); + zassert_mem_equal(nb->data, test_response_read_data_start, + sizeof(test_response_read_data_start), + "SMP response start mismatch"); + zassert_mem_equal(&nb->data[nb->len - sizeof(test_response_read_data_end)], + test_response_read_data_end, + sizeof(test_response_read_data_end), + "SMP response end mismatch"); + zassert_equal(smp_header->nh_flags, 0, "SMP header flags mismatch"); zassert_equal(smp_header->nh_op, MGMT_OP_READ_RSP, "SMP header operation mismatch"); zassert_equal(smp_header->nh_group, sys_cpu_to_be16(MGMT_GROUP_ID_SETTINGS), @@ -1313,6 +1346,14 @@ ZTEST(settings_mgmt, test_delete) zassert_true(smp_header->nh_len > sys_cpu_to_be16(TEST_RESPONSE_READ_DATA_LENGTH), "SMP header length mismatch"); + zassert_mem_equal(nb->data, test_response_read_data_start, + sizeof(test_response_read_data_start), + "SMP response start mismatch"); + zassert_mem_equal(&nb->data[nb->len - sizeof(test_response_read_data_end)], + test_response_read_data_end, + sizeof(test_response_read_data_end), + "SMP response end mismatch"); + zassert_equal(smp_header->nh_flags, 0, "SMP header flags mismatch"); zassert_equal(smp_header->nh_op, MGMT_OP_READ_RSP, "SMP header operation mismatch"); zassert_equal(smp_header->nh_group, sys_cpu_to_be16(MGMT_GROUP_ID_SETTINGS), @@ -1558,6 +1599,14 @@ ZTEST(settings_mgmt, test_delete) zassert_true(smp_header->nh_len > sys_cpu_to_be16(TEST_RESPONSE_READ_DATA_LENGTH), "SMP header length mismatch"); + zassert_mem_equal(nb->data, test_response_read_data_start, + sizeof(test_response_read_data_start), + "SMP response start mismatch"); + zassert_mem_equal(&nb->data[nb->len - sizeof(test_response_read_data_end)], + test_response_read_data_end, + sizeof(test_response_read_data_end), + "SMP response end mismatch"); + zassert_equal(smp_header->nh_flags, 0, "SMP header flags mismatch"); zassert_equal(smp_header->nh_op, MGMT_OP_READ_RSP, "SMP header operation mismatch"); zassert_equal(smp_header->nh_group, sys_cpu_to_be16(MGMT_GROUP_ID_SETTINGS), From ec3c28db0f5fad13f6adb01a393234d128aa0581 Mon Sep 17 00:00:00 2001 From: Peter Hoddie Date: Fri, 16 Jan 2026 17:52:43 -0800 Subject: [PATCH 0032/6328] boards: adafruit: correct gpio pin numbers for feathers These DTS uses absolute GPIO numbers for some pins where relative pin numbers are required. This causes crash on booth when these pins are enabled. Follow on PR to #101857. Signed-off-by: Peter Hoddie --- .../adafruit_feather_esp32s2_tft.dts | 6 +++--- .../adafruit_feather_esp32s2_tft_reverse.dts | 6 +++--- .../feather_esp32s2/feather_connector.dtsi | 16 ++++++++-------- .../feather_esp32s2/feather_connector_tft.dtsi | 12 ++++++------ .../feather_esp32s3/feather_connector.dtsi | 12 ++++++------ .../feather_esp32s3_tft/feather_connector.dtsi | 12 ++++++------ ...afruit_feather_esp32s3_tft_reverse_procpu.dts | 6 +++--- .../feather_connector.dtsi | 12 ++++++------ 8 files changed, 41 insertions(+), 41 deletions(-) diff --git a/boards/adafruit/feather_esp32s2/adafruit_feather_esp32s2_tft.dts b/boards/adafruit/feather_esp32s2/adafruit_feather_esp32s2_tft.dts index 114a2d9cb91d..6fa376564196 100644 --- a/boards/adafruit/feather_esp32s2/adafruit_feather_esp32s2_tft.dts +++ b/boards/adafruit/feather_esp32s2/adafruit_feather_esp32s2_tft.dts @@ -27,7 +27,7 @@ led1: led_1 { label = "TFT Backlight"; - gpios = <&gpio1 45 GPIO_ACTIVE_HIGH>; + gpios = <&gpio1 13 GPIO_ACTIVE_HIGH>; }; }; @@ -46,8 +46,8 @@ mipi_dbi { compatible = "zephyr,mipi-dbi-spi"; spi-dev = <&spi2>; - dc-gpios = <&gpio1 39 GPIO_ACTIVE_HIGH>; - reset-gpios = <&gpio1 40 GPIO_ACTIVE_LOW>; + dc-gpios = <&gpio1 7 GPIO_ACTIVE_HIGH>; + reset-gpios = <&gpio1 8 GPIO_ACTIVE_LOW>; write-only; #address-cells = <1>; #size-cells = <0>; diff --git a/boards/adafruit/feather_esp32s2/adafruit_feather_esp32s2_tft_reverse.dts b/boards/adafruit/feather_esp32s2/adafruit_feather_esp32s2_tft_reverse.dts index fe6a7eba826d..8896f38433b2 100644 --- a/boards/adafruit/feather_esp32s2/adafruit_feather_esp32s2_tft_reverse.dts +++ b/boards/adafruit/feather_esp32s2/adafruit_feather_esp32s2_tft_reverse.dts @@ -28,7 +28,7 @@ led1: led_1 { label = "TFT Backlight"; - gpios = <&gpio1 45 GPIO_ACTIVE_HIGH>; + gpios = <&gpio1 13 GPIO_ACTIVE_HIGH>; }; }; @@ -60,8 +60,8 @@ mipi_dbi { compatible = "zephyr,mipi-dbi-spi"; spi-dev = <&spi2>; - dc-gpios = <&gpio1 40 GPIO_ACTIVE_HIGH>; - reset-gpios = <&gpio1 41 GPIO_ACTIVE_LOW>; + dc-gpios = <&gpio1 8 GPIO_ACTIVE_HIGH>; + reset-gpios = <&gpio1 9 GPIO_ACTIVE_LOW>; write-only; #address-cells = <1>; #size-cells = <0>; diff --git a/boards/adafruit/feather_esp32s2/feather_connector.dtsi b/boards/adafruit/feather_esp32s2/feather_connector.dtsi index dd39d9404dba..9893f46b834a 100644 --- a/boards/adafruit/feather_esp32s2/feather_connector.dtsi +++ b/boards/adafruit/feather_esp32s2/feather_connector.dtsi @@ -18,14 +18,14 @@ <3 0 &gpio0 15 0>, /* A3 */ <4 0 &gpio0 14 0>, /* A4 */ <5 0 &gpio0 8 0>, /* A5 */ - <6 0 &gpio1 36 0>, /* SCK */ - <7 0 &gpio1 35 0>, /* MOSI */ - <8 0 &gpio1 37 0>, /* MISO */ - <9 0 &gpio1 38 0>, /* RX */ - <10 0 &gpio1 39 0>, /* TX */ - <11 0 &gpio1 43 0>, /* DB */ - <12 0 &gpio1 3 0>, /* SDA */ - <13 0 &gpio1 4 0>, /* SCL */ + <6 0 &gpio1 4 0>, /* SCK */ + <7 0 &gpio1 3 0>, /* MOSI */ + <8 0 &gpio1 5 0>, /* MISO */ + <9 0 &gpio1 6 0>, /* RX */ + <10 0 &gpio1 7 0>, /* TX */ + <11 0 &gpio1 11 0>, /* DB */ + <12 0 &gpio0 3 0>, /* SDA */ + <13 0 &gpio0 4 0>, /* SCL */ <14 0 &gpio0 5 0>, /* D5 */ <15 0 &gpio0 6 0>, /* D6 */ <16 0 &gpio0 9 0>, /* D9 */ diff --git a/boards/adafruit/feather_esp32s2/feather_connector_tft.dtsi b/boards/adafruit/feather_esp32s2/feather_connector_tft.dtsi index 9c1083d1208c..b2f3d514ff41 100644 --- a/boards/adafruit/feather_esp32s2/feather_connector_tft.dtsi +++ b/boards/adafruit/feather_esp32s2/feather_connector_tft.dtsi @@ -18,14 +18,14 @@ <3 0 &gpio0 15 0>, /* A3 */ <4 0 &gpio0 14 0>, /* A4 */ <5 0 &gpio0 8 0>, /* A5 */ - <6 0 &gpio1 36 0>, /* SCK */ - <7 0 &gpio1 35 0>, /* MOSI */ - <8 0 &gpio1 37 0>, /* MISO */ + <6 0 &gpio1 4 0>, /* SCK */ + <7 0 &gpio1 3 0>, /* MOSI */ + <8 0 &gpio1 5 0>, /* MISO */ <9 0 &gpio0 2 0>, /* RX */ <10 0 &gpio0 1 0>, /* TX */ - <11 0 &gpio1 43 0>, /* DB */ - <12 0 &gpio1 42 0>, /* SDA */ - <13 0 &gpio1 41 0>, /* SCL */ + <11 0 &gpio1 11 0>, /* DB */ + <12 0 &gpio1 10 0>, /* SDA */ + <13 0 &gpio1 9 0>, /* SCL */ <14 0 &gpio0 5 0>, /* D5 */ <15 0 &gpio0 6 0>, /* D6 */ <16 0 &gpio0 9 0>, /* D9 */ diff --git a/boards/adafruit/feather_esp32s3/feather_connector.dtsi b/boards/adafruit/feather_esp32s3/feather_connector.dtsi index d4c567e0830d..1d25345c80d3 100644 --- a/boards/adafruit/feather_esp32s3/feather_connector.dtsi +++ b/boards/adafruit/feather_esp32s3/feather_connector.dtsi @@ -17,12 +17,12 @@ <3 0 &gpio0 15 0>, /* A3 */ <4 0 &gpio0 14 0>, /* A4 */ <5 0 &gpio0 8 0>, /* A5 */ - <6 0 &gpio1 36 0>, /* SCK */ - <7 0 &gpio1 35 0>, /* MOSI */ - <8 0 &gpio1 37 0>, /* MISO */ - <9 0 &gpio1 38 0>, /* RX */ - <10 0 &gpio1 39 0>, /* TX */ - <11 0 &gpio1 44 0>, /* DB */ + <6 0 &gpio1 4 0>, /* SCK */ + <7 0 &gpio1 3 0>, /* MOSI */ + <8 0 &gpio1 5 0>, /* MISO */ + <9 0 &gpio1 6 0>, /* RX */ + <10 0 &gpio1 7 0>, /* TX */ + <11 0 &gpio1 12 0>, /* DB */ <12 0 &gpio0 3 0>, /* SDA */ <13 0 &gpio0 4 0>, /* SCL */ <14 0 &gpio0 5 0>, /* D5 */ diff --git a/boards/adafruit/feather_esp32s3_tft/feather_connector.dtsi b/boards/adafruit/feather_esp32s3_tft/feather_connector.dtsi index 675ab2395f61..999591779a14 100644 --- a/boards/adafruit/feather_esp32s3_tft/feather_connector.dtsi +++ b/boards/adafruit/feather_esp32s3_tft/feather_connector.dtsi @@ -17,14 +17,14 @@ <3 0 &gpio0 15 0>, /* A3 */ <4 0 &gpio0 14 0>, /* A4 */ <5 0 &gpio0 8 0>, /* A5 */ - <6 0 &gpio1 36 0>, /* SCK */ - <7 0 &gpio1 35 0>, /* MOSI */ - <8 0 &gpio1 37 0>, /* MISO */ + <6 0 &gpio1 4 0>, /* SCK */ + <7 0 &gpio1 3 0>, /* MOSI */ + <8 0 &gpio1 5 0>, /* MISO */ <9 0 &gpio0 2 0>, /* RX */ <10 0 &gpio0 1 0>, /* TX */ - <11 0 &gpio1 44 0>, /* DB */ - <12 0 &gpio1 42 0>, /* SDA */ - <13 0 &gpio1 41 0>, /* SCL */ + <11 0 &gpio1 12 0>, /* DB */ + <12 0 &gpio1 10 0>, /* SDA */ + <13 0 &gpio1 9 0>, /* SCL */ <14 0 &gpio0 5 0>, /* D5 */ <15 0 &gpio0 6 0>, /* D6 */ <16 0 &gpio0 9 0>, /* D9 */ diff --git a/boards/adafruit/feather_esp32s3_tft_reverse/adafruit_feather_esp32s3_tft_reverse_procpu.dts b/boards/adafruit/feather_esp32s3_tft_reverse/adafruit_feather_esp32s3_tft_reverse_procpu.dts index 841e85761a15..1595d33cd86e 100644 --- a/boards/adafruit/feather_esp32s3_tft_reverse/adafruit_feather_esp32s3_tft_reverse_procpu.dts +++ b/boards/adafruit/feather_esp32s3_tft_reverse/adafruit_feather_esp32s3_tft_reverse_procpu.dts @@ -75,7 +75,7 @@ led1: led_1 { label = "TFT Backlight"; - gpios = <&gpio1 45 GPIO_ACTIVE_HIGH>; + gpios = <&gpio1 13 GPIO_ACTIVE_HIGH>; }; }; @@ -103,8 +103,8 @@ mipi_dbi { compatible = "zephyr,mipi-dbi-spi"; spi-dev = <&spi2>; - dc-gpios = <&gpio1 40 GPIO_ACTIVE_HIGH>; - reset-gpios = <&gpio1 41 GPIO_ACTIVE_LOW>; + dc-gpios = <&gpio1 8 GPIO_ACTIVE_HIGH>; + reset-gpios = <&gpio1 9 GPIO_ACTIVE_LOW>; write-only; #address-cells = <1>; #size-cells = <0>; diff --git a/boards/adafruit/feather_esp32s3_tft_reverse/feather_connector.dtsi b/boards/adafruit/feather_esp32s3_tft_reverse/feather_connector.dtsi index 6c24ae9d0bce..8be241dd24dc 100644 --- a/boards/adafruit/feather_esp32s3_tft_reverse/feather_connector.dtsi +++ b/boards/adafruit/feather_esp32s3_tft_reverse/feather_connector.dtsi @@ -18,12 +18,12 @@ <3 0 &gpio0 15 0>, /* A3 */ <4 0 &gpio0 14 0>, /* A4 */ <5 0 &gpio0 8 0>, /* A5 */ - <6 0 &gpio1 36 0>, /* SCK */ - <7 0 &gpio1 35 0>, /* MOSI */ - <8 0 &gpio1 37 0>, /* MISO */ - <9 0 &gpio1 38 0>, /* RX */ - <10 0 &gpio1 39 0>, /* TX */ - <11 0 &gpio1 46 0>, /* DB */ + <6 0 &gpio1 4 0>, /* SCK */ + <7 0 &gpio1 3 0>, /* MOSI */ + <8 0 &gpio1 5 0>, /* MISO */ + <9 0 &gpio1 6 0>, /* RX */ + <10 0 &gpio1 7 0>, /* TX */ + <11 0 &gpio1 14 0>, /* DB */ <12 0 &gpio0 3 0>, /* SDA */ <13 0 &gpio0 4 0>, /* SCL */ <14 0 &gpio0 5 0>, /* D5 */ From 215a35c78f20254c425b669e272c575b54ac3a42 Mon Sep 17 00:00:00 2001 From: Lucien Zhao Date: Sun, 4 Jan 2026 16:42:34 +0800 Subject: [PATCH 0033/6328] dts: bindings: hwinfo: add nxp,rcm-hwinfo and nxp,sim-uuid.yaml - add nxp,rcm-hwinfo.yaml and nxp,sim-uuid.yaml to support hwinfo features by using dts ways Signed-off-by: Lucien Zhao --- dts/bindings/hwinfo/nxp,rcm-hwinfo.yaml | 12 ++++++++++++ dts/bindings/hwinfo/nxp,sim-uuid.yaml | 12 ++++++++++++ 2 files changed, 24 insertions(+) create mode 100644 dts/bindings/hwinfo/nxp,rcm-hwinfo.yaml create mode 100644 dts/bindings/hwinfo/nxp,sim-uuid.yaml diff --git a/dts/bindings/hwinfo/nxp,rcm-hwinfo.yaml b/dts/bindings/hwinfo/nxp,rcm-hwinfo.yaml new file mode 100644 index 000000000000..1318c10fd2c8 --- /dev/null +++ b/dts/bindings/hwinfo/nxp,rcm-hwinfo.yaml @@ -0,0 +1,12 @@ +# Copyright 2026 NXP +# SPDX-License-Identifier: Apache-2.0 + +description: NXP RCM get reset cause flags + +compatible: "nxp,rcm-hwinfo" + +include: base.yaml + +properties: + reg: + required: true diff --git a/dts/bindings/hwinfo/nxp,sim-uuid.yaml b/dts/bindings/hwinfo/nxp,sim-uuid.yaml new file mode 100644 index 000000000000..28ba93c09a70 --- /dev/null +++ b/dts/bindings/hwinfo/nxp,sim-uuid.yaml @@ -0,0 +1,12 @@ +# Copyright 2026 NXP +# SPDX-License-Identifier: Apache-2.0 + +description: NXP SIM 128-bit Unique identifier + +compatible: "nxp,sim-uuid" + +include: base.yaml + +properties: + reg: + required: true From eb43ffc6b801a7661e3789c81d309113349c3ebe Mon Sep 17 00:00:00 2001 From: Lucien Zhao Date: Mon, 19 Jan 2026 18:04:05 +0800 Subject: [PATCH 0034/6328] dts: arm: nxp: Add specific compatible strings for RCM and SIM Add vendor-specific compatible strings to RCM and SIM nodes: - "nxp,rcm-hwinfo" for Reset Control Module (hwinfo-reset functionality) - "nxp,sim-uuid" for System Integration Module (hwinfo-UUID functionality) Signed-off-by: Lucien Zhao --- dts/arm/nxp/nxp_k2x.dtsi | 7 ++++++- dts/arm/nxp/nxp_k32l2b3.dtsi | 7 ++++++- dts/arm/nxp/nxp_k6x.dtsi | 7 ++++++- dts/arm/nxp/nxp_k8x.dtsi | 7 ++++++- dts/arm/nxp/nxp_kl25z.dtsi | 7 ++++++- dts/arm/nxp/nxp_kv5x.dtsi | 7 ++++++- dts/arm/nxp/nxp_kw2xd.dtsi | 13 +++++++++++-- dts/arm/nxp/nxp_kw40z.dtsi | 13 +++++++++++-- dts/arm/nxp/nxp_kw41z.dtsi | 7 ++++++- dts/arm/nxp/nxp_mcxc_common.dtsi | 7 ++++++- 10 files changed, 70 insertions(+), 12 deletions(-) diff --git a/dts/arm/nxp/nxp_k2x.dtsi b/dts/arm/nxp/nxp_k2x.dtsi index c56eec74a558..9b6850a5003f 100644 --- a/dts/arm/nxp/nxp_k2x.dtsi +++ b/dts/arm/nxp/nxp_k2x.dtsi @@ -81,8 +81,13 @@ clock-frequency = <32768>; }; + rcm: rcm@4007F000 { + compatible = "nxp,rcm-hwinfo"; + reg = <0x4007F000 0x1000>; + }; + sim: sim@40047000 { - compatible = "nxp,kinetis-sim"; + compatible = "nxp,kinetis-sim", "nxp,sim-uuid"; reg = <0x40047000 0x1060>; #clock-cells = <3>; diff --git a/dts/arm/nxp/nxp_k32l2b3.dtsi b/dts/arm/nxp/nxp_k32l2b3.dtsi index 223c419dce4b..0c2ced6dc83f 100644 --- a/dts/arm/nxp/nxp_k32l2b3.dtsi +++ b/dts/arm/nxp/nxp_k32l2b3.dtsi @@ -87,8 +87,13 @@ #clock-cells = <1>; }; + rcm: rcm@4007F000 { + compatible = "nxp,rcm-hwinfo"; + reg = <0x4007F000 0x1000>; + }; + sim: sim@40047000 { - compatible = "nxp,kinetis-sim"; + compatible = "nxp,kinetis-sim", "nxp,sim-uuid"; reg = <0x40047000 0x1060>; #clock-cells = <3>; diff --git a/dts/arm/nxp/nxp_k6x.dtsi b/dts/arm/nxp/nxp_k6x.dtsi index bd8a859aebb1..0f186f705399 100644 --- a/dts/arm/nxp/nxp_k6x.dtsi +++ b/dts/arm/nxp/nxp_k6x.dtsi @@ -112,8 +112,13 @@ prescaler = <32768>; }; + rcm: rcm@4007F000 { + compatible = "nxp,rcm-hwinfo"; + reg = <0x4007F000 0x1000>; + }; + sim: sim@40047000 { - compatible = "nxp,kinetis-sim"; + compatible = "nxp,kinetis-sim", "nxp,sim-uuid"; reg = <0x40047000 0x1060>; #clock-cells = <3>; diff --git a/dts/arm/nxp/nxp_k8x.dtsi b/dts/arm/nxp/nxp_k8x.dtsi index 351a6f750efc..38ae65795291 100644 --- a/dts/arm/nxp/nxp_k8x.dtsi +++ b/dts/arm/nxp/nxp_k8x.dtsi @@ -45,8 +45,13 @@ status = "disabled"; }; + rcm: rcm@4007F000 { + compatible = "nxp,rcm-hwinfo"; + reg = <0x4007F000 0x1000>; + }; + sim: sim@40047000 { - compatible = "nxp,kinetis-sim"; + compatible = "nxp,kinetis-sim", "nxp,sim-uuid"; reg = <0x40047000 0x2000>; #clock-cells = <3>; diff --git a/dts/arm/nxp/nxp_kl25z.dtsi b/dts/arm/nxp/nxp_kl25z.dtsi index 068071fbf514..af4091f9b28e 100644 --- a/dts/arm/nxp/nxp_kl25z.dtsi +++ b/dts/arm/nxp/nxp_kl25z.dtsi @@ -82,8 +82,13 @@ status = "disabled"; }; + rcm: rcm@4007F000 { + compatible = "nxp,rcm-hwinfo"; + reg = <0x4007F000 0x1000>; + }; + sim: sim@40047000 { - compatible = "nxp,kinetis-sim"; + compatible = "nxp,kinetis-sim", "nxp,sim-uuid"; reg = <0x40047000 0x1060>; #clock-cells = <3>; diff --git a/dts/arm/nxp/nxp_kv5x.dtsi b/dts/arm/nxp/nxp_kv5x.dtsi index ae2107303435..82d8c9d16f35 100644 --- a/dts/arm/nxp/nxp_kv5x.dtsi +++ b/dts/arm/nxp/nxp_kv5x.dtsi @@ -40,8 +40,13 @@ status = "disabled"; }; + rcm: rcm@4007F000 { + compatible = "nxp,rcm-hwinfo"; + reg = <0x4007F000 0x1000>; + }; + sim: sim@40047000 { - compatible = "nxp,kinetis-sim"; + compatible = "nxp,kinetis-sim", "nxp,sim-uuid"; reg = <0x40047000 0x2000>; #clock-cells = <3>; diff --git a/dts/arm/nxp/nxp_kw2xd.dtsi b/dts/arm/nxp/nxp_kw2xd.dtsi index f1fedeb61269..bf0ce0335adf 100644 --- a/dts/arm/nxp/nxp_kw2xd.dtsi +++ b/dts/arm/nxp/nxp_kw2xd.dtsi @@ -1,4 +1,8 @@ -/* SPDX-License-Identifier: Apache-2.0 */ +/* + * Copyright 2026 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ #include #include @@ -79,8 +83,13 @@ clock-frequency = <32768>; }; + rcm: rcm@4007F000 { + compatible = "nxp,rcm-hwinfo"; + reg = <0x4007F000 0x1000>; + }; + sim: sim@40047000 { - compatible = "nxp,kinetis-sim"; + compatible = "nxp,kinetis-sim", "nxp,sim-uuid"; reg = <0x40047000 0x1060>; #clock-cells = <3>; diff --git a/dts/arm/nxp/nxp_kw40z.dtsi b/dts/arm/nxp/nxp_kw40z.dtsi index cd89adf080ce..88feb64b3dbb 100644 --- a/dts/arm/nxp/nxp_kw40z.dtsi +++ b/dts/arm/nxp/nxp_kw40z.dtsi @@ -1,4 +1,8 @@ -/* SPDX-License-Identifier: Apache-2.0 */ +/* + * Copyright 2026 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ #include #include @@ -56,8 +60,13 @@ clock-frequency = <32768>; }; + rcm: rcm@4007F000 { + compatible = "nxp,rcm-hwinfo"; + reg = <0x4007F000 0x1000>; + }; + sim: sim@40047000 { - compatible = "nxp,kinetis-sim"; + compatible = "nxp,kinetis-sim", "nxp,sim-uuid"; reg = <0x40047000 0x1060>; #clock-cells = <3>; diff --git a/dts/arm/nxp/nxp_kw41z.dtsi b/dts/arm/nxp/nxp_kw41z.dtsi index 3896629aa55e..19680e26d6b8 100644 --- a/dts/arm/nxp/nxp_kw41z.dtsi +++ b/dts/arm/nxp/nxp_kw41z.dtsi @@ -63,8 +63,13 @@ prescaler = <32768>; }; + rcm: rcm@4007F000 { + compatible = "nxp,rcm-hwinfo"; + reg = <0x4007F000 0x1000>; + }; + sim: sim@40047000 { - compatible = "nxp,kinetis-sim"; + compatible = "nxp,kinetis-sim", "nxp,sim-uuid"; reg = <0x40047000 0x1060>; #clock-cells = <3>; diff --git a/dts/arm/nxp/nxp_mcxc_common.dtsi b/dts/arm/nxp/nxp_mcxc_common.dtsi index 2756aa6b7721..90a68cd8e058 100644 --- a/dts/arm/nxp/nxp_mcxc_common.dtsi +++ b/dts/arm/nxp/nxp_mcxc_common.dtsi @@ -92,8 +92,13 @@ #clock-cells = <1>; }; + rcm: rcm@4007F000 { + compatible = "nxp,rcm-hwinfo"; + reg = <0x4007F000 0x1000>; + }; + sim: sim@40047000 { - compatible = "nxp,kinetis-sim"; + compatible = "nxp,kinetis-sim", "nxp,sim-uuid"; reg = <0x40047000 0x1060>; #clock-cells = <3>; From 0a6e0160b4f6910a5810a59a0be3328ee9171acd Mon Sep 17 00:00:00 2001 From: Lucien Zhao Date: Sun, 4 Jan 2026 16:47:09 +0800 Subject: [PATCH 0035/6328] hwinfo: mcux_sim/mcux_rcm: Add new dependency Change to use DT_HAS_NXP_SIM_UUID_ENABLED/DT_HAS_NXP_RCM_HWINFO_ENABLED as the dependency condition for HWINFO_MCUX_SIM/HWINFO_MCUX_RCM to enable the driver when the nxp,sim-uuid/nxp,rcm-hwinfo compatible is present in the devicetree. Signed-off-by: Lucien Zhao --- drivers/hwinfo/Kconfig.mcux_rcm | 2 +- drivers/hwinfo/Kconfig.mcux_sim | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/hwinfo/Kconfig.mcux_rcm b/drivers/hwinfo/Kconfig.mcux_rcm index 871bf5be2606..8e687889c3bb 100644 --- a/drivers/hwinfo/Kconfig.mcux_rcm +++ b/drivers/hwinfo/Kconfig.mcux_rcm @@ -4,7 +4,7 @@ config HWINFO_MCUX_RCM bool "NXP kinetis reset cause" default y - depends on HAS_MCUX_RCM + depends on DT_HAS_NXP_RCM_HWINFO_ENABLED select HWINFO_HAS_DRIVER help Enable NXP kinetis mcux RCM hwinfo driver. diff --git a/drivers/hwinfo/Kconfig.mcux_sim b/drivers/hwinfo/Kconfig.mcux_sim index 54224790a282..0b84a6b29ff8 100644 --- a/drivers/hwinfo/Kconfig.mcux_sim +++ b/drivers/hwinfo/Kconfig.mcux_sim @@ -4,7 +4,7 @@ config HWINFO_MCUX_SIM bool "NXP kinetis SIM device ID" default y - depends on HAS_MCUX_SIM + depends on DT_HAS_NXP_SIM_UUID_ENABLED select HWINFO_HAS_DRIVER help Enable NXP kinetis mcux SIM hwinfo driver. From 0e0757cc3c58dadcada2b753270ff25ecd40720e Mon Sep 17 00:00:00 2001 From: Lucien Zhao Date: Mon, 19 Jan 2026 18:01:46 +0800 Subject: [PATCH 0036/6328] soc: nxp: delete HAS_MCUX_SIM/RCM kconfig symbols - Remove HAS_MCUX_SIM and HAS_MCUX_RCM Kconfig symbols on NXP platforms - delete HAS_MCUX_SIM/HAS_MCUX_RCM kconfigs, use dt ways to get enabled SIM/RCM devices Signed-off-by: Lucien Zhao --- modules/hal_nxp/mcux/Kconfig.mcux | 12 ------------ soc/nxp/kinetis/k2x/Kconfig | 4 ---- soc/nxp/kinetis/k32lx/Kconfig | 2 -- soc/nxp/kinetis/k6x/Kconfig | 4 ---- soc/nxp/kinetis/k8x/Kconfig | 2 -- soc/nxp/kinetis/ke1xf/Kconfig | 2 -- soc/nxp/kinetis/ke1xz/Kconfig | 1 - soc/nxp/kinetis/kl2x/Kconfig | 2 -- soc/nxp/kinetis/kv5x/Kconfig | 2 -- soc/nxp/kinetis/kwx/Kconfig | 8 -------- soc/nxp/mcx/mcxc/Kconfig | 2 -- soc/nxp/mcx/mcxe/mcxe24x/Kconfig | 1 - 12 files changed, 42 deletions(-) diff --git a/modules/hal_nxp/mcux/Kconfig.mcux b/modules/hal_nxp/mcux/Kconfig.mcux index a771ce44624b..c12ffb7e8dd8 100644 --- a/modules/hal_nxp/mcux/Kconfig.mcux +++ b/modules/hal_nxp/mcux/Kconfig.mcux @@ -24,12 +24,6 @@ config HAS_MCUX_CACHE help Set if the L1 or L2 cache is present in the SoC. -config HAS_MCUX_SIM - bool - help - Set if the system integration module (SIM) module is present in the - SoC. - config HAS_MCUX_SRC bool help @@ -41,12 +35,6 @@ config HAS_MCUX_RDC help Set if the RDC module is present in the SoC. -config HAS_MCUX_RCM - bool - help - Set if the Reset Control Module (RCM) module is present in - the SoC. - config HAS_MCUX_XCACHE bool help diff --git a/soc/nxp/kinetis/k2x/Kconfig b/soc/nxp/kinetis/k2x/Kconfig index 277962d7d943..dc1b29812594 100644 --- a/soc/nxp/kinetis/k2x/Kconfig +++ b/soc/nxp/kinetis/k2x/Kconfig @@ -18,19 +18,15 @@ config SOC_SERIES_KINETIS_K2X config SOC_MK22F51212 select HAS_MCUX - select HAS_MCUX_SIM select HAS_OSC select HAS_MCG select CPU_HAS_FPU - select HAS_MCUX_RCM # Note- the MK22F12 SKU is a legacy SOC, no longer officially supported by # NXP's MCUX SDK, and not recommended for new designs. config SOC_MK22F12 select HAS_MCUX - select HAS_MCUX_SIM select HAS_OSC select HAS_MCG select CPU_HAS_FPU - select HAS_MCUX_RCM select CPU_HAS_NXP_SYSMPU diff --git a/soc/nxp/kinetis/k32lx/Kconfig b/soc/nxp/kinetis/k32lx/Kconfig index 6f5e3df2370c..e5226ba9b1e3 100644 --- a/soc/nxp/kinetis/k32lx/Kconfig +++ b/soc/nxp/kinetis/k32lx/Kconfig @@ -10,8 +10,6 @@ config SOC_SERIES_K32LX select CPU_CORTEX_M_HAS_VTOR select CPU_CORTEX_M_HAS_SYSTICK select HAS_MCUX - select HAS_MCUX_SIM - select HAS_MCUX_RCM select CLOCK_CONTROL select SOC_RESET_HOOK select SOC_EARLY_INIT_HOOK diff --git a/soc/nxp/kinetis/k6x/Kconfig b/soc/nxp/kinetis/k6x/Kconfig index 0bffab6dd656..4f6d8bb72389 100644 --- a/soc/nxp/kinetis/k6x/Kconfig +++ b/soc/nxp/kinetis/k6x/Kconfig @@ -14,19 +14,15 @@ config SOC_SERIES_KINETIS_K6X config SOC_MK64F12 select HAS_MCUX - select HAS_MCUX_SIM select HAS_OSC select HAS_MCG select CPU_HAS_FPU - select HAS_MCUX_RCM config SOC_MK66F18 select HAS_MCUX - select HAS_MCUX_SIM select HAS_OSC select HAS_MCG select CPU_HAS_FPU - select HAS_MCUX_RCM if SOC_MK66F18 diff --git a/soc/nxp/kinetis/k8x/Kconfig b/soc/nxp/kinetis/k8x/Kconfig index f644593669b8..f858af6b33d7 100644 --- a/soc/nxp/kinetis/k8x/Kconfig +++ b/soc/nxp/kinetis/k8x/Kconfig @@ -12,10 +12,8 @@ config SOC_SERIES_KINETIS_K8X select CPU_HAS_FPU select CLOCK_CONTROL select HAS_MCUX - select HAS_MCUX_SIM select HAS_OSC select HAS_MCG - select HAS_MCUX_RCM select HAS_MCUX_CACHE select SOC_RESET_HOOK select SOC_EARLY_INIT_HOOK diff --git a/soc/nxp/kinetis/ke1xf/Kconfig b/soc/nxp/kinetis/ke1xf/Kconfig index da82f0983f12..be81498f5378 100644 --- a/soc/nxp/kinetis/ke1xf/Kconfig +++ b/soc/nxp/kinetis/ke1xf/Kconfig @@ -13,8 +13,6 @@ config SOC_SERIES_KINETIS_KE1XF select CLOCK_CONTROL select HAS_MCUX select HAS_MCUX_CACHE - select HAS_MCUX_SIM - select HAS_MCUX_RCM select SOC_RESET_HOOK select SOC_EARLY_INIT_HOOK select HAS_PM diff --git a/soc/nxp/kinetis/ke1xz/Kconfig b/soc/nxp/kinetis/ke1xz/Kconfig index 633b24ee7302..f8e878cb13ae 100644 --- a/soc/nxp/kinetis/ke1xz/Kconfig +++ b/soc/nxp/kinetis/ke1xz/Kconfig @@ -14,4 +14,3 @@ config SOC_SERIES_KE1XZ select HAS_PM select SOC_RESET_HOOK select SOC_EARLY_INIT_HOOK - select HAS_MCUX_RCM diff --git a/soc/nxp/kinetis/kl2x/Kconfig b/soc/nxp/kinetis/kl2x/Kconfig index bac4eb5d67a2..7643488e68ee 100644 --- a/soc/nxp/kinetis/kl2x/Kconfig +++ b/soc/nxp/kinetis/kl2x/Kconfig @@ -15,7 +15,5 @@ config SOC_SERIES_KINETIS_KL2X config SOC_MKL25Z4 select CPU_CORTEX_M0PLUS select HAS_MCUX - select HAS_MCUX_SIM select HAS_OSC select HAS_MCG - select HAS_MCUX_RCM diff --git a/soc/nxp/kinetis/kv5x/Kconfig b/soc/nxp/kinetis/kv5x/Kconfig index 086e2f7f85b7..cbbec3bc9865 100644 --- a/soc/nxp/kinetis/kv5x/Kconfig +++ b/soc/nxp/kinetis/kv5x/Kconfig @@ -14,9 +14,7 @@ config SOC_SERIES_KINETIS_KV5X select CPU_HAS_DCACHE select CLOCK_CONTROL select HAS_MCUX - select HAS_MCUX_SIM select HAS_OSC select HAS_MCG - select HAS_MCUX_RCM select SOC_RESET_HOOK select SOC_EARLY_INIT_HOOK diff --git a/soc/nxp/kinetis/kwx/Kconfig b/soc/nxp/kinetis/kwx/Kconfig index 58b8a55e105a..4a2db898b244 100644 --- a/soc/nxp/kinetis/kwx/Kconfig +++ b/soc/nxp/kinetis/kwx/Kconfig @@ -15,32 +15,24 @@ config SOC_MKW22D5 select CPU_CORTEX_M4 select CPU_CORTEX_M_HAS_DWT select HAS_MCUX - select HAS_MCUX_SIM select HAS_OSC select HAS_MCG - select HAS_MCUX_RCM config SOC_MKW24D5 select CPU_CORTEX_M4 select CPU_CORTEX_M_HAS_DWT select HAS_MCUX - select HAS_MCUX_SIM select HAS_OSC select HAS_MCG - select HAS_MCUX_RCM config SOC_MKW40Z4 select CPU_CORTEX_M0PLUS select HAS_MCUX - select HAS_MCUX_SIM select HAS_OSC select HAS_MCG - select HAS_MCUX_RCM config SOC_MKW41Z4 select CPU_CORTEX_M0PLUS select HAS_MCUX - select HAS_MCUX_SIM select HAS_OSC select HAS_MCG - select HAS_MCUX_RCM diff --git a/soc/nxp/mcx/mcxc/Kconfig b/soc/nxp/mcx/mcxc/Kconfig index e37503336493..14aafddeb799 100644 --- a/soc/nxp/mcx/mcxc/Kconfig +++ b/soc/nxp/mcx/mcxc/Kconfig @@ -9,8 +9,6 @@ config SOC_FAMILY_MCXC select CLOCK_CONTROL select SOC_RESET_HOOK select HAS_MCUX - select HAS_MCUX_SIM - select HAS_MCUX_RCM select SOC_EARLY_INIT_HOOK select HAS_SEGGER_RTT if ZEPHYR_SEGGER_MODULE diff --git a/soc/nxp/mcx/mcxe/mcxe24x/Kconfig b/soc/nxp/mcx/mcxe/mcxe24x/Kconfig index 6ed62c6bc95e..94e69e68b807 100644 --- a/soc/nxp/mcx/mcxe/mcxe24x/Kconfig +++ b/soc/nxp/mcx/mcxe/mcxe24x/Kconfig @@ -11,7 +11,6 @@ config SOC_SERIES_MCXE24X select SOC_RESET_HOOK select CPU_HAS_ICACHE select HAS_MCUX_LMEM_CACHE - select HAS_MCUX_RCM if SOC_SERIES_MCXE24X From 0a92e6f908f4eb2d384684ba6dc852c7cf338a89 Mon Sep 17 00:00:00 2001 From: Gang Li Date: Mon, 19 Jan 2026 12:39:41 +0100 Subject: [PATCH 0037/6328] modules: hostap: Fix DPP show UNKNOWN security type after reconfiguration In case DPP reconfiguration test, if the dpp_akm has psk, it will set WPA_KEY_MGMT_PSK | WPA_KEY_MGMT_PSK_SHA256 | WPA_KEY_MGMT_FT_PSK to key_mgmt, then wifi status shows security as "Unknown". Signed-off-by: Gang Li --- modules/hostap/src/supp_api.c | 1 + 1 file changed, 1 insertion(+) diff --git a/modules/hostap/src/supp_api.c b/modules/hostap/src/supp_api.c index 0dced93f4bed..7d6d7b662565 100644 --- a/modules/hostap/src/supp_api.c +++ b/modules/hostap/src/supp_api.c @@ -419,6 +419,7 @@ enum wifi_security_type wpas_key_mgmt_to_zephyr(bool is_hapd, void *config, int } return WIFI_SECURITY_TYPE_UNKNOWN; case WPA_KEY_MGMT_PSK_SHA256 | WPA_KEY_MGMT_PSK: + case WPA_KEY_MGMT_PSK_SHA256 | WPA_KEY_MGMT_PSK | WPA_KEY_MGMT_FT_PSK: case WPA_KEY_MGMT_SAE | WPA_KEY_MGMT_PSK: case WPA_KEY_MGMT_SAE | WPA_KEY_MGMT_PSK_SHA256: case WPA_KEY_MGMT_SAE | WPA_KEY_MGMT_PSK_SHA256 | WPA_KEY_MGMT_PSK: From 4d0852b0051c9b13b59f34bceb0c38148ad12eb1 Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Mon, 19 Jan 2026 13:10:49 +0100 Subject: [PATCH 0038/6328] lib/midi2: Do not add to include path always Do not add this folder to the include path when this component is not enabled. As that creates noise and slows down builds. Signed-off-by: Alberto Escolar Piedras --- lib/midi2/CMakeLists.txt | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/lib/midi2/CMakeLists.txt b/lib/midi2/CMakeLists.txt index 49a11c2ed855..eff93d8a2935 100644 --- a/lib/midi2/CMakeLists.txt +++ b/lib/midi2/CMakeLists.txt @@ -1,8 +1,7 @@ # Copyright (c) 2025 Titouan Christophe # SPDX-License-Identifier: Apache-2.0 -zephyr_include_directories(.) - if(CONFIG_MIDI2_UMP_STREAM_RESPONDER) + zephyr_include_directories(.) zephyr_sources(ump_stream_responder.c) endif() From 2edece9d58db301fbe4a2b76e9a8d298252fedf0 Mon Sep 17 00:00:00 2001 From: Tim Lin Date: Tue, 11 Nov 2025 08:00:21 +0800 Subject: [PATCH 0039/6328] kernel: Add Kconfig option to disable LTO for kernel sources Some SoCs require kernel code to be placed in RAM, which makes link-time optimization (LTO) unsuitable for these files. Disabling LTO allows the affected code to be linked as separate objects and placed in specific memory regions. Running kernel code from RAM can improve execution performance, especially for timing-critical routines or context switch paths. Signed-off-by: Tim Lin --- CMakeLists.txt | 4 +++- kernel/CMakeLists.txt | 5 +++++ kernel/Kconfig | 13 +++++++++++++ 3 files changed, 21 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 7dfdaebe1e34..8502fd51fa13 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -315,7 +315,9 @@ if(CONFIG_LTO) zephyr_compile_options($) add_link_options($) else() - zephyr_compile_options($) + set(genex_tgt_lto "$") + set(genex_lto "$") + zephyr_compile_options("$<$,${genex_tgt_lto}>:${genex_lto}>") add_link_options($) endif() endif() diff --git a/kernel/CMakeLists.txt b/kernel/CMakeLists.txt index 8906da2f6272..29af080b5a63 100644 --- a/kernel/CMakeLists.txt +++ b/kernel/CMakeLists.txt @@ -195,6 +195,11 @@ target_link_libraries(kernel zephyr_interface) endif() +# Optionally build kernel sources without LTO +if(CONFIG_KERNEL_NO_LTO) + set_target_properties(kernel PROPERTIES LTO 0) +endif() + add_dependencies(kernel zephyr_generated_headers) unset(libkernel) diff --git a/kernel/Kconfig b/kernel/Kconfig index 52ef3d531aae..ddfce2a0205f 100644 --- a/kernel/Kconfig +++ b/kernel/Kconfig @@ -1165,6 +1165,19 @@ endif # BOOTARGS endmenu +config KERNEL_NO_LTO + bool + depends on LTO + depends on XIP + help + Some SoCs require kernel code to be placed in RAM, which makes link-time + optimization (LTO) unsuitable for these files (-fno-lto). Disabling LTO + allows the affected code to be linked as separate objects and placed in + specific memory regions. + + Running kernel code from RAM can improve execution performance, especially + for timing-critical routines or context switch paths. + rsource "Kconfig.device" rsource "Kconfig.vm" rsource "Kconfig.init" From 125d88c172dc3ee7a90058615b2c59ed50842d97 Mon Sep 17 00:00:00 2001 From: Tim Lin Date: Tue, 11 Nov 2025 08:51:52 +0800 Subject: [PATCH 0040/6328] soc: it8xxx2: Select KERNEL_NO_LTO only when LTO is enabled Select KERNEL_NO_LTO only when LTO is enabled. This ensures proper handling when kernel code is placed in RAM. Signed-off-by: Tim Lin --- soc/ite/ec/it8xxx2/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/soc/ite/ec/it8xxx2/Kconfig b/soc/ite/ec/it8xxx2/Kconfig index 12b3aeabd591..5a58bf3f3f00 100644 --- a/soc/ite/ec/it8xxx2/Kconfig +++ b/soc/ite/ec/it8xxx2/Kconfig @@ -235,6 +235,7 @@ config SOC_IT8XXX2_KERNEL_IN_RAM bool "Place kernel handling code in RAM" select SOC_IT8XXX2_USE_ILM select SOC_IT8XXX2_LIBRARY_TO_RAM + select KERNEL_NO_LTO if LTO help Place kernel handling code in ILM. This can significantly improve performance. From f9de2777d993c5905b57ba3e59062b097cd2931f Mon Sep 17 00:00:00 2001 From: Aditya Ganesh Date: Wed, 19 Nov 2025 01:20:01 -0700 Subject: [PATCH 0041/6328] drivers: sensor: i3g4250d: migrate SPI support to stmemsc Convert the i3g4250d driver to use the ST MEMS SC API for SPI Signed-off-by: Aditya Ganesh --- drivers/sensor/st/i3g4250d/CMakeLists.txt | 2 +- drivers/sensor/st/i3g4250d/i3g4250d.c | 69 ++++++++------ drivers/sensor/st/i3g4250d/i3g4250d.h | 21 ++++- drivers/sensor/st/i3g4250d/i3g4250d_spi.c | 107 ---------------------- 4 files changed, 59 insertions(+), 140 deletions(-) delete mode 100644 drivers/sensor/st/i3g4250d/i3g4250d_spi.c diff --git a/drivers/sensor/st/i3g4250d/CMakeLists.txt b/drivers/sensor/st/i3g4250d/CMakeLists.txt index 42a2825ad1ca..ec6b72d1392e 100644 --- a/drivers/sensor/st/i3g4250d/CMakeLists.txt +++ b/drivers/sensor/st/i3g4250d/CMakeLists.txt @@ -2,6 +2,6 @@ zephyr_library() -zephyr_library_sources(i3g4250d.c i3g4250d_spi.c) +zephyr_library_sources(i3g4250d.c) zephyr_library_include_directories(../stmemsc) diff --git a/drivers/sensor/st/i3g4250d/i3g4250d.c b/drivers/sensor/st/i3g4250d/i3g4250d.c index 00e5a20fceaa..559f4043edb8 100644 --- a/drivers/sensor/st/i3g4250d/i3g4250d.c +++ b/drivers/sensor/st/i3g4250d/i3g4250d.c @@ -25,6 +25,8 @@ LOG_MODULE_REGISTER(i3g4250d, CONFIG_SENSOR_LOG_LEVEL); static int i3g4250d_sample_fetch(const struct device *dev, enum sensor_channel chan) { + const struct i3g4250d_device_config *cfg = dev->config; + stmdev_ctx_t *ctx = (stmdev_ctx_t *)&cfg->ctx; struct i3g4250d_data *i3g4250d = dev->data; int ret; uint8_t reg; @@ -34,12 +36,12 @@ static int i3g4250d_sample_fetch(const struct device *dev, return -ENOTSUP; } - ret = i3g4250d_flag_data_ready_get(i3g4250d->ctx, ®); + ret = i3g4250d_flag_data_ready_get(ctx, ®); if (ret < 0 || reg != 1) { return ret; } - ret = i3g4250d_angular_rate_raw_get(i3g4250d->ctx, buf); + ret = i3g4250d_angular_rate_raw_get(ctx, buf); if (ret < 0) { LOG_ERR("Failed to fetch raw data sample!"); return ret; @@ -128,13 +130,14 @@ static int i3g4250d_config_gyro(const struct device *dev, enum sensor_attribute attr, const struct sensor_value *val) { - struct i3g4250d_data *i3g4250d = dev->data; + const struct i3g4250d_device_config *cfg = dev->config; + stmdev_ctx_t *ctx = (stmdev_ctx_t *)&cfg->ctx; i3g4250d_dr_t dr_reg; switch (attr) { case SENSOR_ATTR_SAMPLING_FREQUENCY: dr_reg = gyr_odr_to_reg(val); - return i3g4250d_data_rate_set(i3g4250d->ctx, dr_reg); + return i3g4250d_data_rate_set(ctx, dr_reg); default: LOG_ERR("Gyro attribute not supported"); break; @@ -166,16 +169,13 @@ static DEVICE_API(sensor, i3g4250d_driver_api) = { static int i3g4250d_init(const struct device *dev) { - struct i3g4250d_data *i3g4250d = dev->data; + const struct i3g4250d_device_config *cfg = dev->config; + stmdev_ctx_t *ctx = (stmdev_ctx_t *)&cfg->ctx; uint8_t wai; int ret = 0; - ret = i3g4250d_spi_init(dev); - if (ret != 0) { - return ret; - } - ret = i3g4250d_device_id_get(i3g4250d->ctx, &wai); + ret = i3g4250d_device_id_get(ctx, &wai); if (ret != 0) { return ret; } @@ -186,20 +186,20 @@ static int i3g4250d_init(const struct device *dev) } /* Configure filtering chain - Gyroscope - High Pass */ - ret = i3g4250d_filter_path_set(i3g4250d->ctx, I3G4250D_LPF1_HP_ON_OUT); + ret = i3g4250d_filter_path_set(ctx, I3G4250D_LPF1_HP_ON_OUT); if (ret != 0) { LOG_ERR("Failed setting filter path"); return ret; } - ret = i3g4250d_hp_bandwidth_set(i3g4250d->ctx, I3G4250D_HP_LEVEL_3); + ret = i3g4250d_hp_bandwidth_set(ctx, I3G4250D_HP_LEVEL_3); if (ret != 0) { LOG_ERR("Failed setting high pass"); return ret; } /* Set Output data rate */ - ret = i3g4250d_data_rate_set(i3g4250d->ctx, I3G4250D_ODR_100Hz); + ret = i3g4250d_data_rate_set(ctx, I3G4250D_ODR_100Hz); if (ret != 0) { LOG_ERR("Failed setting data rate"); return ret; @@ -208,20 +208,33 @@ static int i3g4250d_init(const struct device *dev) return 0; } -#define I3G4250D_DEVICE_INIT(inst) \ - static struct i3g4250d_data i3g4250d_data_##inst; \ - static const struct i3g4250d_device_config i3g4250d_config_##inst = { \ - .spi = SPI_DT_SPEC_INST_GET(inst, \ - SPI_OP_MODE_MASTER | SPI_MODE_CPOL | \ - SPI_MODE_CPHA | SPI_WORD_SET(8) | SPI_LINES_SINGLE) \ - }; \ - SENSOR_DEVICE_DT_INST_DEFINE(inst, \ - i3g4250d_init, \ - NULL, \ - &i3g4250d_data_##inst, \ - &i3g4250d_config_##inst, \ - POST_KERNEL, \ - CONFIG_SENSOR_INIT_PRIORITY, \ +#define I3G4250D_DEVICE_INIT(inst) \ + static struct i3g4250d_data i3g4250d_data_##inst; \ + SENSOR_DEVICE_DT_INST_DEFINE(inst, \ + i3g4250d_init, \ + NULL, \ + &i3g4250d_data_##inst, \ + &i3g4250d_device_config_##inst, \ + POST_KERNEL, \ + CONFIG_SENSOR_INIT_PRIORITY, \ &i3g4250d_driver_api); +#define I3G4250D_CONFIG_SPI(inst) \ + { \ + STMEMSC_CTX_SPI(&i3g4250d_device_config_##inst.stmemsc_cfg), \ + .stmemsc_cfg = { \ + .spi = SPI_DT_SPEC_INST_GET( \ + inst, \ + SPI_OP_MODE_MASTER | SPI_MODE_CPOL | \ + SPI_MODE_CPHA | SPI_WORD_SET(8) | \ + SPI_LINES_SINGLE), \ + }, \ + } + +#define I3G4250D_DEFINE_SPI(inst) \ + static const struct i3g4250d_device_config i3g4250d_device_config_##inst = \ + I3G4250D_CONFIG_SPI(inst); +#define I3G4250D_DEFINE(inst) \ + I3G4250D_DEFINE_SPI(inst); \ + I3G4250D_DEVICE_INIT(inst) -DT_INST_FOREACH_STATUS_OKAY(I3G4250D_DEVICE_INIT) +DT_INST_FOREACH_STATUS_OKAY(I3G4250D_DEFINE) diff --git a/drivers/sensor/st/i3g4250d/i3g4250d.h b/drivers/sensor/st/i3g4250d/i3g4250d.h index 143b021e0419..75599b64ab7a 100644 --- a/drivers/sensor/st/i3g4250d/i3g4250d.h +++ b/drivers/sensor/st/i3g4250d/i3g4250d.h @@ -12,6 +12,7 @@ #define ZEPHYR_DRIVERS_SENSOR_I3G4250D_I3G4250D_H_ #include +#include #include #include #include @@ -19,16 +20,28 @@ #include #include "i3g4250d_reg.h" +#define DT_DRV_COMPAT_I3G4250D st_i3g4250d + +#define I3G4250D_ANY_INST_ON_BUS_STATUS_OKAY(bus) \ +(DT_HAS_COMPAT_ON_BUS_STATUS_OKAY(DT_DRV_COMPAT_I3G4250D, bus)) + + +#if I3G4250D_ANY_INST_ON_BUS_STATUS_OKAY(spi) +#include +#endif /* I3G4250D_ANY_INST_ON_BUS_STATUS_OKAY(spi) */ + struct i3g4250d_device_config { - struct spi_dt_spec spi; + stmdev_ctx_t ctx; + union { + #if I3G4250D_ANY_INST_ON_BUS_STATUS_OKAY(spi) + const struct spi_dt_spec spi; + #endif + } stmemsc_cfg; }; /* sensor data */ struct i3g4250d_data { int16_t angular_rate[3]; - stmdev_ctx_t *ctx; }; -int i3g4250d_spi_init(const struct device *dev); - #endif /* __SENSOR_I3G4250D__ */ diff --git a/drivers/sensor/st/i3g4250d/i3g4250d_spi.c b/drivers/sensor/st/i3g4250d/i3g4250d_spi.c deleted file mode 100644 index 2483b695f3ca..000000000000 --- a/drivers/sensor/st/i3g4250d/i3g4250d_spi.c +++ /dev/null @@ -1,107 +0,0 @@ -/* - * Copyright (c) 2021 Jonathan Hahn - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#define DT_DRV_COMPAT st_i3g4250d - -#include -#include "i3g4250d.h" - -#if DT_ANY_INST_ON_BUS_STATUS_OKAY(spi) - -#define I3G4250D_SPI_READM (3 << 6) /* 0xC0 */ -#define I3G4250D_SPI_WRITEM (1 << 6) /* 0x40 */ - -LOG_MODULE_DECLARE(i3g4250d, CONFIG_SENSOR_LOG_LEVEL); - -static int i3g4250d_spi_read(const struct device *dev, uint8_t reg, - uint8_t *data, uint16_t len) -{ - int ret; - const struct i3g4250d_device_config *config = dev->config; - uint8_t buffer_tx[2] = { reg | I3G4250D_SPI_READM, 0 }; - const struct spi_buf tx_buf = { - .buf = buffer_tx, - .len = 2, - }; - const struct spi_buf_set tx = { - .buffers = &tx_buf, - .count = 1, - }; - const struct spi_buf rx_buf[2] = { - { - .buf = NULL, - .len = 1, - }, - { - .buf = data, - .len = len, - } - }; - const struct spi_buf_set rx = { - .buffers = rx_buf, - .count = 2, - }; - - ret = spi_transceive_dt(&config->spi, &tx, &rx); - if (ret < 0) { - return ret; - } - - return 0; -} - -static int i3g4250d_spi_write(const struct device *dev, uint8_t reg, - uint8_t *data, uint16_t len) -{ - int ret; - const struct i3g4250d_device_config *config = dev->config; - uint8_t buffer_tx[2] = { reg | I3G4250D_SPI_WRITEM, 0 }; - const struct spi_buf tx_buf[2] = { - { - .buf = buffer_tx, - .len = 1, - }, - { - .buf = data, - .len = len, - } - }; - const struct spi_buf_set tx = { - .buffers = tx_buf, - .count = 2, - }; - - ret = spi_write_dt(&config->spi, &tx); - if (ret < 0) { - return ret; - } - - return 0; -} - -stmdev_ctx_t i3g4250d_spi_ctx = { - .read_reg = (stmdev_read_ptr) i3g4250d_spi_read, - .write_reg = (stmdev_write_ptr) i3g4250d_spi_write, - .mdelay = (stmdev_mdelay_ptr) stmemsc_mdelay, -}; - -int i3g4250d_spi_init(const struct device *dev) -{ - struct i3g4250d_data *i3g4250d = dev->data; - const struct i3g4250d_device_config *cfg = dev->config; - - if (!spi_is_ready_dt(&cfg->spi)) { - LOG_ERR("spi not ready"); - return -ENODEV; - } - - i3g4250d->ctx = &i3g4250d_spi_ctx; - i3g4250d->ctx->handle = (void *)dev; - - return 0; -} - -#endif /* DT_ANY_INST_ON_BUS_STATUS_OKAY(spi) */ From 6524e670b347525a2bd0936967b52120696cdcfc Mon Sep 17 00:00:00 2001 From: James Roy Date: Fri, 12 Dec 2025 22:41:43 +0800 Subject: [PATCH 0042/6328] edtlib: Fix the accidental merging of examples in the binding Fix the example nodes in the examples block being accidentally merged and overwritten during build. Signed-off-by: James Roy --- scripts/dts/python-devicetree/src/devicetree/edtlib.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/dts/python-devicetree/src/devicetree/edtlib.py b/scripts/dts/python-devicetree/src/devicetree/edtlib.py index 8151388a6df2..5324a7553ecd 100644 --- a/scripts/dts/python-devicetree/src/devicetree/edtlib.py +++ b/scripts/dts/python-devicetree/src/devicetree/edtlib.py @@ -2753,7 +2753,7 @@ def _bad_overwrite(to_dict: dict, from_dict: dict, prop: str, return False # These are overridden deliberately - if prop in {"title", "description", "compatible"}: + if prop in {"title", "description", "compatible", "examples"}: return False if prop == "required": From 3989a59e9b0134ed8dd3a612fca317a36dd9db05 Mon Sep 17 00:00:00 2001 From: James Roy Date: Fri, 12 Dec 2025 21:23:45 +0800 Subject: [PATCH 0043/6328] dts: bindings: auxdisplay: Move the dts clips to the examples Move the dts sample nodes from the binding `description` into the `examples` block. Signed-off-by: James Roy --- dts/bindings/auxdisplay/gpio-7-segment.yaml | 48 ++++++++++---------- dts/bindings/auxdisplay/sparkfun,serlcd.yaml | 25 +++++----- 2 files changed, 37 insertions(+), 36 deletions(-) diff --git a/dts/bindings/auxdisplay/gpio-7-segment.yaml b/dts/bindings/auxdisplay/gpio-7-segment.yaml index fb7afddf0150..1299a66a9323 100644 --- a/dts/bindings/auxdisplay/gpio-7-segment.yaml +++ b/dts/bindings/auxdisplay/gpio-7-segment.yaml @@ -17,30 +17,6 @@ description: | high and active low respectively, meaning that the current flows from digit-gpios to segment-gpios. Vice versa for common cathode. - Example: - - #include - - / { - auxdisplay_0: digi-display { - compatible = "gpio-7-segment"; - columns = <3>; - rows = <1>; - segment-gpios = <&gpio0 0 GPIO_ACTIVE_LOW>, /* A */ - <&gpio0 1 GPIO_ACTIVE_LOW>, /* B */ - <&gpio0 2 GPIO_ACTIVE_LOW>, /* C */ - <&gpio0 3 GPIO_ACTIVE_LOW>, /* D */ - <&gpio0 4 GPIO_ACTIVE_LOW>, /* E */ - <&gpio0 5 GPIO_ACTIVE_LOW>, /* F */ - <&gpio0 6 GPIO_ACTIVE_LOW>, /* G */ - <&gpio0 7 GPIO_ACTIVE_LOW>; /* DP */ - digit-gpios = <&gpio1 0 GPIO_ACTIVE_HIGH>, /* DIG1 */ - <&gpio1 1 GPIO_ACTIVE_HIGH>, /* DIG2 */ - <&gpio1 2 GPIO_ACTIVE_HIGH>; /* DIG3 */ - refresh-period-ms = <1>; - }; - }; - compatible: "gpio-7-segment" include: auxdisplay-device.yaml @@ -86,3 +62,27 @@ properties: This is the time between the display of each digit. The refresh period must be long enough to allow the segments to be driven and the digit to be selected. + +examples: + - | + #include + + / { + auxdisplay_0: digi-display { + compatible = "gpio-7-segment"; + columns = <3>; + rows = <1>; + segment-gpios = <&gpio0 0 GPIO_ACTIVE_LOW>, /* A */ + <&gpio0 1 GPIO_ACTIVE_LOW>, /* B */ + <&gpio0 2 GPIO_ACTIVE_LOW>, /* C */ + <&gpio0 3 GPIO_ACTIVE_LOW>, /* D */ + <&gpio0 4 GPIO_ACTIVE_LOW>, /* E */ + <&gpio0 5 GPIO_ACTIVE_LOW>, /* F */ + <&gpio0 6 GPIO_ACTIVE_LOW>, /* G */ + <&gpio0 7 GPIO_ACTIVE_LOW>; /* DP */ + digit-gpios = <&gpio1 0 GPIO_ACTIVE_HIGH>, /* DIG1 */ + <&gpio1 1 GPIO_ACTIVE_HIGH>, /* DIG2 */ + <&gpio1 2 GPIO_ACTIVE_HIGH>; /* DIG3 */ + refresh-period-ms = <1>; + }; + }; diff --git a/dts/bindings/auxdisplay/sparkfun,serlcd.yaml b/dts/bindings/auxdisplay/sparkfun,serlcd.yaml index 2cbfd6a27688..d718d5706877 100644 --- a/dts/bindings/auxdisplay/sparkfun,serlcd.yaml +++ b/dts/bindings/auxdisplay/sparkfun,serlcd.yaml @@ -4,18 +4,6 @@ description: | SparkFun SerLCD Dot Character VFD Controller/Driver IC - Example: - &i2c1 { - serlcd@72 { - compatible = "sparkfun,serlcd"; - reg = <0x72>; - columns = <16>; - rows = <2>; - command-delay-ms = <10>; - special-command-delay-ms = <50>; - }; - }; - compatible: "sparkfun,serlcd" include: [auxdisplay-device.yaml, i2c-device.yaml] @@ -54,3 +42,16 @@ properties: implementation which assumes 100 kbps I2C configuration. This value might require tweaking if using I2C at a higher bitrate and/or relatively high update frequency of the display. + +examples: + - | + &i2c1 { + serlcd@72 { + compatible = "sparkfun,serlcd"; + reg = <0x72>; + columns = <16>; + rows = <2>; + command-delay-ms = <10>; + special-command-delay-ms = <50>; + }; + }; From a93c789c51eba8abd46a9abafe84e53c5e0f1969 Mon Sep 17 00:00:00 2001 From: James Roy Date: Fri, 12 Dec 2025 21:24:24 +0800 Subject: [PATCH 0044/6328] dts: bindings: charger: Move the dts clips to the examples Move the dts sample nodes from the binding `description` into the `examples` block. Signed-off-by: James Roy --- dts/bindings/charger/ti,bq24190.yaml | 22 ++++++------ dts/bindings/charger/ti,bq25180.yaml | 20 +++++------ dts/bindings/charger/ti,bq25186.yaml | 21 ++++++------ dts/bindings/charger/ti,bq25188.yaml | 18 +++++----- dts/bindings/charger/ti,bq25713.yaml | 24 ++++++------- .../charger/x-powers,axp2101-charger.yaml | 34 +++++++++---------- 6 files changed, 70 insertions(+), 69 deletions(-) diff --git a/dts/bindings/charger/ti,bq24190.yaml b/dts/bindings/charger/ti,bq24190.yaml index 78aa7654b57c..b2e3b0d1e508 100644 --- a/dts/bindings/charger/ti,bq24190.yaml +++ b/dts/bindings/charger/ti,bq24190.yaml @@ -8,17 +8,6 @@ description: | BQ2419x I2C controlled, 1-Cell, 4.5-A, USB/Adapter Charger with Narrow VDC Power Path Management and USB OTG - This charger is represented by device tree child node, e.g: - - charger: bq24190@6b { - compatible = "ti,bq24190"; - reg = <0x6b>; - status = "okay"; - - constant-charge-current-max-microamp = <1000000>; - constant-charge-voltage-max-microvolt = <3800000>; - }; - include: [battery.yaml, i2c-device.yaml] compatible: "ti,bq24190" @@ -41,3 +30,14 @@ properties: ce-gpios: type: phandle-array description: Active low, charge enable pin + +examples: + - | + charger: bq24190@6b { + compatible = "ti,bq24190"; + reg = <0x6b>; + status = "okay"; + + constant-charge-current-max-microamp = <1000000>; + constant-charge-voltage-max-microvolt = <3800000>; + }; diff --git a/dts/bindings/charger/ti,bq25180.yaml b/dts/bindings/charger/ti,bq25180.yaml index 200add399b63..022d314d88ba 100644 --- a/dts/bindings/charger/ti,bq25180.yaml +++ b/dts/bindings/charger/ti,bq25180.yaml @@ -3,17 +3,17 @@ description: | BQ25180 I2C Controlled, 1-Cell, 1-A Linear Battery Charger with Power Path - and Ship Mode. - - The device has a single node for the charger. For example: - - bq25180@6a { - compatible = "ti,bq25180"; - reg = <0x6a>; - - constant-charge-current-max-microamp = <500000>; - }; + and Ship Mode. The device has a single node for the charger. compatible: "ti,bq25180" include: ti,bq2518x-common.yaml + +examples: + - | + bq25180@6a { + compatible = "ti,bq25180"; + reg = <0x6a>; + + constant-charge-current-max-microamp = <500000>; + }; diff --git a/dts/bindings/charger/ti,bq25186.yaml b/dts/bindings/charger/ti,bq25186.yaml index 0dd8a54b0c07..5d7efc4d29ca 100644 --- a/dts/bindings/charger/ti,bq25186.yaml +++ b/dts/bindings/charger/ti,bq25186.yaml @@ -3,17 +3,18 @@ description: | BQ25186 I2C Controlled, 1-Cell, 1-A Linear Battery Charger with Power Path, - Ship Mode, Shutdown Mode and Battery Tracking VINDPM. - - The device has a single node for the charger. For example: - - bq25186@6a { - compatible = "ti,bq25186"; - reg = <0x6a>; - - constant-charge-current-max-microamp = <500000>; - }; + Ship Mode, Shutdown Mode and Battery Tracking VINDPM. The device has a single + node for the charger. compatible: "ti,bq25186" include: ti,bq2518x-common.yaml + +examples: + - | + bq25186@6a { + compatible = "ti,bq25186"; + reg = <0x6a>; + + constant-charge-current-max-microamp = <500000>; + }; diff --git a/dts/bindings/charger/ti,bq25188.yaml b/dts/bindings/charger/ti,bq25188.yaml index c3838a46b76a..8a061083f8ba 100644 --- a/dts/bindings/charger/ti,bq25188.yaml +++ b/dts/bindings/charger/ti,bq25188.yaml @@ -5,15 +5,15 @@ description: | BQ25188 I2C Controlled, 1-Cell, 1-A Linear Battery Charger with Power Path, Ship Mode, Shutdown Mode, Battery Tracking VINDPM, and Wide WIN Support. - The device has a single node for the charger. For example: - - bq25188@6a { - compatible = "ti,bq25188"; - reg = <0x6a>; - - constant-charge-current-max-microamp = <500000>; - }; - compatible: "ti,bq25188" include: ti,bq2518x-common.yaml + +examples: + - | + bq25188@6a { + compatible = "ti,bq25188"; + reg = <0x6a>; + + constant-charge-current-max-microamp = <500000>; + }; diff --git a/dts/bindings/charger/ti,bq25713.yaml b/dts/bindings/charger/ti,bq25713.yaml index 1eda1664f351..b32a94c5f63a 100644 --- a/dts/bindings/charger/ti,bq25713.yaml +++ b/dts/bindings/charger/ti,bq25713.yaml @@ -7,18 +7,6 @@ description: | BQ25713 targets 1s to 4s Cell, USB Power Delivery/Adapter Charger with Narrow VDC Power Path Management and Processor Hot Monitor - This charger is represented by device tree child node, e.g: - - charger: bq25713@6b { - compatible = "ti,bq25713"; - reg = <0x6b>; - status = "okay"; - - constant-charge-current-max-microamp = <1000000>; - constant-charge-voltage-max-microvolt = <3800000>; - system-voltage-min-threshold-microvolt = <3328000>; - }; - include: [battery.yaml, i2c-device.yaml] compatible: "ti,bq25713" @@ -46,3 +34,15 @@ properties: Voltage that will be set above when the system voltage drops this level. This value will be set at initialization time. Range: 1.024 V to 16.128 V. The value specified will be rounded down to the closest implemented value. + +examples: + - | + charger: bq25713@6b { + compatible = "ti,bq25713"; + reg = <0x6b>; + status = "okay"; + + constant-charge-current-max-microamp = <1000000>; + constant-charge-voltage-max-microvolt = <3800000>; + system-voltage-min-threshold-microvolt = <3328000>; + }; diff --git a/dts/bindings/charger/x-powers,axp2101-charger.yaml b/dts/bindings/charger/x-powers,axp2101-charger.yaml index d1970411f87e..ceaff03adfcb 100644 --- a/dts/bindings/charger/x-powers,axp2101-charger.yaml +++ b/dts/bindings/charger/x-powers,axp2101-charger.yaml @@ -4,23 +4,6 @@ description: | Charger part of the AXP2101 PMU MFD device. - This charger should be instantiated as child of the AXP2101 MFD device, i.e. - - axp2101@34 { - compatible = "x-powers,axp2101"; - reg = <0x34>; - - charger { - compatible = "x-powers,axp2101-charger"; - constant-charge-current-max-microamp = <300000>; - constant-charge-voltage-max-microvolt = <4200000>; - }; - - regulators { - ... - } - } - compatible: "x-powers,axp2101-charger" on-bus: axp2101 @@ -75,3 +58,20 @@ properties: description: Enable Vbackup on boot. This is normally used to charge a button battery that is used by some RTC IC. + +examples: + - | + axp2101@34 { + compatible = "x-powers,axp2101"; + reg = <0x34>; + + charger { + compatible = "x-powers,axp2101-charger"; + constant-charge-current-max-microamp = <300000>; + constant-charge-voltage-max-microvolt = <4200000>; + }; + + regulators { + ... + } + } From 08ba0d242c58d488667ef68e017d62117e023d45 Mon Sep 17 00:00:00 2001 From: James Roy Date: Tue, 16 Dec 2025 11:14:48 +0800 Subject: [PATCH 0045/6328] dts: bindings: cache: Move the dts clips to the examples Move the dts sample nodes from the binding `description` into the `examples` block. Signed-off-by: James Roy --- dts/bindings/cache/bflb,l1c.yaml | 27 +++++++++++---------------- 1 file changed, 11 insertions(+), 16 deletions(-) diff --git a/dts/bindings/cache/bflb,l1c.yaml b/dts/bindings/cache/bflb,l1c.yaml index 43378277a6fe..b4ba025d3516 100644 --- a/dts/bindings/cache/bflb,l1c.yaml +++ b/dts/bindings/cache/bflb,l1c.yaml @@ -7,22 +7,8 @@ description: | Bouffalo Lab L1C cache control. - The node should be added in the soc group and be provided disabled ways - - soc { - - ... - - cache { - compatible = "bflb,l1c"; - dcache-ways-disabled = <0>; - }; - - ... - - }; - - The cache configuration is specific to the platform, this only provides controls for it. + The node should be added in the soc group and be provided disabled ways, the + cache configuration is specific to the platform. compatible: "bflb,l1c" @@ -39,3 +25,12 @@ properties: - 2 - 3 - 4 + +examples: + - | + soc { + cache { + compatible = "bflb,l1c"; + dcache-ways-disabled = <0>; + }; + }; From 55870811db826f876b53c4785f4b75c43e053934 Mon Sep 17 00:00:00 2001 From: James Roy Date: Tue, 16 Dec 2025 11:15:14 +0800 Subject: [PATCH 0046/6328] dts: bindings: timer: Move the dts clips to the examples Move the dts sample nodes from the binding `description` into the `examples` block. Signed-off-by: James Roy --- dts/bindings/timer/nordic,nrf-grtc.yaml | 23 ++++++++++++----------- dts/bindings/timer/st,stm32-lptim.yaml | 15 +++++++++------ 2 files changed, 21 insertions(+), 17 deletions(-) diff --git a/dts/bindings/timer/nordic,nrf-grtc.yaml b/dts/bindings/timer/nordic,nrf-grtc.yaml index 5b57c8dbeae5..c4e90358a48c 100644 --- a/dts/bindings/timer/nordic,nrf-grtc.yaml +++ b/dts/bindings/timer/nordic,nrf-grtc.yaml @@ -7,17 +7,6 @@ description: | Nordic GRTC (Global RTC) - Example of using clock outputs: - &grtc { - pinctrl-0 = <&grtc_default>; - pinctrl-1 = <&grtc_sleep>; - pinctrl-names = "default", "sleep"; - clkout-fast-frequency-hz = <8000000>; - clkout-32k; - /* In case of nRF54H20 devices: */ - nordic,clockpin-enable = ; - }; - compatible: "nordic,nrf-grtc" include: @@ -52,3 +41,15 @@ properties: description: | Clock frequency information for tick increment operations, this default value comes from the nRF54L15 datasheet. + +examples: + - | + &grtc { + pinctrl-0 = <&grtc_default>; + pinctrl-1 = <&grtc_sleep>; + pinctrl-names = "default", "sleep"; + clkout-fast-frequency-hz = <8000000>; + clkout-32k; + /* In case of nRF54H20 devices: */ + nordic,clockpin-enable = ; + }; diff --git a/dts/bindings/timer/st,stm32-lptim.yaml b/dts/bindings/timer/st,stm32-lptim.yaml index 43b9e311f663..e29b47d81df4 100644 --- a/dts/bindings/timer/st,stm32-lptim.yaml +++ b/dts/bindings/timer/st,stm32-lptim.yaml @@ -4,12 +4,6 @@ description: | STM32 low-power timer (LPTIM). - The lptim node to be used for counting ticks during lowpower modes - must be named stm32_lp_tick_source in the DTS, as follows: - stm32_lp_tick_source: &lptim1 { - status = "okay"; - } - compatible: "st,stm32-lptim" include: @@ -51,3 +45,12 @@ properties: Gives the LPTIM an exact counting value (s) for timeout expiration. Valid range is [1, 256] and should be consistent with st,prescaler pre-defined setting. If not, an error is raised. + +examples: + - | + stm32_lp_tick_source: &lptim1 { + status = "okay"; + } + + The lptim node to be used for counting ticks during lowpower modes + must be named stm32_lp_tick_source in the DTS. From ae556f89143e683f5f6cab2f2c60a88ca48ca1d5 Mon Sep 17 00:00:00 2001 From: James Roy Date: Tue, 20 Jan 2026 23:06:50 +0800 Subject: [PATCH 0047/6328] dts: bindings: can: Move the dts clips to the examples Move the dts sample nodes from the binding `description` into the `examples` block. Signed-off-by: James Roy --- dts/bindings/can/microchip,mcp251xfd.yaml | 35 ++++++++++--------- dts/bindings/can/nxp,flexcan-fd.yaml | 25 +++++++------- dts/bindings/can/nxp,flexcan.yaml | 37 ++++++++++---------- dts/bindings/can/ti,tcan4x5x.yaml | 41 ++++++++++++----------- 4 files changed, 70 insertions(+), 68 deletions(-) diff --git a/dts/bindings/can/microchip,mcp251xfd.yaml b/dts/bindings/can/microchip,mcp251xfd.yaml index ed63da20b4fd..7ffd271f4098 100644 --- a/dts/bindings/can/microchip,mcp251xfd.yaml +++ b/dts/bindings/can/microchip,mcp251xfd.yaml @@ -4,24 +4,6 @@ description: | Microchip MCP251XFD SPI CAN FD controller - The MCP251XFD node is defined on an SPI bus. An example - configuration is: - - &mikrobus_spi { - cs-gpios = <&mikrobus_header 2 GPIO_ACTIVE_LOW>; - - mcp2518fd_mikroe_mcp2518fd_click: mcp2518fd@0 { - compatible = "microchip,mcp251xfd"; - status = "okay"; - - spi-max-frequency = <18000000>; - int-gpios = <&mikrobus_header 7 GPIO_ACTIVE_LOW>; - reg = <0x0>; - osc-freq = <40000000>; - - }; - }; - compatible: "microchip,mcp251xfd" include: [spi-device.yaml, can-fd-controller.yaml] @@ -78,3 +60,20 @@ properties: - 2 - 4 - 10 + +examples: + - | + &mikrobus_spi { + cs-gpios = <&mikrobus_header 2 GPIO_ACTIVE_LOW>; + + mcp2518fd_mikroe_mcp2518fd_click: mcp2518fd@0 { + compatible = "microchip,mcp251xfd"; + status = "okay"; + + spi-max-frequency = <18000000>; + int-gpios = <&mikrobus_header 7 GPIO_ACTIVE_LOW>; + reg = <0x0>; + osc-freq = <40000000>; + + }; + }; diff --git a/dts/bindings/can/nxp,flexcan-fd.yaml b/dts/bindings/can/nxp,flexcan-fd.yaml index 4614cdd9a12b..bc5328b29500 100644 --- a/dts/bindings/can/nxp,flexcan-fd.yaml +++ b/dts/bindings/can/nxp,flexcan-fd.yaml @@ -6,7 +6,19 @@ description: | This is a specialization of the NXP FlexCAN CAN controller with support for CAN FD. - Example: +compatible: "nxp,flexcan-fd" + +include: ["nxp,flexcan.yaml", "can-fd-controller.yaml", "pinctrl-device.yaml", + "nxp,rdc-policy.yaml"] + +properties: + number-of-mb-fd: + type: int + required: true + description: Number of 64-byte payload message buffers FlexCAN FD instance supported + +examples: + - | flexcan3: can@401d8000 { status = "okay"; compatible = "nxp,flexcan-fd", "nxp,flexcan"; @@ -24,14 +36,3 @@ description: | max-bitrate = <5000000>; }; }; - -compatible: "nxp,flexcan-fd" - -include: ["nxp,flexcan.yaml", "can-fd-controller.yaml", "pinctrl-device.yaml", - "nxp,rdc-policy.yaml"] - -properties: - number-of-mb-fd: - type: int - required: true - description: Number of 64-byte payload message buffers FlexCAN FD instance supported diff --git a/dts/bindings/can/nxp,flexcan.yaml b/dts/bindings/can/nxp,flexcan.yaml index 2f6581effd24..731e21aea197 100644 --- a/dts/bindings/can/nxp,flexcan.yaml +++ b/dts/bindings/can/nxp,flexcan.yaml @@ -4,24 +4,6 @@ description: | NXP FlexCAN controller - Example: - flexcan0: can@40024000 { - status = "okay"; - compatible = "nxp,flexcan"; - reg = <0x40024000 0x1000>; - interrupts = <78 0>, <79 0>, <80 0>, <81 0>; - interrupt-names = "warning", "error", "wake-up", "mb-0-15"; - clocks = <&scg KINETIS_SCG_BUS_CLK>; - clk-source = <1>; - number-of-mb = <16>; - pinctrl-0 = <&pinmux_flexcan0>; - pinctrl-names = "default"; - - can-transceiver { - max-bitrate = <1000000>; - }; - }; - compatible: "nxp,flexcan" include: ["can-controller.yaml", "pinctrl-device.yaml"] @@ -60,3 +42,22 @@ properties: type: int required: true description: Number of 8-byte payload message buffers FlexCAN instance supported + +examples: + - | + flexcan0: can@40024000 { + status = "okay"; + compatible = "nxp,flexcan"; + reg = <0x40024000 0x1000>; + interrupts = <78 0>, <79 0>, <80 0>, <81 0>; + interrupt-names = "warning", "error", "wake-up", "mb-0-15"; + clocks = <&scg KINETIS_SCG_BUS_CLK>; + clk-source = <1>; + number-of-mb = <16>; + pinctrl-0 = <&pinmux_flexcan0>; + pinctrl-names = "default"; + + can-transceiver { + max-bitrate = <1000000>; + }; + }; diff --git a/dts/bindings/can/ti,tcan4x5x.yaml b/dts/bindings/can/ti,tcan4x5x.yaml index 75b115d697ce..3a8de6e08993 100644 --- a/dts/bindings/can/ti,tcan4x5x.yaml +++ b/dts/bindings/can/ti,tcan4x5x.yaml @@ -4,26 +4,6 @@ description: | Texas Instruments TCAN4x5x SPI CAN FD controller. - Example: - &spi0 { - tcan4x5x: can@0 { - compatible = ti,tcan4x5x"; - reg = <0>; - spi-max-frequency = <18000000>; - clock-frequency = <40000000>; - device-state-gpios = <&gpio0 0 GPIO_ACTIVE_LOW>; - device-wake-gpios = <&gpio0 1 GPIO_ACTIVE_HIGH>; - reset-gpios = <&gpio0 2 GPIO_ACTIVE_HIGH>; - int-gpios = <&gpio0 3 GPIO_ACTIVE_LOW>; - bosch,mram-cfg = <0x0 15 15 5 5 0 10 10>; - status = "okay"; - - can-transceiver { - max-bitrate = <8000000>; - }; - }; - }; - compatible: "ti,tcan4x5x" include: ["bosch,m_can-base.yaml", "spi-device.yaml"] @@ -58,3 +38,24 @@ properties: required: true description: | GPIO connected to the TCAN4x5x nINT interrupt output. This signal is open-drain, active low. + +examples: + - | + &spi0 { + tcan4x5x: can@0 { + compatible = ti,tcan4x5x"; + reg = <0>; + spi-max-frequency = <18000000>; + clock-frequency = <40000000>; + device-state-gpios = <&gpio0 0 GPIO_ACTIVE_LOW>; + device-wake-gpios = <&gpio0 1 GPIO_ACTIVE_HIGH>; + reset-gpios = <&gpio0 2 GPIO_ACTIVE_HIGH>; + int-gpios = <&gpio0 3 GPIO_ACTIVE_LOW>; + bosch,mram-cfg = <0x0 15 15 5 5 0 10 10>; + status = "okay"; + + can-transceiver { + max-bitrate = <8000000>; + }; + }; + }; From d4bf9ea2e805a8cf36639e207e3eb1c6dc879b13 Mon Sep 17 00:00:00 2001 From: Pieter De Gendt Date: Thu, 8 Jan 2026 15:03:32 +0100 Subject: [PATCH 0048/6328] tests: lib: cobs: Remove malloc/free Use static fixture struct so no malloc/free is needed. Signed-off-by: Pieter De Gendt --- tests/lib/cobs/prj.conf | 2 -- tests/lib/cobs/src/main.c | 41 ++++++++++++++------------------------- 2 files changed, 15 insertions(+), 28 deletions(-) diff --git a/tests/lib/cobs/prj.conf b/tests/lib/cobs/prj.conf index a0821ce3f291..3f2a19bc89b7 100644 --- a/tests/lib/cobs/prj.conf +++ b/tests/lib/cobs/prj.conf @@ -1,4 +1,2 @@ CONFIG_COBS=y CONFIG_ZTEST=y -# cobs test needs some heap, but MINIMAL_LIBC has none by default. -CONFIG_COMMON_LIBC_MALLOC_ARENA_SIZE=256 diff --git a/tests/lib/cobs/src/main.c b/tests/lib/cobs/src/main.c index e9bcc1c9331c..c58bace63dee 100644 --- a/tests/lib/cobs/src/main.c +++ b/tests/lib/cobs/src/main.c @@ -1,9 +1,8 @@ /* * Copyright (c) 2024 Kelly Helmut Lord + * Copyright (c) 2026 Basalte bv * SPDX-License-Identifier: Apache-2.0 */ -#include "zephyr/ztest_assert.h" -#include #include #include @@ -20,23 +19,21 @@ struct cobs_tests_fixture { static void *cobs_test_setup(void) { - struct cobs_tests_fixture *fixture = malloc(sizeof(struct cobs_tests_fixture)); + static struct cobs_tests_fixture fixture; - zassume_not_null(fixture); + fixture.test_data = net_buf_alloc(&test_pool, K_NO_WAIT); + fixture.encoded = net_buf_alloc(&test_pool, K_NO_WAIT); + fixture.decoded = net_buf_alloc(&test_pool, K_NO_WAIT); - fixture->test_data = net_buf_alloc(&test_pool, K_NO_WAIT); - fixture->encoded = net_buf_alloc(&test_pool, K_NO_WAIT); - fixture->decoded = net_buf_alloc(&test_pool, K_NO_WAIT); + zassert_not_null(fixture.test_data, "Failed to allocate test_data buffer"); + zassert_not_null(fixture.encoded, "Failed to allocate encoded buffer"); + zassert_not_null(fixture.decoded, "Failed to allocate decoded buffer"); - zassert_not_null(fixture->test_data, "Failed to allocate test_data buffer"); - zassert_not_null(fixture->encoded, "Failed to allocate encoded buffer"); - zassert_not_null(fixture->decoded, "Failed to allocate decoded buffer"); + net_buf_reset(fixture.test_data); + net_buf_reset(fixture.encoded); + net_buf_reset(fixture.decoded); - net_buf_reset(fixture->test_data); - net_buf_reset(fixture->encoded); - net_buf_reset(fixture->decoded); - - return fixture; + return &fixture; } static void cobs_test_before(void *f) @@ -52,17 +49,9 @@ static void cobs_test_teardown(void *f) { struct cobs_tests_fixture *fixture = (struct cobs_tests_fixture *)f; - if (fixture->test_data) { - net_buf_unref(fixture->test_data); - } - if (fixture->encoded) { - net_buf_unref(fixture->encoded); - } - if (fixture->decoded) { - net_buf_unref(fixture->decoded); - } - - free(fixture); + net_buf_unref(fixture->test_data); + net_buf_unref(fixture->encoded); + net_buf_unref(fixture->decoded); } struct cobs_test_item { From f344ab6b98cc58b3e1c5addc18e92c3930bf09df Mon Sep 17 00:00:00 2001 From: Pieter De Gendt Date: Wed, 7 Jan 2026 16:48:11 +0100 Subject: [PATCH 0049/6328] cobs: Introduce streaming This commit does: - Introduce COBS streaming - Refactor custom delimiter with XOR'ed encoded data - Update tests Signed-off-by: Pieter De Gendt --- include/zephyr/data/cobs.h | 216 ++++++++++++++++++++++++++++-- lib/utils/cobs.c | 268 ++++++++++++++++++++++++++++--------- tests/lib/cobs/src/main.c | 62 +++++---- 3 files changed, 447 insertions(+), 99 deletions(-) diff --git a/include/zephyr/data/cobs.h b/include/zephyr/data/cobs.h index e22f1d2aaaf4..da9f2e0339ab 100644 --- a/include/zephyr/data/cobs.h +++ b/include/zephyr/data/cobs.h @@ -1,5 +1,6 @@ /* * Copyright (c) 2024 Kelly Helmut Lord + * Copyright (c) 2026 Basalte bv * * SPDX-License-Identifier: Apache-2.0 */ @@ -16,20 +17,53 @@ extern "C" { #endif + +/** + * @name COBS Encoder/Decoder Flags + * @anchor COBS_FLAGS + * + * @{ + */ + +/** + * @brief Default COBS delimiter value + * + * The standard COBS delimiter is zero (0x00). This is the delimiter value + * used when COBS_FLAG_CUSTOM_DELIMITER is not specified. + */ #define COBS_DEFAULT_DELIMITER 0x00 /** - * Flag indicating that encode and decode should include an implicit end delimiter + * @brief Flag indicating that encode or decode should include a trailing delimiter + * + * When set, the encoder will append a delimiter byte after the encoded data, + * and the decoder will accept a delimiter byte at the end of the encoded data. */ #define COBS_FLAG_TRAILING_DELIMITER BIT(8) /** - * Macro for extracting delimiter from flags. 8 LSB of "flags" is used for the delimiter + * @brief Macro for setting a custom delimiter in flags + * + * The 8 LSB of "flags" is used for the delimiter value. When a custom delimiter is + * configured, the implementation applies an XOR operation with the delimiter value + * on the encoded data after encoding and before decoding. This allows COBS to work + * with delimiters other than zero. + * + * @param x Custom delimiter value (0-255) + * + * @return Delimiter value masked to 8 bits + * * Example usage: + * @code{.c} * cobs_encode(src_buf, dst_buf, COBS_FLAG_TRAILING_DELIMITER | COBS_FLAG_CUSTOM_DELIMITER(0x7F)); + * @endcode */ #define COBS_FLAG_CUSTOM_DELIMITER(x) ((x) & 0xff) +/** + * @} + */ + /** * @defgroup cobs COBS (Consistent Overhead Byte Stuffing) * @ingroup utilities @@ -46,7 +80,7 @@ extern "C" { * @brief Calculate maximum encoded buffer size * * @param decoded_size Size of input data to be encoded - * @param flags COBS_FLAG_TRAILING_DELIMITER to include termination byte in calculation + * @param flags Encoding flags @ref COBS_FLAGS * * @return Required buffer size for worst-case encoding scenario */ @@ -60,11 +94,13 @@ static inline size_t cobs_max_encoded_len(size_t decoded_size, uint32_t flags) } /** - * @brief Standard COBS encoding + * @brief COBS encoding * - * @param src Source buffer to decode - * @param dst Destination buffer for decoded data - * @param flags Decoding flags (reserved) + * Encodes data from source buffer to destination buffer using COBS encoding. + * + * @param src Source buffer to encode + * @param dst Destination buffer for encoded data + * @param flags Encoding flags @ref COBS_FLAGS * * @retval 0 Success * @retval -ENOMEM Insufficient destination space @@ -74,11 +110,13 @@ static inline size_t cobs_max_encoded_len(size_t decoded_size, uint32_t flags) int cobs_encode(struct net_buf *src, struct net_buf *dst, uint32_t flags); /** - * @brief Standard COBS decoding + * @brief COBS decoding + * + * Decodes COBS-encoded data from source buffer to destination buffer. * * @param src Source buffer to decode * @param dst Destination buffer for decoded data - * @param flags Decoding flags (reserved) + * @param flags Decoding flags @ref COBS_FLAGS * * @retval 0 Success * @retval -ENOMEM Insufficient destination space @@ -86,6 +124,166 @@ int cobs_encode(struct net_buf *src, struct net_buf *dst, uint32_t flags); */ int cobs_decode(struct net_buf *src, struct net_buf *dst, uint32_t flags); +/** + * @brief Callback function type for streaming COBS encoder/decoder + * + * This callback is invoked by the streaming encoder/decoder to output + * processed data chunks. + * A decoder that allows trailing delimiters and encounters one will invoke + * this callback with a NULL pointer and zero length indicating a completed frame. + * + * When this callback function returns a negative error value, the encoder or decoder + * stream is aborted and the error will be propagated. + * + * @param buf Buffer containing processed data + * @param len Length of data in buffer + * @param user_data User-provided context pointer + * + * @return 0 on success, negative errno code on failure + */ +typedef int (*cobs_stream_cb)(const uint8_t *buf, size_t len, void *user_data); + +/** + * @brief COBS streaming encoder state + * + * This structure maintains the state for incremental COBS encoding. + * It should be initialized with cobs_encoder_init() before use. + */ +struct cobs_encoder { + /** @cond INTERNAL_HIDDEN */ + /** Callback function to output encoded data */ + cobs_stream_cb cb; + /** User data pointer passed to callback */ + void *cb_user_data; + + /** Internal buffer for partial encoding */ + uint8_t fragment[255]; + /** Encoding flags @ref COBS_FLAGS */ + uint32_t flags; + /** @endcond */ +}; + +/** + * @brief COBS streaming decoder state + * + * This structure maintains the state for incremental COBS decoding. + * It should be initialized with cobs_decoder_init() before use. + */ +struct cobs_decoder { + /** @cond INTERNAL_HIDDEN */ + /** Callback function to output decoded data */ + cobs_stream_cb cb; + /** User data pointer passed to callback */ + void *cb_user_data; + + /** Current COBS code byte being processed */ + uint8_t code; + /** Position within current code block */ + uint8_t code_index; + /** Decoding flags @ref COBS_FLAGS */ + uint32_t flags; + /** @endcond */ +}; + +/** + * @brief Initialize COBS streaming encoder + * + * Initializes a COBS encoder for streaming operation. The encoder will call + * the provided callback function to output encoded data chunks as they become + * available. + * + * @param enc Pointer to encoder structure to initialize + * @param cb Callback function for output data + * @param user_data User data pointer passed to callback + * @param flags Encoding flags @ref COBS_FLAGS + * + * @return 0 on success, negative errno code on failure + */ +int cobs_encoder_init(struct cobs_encoder *enc, cobs_stream_cb cb, void *user_data, uint32_t flags); + +/** + * @brief Finalize COBS streaming encoder + * + * Flushes any remaining data and optionally writes trailing delimiter if + * COBS_FLAG_TRAILING_DELIMITER was set during initialization. + * + * The encoder state will be reset. + * + * @param enc Pointer to encoder structure + * + * @return 0 on success, negative errno code on failure + */ +int cobs_encoder_close(struct cobs_encoder *enc); + +/** + * @brief Write data to COBS streaming encoder + * + * Encodes the provided data and outputs encoded chunks via the registered + * callback function. This function can be called multiple times to encode + * data incrementally. + * + * In case an error is returned, the encoder state will be reset. + * + * @param enc Pointer to encoder structure + * @param buf Buffer containing data to encode + * @param len Length of data in buffer + * + * @return Number of bytes used from @p buf on success, negative errno code on failure + */ +int cobs_encoder_write(struct cobs_encoder *enc, const uint8_t *buf, size_t len); + +/** + * @brief Initialize COBS streaming decoder + * + * Initializes a COBS decoder for streaming operation. The decoder will call + * the provided callback function to output decoded data chunks as they become + * available. + * + * @param dec Pointer to decoder structure to initialize + * @param cb Callback function for output data + * @param user_data User data pointer passed to callback + * @param flags Decoding flags @ref COBS_FLAGS + * + * @return 0 on success, negative errno code on failure + */ +int cobs_decoder_init(struct cobs_decoder *dec, cobs_stream_cb cb, void *user_data, uint32_t flags); + +/** + * @brief Finalize COBS streaming decoder + * + * Completes the decoding process and verifies that the stream ended properly. + * Should be called after all data has been written to the decoder. + * + * The decoder state will be reset. + * + * @param dec Pointer to decoder structure + * + * @retval 0 Success + * @retval -EINVAL More data was expected before closing + */ +int cobs_decoder_close(struct cobs_decoder *dec); + +/** + * @brief Write data to COBS streaming decoder + * + * Decodes the provided encoded data and outputs decoded chunks via the + * registered callback function. This function can be called multiple times + * to decode data incrementally. + * + * In case an error is returned, the decoder state will be reset. + * + * @note If a delimiter is encountered, and the @ref COBS_FLAG_TRAILING_DELIMITER flag + * is set, the registered callback function will be called with a NULL pointer + * indicating a frame end. + * + * @param dec Pointer to decoder structure + * @param buf Buffer containing encoded data + * @param len Length of data in buffer + * + * @return Number of bytes used from @p buf on success, negative errno code on failure + */ +int cobs_decoder_write(struct cobs_decoder *dec, const uint8_t *buf, size_t len); + /** @} */ #ifdef __cplusplus diff --git a/lib/utils/cobs.c b/lib/utils/cobs.c index d500eb2b86f5..e364d1729bb8 100644 --- a/lib/utils/cobs.c +++ b/lib/utils/cobs.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2024 Kelly Helmut Lord + * Copyright (c) 2026 Basalte bv * * SPDX-License-Identifier: Apache-2.0 */ @@ -8,97 +9,242 @@ #include #include +static int cobs_net_buf_cb(const uint8_t *buf, size_t len, void *user_data) +{ + struct net_buf *dst = user_data; + + if (net_buf_tailroom(dst) < len) { + return -ENOMEM; + } + + (void)net_buf_add_mem(dst, buf, len); + + return 0; +} + int cobs_encode(struct net_buf *src, struct net_buf *dst, uint32_t flags) { - uint8_t delimiter = COBS_FLAG_CUSTOM_DELIMITER(flags); + struct cobs_encoder enc; + size_t len = src->len; + int ret; - /* Calculate required space for worst case */ - size_t max_encoded_size = cobs_max_encoded_len(src->len, flags); + (void)cobs_encoder_init(&enc, cobs_net_buf_cb, dst, flags); - /* Check if destination has enough space */ - if (net_buf_tailroom(dst) < max_encoded_size) { - return -ENOMEM; + ret = cobs_encoder_write(&enc, net_buf_pull_mem(src, len), len); + if (ret < 0) { + return ret; } - uint8_t *code_ptr = net_buf_add(dst, 1); - uint8_t code = 1; - - /* Process all input bytes */ - uint8_t data = 0; - - while (src->len > 0) { - data = net_buf_pull_u8(src); - if (data == delimiter) { - /* Delimiter found - write current code and start new block */ - *code_ptr = code; - code_ptr = net_buf_add(dst, 1); - code = 1; - } else { - /* Add non-zero byte to output */ - net_buf_add_u8(dst, data); - code++; - - /* If we've reached maximum block size, start a new block */ - if (code == 0xFF && (src->len - 1 >= 0)) { - *code_ptr = code; - code_ptr = net_buf_add(dst, 1); - code = 1; - } + return cobs_encoder_close(&enc); +} + +int cobs_decode(struct net_buf *src, struct net_buf *dst, uint32_t flags) +{ + struct cobs_decoder dec; + size_t len = src->len; + int ret; + + (void)cobs_decoder_init(&dec, cobs_net_buf_cb, dst, flags); + + ret = cobs_decoder_write(&dec, net_buf_pull_mem(src, len), len); + if (ret < 0) { + return ret; + } + + return cobs_decoder_close(&dec); +} + +static inline void cobs_encoder_reset(struct cobs_encoder *enc) +{ + /* Reset buffer */ + enc->fragment[0] = 1; +} + +static int cobs_encoder_finish(struct cobs_encoder *enc, bool close) +{ + uint8_t sentinel = COBS_FLAG_CUSTOM_DELIMITER(enc->flags); + size_t len = enc->fragment[0]; + int ret; + + if (sentinel != 0x00) { + for (size_t i = 0; i < len; ++i) { + enc->fragment[i] ^= sentinel; } } - *code_ptr = code; + ret = enc->cb(enc->fragment, len, enc->cb_user_data); + if (ret < 0) { + cobs_encoder_reset(enc); + return ret; + } - if (flags & COBS_FLAG_TRAILING_DELIMITER) { - /* Add final delimiter */ - net_buf_add_u8(dst, delimiter); + if (close && (enc->flags & COBS_FLAG_TRAILING_DELIMITER) != 0U) { + ret = enc->cb(&sentinel, 1, enc->cb_user_data); + if (ret < 0) { + cobs_encoder_reset(enc); + return ret; + } } + cobs_encoder_reset(enc); + return 0; } -int cobs_decode(struct net_buf *src, struct net_buf *dst, uint32_t flags) +int cobs_encoder_init(struct cobs_encoder *enc, cobs_stream_cb cb, void *user_data, uint32_t flags) { - uint8_t delimiter = COBS_FLAG_CUSTOM_DELIMITER(flags); + if (cb == NULL) { + return -EINVAL; + } - if (flags & COBS_FLAG_TRAILING_DELIMITER) { - uint8_t end_delim = net_buf_remove_u8(src); + __ASSERT_NO_MSG(enc != NULL); - if (end_delim != delimiter) { - return -EINVAL; - } - } + enc->cb = cb; + enc->cb_user_data = user_data; + enc->flags = flags; + + cobs_encoder_reset(enc); + + return 0; +} + +int cobs_encoder_close(struct cobs_encoder *enc) +{ + __ASSERT_NO_MSG(enc != NULL); + + return cobs_encoder_finish(enc, true); +} + +int cobs_encoder_write(struct cobs_encoder *enc, const uint8_t *buf, size_t len) +{ + int ret; - while (src->len > 0) { - /* Pull the COBS offset byte */ - uint8_t offset = net_buf_pull_u8(src); + __ASSERT_NO_MSG(enc != NULL); + __ASSERT_NO_MSG(len <= INT_MAX); - if (offset == delimiter && !(flags & COBS_FLAG_TRAILING_DELIMITER)) { - return -EINVAL; + for (size_t i = 0; i < len; ++i) { + /* Finish if group is full */ + if (enc->fragment[0] == 0xff) { + ret = cobs_encoder_finish(enc, false); + if (ret < 0) { + return ret; + } } - /* Verify we have enough data */ - if (src->len < (offset - 1)) { - return -EINVAL; + if (buf[i] == 0x00) { + ret = cobs_encoder_finish(enc, false); + if (ret < 0) { + return ret; + } + + continue; } - /* Copy offset-1 bytes */ - for (uint8_t i = 0; i < offset - 1; i++) { - uint8_t byte = net_buf_pull_u8(src); + enc->fragment[enc->fragment[0]] = buf[i]; + enc->fragment[0]++; + } + + return len; +} + +static inline void cobs_decoder_reset(struct cobs_decoder *dec) +{ + dec->code = 0xff; + dec->code_index = 0; +} + +static inline bool cobs_decoder_needs_more_data(struct cobs_decoder *dec) +{ + return dec->code_index != 0; +} + +int cobs_decoder_init(struct cobs_decoder *dec, cobs_stream_cb cb, void *user_data, uint32_t flags) +{ + if (cb == NULL) { + return -EINVAL; + } + + __ASSERT_NO_MSG(dec != NULL); + + dec->cb = cb; + dec->cb_user_data = user_data; + dec->flags = flags; - if (byte == delimiter) { + cobs_decoder_reset(dec); + + return 0; +} + +int cobs_decoder_close(struct cobs_decoder *dec) +{ + int ret; + + __ASSERT_NO_MSG(dec != NULL); + + ret = cobs_decoder_needs_more_data(dec) ? -EINVAL : 0; + cobs_decoder_reset(dec); + + return ret; +} + +int cobs_decoder_write(struct cobs_decoder *dec, const uint8_t *buf, size_t len) +{ + uint8_t sentinel = COBS_FLAG_CUSTOM_DELIMITER(dec->flags); + int ret; + + __ASSERT_NO_MSG(dec != NULL); + __ASSERT_NO_MSG(len <= INT_MAX); + + for (size_t i = 0; i < len; ++i) { + uint8_t data = buf[i] ^ sentinel; + + if (data == 0x00) { + if ((dec->flags & COBS_FLAG_TRAILING_DELIMITER) == 0U || + cobs_decoder_needs_more_data(dec)) { + /* Decoder shouldn't get delimiters or unexpected end of data */ + cobs_decoder_reset(dec); return -EINVAL; } - net_buf_add_u8(dst, byte); + + /* Notify frame delimiter was seen */ + ret = dec->cb(NULL, 0, dec->cb_user_data); + if (ret < 0) { + cobs_decoder_reset(dec); + return ret; + } + + /* Reset state */ + cobs_decoder_reset(dec); + continue; + } + + if (dec->code_index > 0) { + ret = dec->cb(&data, 1, dec->cb_user_data); + if (ret < 0) { + cobs_decoder_reset(dec); + return ret; + } + + dec->code_index--; + continue; } - /* If this wasn't a maximum offset and we have more data, - * there was a delimiter here in the original data - */ - if (offset != 0xFF && src->len > 0) { - net_buf_add_u8(dst, delimiter); + dec->code_index = data; + + if (dec->code != 0xff) { + /* Group finished, output zero byte */ + data = 0x00; + + ret = dec->cb(&data, 1, dec->cb_user_data); + if (ret < 0) { + cobs_decoder_reset(dec); + return ret; + } } + + dec->code = dec->code_index; + dec->code_index--; } - return 0; + return len; } diff --git a/tests/lib/cobs/src/main.c b/tests/lib/cobs/src/main.c index c58bace63dee..5ccaeb55340d 100644 --- a/tests/lib/cobs/src/main.c +++ b/tests/lib/cobs/src/main.c @@ -60,18 +60,20 @@ struct cobs_test_item { size_t decoded_len; const uint8_t *encoded; size_t encoded_len; - uint8_t delimiter; + uint32_t flags; }; #define U8(...) (uint8_t[]) __VA_ARGS__ -#define COBS_ITEM(d, e, del, n) \ - {.name = n, \ - .decoded = d, \ - .decoded_len = sizeof(d), \ - .encoded = e, \ - .encoded_len = sizeof(e), \ - .delimiter = del} +#define COBS_ITEM(d, e, f, n) \ + { \ + .name = n, \ + .decoded = d, \ + .decoded_len = sizeof(d), \ + .encoded = e, \ + .encoded_len = sizeof(e), \ + .flags = f, \ + } static const struct cobs_test_item cobs_dataset[] = { COBS_ITEM(U8({}), U8({0x01}), COBS_DEFAULT_DELIMITER, "Empty"), @@ -91,12 +93,16 @@ static const struct cobs_test_item cobs_dataset[] = { COBS_ITEM(U8({'1', '2', '3', '4', '5', 0x00, '6', '7', '8', '9', 0x00}), U8({0x06, '1', '2', '3', '4', '5', 0x05, '6', '7', '8', '9', 0x01}), COBS_DEFAULT_DELIMITER, "Trailing zero"), - COBS_ITEM(U8({}), U8({0x01}), 0x7F, "Empty with custom delimiter 0x7F"), - COBS_ITEM(U8({'1'}), U8({0x02, '1'}), 0x7F, "One char with custom delimiter 0x7F"), - COBS_ITEM(U8({0x7F}), U8({0x01, 0x01}), 0x7F, "One 0x7F delimiter"), - COBS_ITEM(U8({0x7F, 0x7F}), U8({0x01, 0x01, 0x01}), 0x7F, "Two 0x7F delimiters"), - COBS_ITEM(U8({0x7F, 0x7F, 0x7F}), U8({0x01, 0x01, 0x01, 0x01}), 0x7F, - "Three 0x7F delimiters"), + COBS_ITEM(U8({}), U8({0x01 ^ 0x7F}), COBS_FLAG_CUSTOM_DELIMITER(0x7F), + "Empty with custom delimiter 0x7F"), + COBS_ITEM(U8({'1'}), U8({0x7D, '1' ^ 0x7F}), COBS_FLAG_CUSTOM_DELIMITER(0x7F), + "One char with custom delimiter 0x7F"), + COBS_ITEM(U8({0x7F}), U8({0x7D, 0x00}), COBS_FLAG_CUSTOM_DELIMITER(0x7F), + "One 0x7F delimiter"), + COBS_ITEM(U8({0x7F, 0x7F}), U8({0x7C, 0x00, 0x00}), COBS_FLAG_CUSTOM_DELIMITER(0x7F), + "Two 0x7F delimiters"), + COBS_ITEM(U8({0x7F, 0x7F, 0x7F}), U8({0x7B, 0x00, 0x00, 0x00}), + COBS_FLAG_CUSTOM_DELIMITER(0x7F), "Three 0x7F delimiters"), COBS_ITEM( U8({'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'a', 'b', @@ -354,13 +360,12 @@ ZTEST_F(cobs_tests, test_encode) int ret; ARRAY_FOR_EACH(cobs_dataset, idx) { - uint8_t delimiter = cobs_dataset[idx].delimiter; + uint32_t flags = cobs_dataset[idx].flags; net_buf_add_mem(fixture->test_data, cobs_dataset[idx].decoded, cobs_dataset[idx].decoded_len); - ret = cobs_encode(fixture->test_data, fixture->encoded, - COBS_FLAG_CUSTOM_DELIMITER(delimiter)); + ret = cobs_encode(fixture->test_data, fixture->encoded, flags); zassert_ok(ret, "COBS encoding failed for %s", cobs_dataset[idx].name); zassert_equal(cobs_dataset[idx].encoded_len, fixture->encoded->len, "Encoded length does not match expected for %s", @@ -383,13 +388,12 @@ ZTEST_F(cobs_tests, test_decode) int ret; ARRAY_FOR_EACH(cobs_dataset, idx) { - uint8_t delimiter = cobs_dataset[idx].delimiter; + uint32_t flags = cobs_dataset[idx].flags; net_buf_add_mem(fixture->test_data, cobs_dataset[idx].decoded, cobs_dataset[idx].decoded_len); - ret = cobs_decode(fixture->encoded, fixture->test_data, - COBS_FLAG_CUSTOM_DELIMITER(delimiter)); + ret = cobs_decode(fixture->encoded, fixture->test_data, flags); zassert_ok(ret, "COBS decoding failed for %s", cobs_dataset[idx].name); zassert_equal(cobs_dataset[idx].decoded_len, fixture->test_data->len, "Decoded length does not match expected for %s", @@ -412,14 +416,14 @@ ZTEST_F(cobs_tests, test_encode_trailing_delimiter) int ret; ARRAY_FOR_EACH(cobs_dataset, idx) { - uint8_t delimiter = cobs_dataset[idx].delimiter; + uint32_t flags = cobs_dataset[idx].flags; + uint8_t delimiter = COBS_FLAG_CUSTOM_DELIMITER(flags); net_buf_add_mem(fixture->test_data, cobs_dataset[idx].decoded, cobs_dataset[idx].decoded_len); ret = cobs_encode(fixture->test_data, fixture->encoded, - COBS_FLAG_TRAILING_DELIMITER | - COBS_FLAG_CUSTOM_DELIMITER(delimiter)); + COBS_FLAG_TRAILING_DELIMITER | flags); zassert_ok(ret, "COBS encoding failed for %s", cobs_dataset[idx].name); zassert_equal(cobs_dataset[idx].encoded_len + 1, fixture->encoded->len, "Encoded length does not match expected for %s", @@ -445,7 +449,8 @@ ZTEST_F(cobs_tests, test_decode_trailing_delimiter) int ret; ARRAY_FOR_EACH(cobs_dataset, idx) { - uint8_t delimiter = cobs_dataset[idx].delimiter; + uint32_t flags = cobs_dataset[idx].flags; + uint8_t delimiter = COBS_FLAG_CUSTOM_DELIMITER(flags); net_buf_add_mem(fixture->test_data, cobs_dataset[idx].decoded, cobs_dataset[idx].decoded_len); @@ -453,8 +458,7 @@ ZTEST_F(cobs_tests, test_decode_trailing_delimiter) net_buf_add_u8(fixture->encoded, delimiter); ret = cobs_decode(fixture->encoded, fixture->test_data, - COBS_FLAG_TRAILING_DELIMITER | - COBS_FLAG_CUSTOM_DELIMITER(delimiter)); + COBS_FLAG_TRAILING_DELIMITER | flags); zassert_ok(ret, "COBS decoding failed for %s", cobs_dataset[idx].name); zassert_equal(cobs_dataset[idx].decoded_len, fixture->test_data->len, "Decoded length does not match expected for %s", @@ -479,7 +483,7 @@ ZTEST_F(cobs_tests, test_cobs_invalid_delim_pos) net_buf_add_mem(fixture->encoded, data_enc, sizeof(data_enc)); ret = cobs_decode(fixture->encoded, fixture->decoded, 0); - zassert_true(ret == -EINVAL, "Decoding invalid delimiter caught"); + zassert_equal(ret, -EINVAL, "Decoding invalid delimiter caught"); } ZTEST_F(cobs_tests, test_cobs_consecutive_delims) @@ -489,7 +493,7 @@ ZTEST_F(cobs_tests, test_cobs_consecutive_delims) net_buf_add_mem(fixture->encoded, data_enc, sizeof(data_enc)); ret = cobs_decode(fixture->encoded, fixture->decoded, 0); - zassert_true(ret == -EINVAL, "Decoding consecutive delimiters not caught"); + zassert_equal(ret, -EINVAL, "Decoding consecutive delimiters not caught"); } ZTEST_F(cobs_tests, test_cobs_invalid_overrun) @@ -499,5 +503,5 @@ ZTEST_F(cobs_tests, test_cobs_invalid_overrun) net_buf_add_mem(fixture->encoded, data_enc, sizeof(data_enc)); ret = cobs_decode(fixture->encoded, fixture->decoded, 0); - zassert_true(ret == -EINVAL, "Decoding insufficient data not caught"); + zassert_equal(ret, -EINVAL, "Decoding insufficient data not caught"); } From aa76c1d10def3d4d50839e5c42cba946b7e587a0 Mon Sep 17 00:00:00 2001 From: Pieter De Gendt Date: Thu, 8 Jan 2026 14:09:32 +0100 Subject: [PATCH 0050/6328] tests: lib: cobs: Add streaming tests Add test cases for streaming variants of COBS encoder/decoder. Signed-off-by: Pieter De Gendt --- tests/lib/cobs/src/main.c | 160 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 160 insertions(+) diff --git a/tests/lib/cobs/src/main.c b/tests/lib/cobs/src/main.c index 5ccaeb55340d..1e4f5039e707 100644 --- a/tests/lib/cobs/src/main.c +++ b/tests/lib/cobs/src/main.c @@ -383,6 +383,46 @@ ZTEST_F(cobs_tests, test_encode) } } +static int cobs_net_buf_cb(const uint8_t *buf, size_t len, void *user_data) +{ + struct net_buf *dst = user_data; + + if (net_buf_tailroom(dst) < len) { + return -ENOMEM; + } + + (void)net_buf_add_mem(dst, buf, len); + + return 0; +} + +ZTEST_F(cobs_tests, test_encode_stream) +{ + int ret; + + ARRAY_FOR_EACH(cobs_dataset, idx) { + const struct cobs_test_item *test = &cobs_dataset[idx]; + struct cobs_encoder enc; + + ret = cobs_encoder_init(&enc, cobs_net_buf_cb, fixture->encoded, test->flags); + zassert_ok(ret, "encoder init failed for %s (%d)", test->name, ret); + + /* Simulate chunks by sending each byte */ + for (size_t i = 0; i < test->decoded_len; ++i) { + ret = cobs_encoder_write(&enc, &test->decoded[i], 1); + zassert_equal(ret, 1, "encoder write failed (%d) for %s", ret, test->name); + } + + ret = cobs_encoder_close(&enc); + zassert_ok(ret, "encoder close failed for %s (%d)", test->name, ret); + + zassert_equal(test->encoded_len, fixture->encoded->len); + zassert_mem_equal(test->encoded, fixture->encoded->data, test->encoded_len); + + net_buf_reset(fixture->encoded); + } +} + ZTEST_F(cobs_tests, test_decode) { int ret; @@ -411,6 +451,126 @@ ZTEST_F(cobs_tests, test_decode) } } +ZTEST_F(cobs_tests, test_decode_stream) +{ + int ret; + + ARRAY_FOR_EACH(cobs_dataset, idx) { + const struct cobs_test_item *test = &cobs_dataset[idx]; + struct cobs_decoder dec; + + ret = cobs_decoder_init(&dec, cobs_net_buf_cb, fixture->decoded, test->flags); + zassert_ok(ret, "decoder init failed for %s (%d)", test->name, ret); + + /* Simulate chunks by sending each byte */ + for (size_t i = 0; i < test->encoded_len; ++i) { + ret = cobs_decoder_write(&dec, &test->encoded[i], 1); + zassert_equal(ret, 1, "decoder write failed (%d) for %s", ret, test->name); + } + + ret = cobs_decoder_close(&dec); + zassert_ok(ret, "decoder close failed for %s (%d)", test->name, ret); + + zassert_equal(test->decoded_len, fixture->decoded->len); + zassert_mem_equal(test->decoded, fixture->decoded->data, test->decoded_len); + + net_buf_reset(fixture->decoded); + } +} + +static int cobs_forward_to_decoder(const uint8_t *buf, size_t len, void *user_data) +{ + struct cobs_decoder *dec = user_data; + + return cobs_decoder_write(dec, buf, len); +} + +ZTEST_F(cobs_tests, test_encode_decode_stream) +{ + int ret; + + ARRAY_FOR_EACH(cobs_dataset, idx) { + const struct cobs_test_item *test = &cobs_dataset[idx]; + struct cobs_encoder enc; + struct cobs_decoder dec; + + ret = cobs_encoder_init(&enc, cobs_forward_to_decoder, &dec, test->flags); + zassert_ok(ret, "encoder init failed for %s (%d)", test->name, ret); + + ret = cobs_decoder_init(&dec, cobs_net_buf_cb, fixture->decoded, test->flags); + zassert_ok(ret, "decoder init failed for %s (%d)", test->name, ret); + + ret = cobs_encoder_write(&enc, test->decoded, test->decoded_len); + zassert_equal(ret, test->decoded_len, "encoder write failed for %s (%d)", + test->name, ret); + + ret = cobs_encoder_close(&enc); + zassert_ok(ret, "encoder close failed for %s (%d)", test->name, ret); + + ret = cobs_decoder_close(&dec); + zassert_ok(ret, "decoder close failed for %s (%d)", test->name, ret); + + zassert_equal(test->decoded_len, fixture->decoded->len); + zassert_mem_equal(test->decoded, fixture->decoded->data, test->decoded_len); + + net_buf_reset(fixture->decoded); + } +} + +static size_t frame_test_idx; + +static int cobs_frame_tester(const uint8_t *buf, size_t len, void *user_data) +{ + struct net_buf *dst = user_data; + + if (buf == NULL) { + const struct cobs_test_item *test = &cobs_dataset[frame_test_idx]; + + zassert_equal(test->decoded_len, dst->len); + zassert_mem_equal(test->decoded, dst->data, test->decoded_len); + + net_buf_reset(dst); + frame_test_idx++; + return 0; + } + + if (net_buf_tailroom(dst) < len) { + return -ENOMEM; + } + + (void)net_buf_add_mem(dst, buf, len); + + return 0; +} + +ZTEST_F(cobs_tests, test_decode_stream_frame_complete) +{ + struct cobs_encoder enc; + struct cobs_decoder dec; + int ret; + + /* This test re-uses the same encoder/decoder pair and streams multiple frames */ + + ret = cobs_encoder_init(&enc, cobs_forward_to_decoder, &dec, COBS_FLAG_TRAILING_DELIMITER); + zassert_ok(ret, "encoder init failed (%d)", ret); + + ret = cobs_decoder_init(&dec, cobs_frame_tester, fixture->decoded, + COBS_FLAG_TRAILING_DELIMITER); + zassert_ok(ret, "decoder init failed (%d)", ret); + + ARRAY_FOR_EACH(cobs_dataset, idx) { + ret = cobs_encoder_write(&enc, cobs_dataset[idx].decoded, + cobs_dataset[idx].decoded_len); + zassert_equal(ret, cobs_dataset[idx].decoded_len); + + /* Closing will write a delimiter and reset the state */ + ret = cobs_encoder_close(&enc); + zassert_ok(ret); + } + + zassert_equal(frame_test_idx, ARRAY_SIZE(cobs_dataset)); +} + ZTEST_F(cobs_tests, test_encode_trailing_delimiter) { int ret; From 3a961db1261055cba3814ac371c090fb2e3b038d Mon Sep 17 00:00:00 2001 From: Pieter De Gendt Date: Fri, 9 Jan 2026 13:17:58 +0100 Subject: [PATCH 0051/6328] doc: releases: 4.4: Add COBS streaming support entry Add a Utilities entry with added COBS structs and functions. Signed-off-by: Pieter De Gendt --- doc/releases/release-notes-4.4.rst | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/doc/releases/release-notes-4.4.rst b/doc/releases/release-notes-4.4.rst index 28e31ee4f11c..a839131be85c 100644 --- a/doc/releases/release-notes-4.4.rst +++ b/doc/releases/release-notes-4.4.rst @@ -243,6 +243,19 @@ New APIs and options * :kconfig:option:`CONFIG_TIMEUTIL_APPLY_SKEW` +* Utilities + + * :abbr:`COBS (Consistent Overhead Byte Stuffing)` streaming support + + * :c:struct:`cobs_decoder` + * :c:func:`cobs_decoder_init` + * :c:func:`cobs_decoder_write` + * :c:func:`cobs_decoder_close` + * :c:struct:`cobs_encoder` + * :c:func:`cobs_encoder_init` + * :c:func:`cobs_encoder_write` + * :c:func:`cobs_encoder_close` + * Video * :kconfig:option:`CONFIG_VIDEO_BUFFER_POOL_HEAP_SIZE` From ae44e1e7b7189d8e10377aa5b34b94d6190fd400 Mon Sep 17 00:00:00 2001 From: Gaetan Perrot Date: Fri, 9 Jan 2026 01:51:01 +0900 Subject: [PATCH 0052/6328] drivers: sensor: ina2xx: fetch: remove redundant channel NULL checks The INA2xx fetch path assumes valid channel descriptors for all supported sensor channels. NULL checks performed after channel data is accessed are ineffective and misleading, as invalid channel definitions indicate a configuration error rather than a runtime condition. Remove the redundant checks and keep the channel handling consistent with the driver expectations. No functional change intended. Signed-off-by: Gaetan Perrot --- drivers/sensor/ti/ina2xx/ina2xx_fetch.c | 28 ------------------------- 1 file changed, 28 deletions(-) diff --git a/drivers/sensor/ti/ina2xx/ina2xx_fetch.c b/drivers/sensor/ti/ina2xx/ina2xx_fetch.c index 01e7ef138e78..c0b39e03d78c 100644 --- a/drivers/sensor/ti/ina2xx/ina2xx_fetch.c +++ b/drivers/sensor/ti/ina2xx/ina2xx_fetch.c @@ -13,10 +13,6 @@ static int ina2xx_fetch_bus_voltage(const struct device *dev) const struct ina2xx_channel *ch = config->channels->voltage; struct ina2xx_data *data = dev->data; - if (ch == NULL) { - return -ENOTSUP; - } - return ina2xx_reg_read(&config->bus, ch->reg, data->voltage, sizeof(data->voltage)); } @@ -30,10 +26,6 @@ static int ina2xx_fetch_shunt_voltage(const struct device *dev) const struct ina2xx_channel *ch = config->channels->vshunt; struct ina2xx_data *data = dev->data; - if (ch == NULL) { - return -ENOTSUP; - } - return ina2xx_reg_read(&config->bus, ch->reg, data->vshunt, sizeof(data->vshunt)); } @@ -47,10 +39,6 @@ static int ina2xx_fetch_current(const struct device *dev) const struct ina2xx_channel *ch = config->channels->current; struct ina2xx_data *data = dev->data; - if (ch == NULL) { - return -ENOTSUP; - } - return ina2xx_reg_read(&config->bus, ch->reg, data->current, sizeof(data->current)); } @@ -64,10 +52,6 @@ static int ina2xx_fetch_power(const struct device *dev) const struct ina2xx_channel *ch = config->channels->power; struct ina2xx_data *data = dev->data; - if (ch == NULL) { - return -ENOTSUP; - } - return ina2xx_reg_read(&config->bus, ch->reg, data->power, sizeof(data->power)); } @@ -81,10 +65,6 @@ static int ina2xx_fetch_die_temp(const struct device *dev) const struct ina2xx_channel *ch = config->channels->die_temp; struct ina2xx_data *data = dev->data; - if (ch == NULL) { - return -ENOTSUP; - } - return ina2xx_reg_read(&config->bus, ch->reg, data->die_temp, sizeof(data->die_temp)); } @@ -99,10 +79,6 @@ static int ina2xx_fetch_energy(const struct device *dev) const struct ina2xx_channel *ch = config->channels->energy; struct ina2xx_data *data = dev->data; - if (ch == NULL) { - return -ENOTSUP; - } - return ina2xx_reg_read(&config->bus, ch->reg, data->energy, sizeof(data->energy)); } @@ -116,10 +92,6 @@ static int ina2xx_fetch_charge(const struct device *dev) const struct ina2xx_channel *ch = config->channels->charge; struct ina2xx_data *data = dev->data; - if (ch == NULL) { - return -ENOTSUP; - } - return ina2xx_reg_read(&config->bus, ch->reg, data->charge, sizeof(data->charge)); } From 8340e8c264ca491157516335fa09e1541e3961f2 Mon Sep 17 00:00:00 2001 From: Gaetan Perrot Date: Fri, 9 Jan 2026 01:50:38 +0900 Subject: [PATCH 0053/6328] drivers: sensor: ina2xx: get: remove redundant channel NULL checks The ina2xx channel get helpers assume that channel descriptors are valid when the driver exposes a given sensor channel. Checking for NULL channel pointers after they are already dereferenced does not provide any real safety and can hide configuration errors. Drop the late NULL checks and rely on the driver contract that supported channels must be properly defined. No functional change intended. Signed-off-by: Gaetan Perrot --- drivers/sensor/ti/ina2xx/ina2xx_get.c | 28 --------------------------- 1 file changed, 28 deletions(-) diff --git a/drivers/sensor/ti/ina2xx/ina2xx_get.c b/drivers/sensor/ti/ina2xx/ina2xx_get.c index cc8777be51ef..27fd13201db3 100644 --- a/drivers/sensor/ti/ina2xx/ina2xx_get.c +++ b/drivers/sensor/ti/ina2xx/ina2xx_get.c @@ -20,10 +20,6 @@ static int ina2xx_get_bus_voltage(const struct device *dev, struct sensor_value int32_t s32; } value; - if (ch == NULL) { - return -ENOTSUP; - } - /* 16 or 20 bit, two's complement */ if (bytes == 2) { value.u32 = sys_get_be16(data->voltage) >> ch->shift; @@ -51,10 +47,6 @@ static int ina2xx_get_shunt_voltage(const struct device *dev, struct sensor_valu int32_t s32; } value; - if (ch == NULL) { - return -ENOTSUP; - } - /* 16 or 20 bit, two's complement */ if (bytes == 2) { value.u32 = sys_get_be16(data->vshunt) >> ch->shift; @@ -82,10 +74,6 @@ static int ina2xx_get_current(const struct device *dev, struct sensor_value *val int32_t s32; } value; - if (ch == NULL) { - return -ENOTSUP; - } - /* 16 or 20 bit, two's complement. Multiplied by current lsb */ if (bytes == 2) { value.u32 = sys_get_be16(data->current) >> ch->shift; @@ -110,10 +98,6 @@ static int ina2xx_get_power(const struct device *dev, struct sensor_value *val) struct ina2xx_data *data = dev->data; uint64_t value; - if (ch == NULL) { - return -ENOTSUP; - } - /* 16 or 24 bit, unsigned. Multiplied by current lsb */ if (bytes == 2) { value = sys_get_be16(data->power) >> ch->shift; @@ -139,10 +123,6 @@ static int ina2xx_get_die_temp(const struct device *dev, struct sensor_value *va int64_t s64; } value; - if (ch == NULL) { - return -ENOTSUP; - } - /* 12 or 16 bit, two's complement. */ if (bytes == 2) { value.u64 = sys_get_be16(data->die_temp) >> ch->shift; @@ -164,10 +144,6 @@ static int ina2xx_get_energy(const struct device *dev, struct sensor_value *val) struct ina2xx_data *data = dev->data; uint64_t value; - if (ch == NULL) { - return -ENOTSUP; - } - /* 40 bit, unsigned. Multiplied by current lsb */ if (bytes == 5) { value = sys_get_be40(data->energy) >> ch->shift; @@ -191,10 +167,6 @@ static int ina2xx_get_charge(const struct device *dev, struct sensor_value *val) int64_t s64; } value; - if (ch == NULL) { - return -ENOTSUP; - } - /* 40 bit, two's complement. Multiplied by current lsb */ if (bytes == 5) { value.u64 = sys_get_be40(data->charge) >> ch->shift; From efc36d96d34acc283674ac576ba564f9be163c57 Mon Sep 17 00:00:00 2001 From: Grzegorz Chwierut Date: Fri, 9 Jan 2026 17:51:58 +0100 Subject: [PATCH 0054/6328] twister: refactor DUT class to dataclass for serialization support Convert the DUT class from a traditional class to a dataclass to enable proper serialization and support for future multi-device testing with pytest-harness. Key changes: - Migrated DUT class to use `dataclass` decorator with proper type hints - Renamed `baud` property to `serial_baud` for consistency - Updated hardware map schema to support both `baud` (legacy) and `serial_baud` fields for backward compatibility - Updated tests Signed-off-by: Grzegorz Chwierut --- scripts/pylib/twister/twisterlib/handlers.py | 6 +- .../pylib/twister/twisterlib/hardwaremap.py | 91 ++++++++----------- scripts/pylib/twister/twisterlib/harness.py | 2 +- scripts/schemas/twister/hwmap-schema.yaml | 3 + scripts/tests/twister/test_hardwaremap.py | 38 +++----- scripts/tests/twister/test_harness.py | 2 +- .../twister_blackbox/test_hardwaremap.py | 6 +- 7 files changed, 65 insertions(+), 83 deletions(-) diff --git a/scripts/pylib/twister/twisterlib/handlers.py b/scripts/pylib/twister/twisterlib/handlers.py index 6e321cfec2c0..0b893e8569ed 100755 --- a/scripts/pylib/twister/twisterlib/handlers.py +++ b/scripts/pylib/twister/twisterlib/handlers.py @@ -765,7 +765,7 @@ def handle(self, harness): ser_pty_master, slave = pty.openpty() serial_device = os.ttyname(slave) - logger.debug(f"Using serial device {serial_device} @ {hardware.baud} baud") + logger.debug(f"Using serial device {serial_device} @ {hardware.serial_baud} baud") command = self._create_command(runner, hardware) @@ -787,7 +787,7 @@ def handle(self, harness): ser = self._create_serial_connection( hardware, serial_port, - hardware.baud, + hardware.serial_baud, flash_timeout, serial_pty, ser_pty_process @@ -848,7 +848,7 @@ def handle(self, harness): try: if serial_pty: ser_pty_process = self._start_serial_pty(serial_pty, ser_pty_master) - logger.debug(f"Attach serial device {serial_device} @ {hardware.baud} baud") + logger.debug(f"Attach serial device {serial_device} @ {hardware.serial_baud} baud") ser.port = serial_device # Apply ESP32-specific RTS/DTR reset logic diff --git a/scripts/pylib/twister/twisterlib/hardwaremap.py b/scripts/pylib/twister/twisterlib/hardwaremap.py index 6bbf22099c32..6f32849f27a4 100644 --- a/scripts/pylib/twister/twisterlib/hardwaremap.py +++ b/scripts/pylib/twister/twisterlib/hardwaremap.py @@ -3,13 +3,16 @@ # # Copyright (c) 2022 Intel Corporation # SPDX-License-Identifier: Apache-2.0 +from __future__ import annotations import logging import os import platform import re +from dataclasses import asdict, dataclass, field from multiprocessing import Lock, Value from pathlib import Path +from typing import Any import scl import yaml @@ -32,50 +35,39 @@ logger = logging.getLogger('twister') +@dataclass class DUT: - def __init__(self, - id=None, - serial=None, - serial_baud=None, - platform=None, - product=None, - serial_pty=None, - connected=False, - runner_params=None, - pre_script=None, - post_script=None, - post_flash_script=None, - script_param=None, - runner=None, - flash_timeout=60, - flash_with_test=False, - flash_before=False): - - self.serial = serial - self.baud = serial_baud or 115200 - self.platform = platform - self.serial_pty = serial_pty + """Device Under Test configuration.""" + id: str | None = None + serial: str | None = None + serial_baud: int = 115200 + platform: str | None = None + product: str | None = None + serial_pty: str | None = None + connected: bool = False + runner_params: str | None = None + pre_script: str | None = None + post_script: str | None = None + post_flash_script: str | None = None + script_param: str | None = None + runner: str | None = None + flash_timeout: int = 60 + flash_with_test: bool = False + flash_before: bool = False + fixtures: list[str] = field(default_factory=list) + probe_id: str | None = None + notes: str | None = None + match: bool = False + + def __post_init__(self): + """Initialize non-serializable objects after dataclass initialization.""" + # These are not dataclass fields, so they won't be serialized by asdict() self._counter = Value("i", 0) self._available = Value("i", 1) self._failures = Value("i", 0) - self.connected = connected - self.pre_script = pre_script - self.id = id - self.product = product - self.runner = runner - self.runner_params = runner_params - self.flash_before = flash_before - self.fixtures = [] - self.post_flash_script = post_flash_script - self.post_script = post_script - self.pre_script = pre_script - self.script_param = script_param - self.probe_id = None - self.notes = None self.lock = Lock() - self.match = False - self.flash_timeout = flash_timeout - self.flash_with_test = flash_with_test + # Ensure serial_baud has a default value + self.serial_baud = self.serial_baud or 115200 @property def available(self): @@ -115,19 +107,16 @@ def failures_increment(self, value=1): with self._failures.get_lock(): self._failures.value += value - def to_dict(self): - d = {} - exclude = ['_available', '_counter', '_failures', 'match'] - v = vars(self) - for k in v: - if k not in exclude and v[k]: - d[k] = v[k] - return d - + def to_dict(self) -> dict[str, Any]: + """Convert DUT dataclass to dictionary for YAML serialization.""" + result = asdict(self) + # Remove None and False values and empty lists to keep YAML clean + return {k: v for k, v in result.items() if v} def __repr__(self): return f"<{self.platform} ({self.product}) on {self.serial}>" + class HardwareMap: schema_path = os.path.join(ZEPHYR_BASE, "scripts", "schemas", "twister", "hwmap-schema.yaml") @@ -170,7 +159,7 @@ class HardwareMap: } def __init__(self, env=None): - self.detected = [] + self.detected: list[DUT] = [] self.duts: list[DUT] = [] self.options = env.options @@ -295,7 +284,7 @@ def load(self, map_file): runner = dut.get('runner') runner_params = dut.get('runner_params') serial = dut.get('serial') - baud = dut.get('baud', None) + serial_baud = dut.get('serial_baud', None) or dut.get('baud', None) product = dut.get('product') fixtures = dut.get('fixtures', []) connected = dut.get('connected') and ((serial or serial_pty) is not None) @@ -309,7 +298,7 @@ def load(self, map_file): id=id, serial_pty=serial_pty, serial=serial, - serial_baud=baud, + serial_baud=serial_baud, connected=connected, pre_script=pre_script, flash_before=flash_before, diff --git a/scripts/pylib/twister/twisterlib/harness.py b/scripts/pylib/twister/twisterlib/harness.py index d00d308c5542..957ebba1b874 100644 --- a/scripts/pylib/twister/twisterlib/harness.py +++ b/scripts/pylib/twister/twisterlib/harness.py @@ -463,7 +463,7 @@ def _generate_parameters_for_hardware(self, handler: Handler): else: command.extend([ f'--device-serial={hardware.serial}', - f'--device-serial-baud={hardware.baud}' + f'--device-serial-baud={hardware.serial_baud}' ]) for extra_serial in handler.get_more_serials_from_device(hardware): command.append(f'--device-serial={extra_serial}') diff --git a/scripts/schemas/twister/hwmap-schema.yaml b/scripts/schemas/twister/hwmap-schema.yaml index 142d4a1969bf..caa58088fd6d 100644 --- a/scripts/schemas/twister/hwmap-schema.yaml +++ b/scripts/schemas/twister/hwmap-schema.yaml @@ -41,6 +41,9 @@ sequence: "baud": type: int required: false + "serial_baud": + type: int + required: false "post_script": type: str required: false diff --git a/scripts/tests/twister/test_hardwaremap.py b/scripts/tests/twister/test_hardwaremap.py index 5d0ea798ed64..f7ed424f996b 100644 --- a/scripts/tests/twister/test_hardwaremap.py +++ b/scripts/tests/twister/test_hardwaremap.py @@ -37,7 +37,7 @@ def mocked_hm(): TESTDATA_1 = [ ( {}, - {'baud': 115200, 'lock': mock.ANY, 'flash_timeout': 60}, + {'serial_baud': 115200, 'flash_timeout': 60}, '' ), ( @@ -63,10 +63,9 @@ def mocked_hm(): } }, { - 'lock': mock.ANY, 'id': 'dummy id', 'serial': 'dummy serial', - 'baud': 4400, + 'serial_baud': 4400, 'platform': 'dummy platform', 'product': 'dummy product', 'serial_pty': 'dummy serial pty', @@ -269,7 +268,7 @@ def test_hardwaremap_load(): runner: r0 flash_with_test: True flash_timeout: 15 - baud: 14400 + serial_baud: 14400 fixtures: - dummy fixture 1 - dummy fixture 2 @@ -310,7 +309,7 @@ def mock_open(*args, **kwargs): 'runner': 'r0', 'flash_timeout': 15, 'flash_with_test': True, - 'baud': 14400, + 'serial_baud': 14400, 'fixtures': ['dummy fixture 1', 'dummy fixture 2'], 'connected': True, 'serial': 'dummy', @@ -322,7 +321,7 @@ def mock_open(*args, **kwargs): 'runner': 'r1', 'flash_timeout': 30, 'flash_with_test': False, - 'baud': 115200, + 'serial_baud': 115200, 'fixtures': [], 'connected': True, 'serial': None, @@ -503,50 +502,45 @@ def mock_exists(path): '', [{ 'serial': 's1', - 'baud': 115200, + 'serial_baud': 115200, 'platform': 'p1', 'connected': True, 'id': 1, 'product': 'pr1', - 'lock': mock.ANY, 'flash_timeout': 60 }, { 'serial': 's2', - 'baud': 115200, + 'serial_baud': 115200, 'platform': 'p2', 'id': 2, 'product': 'pr2', - 'lock': mock.ANY, 'flash_timeout': 60 }, { 'serial': 's3', - 'baud': 115200, + 'serial_baud': 115200, 'platform': 'p3', 'connected': True, 'id': 3, 'product': 'pr3', - 'lock': mock.ANY, 'flash_timeout': 60 }, { 'serial': 's4', - 'baud': 115200, + 'serial_baud': 115200, 'platform': 'p4', 'id': 4, 'product': 'pr4', - 'lock': mock.ANY, 'flash_timeout': 60 }, { 'serial': 's5', - 'baud': 115200, + 'serial_baud': 115200, 'platform': 'p5', 'connected': True, 'id': 5, 'product': 'pr5', - 'lock': mock.ANY, 'flash_timeout': 60 }] ), @@ -603,41 +597,37 @@ def mock_exists(path): }, { 'serial': 's1', - 'baud': 115200, + 'serial_baud': 115200, 'platform': 'p1', 'connected': True, 'id': 1, 'product': 'pr1', - 'lock': mock.ANY, 'flash_timeout': 60 }, { 'serial': 's2', - 'baud': 115200, + 'serial_baud': 115200, 'platform': 'p2', 'id': 2, 'product': 'pr2', - 'lock': mock.ANY, 'flash_timeout': 60 }, { 'serial': 's3', - 'baud': 115200, + 'serial_baud': 115200, 'platform': 'p3', 'connected': True, 'id': 3, 'product': 'pr3', - 'lock': mock.ANY, 'flash_timeout': 60 }, { 'serial': 's5', - 'baud': 115200, + 'serial_baud': 115200, 'platform': 'p5', 'connected': True, 'id': 5, 'product': 'pr5', - 'lock': mock.ANY, 'flash_timeout': 60 }] ), diff --git a/scripts/tests/twister/test_harness.py b/scripts/tests/twister/test_harness.py index fc90205f32e2..62fc6460e788 100644 --- a/scripts/tests/twister/test_harness.py +++ b/scripts/tests/twister/test_harness.py @@ -552,7 +552,7 @@ def test_pytest__generate_parameters_for_hardware(tmp_path, pty_value, hardware_ hardware = mock.Mock() hardware.serial_pty = pty_value hardware.serial = "serial" - hardware.baud = 115200 + hardware.serial_baud = 115200 hardware.runner = "runner" hardware.runner_params = ["--runner-param1", "runner-param2"] hardware.fixtures = ["fixture1:option1", "fixture2"] diff --git a/scripts/tests/twister_blackbox/test_hardwaremap.py b/scripts/tests/twister_blackbox/test_hardwaremap.py index 01bab62313e0..e39ab75c2638 100644 --- a/scripts/tests/twister_blackbox/test_hardwaremap.py +++ b/scripts/tests/twister_blackbox/test_hardwaremap.py @@ -112,7 +112,7 @@ def teardown_class(cls): def test_generate(self, capfd, out_path, manufacturer, product, serial, runner): file_name = "test-map.yaml" path = os.path.join(ZEPHYR_BASE, file_name) - args = ['--outdir', out_path, '--generate-hardware-map', file_name] + args = ['--outdir', out_path, '--generate-hardware-map', path] if os.path.exists(path): os.remove(path) @@ -164,7 +164,7 @@ def mocked_comports(): def test_few_generate(self, capfd, out_path, manufacturer, product, serial, runner): file_name = "test-map.yaml" path = os.path.join(ZEPHYR_BASE, file_name) - args = ['--outdir', out_path, '--generate-hardware-map', file_name] + args = ['--outdir', out_path, '--generate-hardware-map', path] if os.path.exists(path): os.remove(path) @@ -245,7 +245,7 @@ def mocked_comports(): def test_texas_exeption(self, capfd, out_path, manufacturer, product, serial, location): file_name = "test-map.yaml" path = os.path.join(ZEPHYR_BASE, file_name) - args = ['--outdir', out_path, '--generate-hardware-map', file_name] + args = ['--outdir', out_path, '--generate-hardware-map', path] if os.path.exists(path): os.remove(path) From f5bee07bf5822f7c13044771ebfae6ff8abff91c Mon Sep 17 00:00:00 2001 From: Albort Xue Date: Tue, 13 Jan 2026 16:30:13 +0800 Subject: [PATCH 0055/6328] drivers: spi: nxp_lpspi: Add clock configuration support Add clock_control_configure() call during initialization to properly configure the LPSPI clock. The implementation gracefully handles platforms that don't support clock configuration by checking for -ENOTSUP and -ENOSYS return codes and continuing with default settings. Real configuration errors are logged and propagated. Signed-off-by: Albort Xue --- drivers/spi/spi_nxp_lpspi/spi_nxp_lpspi_common.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/drivers/spi/spi_nxp_lpspi/spi_nxp_lpspi_common.c b/drivers/spi/spi_nxp_lpspi/spi_nxp_lpspi_common.c index e0b31c2dd8bc..9a9e5495b747 100644 --- a/drivers/spi/spi_nxp_lpspi/spi_nxp_lpspi_common.c +++ b/drivers/spi/spi_nxp_lpspi/spi_nxp_lpspi_common.c @@ -1,5 +1,5 @@ /* - * Copyright 2018, 2024-2025 NXP + * Copyright 2018, 2024-2026 NXP * * SPDX-License-Identifier: Apache-2.0 */ @@ -384,6 +384,16 @@ int spi_nxp_init_common(const struct device *dev) return -ENODEV; } + err = clock_control_configure(config->clock_dev, config->clock_subsys, NULL); + if (err != 0) { + /* Check if error is due to lack of support */ + if (err != -ENOSYS) { + /* Real error occurred */ + LOG_ERR("Failed to configure clock: %d", err); + return err; + } + } + lpspi_module_system_init(base); data->major_version = (base->VERID & LPSPI_VERID_MAJOR_MASK) >> LPSPI_VERID_MAJOR_SHIFT; From a5dd03b02975d4429f02296ec730bc442033b2ca Mon Sep 17 00:00:00 2001 From: Sylvio Alves Date: Wed, 14 Jan 2026 09:50:26 -0300 Subject: [PATCH 0056/6328] tests: drivers: i2s: initialize i2s_config struct to avoid garbage Initialize the i2s_config struct to zero before use in the test_i2s_state_not_ready_neg test case. When frame_clk_freq is set to 0 to unconfigure a stream, other fields in the struct were left uninitialized. On platforms with userspace support, the syscall handler validates block_size against the mem_slab block size before calling the driver. Uninitialized garbage values could cause this validation to fail unexpectedly. Signed-off-by: Sylvio Alves --- tests/drivers/i2s/i2s_api/src/common.c | 2 +- tests/drivers/i2s/i2s_api/src/test_i2s_states.c | 2 +- tests/drivers/i2s/i2s_speed/src/test_i2s_speed.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/drivers/i2s/i2s_api/src/common.c b/tests/drivers/i2s/i2s_api/src/common.c index 3faadeccf79b..c6338b908146 100644 --- a/tests/drivers/i2s/i2s_api/src/common.c +++ b/tests/drivers/i2s/i2s_api/src/common.c @@ -175,7 +175,7 @@ int rx_block_read(const struct device *dev_i2s, int att) int configure_stream(const struct device *dev_i2s, enum i2s_dir dir) { int ret; - struct i2s_config i2s_cfg; + struct i2s_config i2s_cfg = {0}; i2s_cfg.word_size = 16U; i2s_cfg.channels = 2U; diff --git a/tests/drivers/i2s/i2s_api/src/test_i2s_states.c b/tests/drivers/i2s/i2s_api/src/test_i2s_states.c index 190a87007cf7..8ad895ee31c8 100644 --- a/tests/drivers/i2s/i2s_api/src/test_i2s_states.c +++ b/tests/drivers/i2s/i2s_api/src/test_i2s_states.c @@ -18,7 +18,7 @@ */ ZTEST_USER(i2s_states, test_i2s_state_not_ready_neg) { - struct i2s_config i2s_cfg; + struct i2s_config i2s_cfg = {0}; size_t rx_size; int ret; char rx_buf[BLOCK_SIZE]; diff --git a/tests/drivers/i2s/i2s_speed/src/test_i2s_speed.c b/tests/drivers/i2s/i2s_speed/src/test_i2s_speed.c index a27a8465d1f5..23cabf656f88 100644 --- a/tests/drivers/i2s/i2s_speed/src/test_i2s_speed.c +++ b/tests/drivers/i2s/i2s_speed/src/test_i2s_speed.c @@ -129,7 +129,7 @@ static int verify_buf(int16_t *rx_block, int att) static int configure_stream(const struct device *dev_i2s, enum i2s_dir dir, uint32_t frame_clk_freq) { int ret; - struct i2s_config i2s_cfg; + struct i2s_config i2s_cfg = {0}; i2s_cfg.word_size = 16U; i2s_cfg.channels = 2U; From be501ebb0631f954e65e49321616ca688d112874 Mon Sep 17 00:00:00 2001 From: Sylvio Alves Date: Wed, 14 Jan 2026 10:00:57 -0300 Subject: [PATCH 0057/6328] drivers: i2s: skip syscall validation when unconfiguring stream When frame_clk_freq is set to 0, the I2S API specifies that the stream should transition to NOT_READY state (i.e., unconfigure). In this case, other config fields like mem_slab and block_size are not used by the driver. Skip the mem_slab and block_size validation in the syscall handler when frame_clk_freq is 0 to match the driver behavior and avoid rejecting valid unconfigure requests due to uninitialized fields. Signed-off-by: Sylvio Alves --- drivers/i2s/i2s_handlers.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/i2s/i2s_handlers.c b/drivers/i2s/i2s_handlers.c index 3f1c31a46c7a..c9820f00e290 100644 --- a/drivers/i2s/i2s_handlers.c +++ b/drivers/i2s/i2s_handlers.c @@ -23,6 +23,13 @@ static inline int z_vrfy_i2s_configure(const struct device *dev, K_OOPS(k_usermode_from_copy(&config, (const void *)cfg_ptr, sizeof(struct i2s_config))); + /* When frame_clk_freq is 0, the stream is being disabled/unconfigured + * and other config fields are not used, so skip validation. + */ + if (config.frame_clk_freq == 0U) { + goto do_configure; + } + /* Check that the k_mem_slab provided is a valid pointer and that * the caller has permission on it */ @@ -37,6 +44,7 @@ static inline int z_vrfy_i2s_configure(const struct device *dev, goto out; } +do_configure: ret = z_impl_i2s_configure((const struct device *)dev, dir, &config); out: return ret; From 7c66a65c73dfb58a697d90e092cccfd8606244be Mon Sep 17 00:00:00 2001 From: Jonas Berg Date: Sun, 18 Jan 2026 13:25:04 +0100 Subject: [PATCH 0058/6328] boards: shields: Add Adafruit HTS221 humidity sensor shield Tested with the command mentioned in index.rst Compile testing of the overlay file is done via the dht_polling sample. Product photo from https://learn.adafruit.com/assets/89387 Signed-off-by: Jonas Berg --- boards/shields/adafruit_hts221/Kconfig.shield | 5 ++ .../adafruit_hts221/adafruit_hts221.overlay | 21 ++++++ .../adafruit_hts221/doc/adafruit_hts221.webp | Bin 0 -> 42624 bytes boards/shields/adafruit_hts221/doc/index.rst | 63 ++++++++++++++++++ boards/shields/adafruit_hts221/shield.yml | 10 +++ samples/sensor/dht_polling/sample.yaml | 2 + 6 files changed, 101 insertions(+) create mode 100644 boards/shields/adafruit_hts221/Kconfig.shield create mode 100644 boards/shields/adafruit_hts221/adafruit_hts221.overlay create mode 100644 boards/shields/adafruit_hts221/doc/adafruit_hts221.webp create mode 100644 boards/shields/adafruit_hts221/doc/index.rst create mode 100644 boards/shields/adafruit_hts221/shield.yml diff --git a/boards/shields/adafruit_hts221/Kconfig.shield b/boards/shields/adafruit_hts221/Kconfig.shield new file mode 100644 index 000000000000..f7f427c5ca98 --- /dev/null +++ b/boards/shields/adafruit_hts221/Kconfig.shield @@ -0,0 +1,5 @@ +# Copyright (c) 2026 Jonas Berg +# SPDX-License-Identifier: Apache-2.0 + +config SHIELD_ADAFRUIT_HTS221 + def_bool $(shields_list_contains,adafruit_hts221) diff --git a/boards/shields/adafruit_hts221/adafruit_hts221.overlay b/boards/shields/adafruit_hts221/adafruit_hts221.overlay new file mode 100644 index 000000000000..8a244d3c10a9 --- /dev/null +++ b/boards/shields/adafruit_hts221/adafruit_hts221.overlay @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2026 Jonas Berg + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + aliases { + dht0 = &adafruit_hts221; + }; +}; + +&zephyr_i2c { + status = "okay"; + + adafruit_hts221: hts221@5f { + status = "okay"; + compatible = "st,hts221"; + reg = <0x5f>; + }; +}; diff --git a/boards/shields/adafruit_hts221/doc/adafruit_hts221.webp b/boards/shields/adafruit_hts221/doc/adafruit_hts221.webp new file mode 100644 index 0000000000000000000000000000000000000000..c39662fc629ee88394fdd61dde19d3bcc0eb5157 GIT binary patch literal 42624 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®NT0bCO<0G231Ih+kkDv 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 E04?tNE&u=k literal 0 HcmV?d00001 diff --git a/boards/shields/adafruit_hts221/doc/index.rst b/boards/shields/adafruit_hts221/doc/index.rst new file mode 100644 index 000000000000..0f6ecb2d0aa7 --- /dev/null +++ b/boards/shields/adafruit_hts221/doc/index.rst @@ -0,0 +1,63 @@ +.. _adafruit_hts221: + +Adafruit HTS221 Shield +###################### + +Overview +******** + +The `Adafruit HTS221 Temperature and Humidity Sensor Shield`_ features +a `ST Microelectronics HTS221 Humidity and Temperature Sensor`_ and two STEMMA QT connectors. +It measures temperature and humidity. + +.. figure:: adafruit_hts221.webp + :align: center + :alt: Adafruit HTS221 Shield + + Adafruit HTS221 Shield (Credit: Adafruit) + + +Requirements +************ + +This shield can be used with boards which provide an I2C connector, for example STEMMA QT or +Qwiic connectors. The target board must define a ``zephyr_i2c`` node label. +See :ref:`shields` for more details. + + +Pin Assignments +=============== + ++--------------+------------------------------------+ +| Shield Pin | Function | ++==============+====================================+ +| SDA | I2C SDA | ++--------------+------------------------------------+ +| SCL | I2C SCL | ++--------------+------------------------------------+ +| DRDY | Data ready output | ++--------------+------------------------------------+ +| CS | Keep at high level to use I2C mode | ++--------------+------------------------------------+ + +See :dtcompatible:`st,hts221` for details on possible devicetree settings, for example if you +are using the DRDY pin. + + +Programming +*********** + +Set ``--shield adafruit_hts221`` when you invoke ``west build``. For example +when running the :zephyr:code-sample:`dht_polling` sample: + +.. zephyr-app-commands:: + :zephyr-app: samples/sensor/dht_polling + :board: adafruit_feather_scorpio_rp2040 + :shield: adafruit_hts221 + :goals: build flash + +.. _Adafruit HTS221 Temperature and Humidity Sensor Shield: + https://learn.adafruit.com/adafruit-hts221-temperature-humidity-sensor + +.. _ST Microelectronics HTS221 Humidity and Temperature Sensor: + https://www.st.com/resource/en/datasheet/hts221.pdf diff --git a/boards/shields/adafruit_hts221/shield.yml b/boards/shields/adafruit_hts221/shield.yml new file mode 100644 index 000000000000..546ffd6f5b1f --- /dev/null +++ b/boards/shields/adafruit_hts221/shield.yml @@ -0,0 +1,10 @@ +# SPDX-License-Identifier: Apache-2.0 +# +# Copyright (c) 2026, Jonas Berg + +shield: + name: adafruit_hts221 + full_name: Adafruit HTS221 Temperature and Humidity Sensor Shield + vendor: adafruit + supported_features: + - sensor diff --git a/samples/sensor/dht_polling/sample.yaml b/samples/sensor/dht_polling/sample.yaml index 8d0b182a8c33..74ab8e0b1eec 100644 --- a/samples/sensor/dht_polling/sample.yaml +++ b/samples/sensor/dht_polling/sample.yaml @@ -17,11 +17,13 @@ tests: - adafruit_qt_py_rp2040/rp2040 - adafruit_feather_rp2040/rp2040 - adafruit_feather_canbus_rp2040/rp2040 + - adafruit_feather_scorpio_rp2040/rp2040 - nucleo_f401re extra_args: - platform:adafruit_qt_py_rp2040/rp2040:SHIELD="adafruit_aht20" - platform:adafruit_feather_rp2040/rp2040:SHIELD="adafruit_sht4x" - platform:adafruit_feather_canbus_rp2040/rp2040:SHIELD="sparkfun_shtc3" + - platform:adafruit_feather_scorpio_rp2040/rp2040:SHIELD="adafruit_hts221" harness: console harness_config: fixture: fixture_i2c_hs300x From c2011b9d0f66a5ed936d133fcdf2d86e2cce2273 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Magne=20V=C3=A6rnes?= Date: Mon, 19 Jan 2026 13:36:30 +0100 Subject: [PATCH 0059/6328] lib: posix: add missing getopt_long guard MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Added ifdef guard (CONFIG_GETOPT_LONG) around the functions in getopt_shim.c that requires getopt_long implementation. Signed-off-by: Magne Værnes --- lib/posix/c_lib_ext/getopt_shim.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/posix/c_lib_ext/getopt_shim.c b/lib/posix/c_lib_ext/getopt_shim.c index 1187c53440ab..251029b51cf2 100644 --- a/lib/posix/c_lib_ext/getopt_shim.c +++ b/lib/posix/c_lib_ext/getopt_shim.c @@ -34,6 +34,7 @@ void z_getopt_global_state_update_shim(struct sys_getopt_state *state) optarg = state->optarg; } +#if CONFIG_GETOPT_LONG int getopt_long(int argc, char *const argv[], const char *shortopts, const struct option *longopts, int *longind) { @@ -45,3 +46,4 @@ int getopt_long_only(int argc, char *const argv[], const char *shortopts, { return sys_getopt_long_only(argc, argv, shortopts, longopts, longind); } +#endif From 7294fca0ac1cdf5916c82039af66cd33b1a454c6 Mon Sep 17 00:00:00 2001 From: Sudan Landge Date: Wed, 7 Jan 2026 13:29:18 +0000 Subject: [PATCH 0060/6328] boards: arm: musca: Update flash layout to fix ci failure Flash layout of musca_b1 and musca_s1 is updated as recommended by mcuboot. This also fixes the below cmake build failures reported in Zephyr ci. ``` CMake Error at zephyrproject/zephyr/cmake/modules/extensions.cmake:3877 (message): required nodelabel not found: slot0_partition Call Stack (most recent call first): zephyrproject/zephyr/modules/trusted-firmware-m/CMakeLists.txt:489 (dt_nodelabel) ``` Note that the flash address of musca_b1 board is fixed from 0x0A07_0000 to 0x0A08_0000 as this was missed after the layout was changed in TF-M in e1570bd143ef4843a531b57f77f0c2814b075dd9 Signed-off-by: Sudan Landge --- .../v2m_musca_b1/v2m_musca_b1_musca_b1_ns.dts | 29 +++++++++++++++++-- .../v2m_musca_s1/v2m_musca_s1_musca_s1_ns.dts | 29 +++++++++++++++++-- 2 files changed, 54 insertions(+), 4 deletions(-) diff --git a/boards/arm/v2m_musca_b1/v2m_musca_b1_musca_b1_ns.dts b/boards/arm/v2m_musca_b1/v2m_musca_b1_musca_b1_ns.dts index c24d8c256754..550f9996b8a7 100644 --- a/boards/arm/v2m_musca_b1/v2m_musca_b1_musca_b1_ns.dts +++ b/boards/arm/v2m_musca_b1/v2m_musca_b1_musca_b1_ns.dts @@ -1,5 +1,6 @@ /* * Copyright (c) 2019 Linaro Limited + * Copyright 2026 Arm Limited and/or its affiliates * * SPDX-License-Identifier: Apache-2.0 */ @@ -7,6 +8,7 @@ /dts-v1/; #include +#include / { compatible = "arm,v2m-musca"; @@ -19,6 +21,7 @@ zephyr,console = &uart1; zephyr,sram = &sram0; zephyr,flash = &flash0; + zephyr,code-partitions = &slot0_ns_partition; zephyr,shell-uart = &uart1; }; @@ -40,9 +43,31 @@ }; }; - flash0: flash@a070000 { + flash0: flash@a000000 { /* Embedded flash */ - reg = <0xa070000 0x1a0000>; + compatible = "soc-nv-flash"; + reg = <0x0a000000 DT_SIZE_M(2)>; + erase-block-size = ; + write-block-size = <4>; + #address-cells = <1>; + #size-cells = <1>; + + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + /* Please see the memory layout in: + * https://git.trustedfirmware.org/plugins/gitiles/TF-M/trusted-firmware-m.git/+/refs/heads/main/platform/ext/target/arm/musca_b1/partition/flash_layout.h + */ + slot0_partition: partition@20000 { + reg = <0x20000 DT_SIZE_K(384)>; + }; + + slot0_ns_partition: partition@80000 { + reg = <0x80000 DT_SIZE_K(512)>; + }; + }; }; sram0: memory@20040000 { diff --git a/boards/arm/v2m_musca_s1/v2m_musca_s1_musca_s1_ns.dts b/boards/arm/v2m_musca_s1/v2m_musca_s1_musca_s1_ns.dts index afe985c20f6f..8c9775ba215c 100644 --- a/boards/arm/v2m_musca_s1/v2m_musca_s1_musca_s1_ns.dts +++ b/boards/arm/v2m_musca_s1/v2m_musca_s1_musca_s1_ns.dts @@ -1,5 +1,6 @@ /* * Copyright (c) 2019-2020 Linaro Limited + * Copyright 2026 Arm Limited and/or its affiliates * * SPDX-License-Identifier: Apache-2.0 */ @@ -7,6 +8,7 @@ /dts-v1/; #include +#include / { compatible = "arm,v2m-musca"; @@ -19,6 +21,7 @@ zephyr,console = &uart1; zephyr,sram = &sram0; zephyr,flash = &mram0; + zephyr,code-partitions = &slot0_ns_partition; zephyr,shell-uart = &uart1; }; @@ -40,9 +43,31 @@ }; }; - mram0: mram@a080000 { + mram0: mram@a000000 { /* Internal code eMRAM */ - reg = <0x0a080000 0x80000>; + compatible = "soc-nv-flash"; + reg = <0x0a000000 DT_SIZE_M(2)>; + erase-block-size = ; + write-block-size = <1>; + #address-cells = <1>; + #size-cells = <1>; + + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + /* Please see the memory layout in: + * https://github.com/zephyrproject-rtos/trusted-firmware-m/blob/zephyr_tf-m_v2.2.2/platform/ext/target/arm/musca_s1/partition/flash_layout.h + */ + slot0_partition: partition@20000 { + reg = <0x20000 DT_SIZE_K(384)>; + }; + + slot0_ns_partition: partition@80000 { + reg = <0x80000 DT_SIZE_K(512)>; + }; + }; }; sram0: memory@20040000 { From c30ab4e4047e0bd749461ae7724412ba7b35f905 Mon Sep 17 00:00:00 2001 From: Sudan Landge Date: Mon, 19 Jan 2026 20:34:53 +0000 Subject: [PATCH 0061/6328] boards: arm: musca_b1: disable crypto HW acceleration TF-M documentation states that code sharing on Musca-B1 is only supported with software crypto and requires crypto hardware acceleration to be disabled. So, force CRYPTO_HW_ACCELERATOR=OFF for the Musca-B1 non-secure TF-M build to match this requirement. This also fixes CI failures caused by -Werror triggered by prototype mismatches in the crypto accelerator path between TF-M and Mbed TLS. Signed-off-by: Sudan Landge --- boards/arm/v2m_musca_b1/CMakeLists.txt | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/boards/arm/v2m_musca_b1/CMakeLists.txt b/boards/arm/v2m_musca_b1/CMakeLists.txt index 2ba52c47c83c..44358da90628 100644 --- a/boards/arm/v2m_musca_b1/CMakeLists.txt +++ b/boards/arm/v2m_musca_b1/CMakeLists.txt @@ -1,8 +1,15 @@ # # Copyright (c) 2019,2020 Linaro Limited +# Copyright 2026 Arm Limited and/or its affiliates # # SPDX-License-Identifier: Apache-2.0 # zephyr_library() zephyr_library_sources(pinmux.c) + +if(CONFIG_BUILD_WITH_TFM) + set_property(TARGET zephyr_property_target + APPEND PROPERTY TFM_CMAKE_OPTIONS -DCRYPTO_HW_ACCELERATOR=OFF + ) +endif() From 6891d57c012b6d4572db15590997ff24fa6a8b40 Mon Sep 17 00:00:00 2001 From: Sudan Landge Date: Tue, 20 Jan 2026 11:30:27 +0000 Subject: [PATCH 0062/6328] boards: arm: musca_s1: disable crypto HW acceleration Disable HW acceleration to fix CI failures caused by -Werror triggered by prototype mismatches in the crypto accelerator path between TF-M and Mbed TLS. Signed-off-by: Sudan Landge --- boards/arm/v2m_musca_s1/CMakeLists.txt | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/boards/arm/v2m_musca_s1/CMakeLists.txt b/boards/arm/v2m_musca_s1/CMakeLists.txt index bbb12938dcee..15313d539ab3 100644 --- a/boards/arm/v2m_musca_s1/CMakeLists.txt +++ b/boards/arm/v2m_musca_s1/CMakeLists.txt @@ -1,8 +1,15 @@ # # Copyright (c) 2019-2020 Linaro Limited +# Copyright 2026 Arm Limited and/or its affiliates # # SPDX-License-Identifier: Apache-2.0 # zephyr_library() zephyr_library_sources(pinmux.c) + +if(CONFIG_BUILD_WITH_TFM) + set_property(TARGET zephyr_property_target + APPEND PROPERTY TFM_CMAKE_OPTIONS -DCRYPTO_HW_ACCELERATOR=OFF + ) +endif() From 2a1b814f7bfa5fb13a4f2e246027c1cff2db3938 Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Mon, 19 Jan 2026 12:33:23 +0100 Subject: [PATCH 0063/6328] net: dns: Don't report CNAME records via callback Don't report CNAME records via application callback (as it used to be done). They don't carry any data in the info struct and are only used internally to redirect DNS queries. Signed-off-by: Robert Lubos --- subsys/net/lib/dns/resolve.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/subsys/net/lib/dns/resolve.c b/subsys/net/lib/dns/resolve.c index 408a694a5ef8..f5c469d883bd 100644 --- a/subsys/net/lib/dns/resolve.c +++ b/subsys/net/lib/dns/resolve.c @@ -1395,6 +1395,14 @@ int dns_validate_msg(struct dns_resolve_context *ctx, goto quit; } + + if (answer_type == DNS_RR_TYPE_CNAME) { + /* Don't report CNAME records to the application, they're used internally + * for query redirection. + */ + continue; + } + invoke_query_callback(DNS_EAI_INPROGRESS, &info, &ctx->queries[*query_idx]); if (dns_msg->response_type == DNS_RESPONSE_IP || From 38d9c632d691616a138e1426217874333b333e6c Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Mon, 19 Jan 2026 14:07:40 +0100 Subject: [PATCH 0064/6328] net: dns: Fix query redirection in case of CNAME result In case CNAME record is received with no IP addresses, DNS resolver will attempt to re-send the query for the name indicated by the CNAME record. The logic for scheduling the new query was inconsistent though: dispatcher_cb() assumes that it'll reuse the query context with the same query id, while dns_read() cancelled the query, which shouldn't really happen, as that would cause an error to be reported to the application via callback. Fix that by skipping the query cancel in case of DNS_EAI_AGAIN result. The query context will be properly reused then, and freed either when reply for another query arrives, or the query times out. Signed-off-by: Robert Lubos --- subsys/net/lib/dns/resolve.c | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/subsys/net/lib/dns/resolve.c b/subsys/net/lib/dns/resolve.c index f5c469d883bd..0e1d04dd5733 100644 --- a/subsys/net/lib/dns/resolve.c +++ b/subsys/net/lib/dns/resolve.c @@ -1490,12 +1490,12 @@ static int dns_read(struct dns_resolve_context *ctx, ret = dns_validate_msg(ctx, &dns_msg, dns_id, &query_idx, dns_cname, query_hash); if (ret == DNS_EAI_AGAIN) { - goto finished; + return ret; } if ((ret < 0 && ret != DNS_EAI_ALLDONE) || query_idx < 0 || query_idx > CONFIG_DNS_NUM_CONCUR_QUERIES) { - goto quit; + return ret; } #if defined(CONFIG_DNS_RESOLVER_PACKET_FORWARDING) @@ -1518,13 +1518,6 @@ static int dns_read(struct dns_resolve_context *ctx, } return 0; - -finished: - dns_resolve_cancel_with_name(ctx, *dns_id, - ctx->queries[query_idx].query, - ctx->queries[query_idx].query_type); -quit: - return ret; } static int set_ttl_hop_limit(int sock, int level, int option, int new_limit) From fbd9079148975b0f45170611c4cbf10e4bacaadd Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Mon, 19 Jan 2026 14:50:15 +0100 Subject: [PATCH 0065/6328] net: dns: Implement CONFIG_DNS_RESOLVER_ADDITIONAL_QUERIES There was a Kconfig option defined to limit the number of additional DNS queries sent for aliases received in CNAME records (to avoid potential query loops), however it was not implemented. This commit implements the feature - the resolver will now only send up to CONFIG_DNS_RESOLVER_ADDITIONAL_QUERIES follow-up queries after receiving CNAME record with an alias w/o any IP addresses. Signed-off-by: Robert Lubos --- include/zephyr/net/dns_resolve.h | 5 +++++ subsys/net/lib/dns/resolve.c | 8 ++++++++ 2 files changed, 13 insertions(+) diff --git a/include/zephyr/net/dns_resolve.h b/include/zephyr/net/dns_resolve.h index eeaa1adf2db8..9af09951dfbf 100644 --- a/include/zephyr/net/dns_resolve.h +++ b/include/zephyr/net/dns_resolve.h @@ -530,6 +530,11 @@ struct dns_resolve_context { */ uint16_t query_hash; + /* Number of additional queries sent to resolve CNAME record + * name aliases. + */ + uint8_t additional_queries; + /** Flag to indicate that the callback has been called at least once. */ bool cb_called; } queries[DNS_NUM_CONCUR_QUERIES]; diff --git a/subsys/net/lib/dns/resolve.c b/subsys/net/lib/dns/resolve.c index 0e1d04dd5733..a8a853b78213 100644 --- a/subsys/net/lib/dns/resolve.c +++ b/subsys/net/lib/dns/resolve.c @@ -318,6 +318,11 @@ static int dispatcher_cb(struct dns_socket_dispatcher *my_ctx, int sock, goto free_buf; } + if (ctx->queries[i].additional_queries >= CONFIG_DNS_RESOLVER_ADDITIONAL_QUERIES) { + ret = DNS_EAI_FAIL; + goto quit; + } + for (j = 0; j < SERVER_COUNT; j++) { if (ctx->servers[j].sock < 0) { continue; @@ -332,6 +337,8 @@ static int dispatcher_cb(struct dns_socket_dispatcher *my_ctx, int sock, } } + ctx->queries[i].additional_queries++; + if (nfail > 0) { NET_DBG("DNS cname query %d fails on %d attempts", nfail, ntry); @@ -2041,6 +2048,7 @@ int dns_resolve_name_internal(struct dns_resolve_context *ctx, ctx->queries[i].user_data = user_data; ctx->queries[i].ctx = ctx; ctx->queries[i].query_hash = 0; + ctx->queries[i].additional_queries = 0; ctx->queries[i].cb_called = false; k_work_init_delayable(&ctx->queries[i].timer, query_timeout); From a10f7f3541749bd036bd411626892c2026d0751c Mon Sep 17 00:00:00 2001 From: Jeroen Broersen Date: Fri, 16 Jan 2026 11:27:23 +0100 Subject: [PATCH 0066/6328] net: lwm2m: senml opaque base64 encoding fix The SenML-JSON specification mentions base64-encoded data with the URL-safe alphabet and padding omitted. For sending data, zephyr used normal base64 with padding. Change the base64 data to use the URL-safe format without padding when sending opaque data via SenML-JSON. Fixes #102390 Signed-off-by: Jeroen Broersen --- subsys/net/lib/lwm2m/lwm2m_rw_senml_json.c | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/subsys/net/lib/lwm2m/lwm2m_rw_senml_json.c b/subsys/net/lib/lwm2m/lwm2m_rw_senml_json.c index 534563f0aab1..7b2a07d73f53 100644 --- a/subsys/net/lib/lwm2m/lwm2m_rw_senml_json.c +++ b/subsys/net/lib/lwm2m/lwm2m_rw_senml_json.c @@ -905,8 +905,28 @@ static int json_append_bytes_base64(const char *bytes, size_t len, void *data) /* No space available for base64 data */ return -ENOMEM; } + + /* Change base64 data to URL-safe BASE64 data without padding */ + int padding_removed = 0; + + for (int i = 0; i < temp_length; i++) { + switch (CPKT_BUF_W_PTR(out->out_cpkt)[i]) { + case '+': + CPKT_BUF_W_PTR(out->out_cpkt)[i] = '-'; + break; + case '/': + CPKT_BUF_W_PTR(out->out_cpkt)[i] = '_'; + break; + case '=': + CPKT_BUF_W_PTR(out->out_cpkt)[i] = 0; + padding_removed++; + break; + default: + break; + } + } /* Update Data offset */ - out->out_cpkt->offset += temp_length; + out->out_cpkt->offset += (temp_length - padding_removed); } else { if (buf_append(CPKT_BUF_WRITE(fd->out->out_cpkt), bytes, len) < 0) { return -ENOMEM; From 96121bfb5735b9a19e464b569c922e9fd0e173d9 Mon Sep 17 00:00:00 2001 From: Jukka Rissanen Date: Wed, 21 Jan 2026 11:06:45 +0200 Subject: [PATCH 0067/6328] net: posix: Avoid multiple definitions of IFNAMSIZ symbol One might see this compile error depending on what order the POSIX headers are included include/zephyr/net/net_compat.h:143: error: "IFNAMSIZ" redefined .../zephyr/include/zephyr/net/net_compat.h:143: error: "IFNAMSIZ" redefined [-Werror] 143 | #define IFNAMSIZ NET_IFNAMSIZ | In file included from ... .../zephyr/include/zephyr/posix/net/if.h:16: note: this is the location of the previous definition 16 | #define IFNAMSIZ IF_NAMESIZE | Signed-off-by: Jukka Rissanen --- include/zephyr/net/net_compat.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/zephyr/net/net_compat.h b/include/zephyr/net/net_compat.h index c044d86cfa87..927c8d5087e9 100644 --- a/include/zephyr/net/net_compat.h +++ b/include/zephyr/net/net_compat.h @@ -140,7 +140,9 @@ extern "C" { #define IN6ADDR_ANY_INIT NET_IN6ADDR_ANY_INIT #define IN6ADDR_LOOPBACK_INIT NET_IN6ADDR_LOOPBACK_INIT +#if !defined(IFNAMSIZ) #define IFNAMSIZ NET_IFNAMSIZ +#endif /* IFNAMSIZ */ #define in_pktinfo net_in_pktinfo #define ip_mreqn net_ip_mreqn From 2de323cd3eb7490ee1d571b0747cb59a62519f79 Mon Sep 17 00:00:00 2001 From: Tahsin Mutlugun Date: Wed, 21 Jan 2026 12:27:36 +0300 Subject: [PATCH 0068/6328] testsuite: Correct broken link to coverage documentation The existing documentation link pointed to a non-existent page. Update the link to use the current documentation URL. Signed-off-by: Tahsin Mutlugun --- subsys/testsuite/Kconfig.coverage | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/subsys/testsuite/Kconfig.coverage b/subsys/testsuite/Kconfig.coverage index 9209052b7905..3f7cd2c0b0de 100644 --- a/subsys/testsuite/Kconfig.coverage +++ b/subsys/testsuite/Kconfig.coverage @@ -17,7 +17,7 @@ config COVERAGE This option will build your application with the -coverage option which will generate data that can be used to create coverage reports. For more information see - https://docs.zephyrproject.org/latest/guides/coverage.html + https://docs.zephyrproject.org/latest/develop/test/coverage.html choice prompt "Coverage mode" From ff78913fa86419fb53bf30e98cbed98b8fa884ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Mon, 19 Jan 2026 18:14:17 +0100 Subject: [PATCH 0069/6328] arch: arm: smp: Master core should be referred to as "primary" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit As per Zephyr guidelines re: inclusive language, the term "master" is replaced with "primary". Signed-off-by: Benjamin Cabé --- arch/arm/core/cortex_a_r/smp.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/arch/arm/core/cortex_a_r/smp.c b/arch/arm/core/cortex_a_r/smp.c index 099d28fd6a2d..fd8790e337b2 100644 --- a/arch/arm/core/cortex_a_r/smp.c +++ b/arch/arm/core/cortex_a_r/smp.c @@ -98,18 +98,18 @@ void arch_cpu_start(int cpu_num, k_thread_stack_t *stack, int sz, arch_cpustart_ { int cpu_count, i, j; uint32_t cpu_mpid = 0; - uint32_t master_core_mpid; + uint32_t primary_core_mpid; - /* Now it is on master core */ + /* Now it is on primary core */ __ASSERT(arch_curr_cpu()->id == 0, ""); - master_core_mpid = MPIDR_TO_CORE(GET_MPIDR()); + primary_core_mpid = MPIDR_TO_CORE(GET_MPIDR()); cpu_count = ARRAY_SIZE(cpu_node_list); __ASSERT(cpu_count == CONFIG_MP_MAX_NUM_CPUS, "The count of CPU Cores nodes in dts is not equal to CONFIG_MP_MAX_NUM_CPUS\n"); for (i = 0, j = 0; i < cpu_count; i++) { - if (cpu_node_list[i] == master_core_mpid) { + if (cpu_node_list[i] == primary_core_mpid) { continue; } if (j == cpu_num - 1) { From f64bb4bf1e021d20f9b57e66719fde46764e22c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Mon, 19 Jan 2026 18:02:37 +0100 Subject: [PATCH 0070/6328] arch: riscv: avoid the use of "sanity check" term MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit As per coding guidelines, "sanity check" must be avoided. Signed-off-by: Benjamin Cabé --- arch/riscv/core/pmp.c | 2 +- arch/riscv/custom/andes/pma.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/riscv/core/pmp.c b/arch/riscv/core/pmp.c index 5e20970b0a55..348c607cbb09 100644 --- a/arch/riscv/core/pmp.c +++ b/arch/riscv/core/pmp.c @@ -318,7 +318,7 @@ extern void z_riscv_write_pmp_entries(unsigned int start, unsigned int end, /** * @brief Write a range of PMP entries to corresponding PMP registers * - * This performs some sanity checks before calling z_riscv_write_pmp_entries(). + * This performs some coherence checks before calling z_riscv_write_pmp_entries(). * * @param start Start of the PMP range to be written * @param end End (exclusive) of the PMP range to be written diff --git a/arch/riscv/custom/andes/pma.c b/arch/riscv/custom/andes/pma.c index 1e9d41c4f54f..11f2a46d02ec 100644 --- a/arch/riscv/custom/andes/pma.c +++ b/arch/riscv/custom/andes/pma.c @@ -141,7 +141,7 @@ static void region_init(const uint32_t index, } /* - * This internal function performs run-time sanity check for + * This internal function performs run-time coherence check for * PMA region start address and size. */ static int pma_region_is_valid(const struct pma_region *region) From 5a9715add1ef6e9d2c1ccbb9f35cc0f57e12926a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Mon, 19 Jan 2026 18:02:58 +0100 Subject: [PATCH 0071/6328] arch: x86: avoid the use of "sanity check" term MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit As per coding guidelines, "sanity check" must be avoided. Signed-off-by: Benjamin Cabé --- arch/x86/gen_idt.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/x86/gen_idt.py b/arch/x86/gen_idt.py index a302c13bff55..f424f4eb9330 100755 --- a/arch/x86/gen_idt.py +++ b/arch/x86/gen_idt.py @@ -136,7 +136,7 @@ def setup_idt(spur_code, spur_nocode, intlist, max_vec, max_irq): irq_vec_map = [0 for i in range(max_irq)] vectors = [None for i in range(max_vec)] - # Pass 1: sanity check and set up hard-coded interrupt vectors + # Pass 1: coherence check and set up hard-coded interrupt vectors for handler, irq, prio, vec, dpl, tss in intlist: if vec == -1: if prio == -1: From 71262d0e075bb6670b81534c820b68e7c6cc3c55 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Mon, 19 Jan 2026 18:02:09 +0100 Subject: [PATCH 0072/6328] arch: xtensa: avoid the use of "sanity check" term MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit As per coding guidelines, "sanity check" must be avoided. Signed-off-by: Benjamin Cabé --- arch/xtensa/core/xtensa_asm2_util.S | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/xtensa/core/xtensa_asm2_util.S b/arch/xtensa/core/xtensa_asm2_util.S index 00e7b1bcd3fd..377edcd590ab 100644 --- a/arch/xtensa/core/xtensa_asm2_util.S +++ b/arch/xtensa/core/xtensa_asm2_util.S @@ -344,7 +344,7 @@ noflush: /* Switch stack pointer and restore. The jump to * _restore_context does not return as such, but we arrange * for the restored "next" address to be immediately after for - * sanity. + * coherence. */ l32i a1, a2, ___xtensa_irq_bsa_t_a2_OFFSET From 27120315d3df4ad8add9a950c0cab315f59505e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Mon, 19 Jan 2026 18:01:35 +0100 Subject: [PATCH 0073/6328] arch: arm: avoid the use of "sanity check" term MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit As per coding guidelines, "sanity check" must be avoided. Signed-off-by: Benjamin Cabé --- arch/arm/core/mpu/arm_mpu.c | 10 +++++----- arch/arm/core/mpu/arm_mpu_v7_internal.h | 6 +++--- arch/arm/core/mpu/arm_mpu_v8_internal.h | 14 +++++++------- arch/arm/core/mpu/nxp_mpu.c | 12 ++++++------ 4 files changed, 21 insertions(+), 21 deletions(-) diff --git a/arch/arm/core/mpu/arm_mpu.c b/arch/arm/core/mpu/arm_mpu.c index 602e56010bff..a72fea183e3d 100644 --- a/arch/arm/core/mpu/arm_mpu.c +++ b/arch/arm/core/mpu/arm_mpu.c @@ -210,11 +210,11 @@ static int mpu_configure_region(const uint8_t index, !defined(CONFIG_MPU_GAP_FILLING) /* This internal function programs a set of given MPU regions * over a background memory area, optionally performing a - * sanity check of the memory regions to be programmed. + * coherence check of the memory regions to be programmed. */ static int mpu_configure_regions(const struct z_arm_mpu_partition regions[], uint8_t regions_num, uint8_t start_reg_index, - bool do_sanity_check) + bool do_coherence_check) { int i; int reg_index = start_reg_index; @@ -225,9 +225,9 @@ static int mpu_configure_regions(const struct z_arm_mpu_partition } /* Non-empty region. */ - if (do_sanity_check && + if (do_coherence_check && (!mpu_partition_is_valid(®ions[i]))) { - LOG_ERR("Partition %u: sanity check failed.", i); + LOG_ERR("Partition %u: coherence check failed.", i); return -EINVAL; } @@ -620,7 +620,7 @@ int z_arm_mpu_init(void) #endif #endif /* CONFIG_NULL_POINTER_EXCEPTION_DETECTION_MPU */ - /* Sanity check for number of regions in Cortex-M0+, M3, and M4. */ + /* Coherence check for number of regions in Cortex-M0+, M3, and M4. */ #if defined(CONFIG_CPU_CORTEX_M0PLUS) || \ defined(CONFIG_CPU_CORTEX_M3) || \ defined(CONFIG_CPU_CORTEX_M4) diff --git a/arch/arm/core/mpu/arm_mpu_v7_internal.h b/arch/arm/core/mpu/arm_mpu_v7_internal.h index 40d03865d07c..17cf2cb38e62 100644 --- a/arch/arm/core/mpu/arm_mpu_v7_internal.h +++ b/arch/arm/core/mpu/arm_mpu_v7_internal.h @@ -52,9 +52,9 @@ static void region_init(const uint32_t index, #endif } -/* @brief Partition sanity check +/* @brief Partition coherence check * - * This internal function performs run-time sanity check for + * This internal function performs run-time coherence check for * MPU region start address and size. * * @param part Pointer to the data structure holding the partition @@ -207,7 +207,7 @@ static int mpu_configure_region(const uint8_t index, static int mpu_configure_regions(const struct z_arm_mpu_partition regions[], uint8_t regions_num, uint8_t start_reg_index, - bool do_sanity_check); + bool do_coherence_check); /* This internal function programs the static MPU regions. * diff --git a/arch/arm/core/mpu/arm_mpu_v8_internal.h b/arch/arm/core/mpu/arm_mpu_v8_internal.h index 2ce810047e1d..995263db2990 100644 --- a/arch/arm/core/mpu/arm_mpu_v8_internal.h +++ b/arch/arm/core/mpu/arm_mpu_v8_internal.h @@ -184,9 +184,9 @@ static void region_init(const uint32_t index, region_conf->attr.mair_idx, region_conf->attr.r_limit); } -/* @brief Partition sanity check +/* @brief Partition coherence check * - * This internal function performs run-time sanity check for + * This internal function performs run-time coherence check for * MPU region start address and size. * * @param part Pointer to the data structure holding the partition @@ -519,19 +519,19 @@ static int mpu_configure_region(const uint8_t index, #if !defined(CONFIG_MPU_GAP_FILLING) static int mpu_configure_regions(const struct z_arm_mpu_partition regions[], uint8_t regions_num, uint8_t start_reg_index, - bool do_sanity_check); + bool do_coherence_check); #endif /* This internal function programs a set of given MPU regions * over a background memory area, optionally performing a - * sanity check of the memory regions to be programmed. + * coherence check of the memory regions to be programmed. * * The function performs a full partition of the background memory * area, effectively, leaving no space in this area uncovered by MPU. */ static int mpu_configure_regions_and_partition(const struct z_arm_mpu_partition regions[], uint8_t regions_num, uint8_t start_reg_index, - bool do_sanity_check) + bool do_coherence_check) { int i; int reg_index = start_reg_index; @@ -542,9 +542,9 @@ static int mpu_configure_regions_and_partition(const struct z_arm_mpu_partition } /* Non-empty region. */ - if (do_sanity_check && + if (do_coherence_check && (!mpu_partition_is_valid(®ions[i]))) { - LOG_ERR("Partition %u: sanity check failed.", i); + LOG_ERR("Partition %u: coherence check failed.", i); return -EINVAL; } diff --git a/arch/arm/core/mpu/nxp_mpu.c b/arch/arm/core/mpu/nxp_mpu.c index ae893086901c..639a6f86b646 100644 --- a/arch/arm/core/mpu/nxp_mpu.c +++ b/arch/arm/core/mpu/nxp_mpu.c @@ -51,9 +51,9 @@ static inline uint8_t get_num_regions(void) return FSL_FEATURE_SYSMPU_DESCRIPTOR_COUNT; } -/* @brief Partition sanity check +/* @brief Partition coherence check * - * This internal function performs run-time sanity check for + * This internal function performs run-time coherence check for * MPU region start address and size. * * @param part Pointer to the data structure holding the partition @@ -297,11 +297,11 @@ static int mpu_sram_partitioning(uint8_t index, /* This internal function programs a set of given MPU regions * over a background memory area, optionally performing a - * sanity check of the memory regions to be programmed. + * coherence check of the memory regions to be programmed. */ static int mpu_configure_regions(const struct z_arm_mpu_partition regions[], uint8_t regions_num, uint8_t start_reg_index, - bool do_sanity_check) + bool do_coherence_check) { int i; int reg_index = start_reg_index; @@ -312,9 +312,9 @@ static int mpu_configure_regions(const struct z_arm_mpu_partition regions[], } /* Non-empty region. */ - if (do_sanity_check && + if (do_coherence_check && (!mpu_partition_is_valid(®ions[i]))) { - LOG_ERR("Partition %u: sanity check failed.", i); + LOG_ERR("Partition %u: coherence check failed.", i); return -EINVAL; } From 18652dea69fbd19894e438250a58bd1fd3a12075 Mon Sep 17 00:00:00 2001 From: Camille BAUD Date: Sun, 18 Jan 2026 13:28:10 +0100 Subject: [PATCH 0074/6328] drivers: serial: bflb: do not enable rx and err interrupt by default It breaks things when callback doesnt expect them. Signed-off-by: Camille BAUD --- drivers/serial/uart_bflb.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/drivers/serial/uart_bflb.c b/drivers/serial/uart_bflb.c index dae92b91f719..9625a86371c6 100644 --- a/drivers/serial/uart_bflb.c +++ b/drivers/serial/uart_bflb.c @@ -274,14 +274,19 @@ static void uart_bflb_isr(const struct device *dev) { struct bflb_data *const data = dev->data; const struct bflb_config *const cfg = dev->config; - uint32_t tmp = 0; + uint32_t tmp; + bool clear_err = !(sys_read32(cfg->base_reg + UART_INT_MASK_OFFSET) & UART_CR_URX_PCE_MASK); if (data->user_cb) { data->user_cb(dev, data->user_data); } /* clear interrupts that require ack*/ tmp = sys_read32(cfg->base_reg + UART_INT_CLEAR_OFFSET); - tmp = tmp | UART_CR_URX_RTO_CLR; + /* Clear PCE in case callback didn't read it and the interrupt is unmasked */ + if (clear_err) { + tmp |= UART_CR_URX_PCE_CLR; + } + tmp |= UART_CR_URX_RTO_CLR; sys_write32(tmp, cfg->base_reg + UART_INT_CLEAR_OFFSET); } #endif /* CONFIG_UART_INTERRUPT_DRIVEN */ @@ -443,9 +448,6 @@ static int uart_bflb_init(const struct device *dev) sys_write32(0xFF, cfg->base_reg + UART_INT_CLEAR_OFFSET); /* mask all IRQs */ sys_write32(0xFFFFFFFFU, cfg->base_reg + UART_INT_MASK_OFFSET); - /* unmask necessary irqs */ - uart_bflb_irq_rx_enable(dev); - uart_bflb_irq_err_enable(dev); /* enable all irqs */ sys_write32(0xFF, cfg->base_reg + UART_INT_EN_OFFSET); cfg->irq_config_func(dev); From f54a3fa8cdb788ae54d193e466b0c44d03d96e3e Mon Sep 17 00:00:00 2001 From: Sven Ginka Date: Wed, 14 Jan 2026 14:29:35 +0100 Subject: [PATCH 0075/6328] dts: bindings: fix filename typo in sy1xx-i2c.yaml this fixes the incorrect filename of the sy1xx-i2c.yml file. Signed-off-by: Sven Ginka --- .../i2c/{sensry,sy1xxx-i2c.yaml => sensry,sy1xx-i2c.yaml} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename dts/bindings/i2c/{sensry,sy1xxx-i2c.yaml => sensry,sy1xx-i2c.yaml} (100%) diff --git a/dts/bindings/i2c/sensry,sy1xxx-i2c.yaml b/dts/bindings/i2c/sensry,sy1xx-i2c.yaml similarity index 100% rename from dts/bindings/i2c/sensry,sy1xxx-i2c.yaml rename to dts/bindings/i2c/sensry,sy1xx-i2c.yaml From 384abc74897edd1f6fa09b5afcff83514eae9b33 Mon Sep 17 00:00:00 2001 From: Camille BAUD Date: Mon, 12 Jan 2026 18:09:55 +0100 Subject: [PATCH 0076/6328] drivers: display: Introduce SSD1325, update driver Adds SSD1325 support to SSD1327 driver, update and improve driver. Signed-off-by: Camille BAUD --- drivers/display/CMakeLists.txt | 2 +- drivers/display/Kconfig | 2 +- drivers/display/Kconfig.ssd1327 | 29 - drivers/display/Kconfig.ssd1327_5 | 44 ++ drivers/display/display_ssd1327_5.c | 685 ++++++++++++++++++ drivers/display/ssd1327.c | 536 -------------- drivers/display/ssd1327_regs.h | 53 -- dts/bindings/display/solomon,ssd1325-i2c.yaml | 12 + .../display/solomon,ssd1325-mipi.yaml | 12 + .../display/solomon,ssd1327-common.yaml | 16 + ...27fb-i2c.yaml => solomon,ssd1327-i2c.yaml} | 6 +- ...fb-mipi.yaml => solomon,ssd1327-mipi.yaml} | 6 +- ...mon.yaml => solomon,ssd1327_5-common.yaml} | 26 +- 13 files changed, 786 insertions(+), 643 deletions(-) delete mode 100644 drivers/display/Kconfig.ssd1327 create mode 100644 drivers/display/Kconfig.ssd1327_5 create mode 100644 drivers/display/display_ssd1327_5.c delete mode 100644 drivers/display/ssd1327.c delete mode 100644 drivers/display/ssd1327_regs.h create mode 100644 dts/bindings/display/solomon,ssd1325-i2c.yaml create mode 100644 dts/bindings/display/solomon,ssd1325-mipi.yaml create mode 100644 dts/bindings/display/solomon,ssd1327-common.yaml rename dts/bindings/display/{solomon,ssd1327fb-i2c.yaml => solomon,ssd1327-i2c.yaml} (58%) rename dts/bindings/display/{solomon,ssd1327fb-mipi.yaml => solomon,ssd1327-mipi.yaml} (58%) rename dts/bindings/display/{solomon,ssd1327fb-common.yaml => solomon,ssd1327_5-common.yaml} (75%) diff --git a/drivers/display/CMakeLists.txt b/drivers/display/CMakeLists.txt index 8f076e974fb8..135e0929dd5c 100644 --- a/drivers/display/CMakeLists.txt +++ b/drivers/display/CMakeLists.txt @@ -42,7 +42,7 @@ zephyr_library_sources_ifdef(CONFIG_SH1122 display_sh1122.c) zephyr_library_sources_ifdef(CONFIG_SSD1306 ssd1306.c) zephyr_library_sources_ifdef(CONFIG_SSD1320 display_ssd1320.c) zephyr_library_sources_ifdef(CONFIG_SSD1322 ssd1322.c) -zephyr_library_sources_ifdef(CONFIG_SSD1327 ssd1327.c) +zephyr_library_sources_ifdef(CONFIG_SSD1327_5 display_ssd1327_5.c) zephyr_library_sources_ifdef(CONFIG_SSD1331 display_ssd1331.c) zephyr_library_sources_ifdef(CONFIG_SSD135X display_ssd135x.c) zephyr_library_sources_ifdef(CONFIG_SSD1363 display_ssd1363.c) diff --git a/drivers/display/Kconfig b/drivers/display/Kconfig index e7f4f30a866f..b094da33800d 100644 --- a/drivers/display/Kconfig +++ b/drivers/display/Kconfig @@ -51,7 +51,7 @@ source "drivers/display/Kconfig.sh1122" source "drivers/display/Kconfig.ssd1306" source "drivers/display/Kconfig.ssd1320" source "drivers/display/Kconfig.ssd1322" -source "drivers/display/Kconfig.ssd1327" +source "drivers/display/Kconfig.ssd1327_5" source "drivers/display/Kconfig.ssd1331" source "drivers/display/Kconfig.ssd135x" source "drivers/display/Kconfig.ssd1363" diff --git a/drivers/display/Kconfig.ssd1327 b/drivers/display/Kconfig.ssd1327 deleted file mode 100644 index f109d169ecea..000000000000 --- a/drivers/display/Kconfig.ssd1327 +++ /dev/null @@ -1,29 +0,0 @@ -# SSD1327 display controller configuration options - -# Copyright (c) 2024 Savoir-faire Linux -# SPDX-License-Identifier: Apache-2.0 - -menuconfig SSD1327 - bool "SSD1327 display controller driver" - default y - depends on DT_HAS_SOLOMON_SSD1327FB_ENABLED - select I2C if $(dt_compat_on_bus,$(DT_COMPAT_SOLOMON_SSD1327FB),i2c) - select MIPI_DBI if $(dt_compat_on_bus,$(DT_COMPAT_SOLOMON_SSD1327FB),mipi-dbi) - help - Enable driver for SSD1327 display. - -if SSD1327 - -config SSD1327_DEFAULT_CONTRAST - int "SSD1327 default contrast" - default 128 - range 0 255 - help - SSD1327 default contrast. - -config SSD1327_CONV_BUFFER_LINES - int "How many lines can the conversion buffer hold" - default 1 - range 1 128 - -endif # SSD1327 diff --git a/drivers/display/Kconfig.ssd1327_5 b/drivers/display/Kconfig.ssd1327_5 new file mode 100644 index 000000000000..eed8a95fe094 --- /dev/null +++ b/drivers/display/Kconfig.ssd1327_5 @@ -0,0 +1,44 @@ +# SSD1327 and SSD1325 display controller configuration options + +# Copyright (c) 2024 Savoir-faire Linux +# Copyright (c) 2025-2026 MASSDRIVER EI (massdriver.space) +# SPDX-License-Identifier: Apache-2.0 + +menuconfig SSD1327_5 + bool "SSD1327/5 display controller driver" + default y + depends on DT_HAS_SOLOMON_SSD1327_ENABLED || DT_HAS_SOLOMON_SSD1325_ENABLED + select I2C if $(dt_compat_on_bus,$(DT_COMPAT_SOLOMON_SSD1327),i2c) \ + || $(dt_compat_on_bus,$(DT_COMPAT_SOLOMON_SSD1325),i2c) + select MIPI_DBI if $(dt_compat_on_bus,$(DT_COMPAT_SOLOMON_SSD1327),mipi-dbi) \ + || $(dt_compat_on_bus,$(DT_COMPAT_SOLOMON_SSD1325),mipi-dbi) + help + Enable driver for SSD1327 and SSD1325 display controllers. + +if SSD1327_5 + +config SSD1327_DEFAULT_CONTRAST + int "SSD1327 default contrast" + default 128 + range 0 255 + help + SSD1327 default contrast. + +config SSD1327_CONV_BUFFER_LINES + int "How many lines can the conversion buffer hold" + default 1 + range 1 128 + +config SSD1325_DEFAULT_CONTRAST + int "SSD1325 default contrast" + default 128 + range 0 255 + help + SSD1325 default contrast. + +config SSD1325_CONV_BUFFER_LINES + int "How many lines can the conversion buffer hold" + default 1 + range 1 128 + +endif # SSD1327_5 diff --git a/drivers/display/display_ssd1327_5.c b/drivers/display/display_ssd1327_5.c new file mode 100644 index 000000000000..07f55a80a900 --- /dev/null +++ b/drivers/display/display_ssd1327_5.c @@ -0,0 +1,685 @@ +/* + * Copyright (c) 2024 Savoir-faire Linux + * Copyright (c) 2025-2026 MASSDRIVER EI (massdriver.space) + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +LOG_MODULE_REGISTER(ssd1327_5, CONFIG_DISPLAY_LOG_LEVEL); + +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * Commands + */ +#define SSD1327_5_SET_COLUMN_ADDR 0x15 +#define SSD1327_5_SET_ROW_ADDR 0x75 +#define SSD1327_5_SET_CONTRAST_CTRL 0x81 +#define SSD1325_SET_CURRENT_RANGE_QRT 0x84 +#define SSD1325_SET_CURRENT_RANGE_HLF 0x85 +#define SSD1325_SET_CURRENT_RANGE_FLL 0x86 +#define SSD1327_5_SET_REMAPCTL 0xa0 +#define SSD1327_5_SET_DISPLAY_START_LINE 0xa1 +#define SSD1327_5_SET_DISPLAY_OFFSET 0xa2 +#define SSD1327_5_SET_NORMAL_DISPLAY 0xa4 +#define SSD1327_5_SET_ENTIRE_DISPLAY_ON 0xa5 +#define SSD1327_5_SET_ENTIRE_DISPLAY_OFF 0xa6 +#define SSD1327_5_SET_REVERSE_DISPLAY 0xa7 +#define SSD1327_5_SET_MULTIPLEX_RATIO 0xa8 +#define SSD1327_SET_FUNCTION_A 0xab +#define SSD1325_SET_MASTER_CONFIG 0xad +#define SSD1327_5_SET_DISPLAY_OFF 0xae +#define SSD1327_5_SET_DISPLAY_ON 0xaf +#define SSD1325_SET_PRECHARGE_COMP_EN 0xb0 +#define SSD1327_5_SET_PHASE_LENGTH 0xb1 +#define SSD1325_SET_ROW_PERIOD 0xb2 +#define SSD1327_5_SET_OSC_FREQ 0xb3 +#define SSD1325_SET_PRECHARGE_COMP 0xb4 +#define SSD1327_SET_PRECHARGE_PERIOD 0xb6 +#define SSD1327_5_SET_LUT 0xb8 +#define SSD1327_SET_LINEAR_LUT 0xb9 +#define SSD1327_5_SET_PRECHARGE_VOLTAGE 0xbc +#define SSD1327_5_SET_VCOMH 0xbe +#define SSD1327_SET_FUNCTION_B 0xd5 +#define SSD1327_SET_COMMAND_LOCK 0xfd + +/* + * Constants + */ +#define SSD1327_LUT_COUNT 15 +#define SSD1325_LUT_COUNT 8 +#define SSD1327_5_LUT_COUNT SSD1327_LUT_COUNT +#define SSD1327_5_RESET_DELAY 10 +#define SSD1325_PRECHARGE_COMP_EN 0x28 +#define SSD1325_PRECHARGE_COMP_DIS 0x08 +#define SSD1325_ROW_PERIOD_MAX 158 +#define SSD1325_PRECHARGE_COMP_DEFAULT 0x03 +#define SSD1327_5_I2C_ALL_BYTES_CMD 0x0 +#define SSD1327_5_I2C_ALL_BYTES_DATA 0x40 +#define SSD1327_ENABLE_VDD 0x01 +#define SSD1327_UNLOCK_COMMAND 0x12 +#define SSD1327_MAXIMUM_CMD_LENGTH 16 +#define SSD1325_MAXIMUM_CMD_LENGTH 9 +/* Always 0x2, MUST be set to 0x2 via command */ +#define SSD1325_MASTER_CONFIG 0x2 + +/* + * Fields + */ +#define SSD1327_5_PHASE1_LENGTH_MSK 0xf +#define SSD1327_5_PHASE2_LENGTH_MSK 0xf0 +#define SSD1327_5_PHASE2_LENGTH_POS 0x4 + +typedef int (*ssd1327_5_write_bus_cmd_fn)(const struct device *dev, const uint8_t cmd, + const uint8_t *data, size_t len); +typedef int (*ssd1327_5_write_pixels_fn)(const struct device *dev, const uint8_t *buf, + uint32_t pixel_count, + const struct display_buffer_descriptor *desc); + +/* Generate SSD1325's LUT table command input from driver's LUT table storage */ +#define SSD1325_CONV_GS_TABLE(t) \ + { t[0] & 0x7, (t[1] & 0x7) | ((t[2] & 0x7) << 4), (t[3] & 0x7) | ((t[4] & 0x7) << 4), \ + (t[5] & 0x7) | ((t[6] & 0x7) << 4), (t[7] & 0x7) | ((t[8] & 0x7) << 4), \ + (t[9] & 0x7) | ((t[10] & 0x7) << 4), (t[11] & 0x7) | ((t[12] & 0x7) << 4), \ + (t[13] & 0x7) | ((t[14] & 0x7) << 4) }; + +#if DT_HAS_COMPAT_STATUS_OKAY(solomon_ssd1327) +#define SSD1327_5_MAXIMUM_CMD_LENGTH SSD1327_MAXIMUM_CMD_LENGTH +#else +#define SSD1327_5_MAXIMUM_CMD_LENGTH SSD1325_MAXIMUM_CMD_LENGTH +#endif + +/* SSD1327 grayscale levels are direct DCLK values of 5-bits width, starts at GS1 and ends at GS15. + * Table from Datasheet. + */ +static const uint8_t ssd1327_default_grayscale_table[SSD1327_5_LUT_COUNT] = { + 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28 +}; + +/* SSD1325 grayscale levels are calculated as gs = x[i] + x[i-1] + x[0:i-1], + * such as here, 0 + 1 + 2 + 2 + 2 ... gives: + * (0) 1 3 5 7 9 11 13 15 17 19 21 23 25 27 29 + * and so GS0 is 0 DCLK and GS15 is 29 DCLK. + * It effectively is almost identical to SSD1327's after calculations. + * Table from Datasheet. + */ +static const uint8_t ssd1325_default_grayscale_table[SSD1327_5_LUT_COUNT] = { + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 +}; + +enum ssd1327_5_variant { + display_ssd1327, + display_ssd1325 +}; + +struct ssd1327_5_config { + enum ssd1327_5_variant variant; + struct i2c_dt_spec i2c; + ssd1327_5_write_bus_cmd_fn write_cmd; + ssd1327_5_write_pixels_fn write_pixels; + const struct device *mipi_dev; + const struct mipi_dbi_config dbi_config; + uint16_t height; + uint16_t width; + uint8_t oscillator_freq; + uint8_t start_line; + uint8_t display_offset; + uint8_t multiplex_ratio; + uint8_t prechargep; + uint8_t remap_value; + uint8_t phase_length; + uint8_t function_selection_b; + uint8_t precharge_voltage; + uint8_t vcomh_voltage; + uint8_t default_contrast; + const uint8_t *grayscale_table; + bool color_inversion; + uint8_t *conversion_buf; + size_t conversion_buf_size; +}; + +struct ssd1327_5_data { + uint8_t contrast; + uint8_t scan_mode; +}; + +static inline int ssd1327_5_write_bus_cmd_mipi(const struct device *dev, const uint8_t cmd, + const uint8_t *data, size_t len) +{ + const struct ssd1327_5_config *config = dev->config; + int err; + + /* Values given after the memory register must be sent with pin D/C set to 0. */ + /* Data is sent as a command following the mipi_cbi api */ + err = mipi_dbi_command_write(config->mipi_dev, &config->dbi_config, cmd, NULL, 0); + if (err) { + return err; + } + for (size_t i = 0; i < len; i++) { + err = mipi_dbi_command_write(config->mipi_dev, &config->dbi_config, + data[i], NULL, 0); + if (err) { + return err; + } + } + mipi_dbi_release(config->mipi_dev, &config->dbi_config); + + return 0; +} + +static inline int ssd1327_5_write_bus_cmd_i2c(const struct device *dev, const uint8_t cmd, + const uint8_t *data, size_t len) +{ + const struct ssd1327_5_config *config = dev->config; + uint8_t buf[SSD1327_5_MAXIMUM_CMD_LENGTH + 1]; + + if (len > SSD1327_5_MAXIMUM_CMD_LENGTH - 1) { + return -EINVAL; + } + + buf[0] = SSD1327_5_I2C_ALL_BYTES_CMD; + buf[1] = cmd; + memcpy(&(buf[2]), data, len); + + return i2c_write_dt(&config->i2c, buf, len + 2); +} + +/* Calculate SSD1325 'K' number, See section 8.3 of datasheet */ +static uint8_t ssd1325_calculate_k(const uint8_t phase_length, const uint8_t grayscale_table[15]) +{ + uint8_t k = (phase_length & SSD1327_5_PHASE1_LENGTH_MSK) + + ((phase_length & SSD1327_5_PHASE2_LENGTH_MSK) >> SSD1327_5_PHASE2_LENGTH_POS) + + grayscale_table[0]; + + for (size_t i = 1; i < 15; i++) { + k += grayscale_table[i-1] + grayscale_table[i]; + } + + return k; +} + +static inline int ssd1327_5_set_timing_setting(const struct device *dev) +{ + const struct ssd1327_5_config *config = dev->config; + const uint8_t *grayscale_table = config->grayscale_table != NULL ? + config->grayscale_table : + (config->variant == display_ssd1325 ? ssd1325_default_grayscale_table : + ssd1327_default_grayscale_table); + const uint8_t gs_table_ssd1325[SSD1325_LUT_COUNT] = SSD1325_CONV_GS_TABLE(grayscale_table); + uint8_t buf = SSD1327_UNLOCK_COMMAND; + int err; + + err = config->write_cmd(dev, SSD1327_5_SET_PHASE_LENGTH, &config->phase_length, 1); + if (err < 0) { + return err; + } + err = config->write_cmd(dev, SSD1327_5_SET_OSC_FREQ, &config->oscillator_freq, 1); + if (err < 0) { + return err; + } + if (config->variant == display_ssd1325) { + buf = ssd1325_calculate_k(config->phase_length, grayscale_table); + if (buf > SSD1325_ROW_PERIOD_MAX) { + LOG_ERR("Invalid grayscale table"); + return -EINVAL; + } + err = config->write_cmd(dev, SSD1325_SET_ROW_PERIOD, &buf, 1); + if (err < 0) { + return err; + } + err = config->write_cmd(dev, SSD1327_5_SET_LUT, + gs_table_ssd1325, SSD1325_LUT_COUNT); + if (err < 0) { + return err; + } + } else { + err = config->write_cmd(dev, SSD1327_5_SET_LUT, grayscale_table, SSD1327_LUT_COUNT); + if (err < 0) { + return err; + } + err = config->write_cmd(dev, SSD1327_SET_PRECHARGE_PERIOD, &config->prechargep, 1); + if (err < 0) { + return err; + } + } + err = config->write_cmd(dev, + SSD1327_5_SET_PRECHARGE_VOLTAGE, &config->precharge_voltage, 1); + if (err < 0) { + return err; + } + err = config->write_cmd(dev, SSD1327_5_SET_VCOMH, &config->vcomh_voltage, 1); + if (err < 0) { + return err; + } + if (config->variant == display_ssd1325) { + buf = SSD1325_PRECHARGE_COMP_DEFAULT; + err = config->write_cmd(dev, SSD1325_SET_PRECHARGE_COMP, &buf, 1); + if (err < 0) { + return err; + } + buf = SSD1325_PRECHARGE_COMP_EN; + return config->write_cmd(dev, SSD1325_SET_PRECHARGE_COMP_EN, &buf, 1); + } + err = config->write_cmd(dev, SSD1327_SET_FUNCTION_B, + &config->function_selection_b, 1); + if (err < 0) { + return err; + } + return config->write_cmd(dev, SSD1327_SET_COMMAND_LOCK, &buf, 1); +} + +static inline int ssd1327_5_set_hardware_config(const struct device *dev) +{ + const struct ssd1327_5_config *config = dev->config; + uint8_t buf; + int err; + + err = config->write_cmd(dev, SSD1327_5_SET_MULTIPLEX_RATIO, &config->multiplex_ratio, 1); + if (err < 0) { + return err; + } + err = config->write_cmd(dev, SSD1327_5_SET_DISPLAY_START_LINE, &config->start_line, 1); + if (err < 0) { + return err; + } + err = config->write_cmd(dev, SSD1327_5_SET_DISPLAY_OFFSET, &config->display_offset, 1); + if (err < 0) { + return err; + } + err = config->write_cmd(dev, SSD1327_5_SET_REMAPCTL, &config->remap_value, 1); + if (err < 0) { + return err; + } + if (config->variant == display_ssd1325) { + buf = SSD1325_MASTER_CONFIG; + err = config->write_cmd(dev, SSD1325_SET_MASTER_CONFIG, &buf, 1); + if (err < 0) { + return err; + } + return config->write_cmd(dev, SSD1325_SET_CURRENT_RANGE_FLL, NULL, 0); + } + buf = SSD1327_ENABLE_VDD; + return config->write_cmd(dev, SSD1327_SET_FUNCTION_A, &buf, 1); +} + +static int ssd1327_5_resume(const struct device *dev) +{ + const struct ssd1327_5_config *config = dev->config; + + return config->write_cmd(dev, SSD1327_5_SET_DISPLAY_ON, NULL, 0); +} + +static int ssd1327_5_suspend(const struct device *dev) +{ + const struct ssd1327_5_config *config = dev->config; + + return config->write_cmd(dev, SSD1327_5_SET_DISPLAY_OFF, NULL, 0); +} + +static int ssd1327_5_set_display(const struct device *dev) +{ + const struct ssd1327_5_config *config = dev->config; + int err; + uint8_t x_position[] = {0, config->width - 1}; + uint8_t y_position[] = {0, config->height - 1}; + + err = config->write_cmd(dev, SSD1327_5_SET_COLUMN_ADDR, x_position, sizeof(x_position)); + if (err < 0) { + return err; + } + err = config->write_cmd(dev, SSD1327_5_SET_ROW_ADDR, y_position, sizeof(y_position)); + if (err < 0) { + return err; + } + return config->write_cmd(dev, SSD1327_5_SET_REMAPCTL, &config->remap_value, 1); +} + +/* Convert what the conversion buffer can hold to pixelx (3:0) and pixelx+1 (7:4) */ +static int ssd1327_5_convert_L_8(const struct device *dev, const uint8_t *buf, int cur_offset, + uint32_t pixel_count) +{ + const struct ssd1327_5_config *config = dev->config; + int i = 0; + + for (; i / 2 < config->conversion_buf_size && pixel_count > cur_offset + i; i += 2) { + config->conversion_buf[i / 2] = buf[cur_offset + i] >> 4; + config->conversion_buf[i / 2] |= (buf[cur_offset + i + 1] >> 4) << 4; + } + return i; +} + +#if DT_HAS_COMPAT_ON_BUS_STATUS_OKAY(solomon_ssd1327, mipi_dbi) \ + || DT_HAS_COMPAT_ON_BUS_STATUS_OKAY(solomon_ssd1325, mipi_dbi) +static int ssd1327_5_write_pixels_mipi(const struct device *dev, const uint8_t *buf, + uint32_t pixel_count, + const struct display_buffer_descriptor *desc) +{ + const struct ssd1327_5_config *config = dev->config; + struct display_buffer_descriptor mipi_desc; + int ret, i; + int total = 0; + + mipi_desc.pitch = desc->pitch; + + while (pixel_count > total) { + i = ssd1327_5_convert_L_8(dev, buf, total, pixel_count); + + mipi_desc.buf_size = i / 2; + mipi_desc.width = mipi_desc.buf_size / desc->height; + mipi_desc.height = mipi_desc.buf_size / desc->width; + + /* This is the wrong format, but it doesn't matter to almost all mipi drivers */ + ret = mipi_dbi_write_display(config->mipi_dev, &config->dbi_config, + config->conversion_buf, &mipi_desc, PIXEL_FORMAT_L_8); + if (ret < 0) { + return ret; + } + total += i; + } + mipi_dbi_release(config->mipi_dev, &config->dbi_config); + return 0; +} +#endif + +#if DT_HAS_COMPAT_ON_BUS_STATUS_OKAY(solomon_ssd1327, i2c) \ + || DT_HAS_COMPAT_ON_BUS_STATUS_OKAY(solomon_ssd1325, i2c) +static int ssd1327_5_write_pixels_i2c(const struct device *dev, const uint8_t *buf, + uint32_t pixel_count, + const struct display_buffer_descriptor *desc) +{ + const struct ssd1327_5_config *config = dev->config; + int ret, i; + int total = 0; + + while (pixel_count > total) { + i = ssd1327_5_convert_L_8(dev, buf, total, pixel_count); + + ret = i2c_burst_write_dt(&config->i2c, SSD1327_5_I2C_ALL_BYTES_DATA, + config->conversion_buf, i / 2); + if (ret < 0) { + return ret; + } + total += i; + } + return 0; +} +#endif + +static int ssd1327_5_write(const struct device *dev, const uint16_t x, const uint16_t y, + const struct display_buffer_descriptor *desc, const void *buf) +{ + const struct ssd1327_5_config *config = dev->config; + int err; + size_t buf_len; + int32_t pixel_count = desc->width * desc->height; + uint8_t x_position[] = {x / 2, (x + desc->width - 1) / 2}; + uint8_t y_position[] = {y, y + desc->height - 1}; + + if (desc->pitch != desc->width) { + LOG_ERR("Pitch is not width"); + return -EINVAL; + } + + /* Following the datasheet, in the GDDRAM, two segment are split in one register */ + buf_len = MIN(desc->buf_size, desc->height * desc->width / 2); + if (buf == NULL || buf_len == 0U) { + LOG_ERR("Display buffer is not available"); + return -EINVAL; + } + + if ((x & 1) != 0U) { + LOG_ERR("Unsupported origin"); + return -EINVAL; + } + + LOG_DBG("x %u, y %u, pitch %u, width %u, height %u, buf_len %u", x, y, desc->pitch, + desc->width, desc->height, buf_len); + + err = config->write_cmd(dev, SSD1327_5_SET_COLUMN_ADDR, x_position, sizeof(x_position)); + if (err) { + return err; + } + + err = config->write_cmd(dev, SSD1327_5_SET_ROW_ADDR, y_position, sizeof(y_position)); + if (err) { + return err; + } + + return config->write_pixels(dev, buf, pixel_count, desc); +} + +static int ssd1327_5_set_contrast(const struct device *dev, const uint8_t contrast) +{ + const struct ssd1327_5_config *config = dev->config; + uint8_t constrast_cp = config->variant == display_ssd1325 ? contrast >> 1 : contrast; + + return config->write_cmd(dev, SSD1327_5_SET_CONTRAST_CTRL, &constrast_cp, 1); +} + +static void ssd1327_5_get_capabilities(const struct device *dev, struct display_capabilities *caps) +{ + const struct ssd1327_5_config *config = dev->config; + + memset(caps, 0, sizeof(struct display_capabilities)); + caps->x_resolution = config->width; + caps->y_resolution = config->height; + caps->supported_pixel_formats = PIXEL_FORMAT_L_8; + caps->current_pixel_format = PIXEL_FORMAT_L_8; + caps->screen_info = 0; +} + +static int ssd1327_5_set_pixel_format(const struct device *dev, const enum display_pixel_format pf) +{ + if (pf == PIXEL_FORMAT_L_8) { + return 0; + } + LOG_ERR("Unsupported pixel format"); + return -ENOTSUP; +} + +static int ssd1327_5_init_device(const struct device *dev) +{ + const struct ssd1327_5_config *config = dev->config; + int err; + + /* Turn display off */ + err = ssd1327_5_suspend(dev); + if (err < 0) { + return err; + } + + err = ssd1327_5_set_display(dev); + if (err < 0) { + return err; + } + + err = ssd1327_5_set_contrast(dev, config->default_contrast); + if (err < 0) { + return err; + } + + err = ssd1327_5_set_hardware_config(dev); + if (err < 0) { + return err; + } + + err = config->write_cmd(dev, + config->color_inversion ? + SSD1327_5_SET_REVERSE_DISPLAY : SSD1327_5_SET_NORMAL_DISPLAY, NULL, 0); + if (err < 0) { + return err; + } + + err = ssd1327_5_set_timing_setting(dev); + if (err < 0) { + return err; + } + + err = ssd1327_5_resume(dev); + if (err < 0) { + return err; + } + + return 0; +} + +#if DT_HAS_COMPAT_ON_BUS_STATUS_OKAY(solomon_ssd1327, mipi_dbi) \ + || DT_HAS_COMPAT_ON_BUS_STATUS_OKAY(solomon_ssd1325, mipi_dbi) +static int ssd1327_5_init(const struct device *dev) +{ + const struct ssd1327_5_config *config = dev->config; + int err; + + LOG_DBG("Initializing device"); + + if (!device_is_ready(config->mipi_dev)) { + LOG_ERR("MIPI Device not ready!"); + return -EINVAL; + } + + err = mipi_dbi_reset(config->mipi_dev, SSD1327_5_RESET_DELAY); + if (err < 0) { + LOG_ERR("Failed to reset device!"); + return err; + } + k_msleep(SSD1327_5_RESET_DELAY); + + err = ssd1327_5_init_device(dev); + if (err < 0) { + LOG_ERR("Failed to initialize device! %d", err); + return err; + } + + return 0; +} +#endif + +#if DT_HAS_COMPAT_ON_BUS_STATUS_OKAY(solomon_ssd1327, i2c) \ + || DT_HAS_COMPAT_ON_BUS_STATUS_OKAY(solomon_ssd1325, i2c) +static int ssd1327_5_init_i2c(const struct device *dev) +{ + const struct ssd1327_5_config *config = dev->config; + int err; + + LOG_DBG("Initializing device"); + + if (!i2c_is_ready_dt(&config->i2c)) { + LOG_ERR("I2C Device not ready!"); + return -EINVAL; + } + + err = ssd1327_5_init_device(dev); + if (err < 0) { + LOG_ERR("Failed to initialize device! %d", err); + return err; + } + + return 0; +} +#endif + +static DEVICE_API(display, ssd1327_5_driver_api) = { + .blanking_on = ssd1327_5_suspend, + .blanking_off = ssd1327_5_resume, + .write = ssd1327_5_write, + .set_contrast = ssd1327_5_set_contrast, + .get_capabilities = ssd1327_5_get_capabilities, + .set_pixel_format = ssd1327_5_set_pixel_format, +}; + +#define SSD1327_5_WORD_SIZE(inst) \ + ((DT_STRING_UPPER_TOKEN(inst, mipi_mode) == MIPI_DBI_MODE_SPI_4WIRE) ? SPI_WORD_SET(8) \ + : SPI_WORD_SET(9)) + +#define SSD1327_5_CONV_BUFFER_SIZE(node_id, n_buf_lines) \ + DIV_ROUND_UP(DT_PROP(node_id, width) * n_buf_lines, 2) + +#define SSD1327_5_GRAYSCALE_TABLE(node_id) \ + .grayscale_table = COND_CODE_1(DT_NODE_HAS_PROP(node_id, grayscale_table), \ + (ssd1327_5_grayscale_table_##node_id), (NULL)) + +#define SSD1327_5_DEFINE_I2C(node_id, n_variant, n_default_contrast, n_buf_lines) \ + static uint8_t conversion_buf##node_id[SSD1327_5_CONV_BUFFER_SIZE(node_id, n_buf_lines)]; \ + static struct ssd1327_5_data data##node_id; \ + COND_CODE_1(DT_NODE_HAS_PROP(node_id, grayscale_table), ( \ + static const uint8_t ssd1327_5_grayscale_table_##node_id[SSD1327_5_LUT_COUNT] = \ + DT_PROP(node_id, grayscale_table);), ()) \ + static const struct ssd1327_5_config config##node_id = { \ + .variant = n_variant, \ + .i2c = I2C_DT_SPEC_GET(node_id), \ + .height = DT_PROP(node_id, height), \ + .width = DT_PROP(node_id, width), \ + .oscillator_freq = DT_PROP(node_id, oscillator_freq), \ + .display_offset = DT_PROP(node_id, display_offset), \ + .start_line = DT_PROP(node_id, start_line), \ + .multiplex_ratio = DT_PROP(node_id, multiplex_ratio), \ + .prechargep = DT_PROP_OR(node_id, prechargep, 0x5), \ + .remap_value = DT_PROP(node_id, remap_value), \ + .color_inversion = DT_PROP(node_id, inversion_on), \ + .phase_length = DT_PROP(node_id, phase_length), \ + .function_selection_b = DT_PROP_OR(node_id, function_selection_b, 0x62), \ + .precharge_voltage = DT_PROP(node_id, precharge_voltage), \ + .vcomh_voltage = DT_PROP(node_id, vcomh_voltage), \ + .default_contrast = n_default_contrast, \ + SSD1327_5_GRAYSCALE_TABLE(node_id), \ + .write_cmd = ssd1327_5_write_bus_cmd_i2c, \ + .write_pixels = ssd1327_5_write_pixels_i2c, \ + .conversion_buf = conversion_buf##node_id, \ + .conversion_buf_size = sizeof(conversion_buf##node_id), \ + }; \ + \ + DEVICE_DT_DEFINE(node_id, ssd1327_5_init_i2c, NULL, &data##node_id, &config##node_id, \ + POST_KERNEL, CONFIG_DISPLAY_INIT_PRIORITY, &ssd1327_5_driver_api); + +#define SSD1327_5_DEFINE_MIPI(node_id, n_variant, n_default_contrast, n_buf_lines) \ + static uint8_t conversion_buf##node_id[SSD1327_5_CONV_BUFFER_SIZE(node_id, n_buf_lines)]; \ + static struct ssd1327_5_data data##node_id; \ + COND_CODE_1(DT_NODE_HAS_PROP(node_id, grayscale_table), ( \ + static const uint8_t ssd1327_5_grayscale_table_##node_id[SSD1327_5_LUT_COUNT] = \ + DT_PROP(node_id, grayscale_table);), ()) \ + static const struct ssd1327_5_config config##node_id = { \ + .variant = n_variant, \ + .mipi_dev = DEVICE_DT_GET(DT_PARENT(node_id)), \ + .dbi_config = MIPI_DBI_CONFIG_DT( \ + node_id, SSD1327_5_WORD_SIZE(node_id) | SPI_OP_MODE_MASTER, 0), \ + .height = DT_PROP(node_id, height), \ + .width = DT_PROP(node_id, width), \ + .oscillator_freq = DT_PROP(node_id, oscillator_freq), \ + .display_offset = DT_PROP(node_id, display_offset), \ + .start_line = DT_PROP(node_id, start_line), \ + .multiplex_ratio = DT_PROP(node_id, multiplex_ratio), \ + .prechargep = DT_PROP_OR(node_id, prechargep, 0x5), \ + .remap_value = DT_PROP(node_id, remap_value), \ + .color_inversion = DT_PROP(node_id, inversion_on), \ + .phase_length = DT_PROP(node_id, phase_length), \ + .function_selection_b = DT_PROP_OR(node_id, function_selection_b, 0x62), \ + .precharge_voltage = DT_PROP(node_id, precharge_voltage), \ + .vcomh_voltage = DT_PROP(node_id, vcomh_voltage), \ + .default_contrast = n_default_contrast, \ + SSD1327_5_GRAYSCALE_TABLE(node_id), \ + .write_cmd = ssd1327_5_write_bus_cmd_mipi, \ + .write_pixels = ssd1327_5_write_pixels_mipi, \ + .conversion_buf = conversion_buf##node_id, \ + .conversion_buf_size = sizeof(conversion_buf##node_id), \ + }; \ + \ + DEVICE_DT_DEFINE(node_id, ssd1327_5_init, NULL, &data##node_id, &config##node_id, \ + POST_KERNEL, CONFIG_DISPLAY_INIT_PRIORITY, &ssd1327_5_driver_api); + +#define SSD1327_5_DEFINE(node_id, n_variant, n_default_contrast, n_buf_lines) \ + COND_CODE_1(DT_ON_BUS(node_id, i2c), \ + (SSD1327_5_DEFINE_I2C(node_id, n_variant, n_default_contrast, n_buf_lines)), \ + (SSD1327_5_DEFINE_MIPI(node_id, n_variant, n_default_contrast, n_buf_lines))) + +DT_FOREACH_STATUS_OKAY_VARGS(solomon_ssd1327, SSD1327_5_DEFINE, display_ssd1327, + CONFIG_SSD1327_DEFAULT_CONTRAST, CONFIG_SSD1327_CONV_BUFFER_LINES) +DT_FOREACH_STATUS_OKAY_VARGS(solomon_ssd1325, SSD1327_5_DEFINE, display_ssd1325, + CONFIG_SSD1325_DEFAULT_CONTRAST, CONFIG_SSD1325_CONV_BUFFER_LINES) diff --git a/drivers/display/ssd1327.c b/drivers/display/ssd1327.c deleted file mode 100644 index 0a4d744f6dbe..000000000000 --- a/drivers/display/ssd1327.c +++ /dev/null @@ -1,536 +0,0 @@ -/* - * Copyright (c) 2024 Savoir-faire Linux - * Copyright (c) 2025 MASSDRIVER EI (massdriver.space) - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include -LOG_MODULE_REGISTER(ssd1327, CONFIG_DISPLAY_LOG_LEVEL); - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "ssd1327_regs.h" - -#define SSD1327_ENABLE_VDD 0x01 -#define SSD1327_UNLOCK_COMMAND 0x12 -#define SSD1327_MAXIMUM_CMD_LENGTH 16 - -typedef int (*ssd1327_write_bus_cmd_fn)(const struct device *dev, const uint8_t cmd, - const uint8_t *data, size_t len); -typedef int (*ssd1327_write_pixels_fn)(const struct device *dev, const uint8_t *buf, - uint32_t pixel_count, - const struct display_buffer_descriptor *desc); - -struct ssd1327_config { - struct i2c_dt_spec i2c; - ssd1327_write_bus_cmd_fn write_cmd; - ssd1327_write_pixels_fn write_pixels; - const struct device *mipi_dev; - const struct mipi_dbi_config dbi_config; - uint16_t height; - uint16_t width; - uint8_t oscillator_freq; - uint8_t start_line; - uint8_t display_offset; - uint8_t multiplex_ratio; - uint8_t prechargep; - uint8_t remap_value; - uint8_t phase_length; - uint8_t function_selection_b; - uint8_t precharge_voltage; - uint8_t vcomh_voltage; - const uint8_t *grayscale_table; - bool color_inversion; - uint8_t *conversion_buf; - size_t conversion_buf_size; -}; - -struct ssd1327_data { - uint8_t contrast; - uint8_t scan_mode; -}; - -static inline int ssd1327_write_bus_cmd_mipi(const struct device *dev, const uint8_t cmd, - const uint8_t *data, size_t len) -{ - const struct ssd1327_config *config = dev->config; - int err; - - /* Values given after the memory register must be sent with pin D/C set to 0. */ - /* Data is sent as a command following the mipi_cbi api */ - err = mipi_dbi_command_write(config->mipi_dev, &config->dbi_config, cmd, NULL, 0); - if (err) { - return err; - } - for (size_t i = 0; i < len; i++) { - err = mipi_dbi_command_write(config->mipi_dev, &config->dbi_config, - data[i], NULL, 0); - if (err) { - return err; - } - } - mipi_dbi_release(config->mipi_dev, &config->dbi_config); - - return 0; -} - -static inline int ssd1327_write_bus_cmd_i2c(const struct device *dev, const uint8_t cmd, - const uint8_t *data, size_t len) -{ - const struct ssd1327_config *config = dev->config; - uint8_t buf[SSD1327_MAXIMUM_CMD_LENGTH + 1]; - - if (len > SSD1327_MAXIMUM_CMD_LENGTH - 1) { - return -EINVAL; - } - - buf[0] = SSD1327_CONTROL_ALL_BYTES_CMD; - buf[1] = cmd; - memcpy(&(buf[2]), data, len); - - return i2c_write_dt(&config->i2c, buf, len + 2); -} - -static inline int ssd1327_set_timing_setting(const struct device *dev) -{ - const struct ssd1327_config *config = dev->config; - uint8_t buf = SSD1327_UNLOCK_COMMAND; - int err; - - err = config->write_cmd(dev, SSD1327_SET_PHASE_LENGTH, &config->phase_length, 1); - if (err < 0) { - return err; - } - err = config->write_cmd(dev, SSD1327_SET_OSC_FREQ, &config->oscillator_freq, 1); - if (err < 0) { - return err; - } - err = config->write_cmd(dev, SSD1327_SET_PRECHARGE_PERIOD, &config->prechargep, 1); - if (err < 0) { - return err; - } - err = config->write_cmd(dev, SSD1327_LINEAR_LUT, NULL, 0); - if (err < 0) { - return err; - } - if (config->grayscale_table != NULL) { - err = config->write_cmd(dev, SSD1327_SET_LUT, config->grayscale_table, - SSD1327_SET_LUT_COUNT); - if (err < 0) { - return err; - } - } - err = config->write_cmd(dev, SSD1327_SET_PRECHARGE_VOLTAGE, &config->precharge_voltage, 1); - if (err < 0) { - return err; - } - err = config->write_cmd(dev, SSD1327_SET_VCOMH, &config->vcomh_voltage, 1); - if (err < 0) { - return err; - } - err = config->write_cmd(dev, SSD1327_FUNCTION_SELECTION_B, &config->function_selection_b, - 1); - if (err < 0) { - return err; - } - return config->write_cmd(dev, SSD1327_SET_COMMAND_LOCK, &buf, 1); -} - -static inline int ssd1327_set_hardware_config(const struct device *dev) -{ - const struct ssd1327_config *config = dev->config; - uint8_t buf; - int err; - - err = config->write_cmd(dev, SSD1327_SET_DISPLAY_START_LINE, &config->start_line, 1); - if (err < 0) { - return err; - } - err = config->write_cmd(dev, SSD1327_SET_DISPLAY_OFFSET, &config->display_offset, 1); - if (err < 0) { - return err; - } - err = config->write_cmd(dev, SSD1327_SET_NORMAL_DISPLAY, NULL, 0); - if (err < 0) { - return err; - } - err = config->write_cmd(dev, SSD1327_SET_SEGMENT_MAP_REMAPED, &config->remap_value, 1); - if (err < 0) { - return err; - } - err = config->write_cmd(dev, SSD1327_SET_MULTIPLEX_RATIO, &config->multiplex_ratio, 1); - if (err < 0) { - return err; - } - buf = SSD1327_ENABLE_VDD; - return config->write_cmd(dev, SSD1327_SET_FUNCTION_A, &buf, 1); -} - -static int ssd1327_resume(const struct device *dev) -{ - const struct ssd1327_config *config = dev->config; - - return config->write_cmd(dev, SSD1327_DISPLAY_ON, NULL, 0); -} - -static int ssd1327_suspend(const struct device *dev) -{ - const struct ssd1327_config *config = dev->config; - - return config->write_cmd(dev, SSD1327_DISPLAY_OFF, NULL, 0); -} - -static int ssd1327_set_display(const struct device *dev) -{ - const struct ssd1327_config *config = dev->config; - int err; - uint8_t x_position[] = {0, config->width - 1}; - uint8_t y_position[] = {0, config->height - 1}; - - err = config->write_cmd(dev, SSD1327_SET_COLUMN_ADDR, x_position, sizeof(x_position)); - if (err < 0) { - return err; - } - err = config->write_cmd(dev, SSD1327_SET_ROW_ADDR, y_position, sizeof(y_position)); - if (err < 0) { - return err; - } - return config->write_cmd(dev, SSD1327_SET_SEGMENT_MAP_REMAPED, &config->remap_value, 1); -} - -/* Convert what the conversion buffer can hold to pixelx (3:0) and pixelx+1 (7:4) */ -static int ssd1327_convert_L_8(const struct device *dev, const uint8_t *buf, int cur_offset, - uint32_t pixel_count) -{ - const struct ssd1327_config *config = dev->config; - int i = 0; - - for (; i / 2 < config->conversion_buf_size && pixel_count > cur_offset + i; i += 2) { - config->conversion_buf[i / 2] = buf[cur_offset + i] >> 4; - config->conversion_buf[i / 2] |= (buf[cur_offset + i + 1] >> 4) << 4; - } - return i; -} - -#if DT_HAS_COMPAT_ON_BUS_STATUS_OKAY(solomon_ssd1327fb, mipi_dbi) -static int ssd1327_write_pixels_mipi(const struct device *dev, const uint8_t *buf, - uint32_t pixel_count, - const struct display_buffer_descriptor *desc) -{ - const struct ssd1327_config *config = dev->config; - struct display_buffer_descriptor mipi_desc; - int ret, i; - int total = 0; - - mipi_desc.pitch = desc->pitch; - - while (pixel_count > total) { - i = ssd1327_convert_L_8(dev, buf, total, pixel_count); - - mipi_desc.buf_size = i / 2; - mipi_desc.width = mipi_desc.buf_size / desc->height; - mipi_desc.height = mipi_desc.buf_size / desc->width; - - /* This is the wrong format, but it doesn't matter to almost all mipi drivers */ - ret = mipi_dbi_write_display(config->mipi_dev, &config->dbi_config, - config->conversion_buf, &mipi_desc, PIXEL_FORMAT_L_8); - if (ret < 0) { - return ret; - } - total += i; - } - mipi_dbi_release(config->mipi_dev, &config->dbi_config); - return 0; -} -#endif - -#if DT_HAS_COMPAT_ON_BUS_STATUS_OKAY(solomon_ssd1327fb, i2c) -static int ssd1327_write_pixels_i2c(const struct device *dev, const uint8_t *buf, - uint32_t pixel_count, - const struct display_buffer_descriptor *desc) -{ - const struct ssd1327_config *config = dev->config; - int ret, i; - int total = 0; - - while (pixel_count > total) { - i = ssd1327_convert_L_8(dev, buf, total, pixel_count); - - ret = i2c_burst_write_dt(&config->i2c, SSD1327_CONTROL_ALL_BYTES_DATA, - config->conversion_buf, i / 2); - if (ret < 0) { - return ret; - } - total += i; - } - return 0; -} -#endif - -static int ssd1327_write(const struct device *dev, const uint16_t x, const uint16_t y, - const struct display_buffer_descriptor *desc, const void *buf) -{ - const struct ssd1327_config *config = dev->config; - int err; - size_t buf_len; - int32_t pixel_count = desc->width * desc->height; - uint8_t x_position[] = {x / 2, (x + desc->width - 1) / 2}; - uint8_t y_position[] = {y, y + desc->height - 1}; - - if (desc->pitch != desc->width) { - LOG_ERR("Pitch is not width"); - return -EINVAL; - } - - /* Following the datasheet, in the GDDRAM, two segment are split in one register */ - buf_len = MIN(desc->buf_size, desc->height * desc->width / 2); - if (buf == NULL || buf_len == 0U) { - LOG_ERR("Display buffer is not available"); - return -EINVAL; - } - - if ((x & 1) != 0U) { - LOG_ERR("Unsupported origin"); - return -EINVAL; - } - - LOG_DBG("x %u, y %u, pitch %u, width %u, height %u, buf_len %u", x, y, desc->pitch, - desc->width, desc->height, buf_len); - - err = config->write_cmd(dev, SSD1327_SET_COLUMN_ADDR, x_position, sizeof(x_position)); - if (err) { - return err; - } - - err = config->write_cmd(dev, SSD1327_SET_ROW_ADDR, y_position, sizeof(y_position)); - if (err) { - return err; - } - - return config->write_pixels(dev, buf, pixel_count, desc); -} - -static int ssd1327_set_contrast(const struct device *dev, const uint8_t contrast) -{ - const struct ssd1327_config *config = dev->config; - - return config->write_cmd(dev, SSD1327_SET_CONTRAST_CTRL, &contrast, 1); -} - -static void ssd1327_get_capabilities(const struct device *dev, struct display_capabilities *caps) -{ - const struct ssd1327_config *config = dev->config; - - memset(caps, 0, sizeof(struct display_capabilities)); - caps->x_resolution = config->width; - caps->y_resolution = config->height; - caps->supported_pixel_formats = PIXEL_FORMAT_L_8; - caps->current_pixel_format = PIXEL_FORMAT_L_8; - caps->screen_info = 0; -} - -static int ssd1327_set_pixel_format(const struct device *dev, const enum display_pixel_format pf) -{ - if (pf == PIXEL_FORMAT_L_8) { - return 0; - } - LOG_ERR("Unsupported pixel format"); - return -ENOTSUP; -} - -static int ssd1327_init_device(const struct device *dev) -{ - const struct ssd1327_config *config = dev->config; - uint8_t buf; - int err; - - /* Turn display off */ - err = ssd1327_suspend(dev); - if (err < 0) { - return err; - } - - err = ssd1327_set_display(dev); - if (err < 0) { - return err; - } - - err = ssd1327_set_contrast(dev, CONFIG_SSD1327_DEFAULT_CONTRAST); - if (err < 0) { - return err; - } - - err = ssd1327_set_hardware_config(dev); - if (err < 0) { - return err; - } - - buf = (config->color_inversion ? SSD1327_SET_REVERSE_DISPLAY : SSD1327_SET_NORMAL_DISPLAY); - err = config->write_cmd(dev, SSD1327_SET_ENTIRE_DISPLAY_OFF, &buf, 1); - if (err < 0) { - return err; - } - - err = ssd1327_set_timing_setting(dev); - if (err < 0) { - return err; - } - - err = ssd1327_resume(dev); - if (err < 0) { - return err; - } - - return 0; -} - -#if DT_HAS_COMPAT_ON_BUS_STATUS_OKAY(solomon_ssd1327fb, mipi_dbi) -static int ssd1327_init(const struct device *dev) -{ - const struct ssd1327_config *config = dev->config; - int err; - - LOG_DBG("Initializing device"); - - if (!device_is_ready(config->mipi_dev)) { - LOG_ERR("MIPI Device not ready!"); - return -EINVAL; - } - - err = mipi_dbi_reset(config->mipi_dev, SSD1327_RESET_DELAY); - if (err < 0) { - LOG_ERR("Failed to reset device!"); - return err; - } - k_msleep(SSD1327_RESET_DELAY); - - err = ssd1327_init_device(dev); - if (err < 0) { - LOG_ERR("Failed to initialize device! %d", err); - return err; - } - - return 0; -} -#endif - -#if DT_HAS_COMPAT_ON_BUS_STATUS_OKAY(solomon_ssd1327fb, i2c) -static int ssd1327_init_i2c(const struct device *dev) -{ - const struct ssd1327_config *config = dev->config; - int err; - - LOG_DBG("Initializing device"); - - if (!i2c_is_ready_dt(&config->i2c)) { - LOG_ERR("I2C Device not ready!"); - return -EINVAL; - } - - err = ssd1327_init_device(dev); - if (err < 0) { - LOG_ERR("Failed to initialize device! %d", err); - return err; - } - - return 0; -} -#endif - -static DEVICE_API(display, ssd1327_driver_api) = { - .blanking_on = ssd1327_suspend, - .blanking_off = ssd1327_resume, - .write = ssd1327_write, - .set_contrast = ssd1327_set_contrast, - .get_capabilities = ssd1327_get_capabilities, - .set_pixel_format = ssd1327_set_pixel_format, -}; - -#define SSD1327_WORD_SIZE(inst) \ - ((DT_STRING_UPPER_TOKEN(inst, mipi_mode) == MIPI_DBI_MODE_SPI_4WIRE) ? SPI_WORD_SET(8) \ - : SPI_WORD_SET(9)) - -#define SSD1327_CONV_BUFFER_SIZE(node_id) \ - DIV_ROUND_UP(DT_PROP(node_id, width) * CONFIG_SSD1327_CONV_BUFFER_LINES, 2) - -#define SSD1327_GRAYSCALE_TABLE(node_id) \ - .grayscale_table = COND_CODE_1(DT_NODE_HAS_PROP(node_id, grayscale_table), \ - (ssd1327_grayscale_table_##node_id), (NULL)) - -#define SSD1327_DEFINE_I2C(node_id) \ - static uint8_t conversion_buf##node_id[SSD1327_CONV_BUFFER_SIZE(node_id)]; \ - static struct ssd1327_data data##node_id; \ - COND_CODE_1(DT_NODE_HAS_PROP(node_id, grayscale_table), ( \ - static const uint8_t ssd1327_grayscale_table_##node_id[SSD1327_SET_LUT_COUNT] = \ - DT_PROP(node_id, grayscale_table);), ()) \ - static const struct ssd1327_config config##node_id = { \ - .i2c = I2C_DT_SPEC_GET(node_id), \ - .height = DT_PROP(node_id, height), \ - .width = DT_PROP(node_id, width), \ - .oscillator_freq = DT_PROP(node_id, oscillator_freq), \ - .display_offset = DT_PROP(node_id, display_offset), \ - .start_line = DT_PROP(node_id, start_line), \ - .multiplex_ratio = DT_PROP(node_id, multiplex_ratio), \ - .prechargep = DT_PROP(node_id, prechargep), \ - .remap_value = DT_PROP(node_id, remap_value), \ - .color_inversion = DT_PROP(node_id, inversion_on), \ - .phase_length = DT_PROP(node_id, phase_length), \ - .function_selection_b = DT_PROP(node_id, function_selection_b), \ - .precharge_voltage = DT_PROP(node_id, precharge_voltage), \ - .vcomh_voltage = DT_PROP(node_id, vcomh_voltage), \ - SSD1327_GRAYSCALE_TABLE(node_id), \ - .write_cmd = ssd1327_write_bus_cmd_i2c, \ - .write_pixels = ssd1327_write_pixels_i2c, \ - .conversion_buf = conversion_buf##node_id, \ - .conversion_buf_size = sizeof(conversion_buf##node_id), \ - }; \ - \ - DEVICE_DT_DEFINE(node_id, ssd1327_init_i2c, NULL, &data##node_id, &config##node_id, \ - POST_KERNEL, CONFIG_DISPLAY_INIT_PRIORITY, &ssd1327_driver_api); - -#define SSD1327_DEFINE_MIPI(node_id) \ - static uint8_t conversion_buf##node_id[SSD1327_CONV_BUFFER_SIZE(node_id)]; \ - static struct ssd1327_data data##node_id; \ - COND_CODE_1(DT_NODE_HAS_PROP(node_id, grayscale_table), ( \ - static const uint8_t ssd1327_grayscale_table_##node_id[SSD1327_SET_LUT_COUNT] = \ - DT_PROP(node_id, grayscale_table);), ()) \ - static const struct ssd1327_config config##node_id = { \ - .mipi_dev = DEVICE_DT_GET(DT_PARENT(node_id)), \ - .dbi_config = MIPI_DBI_CONFIG_DT( \ - node_id, SSD1327_WORD_SIZE(node_id) | SPI_OP_MODE_MASTER, 0), \ - .height = DT_PROP(node_id, height), \ - .width = DT_PROP(node_id, width), \ - .oscillator_freq = DT_PROP(node_id, oscillator_freq), \ - .display_offset = DT_PROP(node_id, display_offset), \ - .start_line = DT_PROP(node_id, start_line), \ - .multiplex_ratio = DT_PROP(node_id, multiplex_ratio), \ - .prechargep = DT_PROP(node_id, prechargep), \ - .remap_value = DT_PROP(node_id, remap_value), \ - .color_inversion = DT_PROP(node_id, inversion_on), \ - .phase_length = DT_PROP(node_id, phase_length), \ - .function_selection_b = DT_PROP(node_id, function_selection_b), \ - .precharge_voltage = DT_PROP(node_id, precharge_voltage), \ - .vcomh_voltage = DT_PROP(node_id, vcomh_voltage), \ - SSD1327_GRAYSCALE_TABLE(node_id), \ - .write_cmd = ssd1327_write_bus_cmd_mipi, \ - .write_pixels = ssd1327_write_pixels_mipi, \ - .conversion_buf = conversion_buf##node_id, \ - .conversion_buf_size = sizeof(conversion_buf##node_id), \ - }; \ - \ - DEVICE_DT_DEFINE(node_id, ssd1327_init, NULL, &data##node_id, &config##node_id, \ - POST_KERNEL, CONFIG_DISPLAY_INIT_PRIORITY, &ssd1327_driver_api); - -#define SSD1327_DEFINE(node_id) \ - COND_CODE_1(DT_ON_BUS(node_id, i2c), \ - (SSD1327_DEFINE_I2C(node_id)), (SSD1327_DEFINE_MIPI(node_id))) - -DT_FOREACH_STATUS_OKAY(solomon_ssd1327fb, SSD1327_DEFINE) diff --git a/drivers/display/ssd1327_regs.h b/drivers/display/ssd1327_regs.h deleted file mode 100644 index 36e72d7f66a8..000000000000 --- a/drivers/display/ssd1327_regs.h +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright (c) 2024 Savoir-faire Linux - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#ifndef __SSD1327_REGS_H__ -#define __SSD1327_REGS_H__ - -/* - * Fundamental Command Table - */ -#define SSD1327_SET_COLUMN_ADDR 0x15 -#define SSD1327_SET_ROW_ADDR 0x75 - -#define SSD1327_SET_CONTRAST_CTRL 0x81 - -#define SSD1327_SET_SEGMENT_MAP_REMAPED 0xa0 -#define SSD1327_SET_DISPLAY_START_LINE 0xa1 -#define SSD1327_SET_DISPLAY_OFFSET 0xa2 - -#define SSD1327_SET_NORMAL_DISPLAY 0xa4 -#define SSD1327_SET_ENTIRE_DISPLAY_ON 0xa5 -#define SSD1327_SET_ENTIRE_DISPLAY_OFF 0xa6 -#define SSD1327_SET_REVERSE_DISPLAY 0xa7 -#define SSD1327_SET_MULTIPLEX_RATIO 0xa8 - -#define SSD1327_DISPLAY_OFF 0xae -#define SSD1327_DISPLAY_ON 0xaf - -#define SSD1327_SET_FUNCTION_A 0xab -#define SSD1327_SET_PHASE_LENGTH 0xb1 -#define SSD1327_SET_OSC_FREQ 0xb3 -#define SSD1327_SET_PRECHARGE_PERIOD 0xb6 -#define SSD1327_FUNCTION_SELECTION_B 0xd5 - -#define SSD1327_SET_LUT 0xb8 -#define SSD1327_SET_LUT_COUNT 15 -#define SSD1327_LINEAR_LUT 0xb9 - -#define SSD1327_SET_PRECHARGE_VOLTAGE 0xbc -#define SSD1327_SET_VCOMH 0xbe - - -#define SSD1327_SET_COMMAND_LOCK 0xfd - -/* Time constant in ms */ -#define SSD1327_RESET_DELAY 10 - -#define SSD1327_CONTROL_ALL_BYTES_CMD 0x0 -#define SSD1327_CONTROL_ALL_BYTES_DATA 0x40 - -#endif diff --git a/dts/bindings/display/solomon,ssd1325-i2c.yaml b/dts/bindings/display/solomon,ssd1325-i2c.yaml new file mode 100644 index 000000000000..f4ce7357f1bc --- /dev/null +++ b/dts/bindings/display/solomon,ssd1325-i2c.yaml @@ -0,0 +1,12 @@ +# Copyright (c) 2026 MASSDRIVER EI (massdriver.space) +# SPDX-License-Identifier: Apache-2.0 + +title: Solomon SSD1325 display controller on I2C bus + +description: | + The Solomon SSD1325 is a 4-bit greyscale OLED controller + with a maximum 128x80 resolution. + +include: ["solomon,ssd1327_5-common.yaml", "i2c-device.yaml"] + +compatible: "solomon,ssd1325" diff --git a/dts/bindings/display/solomon,ssd1325-mipi.yaml b/dts/bindings/display/solomon,ssd1325-mipi.yaml new file mode 100644 index 000000000000..802211b4a51e --- /dev/null +++ b/dts/bindings/display/solomon,ssd1325-mipi.yaml @@ -0,0 +1,12 @@ +# Copyright (c) 2026 MASSDRIVER EI (massdriver.space) +# SPDX-License-Identifier: Apache-2.0 + +title: Solomon SSD1325 display controller on MIPI_DBI or SPI bus + +description: | + The Solomon SSD1325 is a 4-bit greyscale OLED controller + with a maximum 128x80 resolution. + +include: ["solomon,ssd1327_5-common.yaml", "mipi-dbi-spi-device.yaml"] + +compatible: "solomon,ssd1325" diff --git a/dts/bindings/display/solomon,ssd1327-common.yaml b/dts/bindings/display/solomon,ssd1327-common.yaml new file mode 100644 index 000000000000..1b7546a8dd64 --- /dev/null +++ b/dts/bindings/display/solomon,ssd1327-common.yaml @@ -0,0 +1,16 @@ +# Copyright (c) 2026 MASSDRIVER EI (massdriver.space) +# SPDX-License-Identifier: Apache-2.0 + +include: "solomon,ssd1327_5-common.yaml" + +properties: + prechargep: + type: int + required: true + description: Pre-charge period ranging from 0 to 15 DCLK's. + + function-selection-b: + type: int + default: 0x62 + description: Enables second precharge (A[1]), and external Voltage Segment Level (A[0]) + The value can either be 0x61, 0x62, or 0x63. Most displays use 0x62. diff --git a/dts/bindings/display/solomon,ssd1327fb-i2c.yaml b/dts/bindings/display/solomon,ssd1327-i2c.yaml similarity index 58% rename from dts/bindings/display/solomon,ssd1327fb-i2c.yaml rename to dts/bindings/display/solomon,ssd1327-i2c.yaml index 4e175835355f..8a87f6e0f8c3 100644 --- a/dts/bindings/display/solomon,ssd1327fb-i2c.yaml +++ b/dts/bindings/display/solomon,ssd1327-i2c.yaml @@ -1,4 +1,4 @@ -# Copyright (c) 2025 MASSDRIVER EI (massdriver.space) +# Copyright (c) 2025-2026 MASSDRIVER EI (massdriver.space) # SPDX-License-Identifier: Apache-2.0 title: Solomon SSD1327 display controller on I2C bus @@ -7,6 +7,6 @@ description: | The Solomon SSD1327 is a 4-bit greyscale OLED controller with a maximum 128x128 resolution. -include: ["solomon,ssd1327fb-common.yaml", "i2c-device.yaml"] +include: ["solomon,ssd1327-common.yaml", "i2c-device.yaml"] -compatible: "solomon,ssd1327fb" +compatible: "solomon,ssd1327" diff --git a/dts/bindings/display/solomon,ssd1327fb-mipi.yaml b/dts/bindings/display/solomon,ssd1327-mipi.yaml similarity index 58% rename from dts/bindings/display/solomon,ssd1327fb-mipi.yaml rename to dts/bindings/display/solomon,ssd1327-mipi.yaml index 4112ef03938c..db7174a54ac8 100644 --- a/dts/bindings/display/solomon,ssd1327fb-mipi.yaml +++ b/dts/bindings/display/solomon,ssd1327-mipi.yaml @@ -1,4 +1,4 @@ -# Copyright (c) 2025 MASSDRIVER EI (massdriver.space) +# Copyright (c) 2025-2026 MASSDRIVER EI (massdriver.space) # SPDX-License-Identifier: Apache-2.0 title: Solomon SSD1327 display controller on MIPI_DBI or SPI bus @@ -7,6 +7,6 @@ description: | The Solomon SSD1327 is a 4-bit greyscale OLED controller with a maximum 128x128 resolution. -include: ["solomon,ssd1327fb-common.yaml", "mipi-dbi-spi-device.yaml"] +include: ["solomon,ssd1327-common.yaml", "mipi-dbi-spi-device.yaml"] -compatible: "solomon,ssd1327fb" +compatible: "solomon,ssd1327" diff --git a/dts/bindings/display/solomon,ssd1327fb-common.yaml b/dts/bindings/display/solomon,ssd1327_5-common.yaml similarity index 75% rename from dts/bindings/display/solomon,ssd1327fb-common.yaml rename to dts/bindings/display/solomon,ssd1327_5-common.yaml index 4e9a5c6062a8..6812f6bafc1a 100644 --- a/dts/bindings/display/solomon,ssd1327fb-common.yaml +++ b/dts/bindings/display/solomon,ssd1327_5-common.yaml @@ -1,4 +1,5 @@ # Copyright (c) 2024, Savoir-faire Linux +# Copyright (c) 2025-2026 MASSDRIVER EI (massdriver.space) # SPDX-License-Identifier: Apache-2.0 include: display-controller.yaml @@ -14,23 +15,19 @@ properties: display-offset: type: int required: true - description: Vertical offset by com from 0 ~ 127. Typically 128 - height. + description: Vertical offset by com from 0 ~ 127 (79 for SSD1325). Typically 128 (80) - height. start-line: type: int required: true - description: Start line of display RAM to be displayed by selecting a value from 0 to 127. - Typically 0. + description: Start line of display RAM to be displayed by selecting a value + from 0 to 127 (79 for SSD1325). Typically 0. multiplex-ratio: type: int required: true - description: Multiplex ratio from 15MUX to 127MUX. Typically same value as height - 1. - - prechargep: - type: int - required: true - description: Pre-charge period ranging from 0 to 15 DCLK's + description: Multiplex ratio from 15MUX to 127MUX (79MUX for SSD1325). + Typically same value as height - 1. remap-value: type: int @@ -53,19 +50,13 @@ properties: type: int required: true description: Phase Length for segment charging (7:4) and discharging (3:0). - Good values to try first are 0x1f and 0xf1. - - function-selection-b: - type: int - default: 0x62 - description: Enables second precharge (A[1]), and external Voltage Segment Level (A[0]) - The value can either be 0x61, 0x62, or 0x63. Most displays use 0x62. + Good values to try first are 0x1f and 0xf1, or 0x22 for SSD1325. precharge-voltage: type: int default: 0x8 description: Set precharge voltage (0:4) from 0.20 x VCC to 0.613 x VCC (0x7) and VCOMH (0x8+). - Most displays support 0x8. + Most displays support 0x8, or 0x10 for SSD1325. vcomh-voltage: type: int @@ -80,3 +71,4 @@ properties: grayscale-table: type: uint8-array description: 15 elements array defines gamma settings for each brightness levels. + 5-bits wide for SSD1327, 3-bits wide with specific calculations for SSD1325. From c5c4df5dd67ee1fe319760529eb7ee321994f742 Mon Sep 17 00:00:00 2001 From: Camille BAUD Date: Mon, 12 Jan 2026 18:14:15 +0100 Subject: [PATCH 0077/6328] tests: build_all: display: Add ssd1325 Add ssd1325 test, rename ssd1327 Signed-off-by: Camille BAUD --- drivers/display/display_ssd1327_5.c | 2 +- tests/drivers/build_all/display/app.overlay | 41 +++++++++++++++++++-- 2 files changed, 38 insertions(+), 5 deletions(-) diff --git a/drivers/display/display_ssd1327_5.c b/drivers/display/display_ssd1327_5.c index 07f55a80a900..4f2eb184554a 100644 --- a/drivers/display/display_ssd1327_5.c +++ b/drivers/display/display_ssd1327_5.c @@ -89,7 +89,7 @@ typedef int (*ssd1327_5_write_pixels_fn)(const struct device *dev, const uint8_t { t[0] & 0x7, (t[1] & 0x7) | ((t[2] & 0x7) << 4), (t[3] & 0x7) | ((t[4] & 0x7) << 4), \ (t[5] & 0x7) | ((t[6] & 0x7) << 4), (t[7] & 0x7) | ((t[8] & 0x7) << 4), \ (t[9] & 0x7) | ((t[10] & 0x7) << 4), (t[11] & 0x7) | ((t[12] & 0x7) << 4), \ - (t[13] & 0x7) | ((t[14] & 0x7) << 4) }; + (t[13] & 0x7) | ((t[14] & 0x7) << 4) } #if DT_HAS_COMPAT_STATUS_OKAY(solomon_ssd1327) #define SSD1327_5_MAXIMUM_CMD_LENGTH SSD1327_MAXIMUM_CMD_LENGTH diff --git a/tests/drivers/build_all/display/app.overlay b/tests/drivers/build_all/display/app.overlay index f87b736713d4..9f2c304e4809 100644 --- a/tests/drivers/build_all/display/app.overlay +++ b/tests/drivers/build_all/display/app.overlay @@ -136,8 +136,8 @@ height = <240>; }; - test_spi_ssd1327fb: ssd1327fb@7 { - compatible = "solomon,ssd1327fb"; + test_spi_ssd1327: ssd1327@7 { + compatible = "solomon,ssd1327"; reg = <7>; mipi-max-frequency = <100000000>; width = <128>; @@ -371,6 +371,24 @@ regulation-ratio = <7>; mipi-mode = "MIPI_DBI_MODE_SPI_4WIRE"; }; + + test_spi_ssd1325: ssd1325@21 { + compatible = "solomon,ssd1325"; + reg = <21>; + mipi-max-frequency = <20000000>; + width = <128>; + height = <64>; + precharge-voltage = <0x10>; + remap-value = <0x50>; + oscillator-freq = <0x91>; + display-offset = <0x4c>; + start-line = <0>; + multiplex-ratio = <0x3f>; + phase-length = <0x22>; + vcomh-voltage = <0x2>; + mipi-mode = "MIPI_DBI_MODE_SPI_4WIRE"; + grayscale-table = [02 02 02 02 02 02 02 02 03 04 05 06 07 07 07]; + }; }; test_mipi_dbi_xfr_16bit_write_only { @@ -679,8 +697,8 @@ vcomh-voltage = <0>; }; - test_ssd1327fb: ssd1327fb@5 { - compatible = "solomon,ssd1327fb"; + test_ssd1327: ssd1327@5 { + compatible = "solomon,ssd1327"; reg = <5>; width = <128>; height = <128>; @@ -707,6 +725,21 @@ multiplex-ratio = <0>; phase-length = <0x0>; }; + + test_ssd1325: ssd1325@7 { + compatible = "solomon,ssd1325"; + reg = <7>; + width = <128>; + height = <64>; + precharge-voltage = <0x10>; + remap-value = <0x50>; + oscillator-freq = <0x91>; + display-offset = <0x4c>; + start-line = <0>; + multiplex-ratio = <0x3f>; + phase-length = <0x22>; + vcomh-voltage = <0x2>; + }; }; }; }; From 9e39daadfdce601e224fbfd937fc8421f98f165b Mon Sep 17 00:00:00 2001 From: Camille BAUD Date: Mon, 12 Jan 2026 18:56:56 +0100 Subject: [PATCH 0078/6328] doc: release: Notes about SSD1327 Driver Adds note about Kconfig change for SSD327 driver Signed-off-by: Camille BAUD --- doc/releases/migration-guide-4.4.rst | 5 +++++ doc/releases/release-notes-4.4.rst | 9 +++++++++ 2 files changed, 14 insertions(+) diff --git a/doc/releases/migration-guide-4.4.rst b/doc/releases/migration-guide-4.4.rst index bfd40de5598a..2b19fcdddd14 100644 --- a/doc/releases/migration-guide-4.4.rst +++ b/doc/releases/migration-guide-4.4.rst @@ -355,6 +355,11 @@ Display :kconfig:option:`SDL_DISPLAY_DEFAULT_PIXEL_FORMAT_RGB_565X` and :kconfig:option:`ST7789V_RGB565X` respectively. (:github:`99276`) +* ``CONFIG_SSD1327`` symbol has been renamed to :kconfig:option:`CONFIG_SSD1327_5` to include ``SSD1325`` as well. + +* ``solomon,ssd1327fb`` devicetree compatible has been renamed :dtcompatible:`solomon,ssd1327` + to harmonize with other display controllers and eliminate the zephyr-irrelevant ``fb`` suffix. + DMA === diff --git a/doc/releases/release-notes-4.4.rst b/doc/releases/release-notes-4.4.rst index a839131be85c..912badc334e6 100644 --- a/doc/releases/release-notes-4.4.rst +++ b/doc/releases/release-notes-4.4.rst @@ -169,6 +169,11 @@ New APIs and options generating slot 1 images automatically in sysbuild projects when using MCUboot in direct-xip mode. +* Display + + * :kconfig:option:`SSD1325_DEFAULT_CONTRAST` + * :kconfig:option:`SSD1325_CONV_BUFFER_LINES` + * Ethernet * Driver MAC address configuration with support for NVMEM cell. @@ -300,6 +305,10 @@ New Drivers * :dtcompatible:`radio-fem-two-ctrl-pins` (renamed from ``generic-fem-two-ctrl-pins``) * :dtcompatible:`radio-gpio-coex` (renamed from ``gpio-radio-coex``) +* Display + + * :dtcompatible:`solomon,ssd1325` + New Samples *********** From 730b301009b415b1f55822bf7e7135ff518ea088 Mon Sep 17 00:00:00 2001 From: Greg Leach Date: Tue, 13 Jan 2026 15:37:12 +0000 Subject: [PATCH 0079/6328] boards: ezurio: Add rm126x_dvk support Add support for the Ezurio RM126x DVK board family. Signed-off-by: Greg Leach --- boards/ezurio/rm126x_dvk/Kconfig.defconfig | 14 + .../rm126x_dvk/Kconfig.rm126x_dvk_rm1261 | 6 + .../rm126x_dvk/Kconfig.rm126x_dvk_rm1262 | 6 + boards/ezurio/rm126x_dvk/board.cmake | 9 + boards/ezurio/rm126x_dvk/board.yml | 11 + .../rm126x_dvk/doc/img/rm126x_dvk_rm1261.webp | Bin 0 -> 29002 bytes .../rm126x_dvk/doc/img/rm126x_dvk_rm1262.webp | Bin 0 -> 29002 bytes .../doc/rm126x_dvk_common_1.rst.inc | 206 +++++++++++++ .../doc/rm126x_dvk_common_2.rst.inc | 33 +++ .../rm126x_dvk/doc/rm126x_dvk_rm1261.rst | 19 ++ .../rm126x_dvk/doc/rm126x_dvk_rm1262.rst | 19 ++ boards/ezurio/rm126x_dvk/pre_dt_board.cmake | 6 + .../ezurio/rm126x_dvk/rm126x_dvk-pinctrl.dtsi | 82 ++++++ boards/ezurio/rm126x_dvk/rm126x_dvk.dtsi | 274 ++++++++++++++++++ .../ezurio/rm126x_dvk/rm126x_dvk_rm1261.dts | 31 ++ .../ezurio/rm126x_dvk/rm126x_dvk_rm1261.yaml | 27 ++ .../rm126x_dvk/rm126x_dvk_rm1261_defconfig | 10 + .../ezurio/rm126x_dvk/rm126x_dvk_rm1262.dts | 32 ++ .../ezurio/rm126x_dvk/rm126x_dvk_rm1262.yaml | 27 ++ .../rm126x_dvk/rm126x_dvk_rm1262_defconfig | 10 + 20 files changed, 822 insertions(+) create mode 100644 boards/ezurio/rm126x_dvk/Kconfig.defconfig create mode 100644 boards/ezurio/rm126x_dvk/Kconfig.rm126x_dvk_rm1261 create mode 100644 boards/ezurio/rm126x_dvk/Kconfig.rm126x_dvk_rm1262 create mode 100644 boards/ezurio/rm126x_dvk/board.cmake create mode 100644 boards/ezurio/rm126x_dvk/board.yml create mode 100644 boards/ezurio/rm126x_dvk/doc/img/rm126x_dvk_rm1261.webp create mode 100644 boards/ezurio/rm126x_dvk/doc/img/rm126x_dvk_rm1262.webp create mode 100644 boards/ezurio/rm126x_dvk/doc/rm126x_dvk_common_1.rst.inc create mode 100644 boards/ezurio/rm126x_dvk/doc/rm126x_dvk_common_2.rst.inc create mode 100644 boards/ezurio/rm126x_dvk/doc/rm126x_dvk_rm1261.rst create mode 100644 boards/ezurio/rm126x_dvk/doc/rm126x_dvk_rm1262.rst create mode 100644 boards/ezurio/rm126x_dvk/pre_dt_board.cmake create mode 100644 boards/ezurio/rm126x_dvk/rm126x_dvk-pinctrl.dtsi create mode 100644 boards/ezurio/rm126x_dvk/rm126x_dvk.dtsi create mode 100644 boards/ezurio/rm126x_dvk/rm126x_dvk_rm1261.dts create mode 100644 boards/ezurio/rm126x_dvk/rm126x_dvk_rm1261.yaml create mode 100644 boards/ezurio/rm126x_dvk/rm126x_dvk_rm1261_defconfig create mode 100644 boards/ezurio/rm126x_dvk/rm126x_dvk_rm1262.dts create mode 100644 boards/ezurio/rm126x_dvk/rm126x_dvk_rm1262.yaml create mode 100644 boards/ezurio/rm126x_dvk/rm126x_dvk_rm1262_defconfig diff --git a/boards/ezurio/rm126x_dvk/Kconfig.defconfig b/boards/ezurio/rm126x_dvk/Kconfig.defconfig new file mode 100644 index 000000000000..d5d17b8b979a --- /dev/null +++ b/boards/ezurio/rm126x_dvk/Kconfig.defconfig @@ -0,0 +1,14 @@ +# Copyright The Zephyr Project Contributors +# Copyright (c) 2026 Ezurio LLC +# SPDX-License-Identifier: Apache-2.0 + +if BOARD_RM126X_DVK_RM1261 || BOARD_RM126X_DVK_RM1262 + +config LOG_BACKEND_SWO_FREQ_HZ + default 875000 + depends on LOG_BACKEND_SWO + +config FPU + default y + +endif diff --git a/boards/ezurio/rm126x_dvk/Kconfig.rm126x_dvk_rm1261 b/boards/ezurio/rm126x_dvk/Kconfig.rm126x_dvk_rm1261 new file mode 100644 index 000000000000..e97bf8a9c050 --- /dev/null +++ b/boards/ezurio/rm126x_dvk/Kconfig.rm126x_dvk_rm1261 @@ -0,0 +1,6 @@ +# Copyright The Zephyr Project Contributors +# Copyright (c) 2026 Ezurio LLC +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_RM126X_DVK_RM1261 + select SOC_EFR32BG22C224F512IM40 diff --git a/boards/ezurio/rm126x_dvk/Kconfig.rm126x_dvk_rm1262 b/boards/ezurio/rm126x_dvk/Kconfig.rm126x_dvk_rm1262 new file mode 100644 index 000000000000..3adb9e1159f1 --- /dev/null +++ b/boards/ezurio/rm126x_dvk/Kconfig.rm126x_dvk_rm1262 @@ -0,0 +1,6 @@ +# Copyright The Zephyr Project Contributors +# Copyright (c) 2026 Ezurio LLC +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_RM126X_DVK_RM1262 + select SOC_EFR32BG22C224F512IM40 diff --git a/boards/ezurio/rm126x_dvk/board.cmake b/boards/ezurio/rm126x_dvk/board.cmake new file mode 100644 index 000000000000..42a606a3cf90 --- /dev/null +++ b/boards/ezurio/rm126x_dvk/board.cmake @@ -0,0 +1,9 @@ +# Copyright The Zephyr Project Contributors +# Copyright (c) 2026 Ezurio LLC +# SPDX-License-Identifier: Apache-2.0 + +board_runner_args(jlink "--device=EFR32BG22C224F512IM40" "--reset-after-load") +include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) + +board_runner_args(silabs_commander "--device=${CONFIG_SOC}") +include(${ZEPHYR_BASE}/boards/common/silabs_commander.board.cmake) diff --git a/boards/ezurio/rm126x_dvk/board.yml b/boards/ezurio/rm126x_dvk/board.yml new file mode 100644 index 000000000000..4038cbcb77e2 --- /dev/null +++ b/boards/ezurio/rm126x_dvk/board.yml @@ -0,0 +1,11 @@ +boards: + - name: rm126x_dvk_rm1261 + full_name: RM1261 DVK + vendor: ezurio + socs: + - name: efr32bg22c224f512im40 + - name: rm126x_dvk_rm1262 + full_name: RM1262 DVK + vendor: ezurio + socs: + - name: efr32bg22c224f512im40 diff --git a/boards/ezurio/rm126x_dvk/doc/img/rm126x_dvk_rm1261.webp b/boards/ezurio/rm126x_dvk/doc/img/rm126x_dvk_rm1261.webp new file mode 100644 index 0000000000000000000000000000000000000000..0979a17fae92d96aa2e07e13535ac4eb330bdb4b GIT binary patch literal 29002 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 BaUTEx literal 0 HcmV?d00001 diff --git a/boards/ezurio/rm126x_dvk/doc/img/rm126x_dvk_rm1262.webp b/boards/ezurio/rm126x_dvk/doc/img/rm126x_dvk_rm1262.webp new file mode 100644 index 0000000000000000000000000000000000000000..0979a17fae92d96aa2e07e13535ac4eb330bdb4b GIT binary patch literal 29002 zcmV(nK=Qv*Nk&FOaR2~UMM6+kP&il$0000G0001f0RV>r06|PpNPz$V009p${}BHb5%~jB2~v04q5?BD?;sCBHtNx znB|K5&;95AbN{*j+<#A!MQ;82agZ~)`g6qO4&5ssFZs?((7D)xX$3fFO;EH(z?33Q zoWGue=JTVR5S|pXTs~nEx%B{6P&go(Z~y?1vjLp}Dt`fp0zQ#GnMoz1BBCnP45+XY z31V(PE6;x3?dRNk_&toWZ@2$<{!8~`+eejr0r*ehzia$!e~-F9b^pud-_GCnf6xA8 z{NDeE|A+l2yr1n~?Z4`NfBgymxqi+1^M2v`*8cksN`M=>mDSc1* zJN{?+FJO<(zoCDo^*H;l+OGkv*Zwb{U$Y-^|G)lw$S3|^^4_!lss2;{Pq-iSfAJok z|IzVX^q<=gfY0iG>HllJ+<(&jzV#dR*X_^1@9a^$e7ul^=@#!lXeIeK)=hv?f8y7j zBOMTaL^BIbmDO*sI(NhFCKE~Q`f9fz`SGSi46dTL^{$)SBC+o1?AX@ggKrT1N zBX)H^?J%yv=Tj=l5`$>~32C^yX&*-t?hhzAGJ!{!T(koJlVL11B_T5Q7OWcvl;FWf zqDQnX92(s!=}CRnQZ|hz$f(40+AD~=Ao*xR-4Y`4ZN~rY`xgQDK5)@o;#`v4=2R7- zqx_n-{8cS5WzXv^Xd9oIhn1A18>(V=PvM^_)`d)La}WevXk^n&v!Bf=eXWjfEOC1+ zE}xoALUQJAMYcs{#`Aimc?0r;MajZel*%+a3ebT8fC6+vj2LRn)jXFT+d=PZQ4WGG zk(0R){)fbqp7Xoki-pOMRqG?)c6m*&Qh^yA#53x=(5LQ0B_N6z$6878FWS%j!NSJh z|Bs=>9WLKi3{#a)7J}+TT_-9?SWsUTXEH<2J)XGta@->t^sl_=##U+-GdtYO54q>o z@^q6Psm9k^gYq`ThXsVQ>36Dpv}4%KvK{Xv-h{x}YvBj;E7bM_QxZq-F%hBorRWJp zR^aA&2py5%lR>By40_!4U`2Kz8thH+J^r>x`n}6ML9I~$@W?3s zRQCYKrEuN>k&zfM2Zn!?{v}`1j<43U?;+|NYcA+qRcD#rq!i2=+tPm2wi^k9X{tb+ z45YXU5ZBZL*})BQO(*Wf8WVH*7WG{3kzBf16`d2=f?YtP;}_&OHC-|x+{7S+f$~Yx z$T-XT-jxntl1qZuoKghD`Y-hqRFmE+D9EskknKL=F`rge87rnl5doS!+{yph?IxT- zY1C;*;3t#C9>U{$(B8kKd+g5bTl#@NBc7y8!Wuw)kPyQ*fHY=R7=EaO1<*`XDx0M9 z<=eoE{FHyQY=}M54M0E(rCnt0gAY6`EX)ZmNSGLwhIG_bL2<=CvSG4FkHx0l0ZC^* zfNJliL(v~l?Hzs~&1&{DLfmnaXk0NAkg7VGKqM+Wx?HNC8 zHZ4Oaa6D7|hy~~oZZb~?Pg;=L79>XD#I(jgW-gmJx&0wgbIm-J@#2Lr15$rXGdBc} zJ{FW-V2N-G_XHzH5-!$Q_=&o#0PA0E0-q0#L1|26`bf86X}QfGzcg%f?c<=XXWK4B&4Qr73_nyyy+-(Ynr}xD2`|j_Ck%MFgHA?7~i!wM>5}-4VG_@7R+%U`IPN3a;A+DO!2K@V7WY{H?wOKGWd zrlvqe?f0pSpp~cY%`k?W-1KxK3_*z3ZGei6Q6FhGC#%d zt&_U``0YoXJ>*e!@$E#ehTuSGJvD-{*Y*nuZsW%?h|?&r^`yvnNj?1R{Y^$Rk?TnWOO+#3wz{r)8i!Pm~BWujya*G0EOL5Y`E8>g#(9lCHW)fn z1ndisE_g8F@nY?i?zfZ%%N++29+ABdewJbQDUnW)YtO#B5PauA`CJ%u4hO@?{(S+Y z0B-nG)Y~fh)hKQc=e2P z>2*NRnY@=MNUQBs;m?>ybXw&KG40I8TkqhJMyP9Qo15Q!m?Ji3RWp*_B% zGd0~I^R5};fXNuP`$ARFIoV`UFN2-U)(Yc#>PBy4` zY>W?Q%scWkXh?6=yC%};xfR$|Z9krtuSa5vQ6fcqFPvHu*h$g3l%$3LK% z6{ow-P=|fO=6XM~W_c&G2=s*?WjJzw6f-<{AdpJh2-E|t3k*qf;JYMUB{$b{iAL_O zC%_|W0dYnK_@}A|_|g=tNv9x$&LKwlx>uR~t>nlGo2#m(M?JnRuW9&D?9zjd?Dz zDtbN7Y|HcKNXw)8F+F>rAJrT_=>d6I`4%8Y>BVkE*N%!V4+?YPwvUL2etZ)iuXkDE z-v+;v$aA*=9jV~oy%~JBxFUennnIO0txy@1qR9ajczmf7uWe8dEqqmax~h^S5mN3) zSM0+4Xd1uK)>tOKsmHg~e8Y_9i_WIUF9qqkfY&MWIZc*#$8}#B9i%NEc!vtIn`y)V z_%+6Lb;JIjd#zmEuJK|{WC296=G$XeN75Tp3$aoG zCM|TAksd1Bi>Wai;{o^73%6`RU(bhIkL?_hBX&N}&mLO}cN6;s&s(qb=G$$T3SZ%F z$GC!ljE5tj?Ie)9(mKkZjnRtBzCkU#Y8MnvR7s! zN+h-}$c<2K$t{$A-CW)99j|A4leIcKf_fSFZis1UEd8Rtj$o%^=Id4DQFxT4u&1JY zlX6d{i=X7=ZD>jkM|9w-drTR&9*j}@))U6K>d#DKGR`=_+4fLAM%_zJ zQ|NpJo*ZtW9pna zLnq<=>!w8(0YJSAg-Y94*YTCF7=6;#_c8k(P@DsPl`tGWSO}Kw*@PH z1adIBB!Tf;kONUdHC97~&*$0VCqc6(@7VPIMh>R;>r*H-1)=x0H8>(OslSqS^juk^ zEp4fxgVQU8$+PetJ>7WHqxwIkWED2Hs~&4}vSphGWBEmJ`%9G;FGLV1vu0;pX{_u! z97kOKhxCERfu^bELBXTepmITI?ZH;4^6ci3mR5m;_|>7Vp}dt=aS6whwafIPv$`3s zTFqf?(_V&ae6ck*aT-y15QrMueKjuc6M1+v_@0Rw;W?>^);L2GU3K1wA-*2D) zk#1e7zEREh$G3Af_?eME&>iHXu397FZsYJHM0<=+PN!kn=9rn6g+>WuH(!&CBC~YeRe=LzRf4L4^w01|@P}aeZK@-52F-=50(}MfZ!k=Y4*t zd)kuJ*3;P0ZZZ%5JscBKBmPHs)10m?WBhXl1`F~Ldqu5reR1U3F~d`i;zZv3bBKLA z&bwKTGt)mB5I&>20?kFNDbhNf8@2lRqjV1XFs^H?$3<>ryQU07oyJt!t4V*X_x+6< z5x=8CEGjCmK(+qRFwcKb+~pYGI7S*nk-{me+b)f%>L>~FcoL-sm8kJ@cn@aj2GcoF z-SAUgGPa#J#er{q-z9$x^TpM#w{yV2G2MT(-xB-dq*wVzg+O^%g2*=dH0a;hiB}XG z$Dd4AX9OTtIP`#q+g`1>%>@Fn(aEp`R)?&hwHw!j4DRvJ0RH7={>0SWHaYzdZ;R8m zG55~JkVt>IhvwpZ0y7>@G$2;q<-$l8e2d_&PpT?*T--$YMgvuAf*}kuBkLI_<1z;h zX=G5>DN*^|n;O}%;${MR?=77;x3)6`0YT~Cf#2b%ucHEdZf9f6# zD<69`=+TDXOE6$$7nE_DdA#7pS}%d56 zo`Id9TGzb-V7RI=L#KT`F528$nt9MBUf9FSK|dYLF|o3$d{m%?Evt2a$2W8?088*jB5Dyh)|t}9pkvB7_|wKzd<~B5 z^U7+~G(PQ)sD;0wh;jQ^9;@*@8zX-(Z`fvtqY9{z&yUXibPMz7&%I8W>0DoQ?e|6a zU;2SSM3R17Wgi4l;>f5TC_vVxaV3}w6);ilp0^x}_PaMuzyV3OXcDX>NZVAtYz1#& z4R?kU8DGmKK%o3wnwG~!2*6-EpMQC#A8mcT6L{)`_$t_6hPLzW8N)379kb5LI6IUL zx6-L+nXm3IP$eHuiFQjKv6RfQ!MC{Hw0s%djgUC=5bu@B5`ut5_Z5{H0a3Hcx@fQS zHmEXDBjF03Iwe3E-U$Xo%Z>X7v!pHK{JXr>SKXR3_nMes>QuB~K?^a}T{{L57)J~k z1nhcEMzDp!PWHgS-M(XYgtRV#o}eG&8`WQTraQ3QD@C^`1+384uvM2X%MG`abBslP zh#V(562c-s(bJm>XbtF%Z!nr86dP&I@#2e6UnkIhVI&N~W#;ILQtDPLUugRcx8s*q z2kHrnc2ogHL!aNxfMl_;oj%OGj~uq#El|N@E=3$mMHC|X0O0FA?|AOwhv|qkNb<(L zNCNN{DpM7Z%6T*o6Pf@8IE|Y{6(t$kzbXhIcr+8elsP4}G#-hfj!0mPOxEK$6SP8g zyO@_0T0g%AS@KlneRz|mfziMRb^CG@=pV$WK%`?-u;KpL;5^Lv-YoyjeLnbPJYxnO z*cF*Z#VtE4oHqF89#bK5bg%+uQHp?gG`R%a#xP|Gr4#ZqhXaAKO}a9_XPCgg_r1gnQKJ zLqFh@asOvo@9)Qt+kpj7VMKb!WwQh~E4W+DMH}nw)Z;{|u5-k67*nVFc!wKIUt{X` zb>+X`WJF#<36fq0nA&n?wcYhtN1|YLb$kMDWob@x$`4a>x(*F#!`#Jl{>gYiM@gU7m=yA^N#zZ7B=z1jUNCs+(^}AyX7+id zDZIP>6KZeE$G@*hlHn;e;`y`CwC?V!Bj=rdKF|^iP$fsyHzq0T0OJ5jc%)r5f;)~QYH2Fv zF@BvfSy6@|^e9~D1%GnOCVG%o0Q*E*$UizC$=%9@$3woHG4d+IV)&ui$U9nyWu7j;tmXDE>GLG)eme)DjR@%zfUe7f9|bZuZ)1(e5?HcFpSU28m`g@)0oS{0({}HKZnbOD&Nx>QEYoE=R>bUuC@MIF5H&K0{KWd5hVR?i zfqL#e1r0_Q>iB2T%Os9SfXKlwO71V{%GjSw(Eck`cq4)ZHwcz@eH-%nx3!HHlv#|$ z3o(XJrwmeGM5s&u>(QBXb(`lpb@QbbD*%ZfJd~K^Zm4Ed>hw_K|P-U za;H89(rR*1P*18MqWmdF-dHtCU+q}o19@uo(#<$8t>aTHXEs~(i$TZM^if4G79EK4>@iQN?C`dm$9W(mB8Q#8@P(V^ z8#mB~LKzXkGEzm+-2us z2E8LnPcaJL7@DZt0GNo}2G}eZSvy`jNPhqhjOS9G=we`!_xz_@#CsR`k`OG%b_?OF z1RWk%o|73iHK6KR{Cnt`rKZEiTPBL^+otcG6UkDfLHzX8kyk$@6O#LVf?zus394?| za7-yn&%0AKzG-RJau?@o$pdQU>sqazJT9~G-NhS1RMYqtp?h5v$E?r0o=E2(2y z*yR3M|KeD?IelqsPQ8>c%u&L1cKp>etLKjU7ty{GLd|Se27h{YaN^1PCLN~I;<7!8 zE|~zzJ6uF~X}6A@_f^Nc?-Ci-yqV(f`er664F?$&^;C%%7=a-|F~;b1ctE*Z`@<3n zhSo+#R!)S3Q-)?`LGx3`4TKEYVFeV%MObH{2{F`>x5eVijkTEe-W_m$qAYbfax{Ga zD6|llBA61QN$_#B{lSHf+Ljx_AZV2jpOUm{%I#;qlj@Vr+<4zp;aZVla}`>hUzte##N5zGSbUVAlnRLYocCaWH`=iZongwtxuFlvH*5uc8zYuO7sjr7PVD6U<_deNU-LhhtWIRZ}b%jww-so3* zMnt3m)T1tonZ__+PGu6ntl;1YC{f@Og2P&^kcp`Zw!rJG82ACR{EI*ddz4h{Fd-@x zL^Rr@xq1~ITS(5HG_(0F9h6Aj?G?tH0tjAThdb2QoC{n!b6O%nZg_&KA7Js7RZAM3 zVt5Xf;P(8uy=>O`hO{&m9sRs-N_Uj(+%uBm`j?At1G>0`oS5X6vH%1B3cSLP{hfp?=kdX^rfRzX#Eyr zFg>gvH(opi%3o|_VE*brNlpZuOl5|{O3MSF00I|Be7UEvLV(%F-M;a~qso>9Xje_k z;9E?!h$r(0oaeFCtbpgOp;3)~9Y(+f=ADTD7cr35c?;662+%p!~-C zq+8MXK5S`DGeFw&y!^^bZJrnKXk>XRL0I#wzH=iXi0)}}$Jnd^3X+%a8^WxM*{{tY z2Y@cRF$kO%t<*BB9!nr;u==(=@A|Z5j|z(b19r!put&4CS!YFd8(d#ZM-}X&DNjEZ z8`8|V0Q|G26-}bY4v%j+K8Ey|^gqRWCY_3HRQXn3x24hT;1uKJMPsl}JqL=QHrOJC zJR+rfKC%_XOP>6Dpo9eZ{e$>nNe(W%@X_!_rm-*ms=_IIf+TfvM7W3TMA+y1*TfP> z<%Ar&C>-@iF-NEytlMl;i|RVIbE1awaayx48@j$2yDn8KDZ(iB;BOI&Jv5E)a65&g zyx+Eh_nOIEkj%~{-<*ZasZ?U5CTpd(>^uljLlI z8cJ9gt&WHY?1-J{354mLjm{DY$N)1QX=yJq(TE{O15ZAstZsH%_BS@Ltl)~#+XNlc z5J7?yh5!}C4p4ekAwaqSci6iQ6%rozs4$puQ2pKyY@)7)vMQPsvzDwys3Q7j{PK2)m-7D@=yT88;NUv!O24nwLf_xHx7m zoQ{;$>;O-0=q#`KNP^pa+Di|@dZm)%gloCvJdVq~SmNX*YufN+mL5LR1E1|M-1q}a8m}!{aI2JjPqn8cQK$$vR!@1;?s+hREyo>!^_uJ4 z%aM3)-JGHDx>Thw*zl-4-3X#q_ACkXL*h`e6}G$>gSQ!VH2wnQEY7}xSz@h){^S_bsafDY9 zYSwdVcjdFmUUKmrlRU}8br{cu04et^Xl%IN-XEGVp7~NG3;-70Gjk0V1IKa|lwb~* znD>87FX7zD6=M$}n&?@81vCjZFCM$Sg^g{KZ6-}NyK&vU##8!0uUr=qr7GZmiP=*< za3RzkCJ&KRB!Rt01gz}GHOiJnyMb<-{9l`+W3zb^v?|HsO$OgM^XWl8tHUH2)0@Q9 zeoaF@&PztMBjdwalj&dqaqu!SZxtIqv^{UkV?bn{6%f|dG zLkoydY(ii_z~745-AD)%K-Y8AzQOx>b4b=jHp5#lj`e)xBY+X@jAyQ)fbJcq%wVUK z22iVDxhwz6X<)9q$4d3Mrmm$J@FAX1%u&u}kZbq{#PJ>cIMRIRF6*7x!WJ%cy{Aq; zk@?t;V4QVb97Lch;`guacA@U;z1ne%@!j;NSkmyBR#b7k*$VrKUer=X3J$ps+&B_& z^#I7}MT^&_Wt*00OR*?t*9PzU!NcR_z1Rpx{Fe^;ZGRNli{+edKwmDK@}ECs1Oiv= zJ$*AG=B?YMnV7;^j6m+5i|Ki1jv5ts{m1UCw0PWiUT{dLU*@rR9}raeeLLXgx`NvZ zd-uKi0U}X|+t{5J7Yn$Z5)xuMk&85ryuk<@R#+?~LFEHPizJIpJ4HShX9Wj&K4$Ii z9?PGMJ=fI8mguDlhsO=Us#HQ-|LuJ@8DG_CM>oVF^R`M{J9(riCdIWig=~$yi_JS#1)M@xAk( z0ZDVB`&fr3z6}OleWEj)RGs}eEX`G^&*A!%`fTeQ2=v@>2l#d zst~*keo`mpz6yCg=ruK>6SNkc(vV~=PWf$b?2fgSEaOcVKnt5EKiPhn+e5RfA$I3Fru)DUe{23ruoIiRmN)kY@di&KE708?_`H7hwHi3<_K?0 zh<;I}@Q|!Tm{|;9jylPDSQa%N<{cQgm#fAtXFax9ehy5 z?_YM~<&r&~#@)A-9sPj&3Lt4FLG6ocSrKpA{WBZqmBZ;WMl&5Pa=aUSUFfL|K{cx2 zoGygQg`uyBzyo>WF^et0Fg&NDqN*5mpefu|Zt6AWcIxaV6ETZ1-bH@aW6-a$k=0K# zQ#Srvb~ypb{`n~%%>IbKTm+)qy%nqzM#WiRs_EbjERMgt$m)f~MUW91>}5Lm@N-$8!fWF$uF141OF4OaYvnQTl zw7r@7KrX1~M@P2=hDNe5=Sy2-T$o8mv#3pM?L9ShN2R-%Sj2F1Z zYnaXcM)BQdkY`?t{L@@5DQthnK5ym;6i)9;c#S{L_GQ6(!ffE6ivs-F7h;X}KD^!; zwLi+m-e2K*v(PZ~JQ>JwSW=PMC89pmPt-mmB18FRh2?$1oI%R3W#yT1s`Vat_5W3q zhPLoaNdbF65naio?5}iAePOFk7NuF9bjfl`(h6m%2f~jhBGeJzK^YyX(yp!>gF{|x zNbi;QdLDmSw%WSobftfuyIy8fR3 z{{h_-)4yB_z_^4731!CdB|^MbY4nV7Qrwh?;O$nx0EJnN<6|4XgJZ7Y=Rm$?YO;i_ z(+#)oO*z3{(qlS+Mj97u7FY_YqhXR=MyyIl^2mgFmdF1q8<8@zV@!JDN{(Z!oDFJ5 zmO`a}N6LtMxy$JJk+!dXC6VPgB{=V-yGxN5;X}<}=M$X#t9! zw>bDogD=4)U91;WH0CFg?U@?PNx3dR_n7%Y24@wOrR=T5 z2jOycSlmgx(tUi5%BG&k-=Ytu`(J($3xV=vm|HP4l1v`c7a;jRXNh~uVP~q$pefO- z1c8{2&}L=hFn;saBaa@dGK2Qj0j4XXjW?Vt>tF459Fd=cPg{A=X`^2HE&NV;{Wv-R z5Ba`}6(g3kD$P<5MBL^3umKI!TZz=dv@^t*m2%6|ykV$Z0T!oP507J>8xqbC56Ggl zC77Y+@bg8)ew>o~bgtN7zorx{#;TBzp_WVb$qcWkCG(dXJ*ge4CrAqt)77oSTTv)a zzo{W$kk{Caa2uIa42sV9vIbSsJfo%fd*oqqt^<`X~(Lr(0bBy zD0cjbrX_v}`ZO{jZ=*Z~(A$$RUb(~5gQzdawM0J>^(9~n#-szigJ!|}#sMC7n%jsc1_Pl0#UI9~#=BtN=_y zj%qZ~%Mc*D8pQ*G`{J(dD^#A=r+%cAoS0;+}r zHeJ-l7I3)-@x&(vb>&5NyhK+p6yaWsTp4z}3`k0yk20DhZpVy^0H%-P2=h@b4GsgN zL*9PwHjH%wA1e<{J>)GEw+WRq%F>{6?Ld+h7VKIv!jpz`jT|;KqD=+)Wn@mh$S4$%eFVqDirgi%By`u&lCWmhb*X z)Yjruk)2&+T2{so+U;vMZ%ojf{=?BexztbQ$1=zr>m zvW}uTaQT|s>RBQdPO_Jvh1O@_Y;A0z4^hqBRnkSo{d2(9Rb^Tv5injspJ<8rTIM3< zM5t>?&Kj!L$N7;N;7lhP__=e+kA54uQb}w?U-`07r~zIIV((~4GCMK?Cef-Z0C29H zxIF?#cdH0^qJ$Ojx}q7unyCKUfb{Pv6b)#ljSRy1X=x7$hK85BApg(QnCjvOj6RUc?e^$jyzI55lWG ztXHw_`@=oPZCqrhs*S(L?T8_CSi<^Js}~xwp&>uMza(Yk>os&kW)f)?Ys!IAuuYkv zHPl{_5UQWQAGE-t?=njKgm!e3BZXzH?{H=Nx#BASs1nOnZ)r)G2R=9}5EQeT-;`0? zy9hgt4A|i;X?H2GTR{&t~)9=U{1KAC=y z*C7d%ar&41Sy-)IGx>F?{$u0|MKbFeeuO+WjSJsL##KDfBT+c13Q{XH5S-8GumJB1 zNa$NBmB*$t%spSxK8*;-PB-T|$B8aH?1bcyB3uJnw751;2~<|lWW3DVg-W2_P$E2y z@w9S#w@oiKt6umDGK4P92x8JFd?6v}Ee{C349QtRZK@hnIw&MwF zuxb81OOz0WHePiWAvuTflQF!FgL1`H4=dLMbb;`{ND7a9QE@R6SitGm~{Q_t^3P+blI zN>n}cLlZCA_H^ez*T0YvTUSvL7asXC_@~sQ?gc2CO^s#kZMKt^Ap(#|!L;%r+GJ)q zVp6hbmIG#b7P`yfI4r>rxw$V*mUt4KOZjm_`tTIq)NNgc8j8YI(9|z#iK~ z>ZioGP|r$)ljqf`ogshf^|{JL2G%7#B-vNKM>y$v96; zk}$p~#@04&SU8W^0Tlny!jQ*LI?+m6mTEJD!FxUwq_XsTa7->y3XfzUaogO3oM@#B zMsbmm_!L!qbt)z>2Ct3>$oDFTMkiJ#$Wv@s$poFQ7gym4C>`l`0>-TX2Tn1Q^-QhN z7Ri}P!9%Cvq6lOGL!ols)2G(4j+KPD|0Yc&z@r;<+So{En(@B}f1Kr9mIZJNbO&H} zfs-5ucRvB+S!-!kexl@45HH175(p zXfW5jP$%Mk7Eu?F2VjpM(6+kT_{)~5f%GV5YFtvibL%;q;xuW`xij(dmt%;5z_h*H zY4Up|Yk^6FK}U5QruPoz?F!D8-e6Y~iTjRpwt~{B8rvyJQ^xqNU6kd{z?U+<{J?o7 zf3b|=iaSD-hB4h!O6`gETT0_(l85HubX;VviLff#XtI+VFq_48ALDYht$tXgC&|Tu zNRY#g40_sHo!)Bf7?5cY#WSPwUTR%<;Y8(tz~?!@9gPwF?LY9RIY;wdl_6_zLOOdp zrMyCX&sw=ZC&Ou$?^|*`_hBW*iGwIyJOCU_&9qo zFA(hCgXc}K%@{@P7yt>|y#TDmK&5``nB6y}Za6dH5l4TWO^2c!gg0`qi#y%+7 zGM!R8$?$$*#!P;IVavWnYM4^i5g>!aAxm}31FMOMO;soh=Vn;$7^gpYV4mprr#4hQ za@TeItFLbA=^1|{`b?slz&B@zhx-U`L#h(lb9%|&)zctN%Nh-gI4m6cn_x8Y5Mx`?jOuOO{9Qx&CdbgHFEK*Dr#&0fQvEIc#A}isCkjt8;)X5K>t`7#E!a zr^9Kq&cGC%N;gZ|S$Awv#ua z|Bi|`h|{C;5j=OZVgNzoWG%o1tOFEcWU_ zkQYZ1Yj*^4k$HNEXEN{XCGArA*;gV=d35Tz!0-gr{s{T@B2+w($eJuBWDYe;qmAe{WIvj>loH{%`)DPPm7GqpRs?0@na4oZ+W*RT5i1H5=%ip6Vt4`J zXXZz(w%2tEKZe@PZ|5{Dsc*sKPkmN|YTmcolxkB?==h+9h!*bAMZ=tTGYynj?b2m` zF>lS&$U%C&JWZR|FtW+^dEh0Jp|Rq;F}*P8QEc=W+MBhi4x+$+UU^?nvI{YiO(y~7 zy>>cMoeesQ1}anSPk3c11BOy-q+4dZ8+aFS0mR=&HhxFWgg?oj+%v!R?{WY+nHEcq z#ZFx5ol_l5>8WZ;o_j&{wUtJPHa;V_tdqo}=<&1NlQ>$Q<_daq@ONsJe)Bn=P|ZIQ z0EAK#VFM84Pk3DE9r=+Xrgu9476z;1@LjM@+0yJ}g|Te|hTh6jX|Kx{*|!RUgw~~S zCuXG4iFFJE)dZMAQKQV)$`(a7XB#!UImBf<(&~D-A;twDBLK>pN>|8rNnG#-TreUc zN7=};ytIT6EHQ5kC3$kY!8CNQUG`1x$zJi$qjPwPepgp4t2pW4ID9EvZh@?iqqqhN zar!55zuCkHY2TmtD?<9N$wDUp(AcBWqRvF}ji%7LnF|^xUE1T|dXKMKnn9hcYQ?x7NfOifrc$f7oR{E=!hC8PuRER3YZgsq;`6Yt*`2{eYEa9onx|S5(Eu zUDR4=F`;d6tjg@>xOk-dlqkt)y!#H{mn@C&z$MY?K)mAcB4yUTvA8Y84sea}czNvf z{XOs2y#VnVN)}XVAK*JErcS0(d(KfBKA+s$0m4hp2mjgn@)vfBWe=OAlkb^5&(-kwR8&N*&6mMvp7XR7ONkhQkHt{#LDxA?VbXL z^f=X5QslzPJgk+~rG)j)o&+B57;B)5tP^%hKz?EVPjf(=10fE#Z^?3lDP%UG@AD+B z4KbKMc)+vwIG)mO0ZxetVol}6pdZ34e$9L%O*7!k^yi-kBBZCCi?eF6q|Na33-bIfm*K}>#@)O*Dfz_yyyqhi>ZhFn}31zu%XFsMljwQwDml?~@G zaCuje8?}x>m{TGbB3=qwXB&E@2*D!u+CaQo&GPXw;aplPCdZ*c5pT5Q0FJLh;y*5$ z&5?OMgumw(CT@GJ`pG=FhVQ;mh$fl0TTN0BTsC_s-y6K4th0u+0Ggy^y22Q%HV5kj z_u;l53HFZTlcX}2Vsfc2BhVSxId!t#1{o-v6H@Ibmx8iK9KBsggQ@PPEU%a%s$5`M zAtK-1Q(#zCd?beT?clCBGUh-;jvJrdJwhkXd=cwQs-*_%@KTQ}vW5jAaxqP&rU*K# zo&@#Jp!a$R*2=I5kkwcM3*2fD>gSR$F|1Yz(A~LGouF*zqPo;3w4;iL&6|5Nhm|mohynQ}&{Ih=aT1&*U6eY ze|RuA6ygiZW&mb7QaM3tm{!+sreaO19uJUvXQkD(gQK$Gl5M#NMVf{AY51je=>G`+ z1jH!t<3GuzW4no?(&ySzFW(*C6vigJxUmmx*m-}Nc%nVt3NpwJ9|#QACb`A+aOFS- zsDtJ{QWm~qHv)r_ZzNGl<#3ihyq<3zj<0=vHIq&(u^D{A3}IBek!a8_uLZfuZnLz~ zk{mro@XO4NY`zWALf)-DIdC}OM)^5c85jy&!egSYe9~7C|2EwCo`^I_43QZxiW~AZ zcOu;yVy3o54J*zJu_S?JF(zvm<@tTa(CTwl6PbCZ=EQ+c&Gza?p0YvbBoC(g{C5WYxOy(jyYm?0hbpQ>ZWXK}1=9|-5A5Z^NgpNf{ z$J3}+2Y>XZxGyIeJw7U;`>)Mt(t#pY>53eR^@P~srk;^lB2D8$TZSm#2!jqi;newT zt)+T6v!!G94!zd)B1~qcUi*Y<`loSYOm zumOoN3e$*g<5|WnW|!T4Gj;v?U{&A7Uzw7-6`DIeRuax%mL~FZ4Azjlt#Ct#hQS24 z;;fOvP|m7Y_j4ptFvUsLsMO`5K9(czA~N?VW5_nAR|y?I3cv*O%pmq4F3De}Qon=* zcGv&;yFT|;3NfEIKYs9rEjpIh3g+LtVHU?zi6TxH{uy00l;=5Z`2js144G)p?esx^iE zp!Ocu@_JB?I;w#weL9So0thIdnt>lf~M%G0bn_L z+QecYxH-Cw7*LrEI<92bP{!AAsuuWr7Rpf2W=M25aH#ccL#!HP6SYG~9WulnkDG^H za&Nb5!^p{kLz{)#ZS91ZA_zwtCw!rsS_S2aGSd)&yx!dszg9v($K0pQrBh1}p8;gA zMPWhWh4*J1-FwG)@F`_;NwRGrQ=2yrsU%er)ZZqRD_W4g;i0%}%EsJ#A6D4X4ol>K z)Xe`UbTT966laSRPn9sG!hy~$yr7~nvm8N)Uj0RzZN#D1lRRPJ6On?|P8RcJk59-i zVdhzp20td>{Ed%ryi^-&1V&w=%aDY1r0|H~X*AE#B_-Ev5QX8aO^t8O{rndj=pebZ zb@!_cLL;S%W7xR)%_`BVx~Xf}n6{bfQU=C~1z*wKFA8K@^s&!ntzz4FkorZR<3h|7 zcn9&;ih3nDl@6|uBALzMv#IXX-y#;g#Up~)NrtmbkxVp5E&)~59#MpSz=@J4mc@%4 z_9kWEL*D8$DVo66>r~;OoS&4i+8f$f9t5380Q(JA zS=@u3*w-9WhR*KQg(tryhp>}UiOVFRoe3aa`ZM2UJalH)u@IZ^by)4VG#o5Kw>+q< zF(8x<9F&;AIo2H!*!YslHif|S)>~up#ZHC#>%=9w!)`5=z0?L?mDEBaz0A9GD^H5I zgR92vC+ykH%@PAVjK3kuYiY@SX@8X>JM~+HueC}_H14@|f~5QUggIxM1>OiJVF7cE zb^e+ks~}xWF1bux0C8xDYm*O(3RY+5sNUBUlUY`qm_`|NXORy}F*8fn&r(4gM-oxW z9{5n;XmiEvMQ&U4sciARB4*gB|9xwwOp+{qyaQiVh9uj+2cVlu{aQLo98jS_O5(iD zw)uv3$x@BAF{bjg?z`Kk&ch%_b;3ZdsmMXAW5Ao=g{_3^ zT%D}Fy*ILx;$A-{rR+Y9kJQbM-#I#T%Ce}qqB%09m0Q>f$7yk5J2h(^vccC;pON{pl|{8Kuphp4D%&1>BD zChTAqAI4Cb+PCzO5ryP`s;^Y2$?XDrocvg^kroDUE-5v+P82YF@EIYJR;#aGnC;38 zlEA>(CTlYJv8(Z{iRwn|kMc9a$B+Mv!}-m$RcNNJ-3Ory;^E%Z1I_E6=MaS9rS;B_ zJRMsZ8BV0l{k?6_%rldEMKSOa=O=_8ts9Wv923V#?(40JDJYr6wZe|*0r{hUc47qh z<_p?lB47b(HC{;3y6eG=Nb~#&p_1y`ScF;3exGG|F zLHA}?w2huh@Hn!a8QL9;y0@DZ~0{Sw*jQJRc>O%T}o%NIA(CQp>3`TBPl zbiD3(rH1bt!il_vv?*H)(&K1NoqCbb;?*7DgNh)c-m zVUln8iK^<1f}*kj5ke{eIvYYyp;+yidv$CfoooaFaFauuhQE-tn@w}_&+S-QnJGl8 zT!>P!eoiI-H(6YSdTjw2Y}xpY0MkvX;dTa<%l84I@Vv|{Pj;5D^QEeZIourDN4Ki3=( zGGtUlHt~_)HB_jm|F~&}qeoYncjhMbKB=wbQ9@=eRII+$Ot+AZb}|@MY0S!5muM2& zx8((Fb<(`euJyBb_lqf=ILtd1_-cxT;V|L$XPqXP;h4z&K6r5!{**>)G*^!q-$eSHA!c zd^@>eFuot(W7=^J%rXhnaf8n>rwX>&iN;&O?ly3dz$2|&G5^6dwfe@RM=g+mW?bPm zW6$JZY4)06_xikV;=R&}mHc^ftq{O+ChMnRn_KfmPya>^J?H&F&e+TE6U3G8amK>w zQ*jwJNLG*_mqT6<=?LfA}B%bKsm0QUGK37d{vsAE$m%?S%d zNvvNMq=OhdBXGt1`O>c3=E0Vlp0%jK04Z{}dTR71**a1yVawt3Yo)k7^GcI(hcxL$ zHoOmb0|YsiDop(cfZn(sEa`CG{)Uy;lO3Dz-7cJ+DAG>K1&zuhLI#-W^r|(z(Mz!= zprPWy93C*IN){FkBH!cEav%|n9+7&pB+`@{K#$Vc20ktV3j=t1IZ#GBZI`^sF~-kL zY&y~Tu_ZD$A9tkyCV&AlnG4yJ@jTqfklA8nMPi0-Z8Z?N>CAA~x~XfHo3+pJYYO9YDzioi9 zR&M8`*a>H}#L`W9(jg&IA{8=s0C_tu`JzVUZo z&pKE_NEGQR<~v~o2h?Y_J1iC9pS(|Yth&0y+gK7jccin+7j5MTU0?am58i z5C?N{>F0{^BbMVP5M@Jgt9Bt;5BjByIJIVy?`U)=SexQgeYs659DLfqGi$Gfp zqCujyO0i!>gplObTos(8kP1*#s#ngA#y~r5(b3bZ46FB%YE2?_ye(l4dWoToqQt~MTI^L_wmN!y33jXY1;vxJ{o<0v z)xJ#(!p?uLQAK^%#?TBlp!qAcE#a~UiN&Cp=WKurf~vK+qkv} zmf5eo)eAz}RsLOX2)G|rqQlmgD@=eU-NrL5oo! z!d3S}v2gVt5nh#-l^PN~Ml*y`8!`m1jvh|`MQ;n*8r*JQPIbT&k*djZaXB3h+aufi z%p;-G2yMP0M);&QCE4GTve?T|oM_yLh|(gFhlI)+9C7f=KMm@`;=XUmy0`aJ_&*e1ZSKKEfZEH}mdnv_PDpV(T8yp&R4I4iMq2n;unElQi2in8 z>3>$ZpTdP?9uQyK@LrkE(T-of6pST=VNcW9&)zmM@_HH= z{HOI_Wo#AO#O$l#znT5;@OVI6@w{6sfj5yjR%Y0ufo{gEJ_tNj*o9OS-{hl!l==kW zO2zE$jX<$!l@I$6hYe7wG(-t{gyU}@Ei4(gsC4U8E$G!krcmY`+uoW#&TkV zZ%Dma-l4&?Jy#PJ97THR%^;R>r?K6~n@*f#g0^#lYzpO)nXm{E<=t#H;AQSMmv}5s zmbx{Hmi6Zz?h8r2jW)r>bEiD%eDjzGs|zi;)14(6$$Pj-_X(zu-qGOHuhErSqA3)L z*WpvR;&^1~jG_EiJ>>e70>b74&;b$KOkL34Fu3U;1xQ*HYwbic5mWh}ga-0L701I+ zP(3BIO)VN)GwHRrfi+r{E;y!pEL8|SPPsV!BFsKU9zo=g3Q^!iah^aAkZU5a!-1`I zFyJuSAl``=Z!|WzK#KU}RJ3}B9a3|!#587TUOshQbG5caf2&F5 zC(#W2k%YIa6O;HE<%fv#yuz|fKp)INxGkYFYwnPu;>Ey#P)#r|dpy0$t&}qOA3MSS zd8_4M+jV^}l$csd@0hVhY#b87TLZK1b(y0Uamb7Y3|cCLYYM$zbe!m@g)F{lv+v1&%#6hDBW%wnlfpB$*NSbu8KfoS=XU;43umw_6& zi1`2grx!KfGOB5O{Du-ke)ZVCaqQAWz4T}p0uyy`LHtW6>R-dr2OqM!kuZ-Ho_jc; zRq}-5Bu@PETid_AcLl2HY|E5WP~>iwM+CqI3jWal4{;-DV&?btO!ywTXa7E75I+Xt z6RKqj$@QT^;-2Aj3b~6pQxdmK^ck0Fbc>vRMeYp1e6ix_d%fE)rG~N%GD%lYmcnZt*IMpc|h&RMj`TuEt{37P-yl@(geJU z4`(y|bB4w0pA{)zN@SoI!*A+E0Dw3sVqr|UN+H9yxwb&XP_vY9Qt3EY?}uG96Rw+0B17{7x;Q+(=f%wUPX%s&b>(BC0j_ihx79{Aw$Gv99H@RyeTv| z!pi7-G1z;Kvz+9}8)x!I{T;a90yVm?@I*g~wKeIwjeSo03?8`JPCmMwI%CrjL;Hrn zwH$CGE!#2h@(k9E8CZM`M*7cS>LU}>y%ce~Rulqqn|6A(n8p`|ii$uw+6t0P_PKw_SUya^H8Qaq zdPUk=k5SkO0#B%&EI)k6qL&;}G`(N6i5<+~=H4%F=We&Y_2OC@UgStk5^HOL>i9Qe zm8d&;3e_e~t;@`V`~H6d3A6UNkG{!TJQ$zpZ;S# zD{9N)AjCgbQXdZBBG)1jpSymZzsyDZSSJe40%2E|(+gxX>724=NM9zQ4J2k(%LJe- z!)4RZcyMI0q%-ZtR9Ik*q`DLVLb~6R@*djM*PWq8(NM61@81AQ-#bC!w_C7SJbz-agSZwmjVs&p;C&3=qEt?QcnH# zg)tb`r_VBxpSB>(UJ0idcjI<-3iplT07uRVI{|F$nhIZ=$Jpw2c^x9=Vf*C4T#8Se z@F+z?-tPCh>0X{DW5ymwB*V{3{w^H{V)Ps6E@N^DUg;T?=cj;}AB3)ZH>WXDoj8)u1}CBMFSTjhR?u*pv_ zJtbuc4vkB#On3fctGwyppD^Qnk2i?*nSiw#Mycy)OQd-)rFF|r?4OOqnd07}-g4n0 zPg)g3132TdC@$pnP-zRKLO@7_?%r|_cuscKUXt2a30J=YD#BO#N6)sqFC#+dx|<2| zg0WTjLmrA%?PtrJBp2sUkov-Qm-y0%zUP*ahLkZ@nj%cPd(?*cR%NM#Q0mfRa2}JLrdyOg8|<7Yr+1U~EL{m?;K5th_zM6gK7t z%b&@753(r%AHq2^ML9meKu3i(^Pab4*3h%Y=3kDewzAXgnyEV0zsrCWw~t zBl)p)gI|~X?c8*Z3r42SHOgG% z6^+JN^V_VV028UeaZY8RCbMU0Hc5NZ3=?RM7AvOJTJg&c%_t)b@4NSVzJ{&PP7jzM z;@w=E^d`BMVQ>6_A>~=d9diGWZuWH_y`w&ScumCq3BWs)Pf#nA19CC5f*x6fWMMTy ztC)?^v3pb@6MSo^$w=i=M4wm*VI}dY1dp`SDF=y1iV8Weh`VSvKDMEdq4%|56AZo{ zsduQ{cPr5>bdL}3IFnkX1nYUCbumF0FSzW#q(-qy%8gVP(kE@^gb28p_1s8m8%~#Q zg7Kj-86|i2m?a1H2=g^GiJ7 z!jMNhC<9D(aT4jNH$S+`AKq;7wgR56UyCRWo4;iE@I0B5ARj;|NvynPo0fs43@$io zXkZxUdP)1OHu9|F@%8%I=%dfci>^f_Yv-di=W7K ziLy!R`;l1bsEuNUhG5N#0M0kH-=r%1#0$`6EKKdWEyIa%9MCaIJ;wqR)7@yz40e;9 zAn~bex<6n>1X58*<1kX2-lfKN9u>jsw`av_78@*d#i1p&PTSt7@XwfhJif~uFvLSp zRp~gK6T-1jfSOFU<7g|HsLM;4`T!khF-1h653D>ix;Ix+8ACh{7F?%;Zl-~%QQ@je zsiv2DA|DpYZ=gLB$9@Ql7wvhWh z!vq?IP$>q#SFrl#pVK;Q>A*{t!oijA*A;hGv`H;lSYv9U_Ihlt2LT_#X4GU3SM;VZ zYyRpPuAK1Z>M6eQyeCnx2|Bi@!{r*kpEGvJu}G>*Wcm%nV(X3Waw6t)AcYW^(4V$o zABVNIE%O)bsQERmjXhNY4PQ0+^Lh&KM<^kOr?6tAy889DBGxgg!_@`}lMJP3HVgf` z+(c_aLGJD-b9tGSM_OAx2B6^Y_Fw~VB+OFQ+z%l1^p}|ImOn2az9N&nO8P`Y>X_52tJ(OWDOw0L;9XJ{mJF6G z1OD)P6#ftVTdF|0##0S#X!=QJ6Nb==TkUr-UYwKwlC&oUvH@Uar**FV-;caX9`;P% zPH@4QyRE=eF|7{DRJ`shRxkJ%% znBTVd8*$u0Y$LiqfJAC~&>I8sC6-SS!pFGhpC|-5zWENtdWyVYxp_@cFlJ9Uq~~V| z_2Jang;7MEh@hfF7XBn>#HVP1Euco8c7jVG+>?jA0$qHAjsbb^C8=FVN4PVWqUOW{ zL6xxk&Jgw?99hZaH)U2P}w40Q-66zJI3 z?I2+EYUoi-!$M(2m0K?jYWh)KZPKO9y8|`4FDmeuDr?nbK0&(GogSaffvN!5%Wqxu zQGkY7q|FuEhM={QHu_?Oephw9))N8#7&tpk<#!Nl@j z5f&?IHDu#`E-DaPL4BOx6WT>P_CWmL#gnf;LsB5lRQ~q$hyF}u0gblFbG)r_P3dJA zxd=6D%TaELIh?cd{tIXx_V_W%HYBSZ&LHpE#=H_^bhXZ3{?dr27_&m zVctqDum$J1l~4KZjxXuqY*UTB*l7L4YmavK6E$$|7w%zDSQfhTb1N`Y^hFG(?G{8>6v0d50fUlhnToL8(~gzf~k?+5%H$-`tWyQgOUsSpBHc6R~e1k(?c-ug|Zx&=Y~ zsg$eDr9*vYIm)sz_?l_;rK%&J*BH1jMUE2DZ|})~k!8d>hP*Ereq<>tlfP(=^v_yO z?t2+x4q?6N1)u=<-bLKLL=1G+eDGN!_m3T^^2TB6WeQ)NF|D(LA(4Gxd7?lk<6U*y zT+x13Wp2XOD{4o{5fpw~Q0($v_Fx~75hIpb@~si_6rTY4HeT!i^2NwAJ=XMzm=-AO3kyyns2smf1p+S3EF7HO8zFo&Shlc@;iX!37Q*3pGBOTvmY@QF0%PfCrHN_GJ}jWYz?)~c zbB^4NROVt$^Yqro5-XL4t8^YlJ9FvB-OH}i(a_3M6d?lbAtPY$9VKYlp-(?{>y~b5 zvv^S{B@XJ~>@}L2PfpH%T<235{}M91Q87N4 z+2351F?z4Lyk4EyjMKT>&ZW!i(NRQLCyx4=b;pgC9FVRy8?Z1lvwa0Ua>@~DcZR94 zrQ%ncd99?{DO}C#KpAz3G9Y_hT6=y+At;+QggPWb=CKaIM5KyacpWhE+ZBRSiV917 zfI-RQ>cppri>t5)nd$fOY3_fxKpU{C4aU;cDT>g{`jL%50X(M%RE6;lWxl95J`I0} zbTbFkWoyQ{`V@%ZSt@oZrr$cS5XVBcQpeV8nZ$2mrl%SPe3NgPN0;CK4M@GeYluUi zRBc*jhkgQ&1|&HOHbcg z>j_^3hm`^^qfIa{29nh)htlCG=chyUZCMW>%*_NFIH*r#9(kCg0=kwd>t!p5%BI`( zgePYVOiXbW!iN(KN^vPlCGzZ?#Z+ddi!=QxNxtLFKXkrEVX0V+xkw&ae0`H(l%>nI@gN1!&9}#zv&Sx zS{-e^i^3LT|BAv{S?(|KWR;2$UH^>r@gG)j4@g)BRx`i_iV}W+`gWfprxJT*I;<2{ z`7|CRCe#&sw6-~wyu$kEsIQgifH8>{0$oD|IAo2WA#^Ud+4JR zk|@&#Hg3qRp2w@ah3rdW1C3AFasb3Mpua`4Ok16f8yrumv=a|!2wD`~x0NrAyGRv)l*O|WK|w9h_QyI8&^246q|EwiaXVgben1YP89T~VE|a# z1+Vl;%r|llL6Iql-RL_$b-N(erI5^4IGJJH4uQ=xO>{rdap}?9;9O1w0w}s7iV8%g zKAyz@sw6C6I0cL$1fQqVaSWq(&}C9#pe(Z;R1LF(j}AWOFSr8f6vhkYt~L%q6PPPvBMCm067IF8Tq3}VyY zg=l3-SVQ+2_6TC7n4N$JFqGH!6~GJD;o4~uN!Xuu;p?olHaI-l)+%Fd8Ha+*1QP&J z$^62L;P7d-cK4$!;#)!Isa(liP^QDKsuFSvr_nC7tPb^p)xBc!w@Iq0i<}@y*$dD2 z`vwQ<)HC!^nuoy(QzoT|YU96oS(PmmRVPmt;D^DIc&#+hL|O~z5UpU1R_o5r?Dw)x z#YY1oi%FHAmOU!>*w#?(t*v|nEM4Yp_}`BK0v8iJiuh4W_K);T+9lglHpKez0!7k? zQO>+fyurAOX2-=hd6Y>&4aNg~)23Svf;FYgX@HN;<{w%<(G?n7DT>^T+^Cf|g;#Pl z$kiROtZH9zkqIxQ_A}~q0CGzp3KIvC%%b(^FoQ=`B=_M&pWNZ)A5n1gTUH@Q7#R^p zMDWkscY>?G5xBXvN1QPOS(X9iEEmw?XEd>J ztwNQw2-BVR&h6GtLyIMXU_ZguBJiC15k3{1x)b0FzCoLi=6>nQysvlHM3Eie#VOpT zOLd=Rt7cEi*@|?qeuuZYo12MV*dFd;5Egl(=Z)@X%n@>sHctI7b0E}JPQa};jU6Yj z(mO|~?k6UAhbDV#j-}lHZbIwd9S_bD;3E=u60Fc&2t)VZ5VzC6ta%Tdo-Oj1nNn-f zSHkUS^hC&^VR?ZmVda$mM)QnsM6quMz0m>}T=uJS^OCQJcpJzAiQE-j;{0c(L~K)|XrR17 zXdy^YYEUX6n)h6M)FX{*J=m)fAI18G$EwaoAY%TU^X|-c&*zrqwl{0q)thUrK-BA7 z;#=-3r@2|f@8+9tcnIWDfSNcxw0}Vyul0nzUCS>&pHtCr|X!`4?wFByffm8s=rN zD_U%sxD6gP3SMp_UG=Db3Zy+!9 z1Z6WZdO!qSOmA$r7eXB57vKuAJyRK|0Do`l-MRL4Uvc6CR9W@yxitSsLN2uf_^Vy9 z^gaK{Hg;`>x%K1-sNd3I$f9m?#BXx*o?V+lK!Cp*^(Wz{5b$JqRS6#OOaIjQ({?D1 znX$wA!S)_v{gb>4C8L%_FKN`$zL`T)9sZ!jkCM5g&TD5;AGtbmFly1V{ZiI~=Z?$-YcfPZnT`-==?D=8mkrdrXX5U_7NK zP2p>oWn2pA3?TpN5klpXY`M8?qa8>*f%U z-k|(Hn;*X5qy;+9SwW=;-Ypv6mQWc)y>BZI2%5GUJW2*wQg=Yp-t*rm6iSR?6JLIx zeJj@L-+Cn4o<%gG9I$awdI>RptvbtPIb62l%yy=OI$ZIUaTU058rWx~j%W4jqowP8 z*;L!mnv>Bb_$2v-!S9y$Atu9l6y*Pii1*62oFHTHP?oq$MCyd1S?szW#LOc!Z>1sZ zy}(wPw&wJYFCPU48P7yc0d!Bscboj3NF-z+Ty42^h_Aj|*Y0#fjMv2I@=W&|gF%Wv zfr}4O<_u@wN|%~AyLqIwaLxH zLKD*iv|#&tehET2uE)hPPJ^FFW2DZJeJ$GP7-W0P)9@68P3W|U`#^13Bb@_uVNRr7x#nc8MF)ifOzCNw@HA*4SLz=9f& zYqcXP5OL-`!UVp9FLTRXh3gLp6CXv9ezbr8s#GN_Ts^^(OdlpL_EJC~#b_AN|I{Qd zn<_iwA^75+$f6wvL(38+7x}sToY6OEc3$UtKmUUkZyr-UifydXJU-tE0wp-z4<81&rP6H?RPxBC$Aw z2TCcGB96nOFx{07`&ZAgMs0QVensNiqQ{}%WQD*7|4P8YKwzj;|LH0VQvsGkRPu#2 zm_9q_1eGQMY6xe%Lmc9l+n5oPa zUqyo{JaNRmkH6pDO{W4yT9F=Djxnwf1=$1iiE^vOf$%3G&&g*Uh>N>GjS={<5}3nAz!MIyK139+^-bD%!~}!em{9lW0_S^bErNjP1xv;(`+YFo2>ONDcoLiq4Z@uqdlP%9 zcbv|Ej;fsvGeejd@c12xdK*SePOcorIL(LcWDE9&OHyADDgBjh*0LOkr49E2nMi?Rs3oNb2trKCX=V1SiPC;6|VzWJX5mPN;xm&?8X>MdhS z?~U(iN6qJ~-zaGvP@;hyV_G3C>-5arx}MByFgaamGVg1k+bFNLsk`#p`Rq<#T;7#?&|>}@ z&bLQ^c096J*e$ary2}Zp(n&oOoNh`L(e4y2(+`mV_163_(BuEX|G}uzl^y+PGH33> z%PLH0!x9&qlVwThP#&b^I>{y*9Z`aE>^1UrjmB)dZpKhMh(dc92Bvm92I#ykG&P!KUh#SHgh7geVJ4g83K&2YMqoC_ zF_CgaHCa30KEbJ(2qdhd>-QG_IMD8}`b?Y(p~d}59`Xs&>lX%KQpD0jeG3HN(yO9T z?VSOaw9uq7`@{)JxA9oI^qYJSh(9HR0>-HZ&;C*RC5YkU_(?U5Nrih{`#OxxDDF%o za8eo@4m#0==HMR&?*(!yc#xattXC)0pZl*&M33NM&=#$+$$fB+n)Rv$pp*hE|jA)ZQrzbOLyJs2jV$S z`q*IxHW2@zbyl2{0fE@<;=;EpQXjyfMzTRToqW-+3L+Uw!O2io1`srod99P09*lcy zGbPiNd=!v$^ewL0ssAq&3eC;?3z4e=ZM9QDJ4!pM@&7KI!or*aaQYqX#7gLr{3B8t zAuvXepIujh;E!5vjUpL>n}}z$Qv#!mrV{~u5S-DZZ#Xu}s5mU;N#QWu{sGwsv}BCJ zx4Y8jx>L8p!qOY+oT9){%U_nx55*g*{BpV^o~AOy4Bz~11ThC;naLuAD(G0OD1X^v zCxcID(U|A8pR~K2zZ!MZmnCJZxxlQe%ora~M9o!{CqNQTeMZ?em)3<63Xl@^DUgJJ z1ui;YlE$hbT~v%Y_PwH6LL3kQuTZo@?iiQ=I3B3ZM~C7UZpVaVoDQATG@3N1ao!Cn zqmjmx$Sfb3s!RoQ0v@YhK!R%53hr=melq~s}x8xa|Tc}V$F~33I1~kt(`6vJY003CrSlOJ4Q^*0{QJn0H(`H7U559Q=WfdYf zeYt`7PcM>dh>|41`gR(rD?u+a`yA;{;kCL1J7zPb4P3qB1X)#KgFoQ_00000003x6 BaUTEx literal 0 HcmV?d00001 diff --git a/boards/ezurio/rm126x_dvk/doc/rm126x_dvk_common_1.rst.inc b/boards/ezurio/rm126x_dvk/doc/rm126x_dvk_common_1.rst.inc new file mode 100644 index 000000000000..13dda7b27a12 --- /dev/null +++ b/boards/ezurio/rm126x_dvk/doc/rm126x_dvk_common_1.rst.inc @@ -0,0 +1,206 @@ +.. SPDX-License-Identifier: Apache-2.0 +.. +.. Copyright (c) 2026 Ezurio LLC + +Overview +******** + +The |RM126x variant| Development Kit provides support for the Ezurio |RM126x variant| LoRa module. + +The module includes an EFR32BG22 Arm Cortex-M33 CPU and a Semtech |SX126x variant| LoRa radio. + +The |RM126x variant| module incorporates the QFN package EFR32BG22 (512kB Flash, 32kB RAM). The part features +up to 16 configurable GPIOs and Lora Radio TX Power up to |LoRa TX Power|. + +The kit features a USB interface, an on-board SEGGER J-Link debugger, one user-LED and button, and +support for hardware add-on boards via a `mikroBUS`_ socket and a `Qwiic`_ connector. + +.. note:: + You can find more information about the RM126x family of modules in the `RM126x product brief`_, the `RM126x datasheet`_ + and on the `RM126x website`_. + + You can find more information about the underlying EFR32BG22 SoC in the `EFR32BG22 datasheet`_ + and `EFR32BG22 reference manual`_. + + You can find more information about the Semtech |SX126x variant| LoRa radio in the `SX126x datasheet`_. + +Hardware +******** + +The |RM126x variant| DVK has one crystal oscillator as follows. + +* Low-frequency 32.768 kHz crystal oscillator (LFXO) + +The crystal oscillator is fitted within the |RM126x variant| module. + +The module supports an external LoRa antenna. + +.. note:: + The MHF4 connector exposed via the |RM126x variant| shield can should be used for antenna connectivity. + +Full details of the DVK can be found in the `RM126x DVK user guide`_ and |Schematics Ref|. + +Supported Features +================== + +.. zephyr:board-supported-hw:: + +DVK Connections and IOs +======================= + +In the following table, the column **Name** contains Pin names. For example, PA2 +means Pin number 2 on PORTA, as used in the board's datasheets and manuals. + +The **Direction** column indicates the pin direction from the module perspective, with +I indicating Input, O Output and I/O both. + ++-------+----------------------+--------------------------------------------------------+-----------+ +| Name | Function | Usage | Direction | ++=======+======================+========================================================+===========+ +| PA1 | SWD_SWCLK | JLink SWCLK | I | ++-------+----------------------+--------------------------------------------------------+-----------+ +| PA2 | SWD_SWDIO | JLink SWDIO | I/O | ++-------+----------------------+--------------------------------------------------------+-----------+ +| PA3 | SWD_SWO | JLink SWO | O | ++-------+----------------------+--------------------------------------------------------+-----------+ +| PB2 | EUART0_RTS | UART Console VCOM_RTS | O | ++-------+----------------------+--------------------------------------------------------+-----------+ +| PB3 | EUART0_RX | UART Console VCOM_RX | I | ++-------+----------------------+--------------------------------------------------------+-----------+ +| PB4 | EUART0_CTS | UART Console VCOM_CTS | I | ++-------+----------------------+--------------------------------------------------------+-----------+ +| PC0 | USART0_SCK | mikroBUS SCK | O | ++-------+----------------------+--------------------------------------------------------+-----------+ +| PC1 | GPIO | mikroBUS CS | I/O | ++-------+----------------------+--------------------------------------------------------+-----------+ +| PC2 | GPIO | mikroBUS AN | I | ++-------+----------------------+--------------------------------------------------------+-----------+ +| PC3 | GPIO | mikroBUS RST | O | ++-------+----------------------+--------------------------------------------------------+-----------+ +| PC4 | GPIO | mikroBUS PWM | O | ++-------+----------------------+--------------------------------------------------------+-----------+ +| PC5 | GPIO | mikroBUS INT / LED0 | I/O | ++-------+----------------------+--------------------------------------------------------+-----------+ +| PC6 | GPIO | Button 0 | I | ++-------+----------------------+--------------------------------------------------------+-----------+ +| PC7 | EUART0_TX | UART Console VCOM_TX | O | ++-------+----------------------+--------------------------------------------------------+-----------+ +| PD2 | USART0_RX / I2C0_SCL | mikroBUS MISO / mikroBUS RX / mikroBUS SCL / Qwiic SCL | I/O | ++-------+----------------------+--------------------------------------------------------+-----------+ +| PD3 | USART0_TX / I2C0_SDA | mikroBUS MOSI / mikroBUS TX / mikroBUS SDA / Qwiic SDA | I/O | ++-------+----------------------+--------------------------------------------------------+-----------+ + +.. note:: + MikroBUS INT and LED0 are multiplexed to the same I/O. Usage is determined by solder bridge SB4. Refer to + the `RM126x DVK user guide`_ and |Schematics Ref| for further details. + + The solder bridge defaults to the closed position to enable LED0 connectivity. + +.. note:: + MikroBUS MISO, RX and SCL are multiplexed to the same I/O. Usage is determined by solder bridges SB5, SB7 and SB8. + Refer to the `RM126x DVK user guide`_ and |Schematics Ref| for further details. + + The SB7 solder bridge defaults to closed to enable MISO connectivity. + +.. note:: + MikroBUS MOSI, TX and SDA are multiplexed to the same I/O. Usage is determined by solder bridges SB9, SB11 and SB12. + Refer to the `RM126x DVK user guide`_ and |Schematics Ref| for further details. + + The SB11 solder bridge defaults to closed to enable MOSI connectivity. + +.. note:: + Qwiic SCL is multipexed to the same I/O as MikroBUS MISO, RX and SCL. MikroBUS I2C based boards can be used + in conjunction with Qwiic based boards by closing solder bridges SB5 and SB6. + + Qwiic SDA is multipexed to the same I/O as MikroBUS MOSI, TX and SDA. MikroBUS I2C based boards can be used + in conjunction with Qwiic based boards by closing solder bridges SB9 and SB10. + + Refer to the `RM126x DVK user guide`_ and |Schematics Ref| for further details. + +EFR32BG22 To |SX126x variant| Radio Connections +=============================================== + +The following are internal to the |RM126x variant| module and describe connectivity between the +EFR32BG22 SoC and the |SX126x variant| LoRa radio. + +In the following table, the column **Name** contains Pin names. For example, PA2 +means Pin number 2 on PORTA, as used in the board's datasheets and manuals. + +The **Direction** column indicates the pin direction from the SoC perspective, with +I indicating Input and O Output. + ++-------+---------------------+------------------------------------------------+-----------+ +| Name | Function | Usage | Direction | ++=======+=====================+================================================+===========+ +| PA0 | USART1_SCK | |SX126x variant| SCK | O | ++-------+---------------------+------------------------------------------------+-----------+ +| PA4 | USART1_TX | |SX126x variant| MOSI | O | ++-------+---------------------+------------------------------------------------+-----------+ +| PA5 | GPIO | |SX126x variant| DIO1 | I | ++-------+---------------------+------------------------------------------------+-----------+ +| PA6 | GPIO | |SX126x variant| RESET | O | ++-------+---------------------+------------------------------------------------+-----------+ +| PA7 | GPIO | |SX126x variant| BUSY | I | ++-------+---------------------+------------------------------------------------+-----------+ +| PA8 | USART1_RX | |SX126x variant| MISO | I | ++-------+---------------------+------------------------------------------------+-----------+ +| PB0 | GPIO | |SX126x variant| CS | O | ++-------+---------------------+------------------------------------------------+-----------+ +| PB1 | GPIO | |SX126x variant| ANT SW | O | ++-------+---------------------+------------------------------------------------+-----------+ + +|SX126x variant| Radio Connections +================================== + +In the following table, the column **Name** contains Pin names as defined in the `SX126x datasheet`_. + +The **Direction** column indicates the pin direction from the radio perspective, with +O indicating Output. + ++-------+---------------------+------------------------------------------------+-----------+ +| Name | Function | Usage | Direction | ++=======+=====================+================================================+===========+ +| DIO2 | GPIO | RF Direction | O | ++-------+---------------------+------------------------------------------------+-----------+ +| DIO3 | GPIO | TCXO Enable | O | ++-------+---------------------+------------------------------------------------+-----------+ + +System Clock +============ + +The |RM126x variant| is configured to use the internal HFRCO oscillator as the System Clock at 38MHz. +It can operate at clock speeds of up to 80 MHz. + +Serial Port +=========== + +The |RM126x variant| has two USARTs and one EUART. + +* USART0 is mapped to the mikroBUS SPI port. +* USART1 is dedicated to the |SX126x variant| radio. +* EUART0 is connected to the board controller and is used for the console. + +Programming and Debugging +************************* + +Applications for the |Board Quoted| board can be built, flashed, and debugged in the usual way. +See :ref:`build_an_application` and :ref:`application_run` for more details on building and running. + +.. note:: + Before using the kit, you should update the J-Link firmware + in `Simplicity Studio`_. + +Testing the LED and button +========================== + +The :zephyr:code-sample:`blinky` sample can be used to test the DVK LED. + +The :zephyr:code-sample:`button` sample can be used to test the DVK button. + +Testing LoRa +============ + +The :zephyr:code-sample:`lorawan-class-a` sample can be programmed to an |RM126x variant| DVK to demonstrate +joining and uplinking to a LoRaWAN network server. + +This is built as follows. diff --git a/boards/ezurio/rm126x_dvk/doc/rm126x_dvk_common_2.rst.inc b/boards/ezurio/rm126x_dvk/doc/rm126x_dvk_common_2.rst.inc new file mode 100644 index 000000000000..950811ac2eec --- /dev/null +++ b/boards/ezurio/rm126x_dvk/doc/rm126x_dvk_common_2.rst.inc @@ -0,0 +1,33 @@ +.. SPDX-License-Identifier: Apache-2.0 +.. +.. Copyright (c) 2026 Ezurio LLC + +.. _RM126x product brief: + https://www.ezurio.com/documentation/product-brief-rm126x-series + +.. _RM126x website: + https://www.ezurio.com/wireless-modules/lorawan-modules-solutions/rm126x-ultra-low-power-lorawan-a-b-c-module + +.. _RM126x datasheet: + https://www.ezurio.com/documentation/datasheet-rm126x-lorawan-module + +.. _EFR32BG22 datasheet: + https://www.silabs.com/documents/public/data-sheets/efr32bg22-datasheet.pdf + +.. _EFR32BG22 reference manual: + https://www.silabs.com/documents/public/reference-manuals/efr32xg22-rm.pdf + +.. _SX126x datasheet: + https://semtech.my.salesforce.com/sfc/p/#E0000000JelG/a/RQ000008n3pp/qXjWn19TZmb.1MgqPZ8Vrc5V7U.M_lOAIoTZHcEAeTI + +.. _mikroBUS: + https://www.mikroe.com/mikrobus + +.. _Qwiic: + https://www.sparkfun.com/qwiic + +.. _RM126x DVK user guide: + https://www.ezurio.com/documentation/user-guide-rm126x-development-kit + +.. _Simplicity Studio: + https://www.silabs.com/software-and-tools/simplicity-studio diff --git a/boards/ezurio/rm126x_dvk/doc/rm126x_dvk_rm1261.rst b/boards/ezurio/rm126x_dvk/doc/rm126x_dvk_rm1261.rst new file mode 100644 index 000000000000..18ae90877e8c --- /dev/null +++ b/boards/ezurio/rm126x_dvk/doc/rm126x_dvk_rm1261.rst @@ -0,0 +1,19 @@ +.. zephyr:board:: rm126x_dvk_rm1261 + +.. |RM126x variant| replace:: RM1261 +.. |SX126x variant| replace:: SX1261 +.. |LoRa TX Power| replace:: 15dBm +.. |Board Quoted| replace:: ``rm126x_dvk_rm1261`` +.. |Schematics Ref| replace:: `RM1261 DVK schematics`_ + +.. include:: rm126x_dvk_common_1.rst.inc + +.. zephyr-app-commands:: + :zephyr-app: samples/subsys/lorawan/class_a + :board: rm126x_dvk_rm1261 + :goals: build + +.. include:: rm126x_dvk_common_2.rst.inc + +.. _RM1261 DVK schematics: + https://www.ezurio.com/documentation/schematic-pcb-assembly-dvk-rm1261-devboard diff --git a/boards/ezurio/rm126x_dvk/doc/rm126x_dvk_rm1262.rst b/boards/ezurio/rm126x_dvk/doc/rm126x_dvk_rm1262.rst new file mode 100644 index 000000000000..defa6b2cde95 --- /dev/null +++ b/boards/ezurio/rm126x_dvk/doc/rm126x_dvk_rm1262.rst @@ -0,0 +1,19 @@ +.. zephyr:board:: rm126x_dvk_rm1262 + +.. |RM126x variant| replace:: RM1262 +.. |SX126x variant| replace:: SX1262 +.. |LoRa TX Power| replace:: 22dBm +.. |Board Quoted| replace:: ``rm126x_dvk_rm1262`` +.. |Schematics Ref| replace:: `RM1262 DVK schematics`_ + +.. include:: rm126x_dvk_common_1.rst.inc + +.. zephyr-app-commands:: + :zephyr-app: samples/subsys/lorawan/class_a + :board: rm126x_dvk_rm1262 + :goals: build + +.. include:: rm126x_dvk_common_2.rst.inc + +.. _RM1262 DVK schematics: + https://www.ezurio.com/documentation/schematic-pcb-assembly-dvk-rm1262-devboard diff --git a/boards/ezurio/rm126x_dvk/pre_dt_board.cmake b/boards/ezurio/rm126x_dvk/pre_dt_board.cmake new file mode 100644 index 000000000000..e0a341833fe4 --- /dev/null +++ b/boards/ezurio/rm126x_dvk/pre_dt_board.cmake @@ -0,0 +1,6 @@ +# Copyright (c) 2021 Linaro Limited +# Copyright (c) 2026 Ezurio LLC +# SPDX-License-Identifier: Apache-2.0 + +# SPI is implemented via usart so node name isn't spi@... +list(APPEND EXTRA_DTC_FLAGS "-Wno-spi_bus_bridge") diff --git a/boards/ezurio/rm126x_dvk/rm126x_dvk-pinctrl.dtsi b/boards/ezurio/rm126x_dvk/rm126x_dvk-pinctrl.dtsi new file mode 100644 index 000000000000..66a271b107b2 --- /dev/null +++ b/boards/ezurio/rm126x_dvk/rm126x_dvk-pinctrl.dtsi @@ -0,0 +1,82 @@ +/* + * Copyright The Zephyr Project Contributors + * Copyright (c) 2026 Ezurio LLC + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +&pinctrl { + timer0_default: timer0_default { + group0 { + pins = ; + drive-push-pull; + output-high; + }; + }; + + usart0_default: usart0_default { + group0 { + pins = , ; + drive-push-pull; + output-high; + }; + + group1 { + pins = ; + input-enable; + silabs,input-filter; + }; + }; + + usart1_default: usart1_default { + group0 { + pins = , ; + drive-push-pull; + output-high; + }; + + group1 { + pins = ; + input-enable; + silabs,input-filter; + }; + }; + + iadc0_default: iadc0_default { + group0 { + silabs,analog-bus = ; + }; + }; + + i2c0_default: i2c0_default { + group0 { + pins = , ; + bias-pull-up; + drive-open-drain; + }; + }; + + euart0_default: euart0_default { + group0 { + pins = , ; + drive-push-pull; + output-high; + }; + + group1 { + pins = , ; + input-enable; + silabs,input-filter; + }; + }; + + itm_default: itm_default { + group0 { + pins = ; + drive-push-pull; + output-high; + }; + }; +}; diff --git a/boards/ezurio/rm126x_dvk/rm126x_dvk.dtsi b/boards/ezurio/rm126x_dvk/rm126x_dvk.dtsi new file mode 100644 index 000000000000..5606eeae0f63 --- /dev/null +++ b/boards/ezurio/rm126x_dvk/rm126x_dvk.dtsi @@ -0,0 +1,274 @@ +/* + * Copyright The Zephyr Project Contributors + * Copyright (c) 2026 Ezurio LLC + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include "rm126x_dvk-pinctrl.dtsi" + +/ { + chosen { + zephyr,code-partition = &slot0_partition; + zephyr,console = &euart0; + zephyr,flash = &flash0; + zephyr,shell-uart = &euart0; + zephyr,sram = &sram0; + zephyr,uart-pipe = &euart0; + }; + + aliases { + led0 = &led0; + pwm-led0 = &pwm_led0; + sw0 = &button0; + watchdog0 = &wdog0; + lora0 = &lora0; + + /* If enabled, MCUboot uses this for recovery mode entrance */ + mcuboot-led0 = &led0; + mcuboot-button0 = &button0; + }; + + buttons { + compatible = "gpio-keys"; + + button0: button_0 { + gpios = <&gpioc 6 GPIO_ACTIVE_LOW>; + zephyr,code = ; + }; + }; + + leds { + compatible = "gpio-leds"; + + led0: led_0 { + gpios = <&gpioc 5 GPIO_ACTIVE_HIGH>; + }; + }; + + mikrobus_header: mikrobus-connector { + compatible = "mikro-bus"; + #gpio-cells = <2>; + gpio-map-mask = <0xffffffff 0>; + gpio-map-pass-thru = <0 GPIO_DT_FLAGS_MASK>; + gpio-map = <0 0 &gpioc 2 0>, /* AN */ + <1 0 &gpioc 3 0>, /* RST */ + <2 0 &gpioc 1 0>, /* CS */ + <3 0 &gpioc 0 0>, /* SCK */ + <4 0 &gpiod 2 0>, /* MISO */ + <5 0 &gpiod 3 0>, /* MOSI */ + <6 0 &gpioc 4 0>, /* PWM */ + <7 0 &gpioc 5 0>, /* INT */ + <8 0 &gpiod 2 0>, /* RX */ + <9 0 &gpiod 3 0>, /* TX */ + <10 0 &gpiod 2 0>, /* SCL */ + <11 0 &gpiod 3 0>; /* SDA */ + }; + + pwmleds { + compatible = "pwm-leds"; + + pwm_led0: pwm_led_0 { + pwms = <&timer0_pwm 0 PWM_MSEC(20) PWM_POLARITY_NORMAL>; + }; + }; + + qwiic_connector: stemma-qt-connector { + compatible = "stemma-qt-connector"; + #gpio-cells = <2>; + gpio-map-mask = <0xffffffff 0>; + gpio-map-pass-thru = <0 GPIO_DT_FLAGS_MASK>; + gpio-map = <0 0 &gpiod 2 0>, /* SCL */ + <1 0 &gpiod 3 0>; /* SDA */ + }; + + mikrobus_adc: zephyr,user { + io-channels = <&adc0 0>; + }; +}; + +&em23grpaclk { + clocks = <&lfxo>; +}; + +&em4grpaclk { + clocks = <&lfxo>; +}; + +&prortcclk { + clocks = <&lfxo>; +}; + +&rtccclk { + clocks = <&lfxo>; +}; + +&wdog0clk { + clocks = <&lfxo>; +}; + +&cpu0 { + clock-frequency = <38000000>; +}; + +&hfrcodpll { + clock-frequency = ; +}; + +&lfxo { + status = "okay"; + ctune = <38>; + precision = <50>; +}; + +&gpio { + status = "okay"; +}; + +&gpioa { + status = "okay"; +}; + +&gpiob { + status = "okay"; +}; + +&gpioc { + status = "okay"; +}; + +&gpiod { + status = "okay"; +}; + +&timer0 { + status = "okay"; + + timer0_pwm: pwm { + pinctrl-0 = <&timer0_default>; + pinctrl-names = "default"; + status = "okay"; + }; +}; + +&usart0 { + compatible = "silabs,usart-spi"; + #address-cells = <1>; + #size-cells = <0>; + pinctrl-0 = <&usart0_default>; + pinctrl-names = "default"; + cs-gpios = <&gpioc 1 GPIO_ACTIVE_LOW>; + status = "okay"; +}; + +&usart1 { + compatible = "silabs,usart-spi"; + #address-cells = <1>; + #size-cells = <0>; + pinctrl-0 = <&usart1_default>; + pinctrl-names = "default"; + cs-gpios = <&gpiob 0 GPIO_ACTIVE_LOW>; + status = "okay"; +}; + +&dcdc { + regulator-boot-on; + regulator-initial-mode = ; + status = "okay"; +}; + +&rtcc0 { + status = "okay"; +}; + +&adc0 { + pinctrl-0 = <&iadc0_default>; + pinctrl-names = "default"; + #address-cells = <1>; + #size-cells = <0>; + status = "okay"; + + channel@0 { + reg = <0>; + zephyr,acquisition-time = ; + zephyr,gain = "ADC_GAIN_1"; + zephyr,input-positive = ; + zephyr,reference = "ADC_REF_VDD_1"; + zephyr,resolution = <12>; + zephyr,vref-mv = <3300>; + }; +}; + +&i2c0 { + pinctrl-0 = <&i2c0_default>; + pinctrl-names = "default"; + status = "disabled"; +}; + +&wdog0 { + status = "okay"; +}; + +&euart0 { + current-speed = <115200>; + pinctrl-0 = <&euart0_default>; + pinctrl-names = "default"; + status = "okay"; +}; + +&trng { + status = "okay"; +}; + +&itm { + pinctrl-0 = <&itm_default>; + pinctrl-names = "default"; + swo-ref-frequency = ; +}; + +mikrobus_i2c: &i2c0 {}; + +mikrobus_spi: &usart0 {}; + +mikrobus_uart: &usart0 {}; + +zephyr_i2c: &i2c0 {}; + +zephyr_spi: &usart0 {}; + +&flash0 { + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + /* Reserve 48 KiB for the bootloader */ + boot_partition: partition@0 { + reg = <0x00000000 DT_SIZE_K(48)>; + label = "mcuboot"; + read-only; + }; + + /* Reserve 224 KiB for the application in slot 0 */ + slot0_partition: partition@c000 { + reg = <0x0000c000 DT_SIZE_K(224)>; + label = "image-0"; + }; + + /* Reserve 224 KiB for the application in slot 1 */ + slot1_partition: partition@44000 { + reg = <0x00044000 DT_SIZE_K(224)>; + label = "image-1"; + }; + + /* Set 16 KiB of storage at the end of the 512 KiB of flash */ + storage_partition: partition@7c000 { + reg = <0x0007c000 DT_SIZE_K(16)>; + label = "storage"; + }; + }; +}; diff --git a/boards/ezurio/rm126x_dvk/rm126x_dvk_rm1261.dts b/boards/ezurio/rm126x_dvk/rm126x_dvk_rm1261.dts new file mode 100644 index 000000000000..95a4a50063ff --- /dev/null +++ b/boards/ezurio/rm126x_dvk/rm126x_dvk_rm1261.dts @@ -0,0 +1,31 @@ +/* + * Copyright The Zephyr Project Contributors + * Copyright (c) 2026 Ezurio LLC + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; +#include +#include "rm126x_dvk.dtsi" +#include + +/ { + model = "Ezurio RM1261 DVK"; + compatible = "ezurio,rm126x_dvk_rm1261", "silabs,efr32bg22"; +}; + +&usart1 { + lora0: lora@0 { + compatible = "semtech,sx1261"; + reg = <0>; + reset-gpios = <&gpioa 6 GPIO_ACTIVE_LOW>; + busy-gpios = <&gpioa 7 (GPIO_PULL_UP | GPIO_ACTIVE_HIGH)>; + antenna-enable-gpios = <&gpiob 1 GPIO_ACTIVE_LOW>; + dio1-gpios = <&gpioa 5 (GPIO_PULL_DOWN | GPIO_ACTIVE_HIGH)>; + dio2-tx-enable; + dio3-tcxo-voltage = ; + tcxo-power-startup-delay-ms = <5>; + spi-max-frequency = <1000000>; + }; +}; diff --git a/boards/ezurio/rm126x_dvk/rm126x_dvk_rm1261.yaml b/boards/ezurio/rm126x_dvk/rm126x_dvk_rm1261.yaml new file mode 100644 index 000000000000..133f11135b88 --- /dev/null +++ b/boards/ezurio/rm126x_dvk/rm126x_dvk_rm1261.yaml @@ -0,0 +1,27 @@ +identifier: rm126x_dvk_rm1261 +name: RM1261 DVK +type: mcu +arch: arm +ram: 32 +flash: 224 +toolchain: + - zephyr + - gnuarmemb +supported: + - adc + - clock_control + - comparator + - counter + - dma + - entropy + - gpio + - flash + - i2c + - led + - lora + - pinctrl + - pwm + - spi + - uart + - watchdog +vendor: ezurio diff --git a/boards/ezurio/rm126x_dvk/rm126x_dvk_rm1261_defconfig b/boards/ezurio/rm126x_dvk/rm126x_dvk_rm1261_defconfig new file mode 100644 index 000000000000..5ee421b84580 --- /dev/null +++ b/boards/ezurio/rm126x_dvk/rm126x_dvk_rm1261_defconfig @@ -0,0 +1,10 @@ +# Copyright The Zephyr Project Contributors +# Copyright (c) 2026 Ezurio LLC +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_ARM_MPU=y +CONFIG_CONSOLE=y +CONFIG_UART_CONSOLE=y +CONFIG_SERIAL=y +CONFIG_GPIO=y +CONFIG_HW_STACK_PROTECTION=y diff --git a/boards/ezurio/rm126x_dvk/rm126x_dvk_rm1262.dts b/boards/ezurio/rm126x_dvk/rm126x_dvk_rm1262.dts new file mode 100644 index 000000000000..32d41444f1e6 --- /dev/null +++ b/boards/ezurio/rm126x_dvk/rm126x_dvk_rm1262.dts @@ -0,0 +1,32 @@ +/* + * Copyright The Zephyr Project Contributors + * Copyright (c) 2026 Ezurio LLC + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; +#include +#include "rm126x_dvk.dtsi" +#include + +/ { + model = "Ezurio RM1262 DVK"; + compatible = "ezurio,rm126x_dvk_rm1262", "silabs,efr32bg22"; +}; + +&usart1 { + lora0: lora@0 { + compatible = "semtech,sx1262"; + reg = <0>; + reset-gpios = <&gpioa 6 GPIO_ACTIVE_LOW>; + busy-gpios = <&gpioa 7 (GPIO_PULL_UP | GPIO_ACTIVE_HIGH)>; + antenna-enable-gpios = <&gpiob 1 GPIO_ACTIVE_LOW>; + dio1-gpios = <&gpioa 5 (GPIO_PULL_DOWN | GPIO_ACTIVE_HIGH)>; + dio2-tx-enable; + dio3-tcxo-voltage = ; + tcxo-power-startup-delay-ms = <5>; + regulator-ldo; + spi-max-frequency = <1000000>; + }; +}; diff --git a/boards/ezurio/rm126x_dvk/rm126x_dvk_rm1262.yaml b/boards/ezurio/rm126x_dvk/rm126x_dvk_rm1262.yaml new file mode 100644 index 000000000000..8a2d60aa8183 --- /dev/null +++ b/boards/ezurio/rm126x_dvk/rm126x_dvk_rm1262.yaml @@ -0,0 +1,27 @@ +identifier: rm126x_dvk_rm1262 +name: RM1262 DVK +type: mcu +arch: arm +ram: 32 +flash: 224 +toolchain: + - zephyr + - gnuarmemb +supported: + - adc + - clock_control + - comparator + - counter + - dma + - entropy + - gpio + - flash + - i2c + - led + - lora + - pinctrl + - pwm + - spi + - uart + - watchdog +vendor: ezurio diff --git a/boards/ezurio/rm126x_dvk/rm126x_dvk_rm1262_defconfig b/boards/ezurio/rm126x_dvk/rm126x_dvk_rm1262_defconfig new file mode 100644 index 000000000000..5ee421b84580 --- /dev/null +++ b/boards/ezurio/rm126x_dvk/rm126x_dvk_rm1262_defconfig @@ -0,0 +1,10 @@ +# Copyright The Zephyr Project Contributors +# Copyright (c) 2026 Ezurio LLC +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_ARM_MPU=y +CONFIG_CONSOLE=y +CONFIG_UART_CONSOLE=y +CONFIG_SERIAL=y +CONFIG_GPIO=y +CONFIG_HW_STACK_PROTECTION=y From 5064eda9a4356d86d860aa93db40668c6c380e2a Mon Sep 17 00:00:00 2001 From: Greg Leach Date: Tue, 13 Jan 2026 15:42:24 +0000 Subject: [PATCH 0080/6328] tests: app_development: Add efr32bg22 support Map test IRQ to SGI to prevent clash with EUART0 TX IRQ for EFR32BG22 SoC. Signed-off-by: Greg Leach --- tests/application_development/ram_context_for_isr/Kconfig | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/application_development/ram_context_for_isr/Kconfig b/tests/application_development/ram_context_for_isr/Kconfig index 53cee6732e7f..5d407f3270b7 100644 --- a/tests/application_development/ram_context_for_isr/Kconfig +++ b/tests/application_development/ram_context_for_isr/Kconfig @@ -13,6 +13,7 @@ config TEST_IRQ_NUM default 1 if (SOC_SERIES_NPCX9 || SOC_SERIES_NPCX7 || SOC_SERIES_NPCK3) default 29 if SOC_K32L2B31A default 28 if SOC_SERIES_NRF54L + default 52 if SOC_SERIES_EFR32BG22 default 0 help IRQ number to use for testing purposes. This should be an @@ -25,6 +26,7 @@ config TEST_IRQ_NUM - STM32C0X series: 18 (available test IRQ) - NPCX9, NPCX7, NPCK3 series: 1 (unused IRQ not mapped to MIWU groups) - K32L2B31A: 29 (available test IRQ) + - EFR32BG22: 52 (available test IRQ (SW0 - SGI), (NUM_IRQS - 1) equates to EUART0 TX) - Other platforms: 0 (magic config value to select the last IRQ: NUM_IRQS - 1) config TEST_IRQ_PRIO From 65438886e603003d7192988e35a96f9f504e980b Mon Sep 17 00:00:00 2001 From: Albort Xue Date: Fri, 9 Jan 2026 11:32:28 +0800 Subject: [PATCH 0081/6328] drivers: serial: uart_mcux_lpuart: configure clock before initialization Add clock configuration step before UART initialization to ensure proper clock setup. The clock is first disabled, then configured if supported by the clock controller. If clock configuration is not supported (ENOTSUP/ENOSYS), the driver continues with default settings. Other errors are treated as failures and propagated to the caller. Signed-off-by: Albort Xue --- drivers/serial/uart_mcux_lpuart.c | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/drivers/serial/uart_mcux_lpuart.c b/drivers/serial/uart_mcux_lpuart.c index d3be5c3e2c77..42608d049a4c 100644 --- a/drivers/serial/uart_mcux_lpuart.c +++ b/drivers/serial/uart_mcux_lpuart.c @@ -1,5 +1,5 @@ /* - * Copyright 2017,2021,2023-2025 NXP + * Copyright 2017,2021,2023-2026 NXP * Copyright (c) 2020 Softube * * SPDX-License-Identifier: Apache-2.0 @@ -1160,9 +1160,14 @@ static int mcux_lpuart_configure_init(const struct device *dev, const struct uar return -ENODEV; } - if (clock_control_get_rate(config->clock_dev, config->clock_subsys, - &clock_freq)) { - return -EINVAL; + ret = clock_control_configure(config->clock_dev, config->clock_subsys, NULL); + if (ret != 0) { + /* Check if error is due to lack of support */ + if (ret != -ENOSYS) { + /* Real error occurred */ + LOG_ERR("Failed to configure clock: %d", ret); + return ret; + } } LPUART_GetDefaultConfig(&uart_config); @@ -1177,6 +1182,13 @@ static int mcux_lpuart_configure_init(const struct device *dev, const struct uar return ret; } + ret = clock_control_get_rate(config->clock_dev, config->clock_subsys, + &clock_freq); + if (ret) { + LOG_ERR("Failed to get clock rate: %d", ret); + return -EINVAL; + } + LPUART_Init(config->base, &uart_config, clock_freq); #ifdef LPUART_HAS_MODEM From abeca66759ef15a87c80712529ec28f2004f8158 Mon Sep 17 00:00:00 2001 From: Jimmy Johnson Date: Tue, 6 Jan 2026 22:11:02 -0800 Subject: [PATCH 0082/6328] sensor: shell: battery: Update support for battery shell queries Added a `supported` flag to battery status query so if the charger does not support the query (returns -ENOTSUP) the command still returns any other supported queries and doesn't error out without reporting anything. Any other errors than -ENOTSUP still cause the request to return immediately, as was the case before the changes. Tested on nordic npm 13xx. Signed-off-by: Jimmy Johnson --- drivers/sensor/shell_battery.c | 120 +++++++++++++++++++++++---------- 1 file changed, 83 insertions(+), 37 deletions(-) diff --git a/drivers/sensor/shell_battery.c b/drivers/sensor/shell_battery.c index 4d7e34ea6286..3a68b560fd37 100644 --- a/drivers/sensor/shell_battery.c +++ b/drivers/sensor/shell_battery.c @@ -11,6 +11,11 @@ #include #include +struct ch_val_result { + struct sensor_value val; + bool supported; +}; + /** * @brief Collect the values for several channels * @@ -29,18 +34,22 @@ static int get_channels(const struct device *dev, ...) va_start(ptr, dev); for (i = 0;; i++) { int chan; - struct sensor_value *val; + struct ch_val_result *val; int err; chan = va_arg(ptr, int); if (chan == -1) { break; } - val = va_arg(ptr, struct sensor_value *); - err = sensor_channel_get(dev, chan, val); - if (err < 0) { + val = va_arg(ptr, struct ch_val_result *); + err = sensor_channel_get(dev, chan, &val->val); + if (err == -ENOTSUP) { + val->supported = false; + } else if (err < 0) { va_end(ptr); return err; + } else { + val->supported = true; } } @@ -51,9 +60,9 @@ static int get_channels(const struct device *dev, ...) /* battery */ static int cmd_battery(const struct shell *sh, size_t argc, char **argv) { - struct sensor_value temp, volt, current, i_desired, charge_remain; - struct sensor_value charge, v_desired, v_design, cap, nom_cap; - struct sensor_value full, empty; + struct ch_val_result temp, volt, current, i_desired, charge_remain; + struct ch_val_result charge, v_desired, v_design, cap, nom_cap; + struct ch_val_result full, empty; const struct device *const dev = DEVICE_DT_GET(DT_ALIAS(battery)); bool allowed; int err; @@ -88,36 +97,73 @@ static int cmd_battery(const struct shell *sh, size_t argc, char **argv) return err; } - shell_print(sh, "Temp: %.1d.%02d C", - temp.val1, temp.val2 / 10000); - shell_print(sh, "V: %5d.%02d V", - volt.val1, volt.val2 / 10000); - shell_print(sh, "V-desired: %d.%02d V", - v_desired.val1, v_desired.val2 / 10000); - shell_fprintf_normal(sh, "I: %lld mA", - sensor_value_to_milli(¤t)); - if (current.val1 > 0) { - shell_fprintf_normal(sh, " (CHG)"); - } else if (current.val1 < 0) { - shell_fprintf_normal(sh, " (DISCHG)"); - } - shell_fprintf_normal(sh, "\n"); - shell_print(sh, "I-desired: %5d mA", - i_desired.val1); - allowed = i_desired.val1 && v_desired.val2 && charge.val1 < 100; - shell_print(sh, "Charging: %sAllowed", - allowed ? "" : "Not "); - shell_print(sh, "Charge: %d %%", charge.val1); - shell_print(sh, "V-design: %d.%02d V", - v_design.val1, v_design.val2 / 10000); - shell_print(sh, "Remaining: %d mAh", - charge_remain.val1); - shell_print(sh, "Cap-full: %d mAh", cap.val1); - shell_print(sh, "Design: %d mAh", nom_cap.val1); - shell_print(sh, "Time full: %dh:%02d", - full.val1 / 60, full.val1 % 60); - shell_print(sh, "Time empty: %dh:%02d", - empty.val1 / 60, empty.val1 % 60); + if (temp.supported) { + shell_print(sh, "Temp: %.1d.%02d C", + temp.val.val1, temp.val.val2 / 10000); + } + + if (volt.supported) { + shell_print(sh, "V: %5d.%02d V", + volt.val.val1, volt.val.val2 / 10000); + } + + if (v_desired.supported) { + shell_print(sh, "V-desired: %d.%02d V", + v_desired.val.val1, v_desired.val.val2 / 10000); + } + + if (current.supported) { + shell_fprintf_normal(sh, "I: %lld mA", + sensor_value_to_milli(¤t.val)); + if (current.val.val1 > 0) { + shell_fprintf_normal(sh, " (CHG)"); + } else if (current.val.val1 < 0) { + shell_fprintf_normal(sh, " (DISCHG)"); + } else { + shell_fprintf_normal(sh, " (UNKWN)"); + } + shell_fprintf_normal(sh, "\n"); + } + + if (i_desired.supported) { + shell_print(sh, "I-desired: %5d mA", + i_desired.val.val1); + allowed = i_desired.val.val1 && v_desired.val.val2 && charge.val.val1 < 100; + shell_print(sh, "Charging: %sAllowed", + allowed ? "" : "Not "); + } + + if (charge.supported) { + shell_print(sh, "Charge: %d %%", charge.val.val1); + } + + if (v_design.supported) { + shell_print(sh, "V-design: %d.%02d V", + v_design.val.val1, v_design.val.val2 / 10000); + } + + if (charge_remain.supported) { + shell_print(sh, "Remaining: %d mAh", + charge_remain.val.val1); + } + + if (cap.supported) { + shell_print(sh, "Cap-full: %d mAh", cap.val.val1); + } + + if (nom_cap.supported) { + shell_print(sh, "Design: %d mAh", nom_cap.val.val1); + } + + if (full.supported) { + shell_print(sh, "Time full: %dh:%02d", + full.val.val1 / 60, full.val.val1 % 60); + } + + if (empty.supported) { + shell_print(sh, "Time empty: %dh:%02d", + empty.val.val1 / 60, empty.val.val1 % 60); + } return 0; } From c84a5eb24fd40ae33dfd3ec2963e534567ab2db4 Mon Sep 17 00:00:00 2001 From: Karol Werner Date: Sun, 4 Jan 2026 22:15:36 +0100 Subject: [PATCH 0083/6328] drivers: sensor: ina3221: fix measurement wait time calculation INA3221 performs measurements sequentially for all enabled channels (see datasheet chapter 7.3.1), but the driver was not accounting for this when calculating the wait time. Additionally, when measuring both bus and shunt voltages, conversion times should be summed rather than taking greater value. Fix by counting enabled channels and multiplying them with per-channel conversion time. For combined measurement, sum both conversion times instead of using MAX(). Signed-off-by: Karol Werner --- drivers/sensor/ti/ina3221/ina3221.c | 30 ++++++++++++++++++----------- 1 file changed, 19 insertions(+), 11 deletions(-) diff --git a/drivers/sensor/ti/ina3221/ina3221.c b/drivers/sensor/ti/ina3221/ina3221.c index 28aab27f386e..21c4ce818871 100644 --- a/drivers/sensor/ti/ina3221/ina3221.c +++ b/drivers/sensor/ti/ina3221/ina3221.c @@ -151,6 +151,8 @@ static int ina3221_sample_fetch(const struct device *dev, enum sensor_channel ch const struct ina3221_config *cfg = dev->config; bool measurement_successful = false; k_timeout_t measurement_time = K_NO_WAIT; + uint8_t enabled_channels = 0; + int32_t channel_conv_time_us = 0; int ret; /* Trigger measurement and wait for completion */ @@ -159,29 +161,35 @@ static int ina3221_sample_fetch(const struct device *dev, enum sensor_channel ch if (ret) { return ret; } - measurement_time = - K_USEC(avg_mode_samples[cfg->avg_mode] * - conv_time_us[cfg->conv_time_bus]); + channel_conv_time_us = conv_time_us[cfg->conv_time_bus]; } else if (chan == SENSOR_CHAN_CURRENT) { ret = start_measurement(dev, false, true); if (ret) { return ret; } - measurement_time = - K_USEC(avg_mode_samples[cfg->avg_mode] * - conv_time_us[cfg->conv_time_shunt]); + channel_conv_time_us = conv_time_us[cfg->conv_time_shunt]; } else if (chan == SENSOR_CHAN_POWER || chan == SENSOR_CHAN_ALL) { ret = start_measurement(dev, true, true); if (ret) { return ret; } - measurement_time = - K_USEC(avg_mode_samples[cfg->avg_mode] * - conv_time_us[MAX(cfg->conv_time_shunt, cfg->conv_time_bus)]); + channel_conv_time_us = + conv_time_us[cfg->conv_time_bus] + conv_time_us[cfg->conv_time_shunt]; } else { return -ENOTSUP; } + for (size_t i = 0; i < 3; ++i) { + if (cfg->enable_channel[i]) { + enabled_channels++; + } + } + + /* Measurements are performed sequentially for all enabled channels. */ + /* See chapter 7.3.1 in the datasheet. */ + measurement_time = + K_USEC(enabled_channels * avg_mode_samples[cfg->avg_mode] * channel_conv_time_us); + for (size_t i = 0; i < MAX_RETRIES; ++i) { k_sleep(measurement_time); if (measurement_ready(dev)) { @@ -285,7 +293,7 @@ static DEVICE_API(sensor, ina3221_api) = { static struct ina3221_data ina3221_data_##index; \ \ SENSOR_DEVICE_DT_INST_DEFINE(index, ina3221_init, NULL, &ina3221_data_##index, \ - &ina3221_config_##index, POST_KERNEL, CONFIG_SENSOR_INIT_PRIORITY, \ - &ina3221_api); + &ina3221_config_##index, POST_KERNEL, \ + CONFIG_SENSOR_INIT_PRIORITY, &ina3221_api); DT_INST_FOREACH_STATUS_OKAY(INST_DT_INA3221); From bd9bf13a0eb6172ad9898c4174ad8e9205e0b462 Mon Sep 17 00:00:00 2001 From: Supper Thomas <78900636@qq.com> Date: Wed, 31 Dec 2025 07:38:48 +0000 Subject: [PATCH 0084/6328] logging: Fix backoff calculation to use K_CYC instead of K_TICK The backoff timeout calculation in z_log_msg_claim_oldest() was incorrectly using K_TICK macro. Changed to K_CYC to properly convert cycle-based timing differences to kernel timeouts for accurate backoff in multi-domain message processing. Signed-off-by: Supper Thomas <78900636@qq.com> --- subsys/logging/log_core.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/subsys/logging/log_core.c b/subsys/logging/log_core.c index f0143480dc67..d8a1f83b0d3f 100644 --- a/subsys/logging/log_core.c +++ b/subsys/logging/log_core.c @@ -759,9 +759,9 @@ union log_msg_generic *z_log_msg_claim_oldest(k_timeout_t *backoff) * long processing shall back off. */ if (timestamp_freq == sys_clock_hw_cycles_per_sec()) { - *backoff = K_TICKS(diff); + *backoff = K_CYC(diff); } else { - *backoff = K_TICKS((diff * sys_clock_hw_cycles_per_sec()) / + *backoff = K_CYC((diff * sys_clock_hw_cycles_per_sec()) / timestamp_freq); } From af6264e4b92dfba47fc738150de3cb87aa150fe5 Mon Sep 17 00:00:00 2001 From: Armando Visconti Date: Wed, 26 Nov 2025 15:00:39 +0100 Subject: [PATCH 0085/6328] drivers/sensor: lsm6dsv16x: add device self test Add device Self Test procedure. It is required to enable the per device self-test DT property as well as the LSM6DSV16X_SELF_TEST configuration. Signed-off-by: Armando Visconti --- drivers/sensor/st/lsm6dsv16x/Kconfig | 7 + drivers/sensor/st/lsm6dsv16x/lsm6dsv16x.c | 249 ++++++++++++++++++ drivers/sensor/st/lsm6dsv16x/lsm6dsv16x.h | 5 + dts/bindings/sensor/st,lsm6dsvxxx-common.yaml | 6 + include/zephyr/drivers/sensor/lsm6dsvxxx.h | 44 ++++ 5 files changed, 311 insertions(+) create mode 100644 include/zephyr/drivers/sensor/lsm6dsvxxx.h diff --git a/drivers/sensor/st/lsm6dsv16x/Kconfig b/drivers/sensor/st/lsm6dsv16x/Kconfig index 06f713cf4a11..1b907ece5404 100644 --- a/drivers/sensor/st/lsm6dsv16x/Kconfig +++ b/drivers/sensor/st/lsm6dsv16x/Kconfig @@ -32,6 +32,13 @@ config LSM6DSV16X_STREAM help Use this config option to enable streaming sensor data via RTIO subsystem. +config LSM6DSV16X_SELF_TEST + bool "Self test attribute" + help + Enable support for configuring the sensor self test bits. + Refer to the datasheet of the sensor for a description of + the appropriate self test procedure. + choice LSM6DSV16X_TRIGGER_MODE default LSM6DSV16X_TRIGGER_GLOBAL_THREAD if LSM6DSV16X_STREAM default LSM6DSV16X_TRIGGER_NONE diff --git a/drivers/sensor/st/lsm6dsv16x/lsm6dsv16x.c b/drivers/sensor/st/lsm6dsv16x/lsm6dsv16x.c index 805e06ec7f7e..8bd621f11c2a 100644 --- a/drivers/sensor/st/lsm6dsv16x/lsm6dsv16x.c +++ b/drivers/sensor/st/lsm6dsv16x/lsm6dsv16x.c @@ -18,6 +18,7 @@ #include #include +#include #include #include "lsm6dsv16x.h" #include "lsm6dsv16x_decoder.h" @@ -282,6 +283,231 @@ static int lsm6dsv16x_accel_wake_duration_set(const struct device *dev, return lsm6dsv16x_act_thresholds_set(ctx, &thresholds); } +#ifdef CONFIG_LSM6DSV16X_SELF_TEST +/* Self test limits. */ +#define MIN_ST_LIMIT_mg 50.0f +#define MAX_ST_LIMIT_mg 1700.0f +#define MIN_ST_LIMIT_mdps 150000.0f +#define MAX_ST_LIMIT_mdps 700000.0f + +/* + * Accelerometer Self Test + */ +static int lsm6dsv16x_accel_self_test(const struct device *dev) +{ + const struct lsm6dsv16x_config *cfg = dev->config; + stmdev_ctx_t *ctx = (stmdev_ctx_t *)&cfg->ctx; + lsm6dsv16x_data_ready_t drdy; + int16_t data_raw[3]; + float_t val_st_off[3]; + float_t val_st_on[3]; + float_t test_val[3]; + uint8_t i, j, st_result; + + /* Set Output Data Rate */ + lsm6dsv16x_xl_data_rate_set(ctx, LSM6DSV16X_ODR_AT_60Hz); + + /* Set full scale */ + lsm6dsv16x_xl_full_scale_set(ctx, LSM6DSV16X_4g); + + /* Wait stable output */ + k_msleep(100); + + /* Check if new value available */ + do { + lsm6dsv16x_flag_data_ready_get(ctx, &drdy); + } while (!drdy.drdy_xl); + + /* Read dummy data and discard it */ + lsm6dsv16x_acceleration_raw_get(ctx, data_raw); + + /* Read 5 sample and get the average vale for each axis */ + memset(val_st_off, 0x0, 3 * sizeof(float)); + + for (i = 0; i < 5; i++) { + /* Check if new value available */ + do { + lsm6dsv16x_flag_data_ready_get(ctx, &drdy); + } while (!drdy.drdy_xl); + + /* Read data and accumulate the mg value */ + lsm6dsv16x_acceleration_raw_get(ctx, data_raw); + + for (j = 0; j < 3; j++) { + val_st_off[j] += lsm6dsv16x_from_fs4_to_mg(data_raw[j]); + } + } + + /* Calculate the mg average values */ + for (i = 0; i < 3; i++) { + val_st_off[i] /= 5.0f; + } + + /* Enable Self Test negative */ + lsm6dsv16x_xl_self_test_set(ctx, LSM6DSV16X_XL_ST_NEGATIVE); + + /* Wait stable output */ + k_msleep(100); + + /* Check if new value available */ + do { + lsm6dsv16x_flag_data_ready_get(ctx, &drdy); + } while (!drdy.drdy_xl); + + /* Read dummy data and discard it */ + lsm6dsv16x_acceleration_raw_get(ctx, data_raw); + /* Read 5 sample and get the average vale for each axis */ + memset(val_st_on, 0x00, 3 * sizeof(float)); + + for (i = 0; i < 5; i++) { + /* Check if new value available */ + do { + lsm6dsv16x_flag_data_ready_get(ctx, &drdy); + } while (!drdy.drdy_xl); + + /* Read data and accumulate the mg value */ + lsm6dsv16x_acceleration_raw_get(ctx, data_raw); + + for (j = 0; j < 3; j++) { + val_st_on[j] += lsm6dsv16x_from_fs4_to_mg(data_raw[j]); + } + } + + /* Calculate the mg average values */ + for (i = 0; i < 3; i++) { + val_st_on[i] /= 5.0f; + } + + /* Calculate the mg values for self test */ + for (i = 0; i < 3; i++) { + test_val[i] = fabsf((val_st_on[i] - val_st_off[i])); + } + + /* Check self test limit */ + st_result = 0; + for (i = 0; i < 3; i++) { + if ((test_val[i] < MIN_ST_LIMIT_mg) || + (test_val[i] > MAX_ST_LIMIT_mg)) { + st_result = -1; + break; + } + } + + /* Disable Self Test */ + lsm6dsv16x_xl_self_test_set(ctx, LSM6DSV16X_XL_ST_DISABLE); + + /* Disable sensor. */ + lsm6dsv16x_xl_data_rate_set(ctx, LSM6DSV16X_ODR_OFF); + + LOG_INF("Accel self-test result: %s", st_result ? "FAIL" : "PASS"); + return st_result; +} + +/* + * Gyroscope Self Test + */ +static int lsm6dsv16x_gyro_self_test(const struct device *dev) +{ + const struct lsm6dsv16x_config *cfg = dev->config; + stmdev_ctx_t *ctx = (stmdev_ctx_t *)&cfg->ctx; + lsm6dsv16x_data_ready_t drdy; + int16_t data_raw[3]; + float_t val_st_off[3]; + float_t val_st_on[3]; + float_t test_val[3]; + uint8_t i, j, st_result; + + /* Set Output Data Rate */ + lsm6dsv16x_gy_data_rate_set(ctx, LSM6DSV16X_ODR_AT_240Hz); + + /* Set full scale */ + lsm6dsv16x_gy_full_scale_set(ctx, LSM6DSV16X_2000dps); + + /* Wait stable output */ + k_msleep(100); + + /* Check if new value available */ + do { + lsm6dsv16x_flag_data_ready_get(ctx, &drdy); + } while (!drdy.drdy_gy); + + /* Read dummy data and discard it */ + lsm6dsv16x_angular_rate_raw_get(ctx, data_raw); + /* Read 5 sample and get the average vale for each axis */ + memset(val_st_off, 0x00, 3 * sizeof(float)); + + for (i = 0; i < 5; i++) { + /* Check if new value available */ + do { + lsm6dsv16x_flag_data_ready_get(ctx, &drdy); + } while (!drdy.drdy_gy); + /* Read data and accumulate the mg value */ + lsm6dsv16x_angular_rate_raw_get(ctx, data_raw); + + for (j = 0; j < 3; j++) { + val_st_off[j] += lsm6dsv16x_from_fs2000_to_mdps(data_raw[j]); + } + } + + /* Calculate the mg average values */ + for (i = 0; i < 3; i++) { + val_st_off[i] /= 5.0f; + } + + /* Enable Self Test positive (or negative) */ + lsm6dsv16x_gy_self_test_set(ctx, LSM6DSV16X_GY_ST_POSITIVE); + + /* Wait stable output */ + k_msleep(100); + + /* Read 5 sample and get the average vale for each axis */ + memset(val_st_on, 0x00, 3 * sizeof(float)); + + for (i = 0; i < 5; i++) { + /* Check if new value available */ + do { + lsm6dsv16x_flag_data_ready_get(ctx, &drdy); + } while (!drdy.drdy_gy); + + /* Read data and accumulate the mg value */ + lsm6dsv16x_angular_rate_raw_get(ctx, data_raw); + + for (j = 0; j < 3; j++) { + val_st_on[j] += lsm6dsv16x_from_fs2000_to_mdps(data_raw[j]); + } + } + + /* Calculate the mg average values */ + for (i = 0; i < 3; i++) { + val_st_on[i] /= 5.0f; + } + + /* Calculate the mg values for self test */ + for (i = 0; i < 3; i++) { + test_val[i] = fabsf((val_st_on[i] - val_st_off[i])); + } + + /* Check self test limit */ + st_result = 0; + for (i = 0; i < 3; i++) { + if ((test_val[i] < MIN_ST_LIMIT_mdps) || + (test_val[i] > MAX_ST_LIMIT_mdps)) { + st_result = -1; + break; + } + } + + /* Disable Self Test */ + lsm6dsv16x_gy_self_test_set(ctx, LSM6DSV16X_GY_ST_DISABLE); + + /* Disable sensor. */ + lsm6dsv16x_gy_data_rate_set(ctx, LSM6DSV16X_ODR_OFF); + + LOG_INF("Gyro self-test result: %s", st_result ? "FAIL" : "PASS"); + return st_result; +} +#endif + static int lsm6dsv16x_accel_config(const struct device *dev, enum sensor_channel chan, enum sensor_attribute attr, @@ -501,6 +727,12 @@ static int lsm6dsv16x_accel_get_config(const struct device *dev, struct lsm6dsv16x_data *data = dev->data; switch (attr) { +#ifdef CONFIG_LSM6DSV16X_SELF_TEST + case SENSOR_ATTR_GET_SELF_TEST_RESULT: + val->val1 = (data->xl_st_result == 0) ? LSM6DSVXXX_ST_OK : LSM6DSVXXX_ST_FAIL; + val->val2 = 0; + break; +#endif case SENSOR_ATTR_FULL_SCALE: sensor_g_to_ms2(cfg->accel_fs_map[data->accel_fs], val); break; @@ -573,6 +805,12 @@ static int lsm6dsv16x_gyro_get_config(const struct device *dev, struct lsm6dsv16x_data *data = dev->data; switch (attr) { +#ifdef CONFIG_LSM6DSV16X_SELF_TEST + case SENSOR_ATTR_GET_SELF_TEST_RESULT: + val->val1 = (data->gy_st_result == 0) ? 0 : 1; + val->val2 = 0; + break; +#endif case SENSOR_ATTR_FULL_SCALE: sensor_degrees_to_rad(lsm6dsv16x_gyro_fs_map[data->gyro_fs], val); break; @@ -1120,6 +1358,15 @@ static int lsm6dsv16x_init_chip(const struct device *dev) k_sleep(K_MSEC(30)); } +#ifdef CONFIG_LSM6DSV16X_SELF_TEST + lsm6dsv16x->xl_st_result = 0; + lsm6dsv16x->gy_st_result = 0; + if (cfg->self_test_en) { + lsm6dsv16x->xl_st_result = lsm6dsv16x_accel_self_test(dev); + lsm6dsv16x->gy_st_result = lsm6dsv16x_gyro_self_test(dev); + } +#endif + fs = cfg->accel_range; LOG_DBG("accel range is %d", fs); if (lsm6dsv16x_accel_set_fs_raw(dev, fs) < 0) { @@ -1281,6 +1528,8 @@ static int lsm6dsv16x_pm_action(const struct device *dev, enum pm_device_action #endif /* CONFIG_LSM6DSV16X_TRIGGER */ #define LSM6DSV16X_CONFIG_COMMON(inst, prefix) \ + IF_ENABLED(CONFIG_LSM6DSV16X_SELF_TEST, \ + (.self_test_en = DT_INST_PROP(inst, self_test),)) \ .accel_odr = DT_INST_PROP(inst, accel_odr), \ .accel_range = DT_INST_ENUM_IDX(inst, accel_range), \ .accel_fs_map = prefix##_accel_fs_map, \ diff --git a/drivers/sensor/st/lsm6dsv16x/lsm6dsv16x.h b/drivers/sensor/st/lsm6dsv16x/lsm6dsv16x.h index 9c21ffe6dd6b..6fa09aed4f0e 100644 --- a/drivers/sensor/st/lsm6dsv16x/lsm6dsv16x.h +++ b/drivers/sensor/st/lsm6dsv16x/lsm6dsv16x.h @@ -68,6 +68,9 @@ struct lsm6dsv16x_config { struct i3c_device_desc **i3c; #endif } stmemsc_cfg; +#ifdef CONFIG_LSM6DSV16X_SELF_TEST + uint8_t self_test_en; +#endif uint8_t accel_pm; uint8_t accel_odr; uint8_t accel_range; @@ -155,6 +158,8 @@ struct lsm6dsv16x_data { uint8_t shub_ext[LSM6DSV16X_SHUB_MAX_NUM_TARGETS]; #endif /* CONFIG_LSM6DSV16X_SENSORHUB */ + uint8_t xl_st_result; + uint8_t gy_st_result; uint8_t accel_freq; uint8_t accel_fs; uint8_t gyro_freq; diff --git a/dts/bindings/sensor/st,lsm6dsvxxx-common.yaml b/dts/bindings/sensor/st,lsm6dsvxxx-common.yaml index 133860e1a90f..604cb7a5263f 100644 --- a/dts/bindings/sensor/st,lsm6dsvxxx-common.yaml +++ b/dts/bindings/sensor/st,lsm6dsvxxx-common.yaml @@ -36,6 +36,12 @@ properties: mandatory and if not present it defaults to 1 which is the configuration at power-up. + self-test: + type: boolean + description: | + Enable device self-test procedure, which applies an electrostatic force to the sensor to + simulate acceleration and rotation without actually moving the device. + accel-odr: type: int default: 0x0 diff --git a/include/zephyr/drivers/sensor/lsm6dsvxxx.h b/include/zephyr/drivers/sensor/lsm6dsvxxx.h new file mode 100644 index 000000000000..effbe2bc64ee --- /dev/null +++ b/include/zephyr/drivers/sensor/lsm6dsvxxx.h @@ -0,0 +1,44 @@ +/* + * Copyright The Zephyr Project Contributors + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @file + * @brief Header file for extended sensor API of LSM6DSVXXX sensor + * @ingroup lsm6dsvxxx_interface + */ + +#ifndef ZEPHYR_INCLUDE_DRIVERS_SENSOR_LSM6DSVXXX_H_ +#define ZEPHYR_INCLUDE_DRIVERS_SENSOR_LSM6DSVXXX_H_ + +/** + * @defgroup lsm6dsvxxx_interface LSM6DSVXXX + * @ingroup sensor_interface_ext + * @brief ST Microelectronics LSM6DSVXXX 3-axis IMU family + * @{ + */ + +#include + +/** + * @brief Custom sensor attributes for LSM6DSVXXX + */ +enum sensor_attribute_lsm6dsvxxx { + /** + * Gets the self-test mode result in sensor_value.val1 field. + */ + SENSOR_ATTR_GET_SELF_TEST_RESULT = SENSOR_ATTR_PRIV_START, +}; + +enum lsm6dsvxxx_self_test_result { + LSM6DSVXXX_ST_OK = 0, + LSM6DSVXXX_ST_FAIL = 1, +}; + +/** + * @} + */ + +#endif /* ZEPHYR_INCLUDE_DRIVERS_SENSOR_LSM6DSVXXX_H_ */ From e9b257a1f9ad39163bdf6cec79e668e618eb7fe5 Mon Sep 17 00:00:00 2001 From: Rex Chen Date: Thu, 30 Oct 2025 11:58:44 +0900 Subject: [PATCH 0086/6328] manifest: hal_nxp: Add scan limit configure item Sync hal_nxp to add scan limit configure item. Signed-off-by: Rex Chen --- west.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/west.yml b/west.yml index 55b322fa978b..9ab9b81e5ded 100644 --- a/west.yml +++ b/west.yml @@ -210,7 +210,7 @@ manifest: groups: - hal - name: hal_nxp - revision: 57b8fcad0337a803cbefd5ac635f8c5d37a7f806 + revision: 2f8883b3358e7be2101075cd0f00dd2e0fa68050 path: modules/hal/nxp groups: - hal From cbc881cc51f10686e04cc14b1ce4fcb05aaf3b15 Mon Sep 17 00:00:00 2001 From: Rex Chen Date: Thu, 30 Oct 2025 12:00:04 +0900 Subject: [PATCH 0087/6328] drivers: wifi: nxp: Add scan limit configure item Expose scan limit configuration to customer. Signed-off-by: Rex Chen --- drivers/wifi/nxp/Kconfig.nxp | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/drivers/wifi/nxp/Kconfig.nxp b/drivers/wifi/nxp/Kconfig.nxp index c6c5e5764022..742666ce4d07 100644 --- a/drivers/wifi/nxp/Kconfig.nxp +++ b/drivers/wifi/nxp/Kconfig.nxp @@ -539,6 +539,12 @@ config NXP_WIFI_STA_RECONNECT This option enables Station auto reconnection support, when disconnected from current associated Access Point. +config NXP_WIFI_MAX_RECONNECT_LIMIT + int "Max reconnect limit" + default 5 + help + This option sets the max reconnect limit. + config NXP_WIFI_AUTO_POWER_SAVE bool "Automatically starts Power Save support" default y @@ -579,6 +585,12 @@ config NXP_WIFI_SCAN_CHANNEL_GAP help This option sets the max scan channel gap time between two scan commands. +config NXP_WIFI_MAX_RESCAN_LIMIT + int "Max scan limit" + default 30 + help + This option sets the max scan limit. + endmenu config NXP_WIFI_WMM_UAPSD From 42fcca480b4a82e2eceba55e0619d98de6dbf9fb Mon Sep 17 00:00:00 2001 From: Bernardo Perez Priego Date: Tue, 21 Oct 2025 16:42:20 -0700 Subject: [PATCH 0088/6328] drivers: i2c: microchip: Add mutex to transaction implementation Currently, I2C transfer implementation does not have a mutex to prevent multiple users from sending data at the same time, this could lead to devices malfunction due to mixing I2C transaction data. This patch adds mutex into transfer implementation to allow only one user to send data at the time. Signed-off-by: Bernardo Perez Priego --- drivers/i2c/i2c_mchp_xec_v2.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/i2c/i2c_mchp_xec_v2.c b/drivers/i2c/i2c_mchp_xec_v2.c index 4feda66823ef..34008b7b2422 100644 --- a/drivers/i2c/i2c_mchp_xec_v2.c +++ b/drivers/i2c/i2c_mchp_xec_v2.c @@ -106,6 +106,7 @@ struct i2c_xec_data { uint8_t i2c_ctrl; uint8_t i2c_addr; uint8_t i2c_status; + struct k_mutex mux; }; /* Recommended programming values based on 16MHz @@ -783,6 +784,7 @@ static int i2c_xec_transfer(const struct device *dev, struct i2c_msg *msgs, } #endif + k_mutex_lock(&data->mux, K_FOREVER); for (uint8_t i = 0; i < num_msgs; i++) { struct i2c_msg *m = &msgs[i]; @@ -798,6 +800,7 @@ static int i2c_xec_transfer(const struct device *dev, struct i2c_msg *msgs, break; } } + k_mutex_unlock(&data->mux); return ret; } @@ -1074,6 +1077,7 @@ static int i2c_xec_init(const struct device *dev) return ret; } + k_mutex_init(&data->mux); #ifdef CONFIG_I2C_TARGET const struct i2c_xec_config *config = (const struct i2c_xec_config *const) (dev->config); From c92d617855e477ca58a3015da57f48c0910ecf3b Mon Sep 17 00:00:00 2001 From: Mark Wang Date: Fri, 24 Oct 2025 15:27:38 +0800 Subject: [PATCH 0089/6328] bluetooth: shell: a2dp: use common function to check a2dp initialization Before every cmd, call one common function to check whether a2dp is initialized. Signed-off-by: Mark Wang --- subsys/bluetooth/host/classic/shell/a2dp.c | 58 ++++++++++------------ 1 file changed, 27 insertions(+), 31 deletions(-) diff --git a/subsys/bluetooth/host/classic/shell/a2dp.c b/subsys/bluetooth/host/classic/shell/a2dp.c index 2802731dab8a..e4d105a66f45 100644 --- a/subsys/bluetooth/host/classic/shell/a2dp.c +++ b/subsys/bluetooth/host/classic/shell/a2dp.c @@ -30,7 +30,7 @@ struct bt_a2dp *default_a2dp; static uint8_t a2dp_sink_sdp_registered; static uint8_t a2dp_source_sdp_registered; -static uint8_t a2dp_initied; +static bool a2dp_cb_registered; BT_A2DP_SBC_SINK_EP_DEFAULT(sink_sbc_endpoint); BT_A2DP_SBC_SOURCE_EP_DEFAULT(source_sbc_endpoint); struct bt_a2dp_codec_ie peer_sbc_capabilities; @@ -523,12 +523,22 @@ static struct bt_a2dp_cb a2dp_cb = { #endif }; +static int check_cb_registration(const struct shell *sh) +{ + if (!a2dp_cb_registered) { + shell_print(sh, "need to register a2dp connection callbacks"); + return -EIO; + } + + return 0; +} + static int cmd_register_cb(const struct shell *sh, int32_t argc, char *argv[]) { int err = -1; - if (a2dp_initied == 0) { - a2dp_initied = 1; + if (!a2dp_cb_registered) { + a2dp_cb_registered = true; err = bt_a2dp_register_cb(&a2dp_cb); if (!err) { @@ -549,8 +559,7 @@ static int cmd_register_ep(const struct shell *sh, int32_t argc, char *argv[]) const char *type; const char *action; - if (a2dp_initied == 0) { - shell_print(sh, "need to register a2dp connection callbacks"); + if (check_cb_registration(sh) != 0) { return -ENOEXEC; } @@ -597,8 +606,7 @@ static int cmd_register_ep(const struct shell *sh, int32_t argc, char *argv[]) static int cmd_connect(const struct shell *sh, int32_t argc, char *argv[]) { - if (a2dp_initied == 0) { - shell_print(sh, "need to register a2dp connection callbacks"); + if (check_cb_registration(sh) != 0) { return -ENOEXEC; } @@ -616,8 +624,7 @@ static int cmd_connect(const struct shell *sh, int32_t argc, char *argv[]) static int cmd_disconnect(const struct shell *sh, int32_t argc, char *argv[]) { - if (a2dp_initied == 0) { - shell_print(sh, "need to register a2dp connection callbacks"); + if (check_cb_registration(sh) != 0) { return -ENOEXEC; } @@ -650,8 +657,7 @@ static int cmd_configure(const struct shell *sh, int32_t argc, char *argv[]) { int err; - if (a2dp_initied == 0) { - shell_print(sh, "need to register a2dp connection callbacks"); + if (check_cb_registration(sh) != 0) { return -ENOEXEC; } @@ -682,8 +688,7 @@ static int cmd_configure(const struct shell *sh, int32_t argc, char *argv[]) static int cmd_reconfigure(const struct shell *sh, int32_t argc, char *argv[]) { - if (a2dp_initied == 0) { - shell_print(sh, "need to register a2dp connection callbacks"); + if (check_cb_registration(sh) != 0) { return -ENOEXEC; } @@ -720,8 +725,7 @@ static int cmd_get_peer_eps(const struct shell *sh, int32_t argc, char *argv[]) { int err = 0; - if (a2dp_initied == 0) { - shell_print(sh, "need to register a2dp connection callbacks"); + if (check_cb_registration(sh) != 0) { return -ENOEXEC; } @@ -746,8 +750,7 @@ static int cmd_get_peer_eps(const struct shell *sh, int32_t argc, char *argv[]) static int cmd_establish(const struct shell *sh, int32_t argc, char *argv[]) { - if (a2dp_initied == 0) { - shell_print(sh, "need to register a2dp connection callbacks"); + if (check_cb_registration(sh) != 0) { return -ENOEXEC; } @@ -759,8 +762,7 @@ static int cmd_establish(const struct shell *sh, int32_t argc, char *argv[]) static int cmd_release(const struct shell *sh, int32_t argc, char *argv[]) { - if (a2dp_initied == 0) { - shell_print(sh, "need to register a2dp connection callbacks"); + if (check_cb_registration(sh) != 0) { return -ENOEXEC; } @@ -772,8 +774,7 @@ static int cmd_release(const struct shell *sh, int32_t argc, char *argv[]) static int cmd_start(const struct shell *sh, int32_t argc, char *argv[]) { - if (a2dp_initied == 0) { - shell_print(sh, "need to register a2dp connection callbacks"); + if (check_cb_registration(sh) != 0) { return -ENOEXEC; } @@ -785,8 +786,7 @@ static int cmd_start(const struct shell *sh, int32_t argc, char *argv[]) static int cmd_suspend(const struct shell *sh, int32_t argc, char *argv[]) { - if (a2dp_initied == 0) { - shell_print(sh, "need to register a2dp connection callbacks"); + if (check_cb_registration(sh) != 0) { return -ENOEXEC; } @@ -798,8 +798,7 @@ static int cmd_suspend(const struct shell *sh, int32_t argc, char *argv[]) static int cmd_abort(const struct shell *sh, int32_t argc, char *argv[]) { - if (a2dp_initied == 0) { - shell_print(sh, "need to register a2dp connection callbacks"); + if (check_cb_registration(sh) != 0) { return -ENOEXEC; } @@ -815,8 +814,7 @@ static int cmd_send_media(const struct shell *sh, int32_t argc, char *argv[]) struct net_buf *buf; int ret; - if (a2dp_initied == 0) { - shell_print(sh, "need to register a2dp connection callbacks"); + if (check_cb_registration(sh) != 0) { return -ENOEXEC; } @@ -847,8 +845,7 @@ static int cmd_send_delay_report(const struct shell *sh, int32_t argc, char *arg { int err; - if (a2dp_initied == 0) { - shell_print(sh, "need to register a2dp connection callbacks"); + if (check_cb_registration(sh) != 0) { return -ENOEXEC; } @@ -863,8 +860,7 @@ static int cmd_send_delay_report(const struct shell *sh, int32_t argc, char *arg static int cmd_get_config(const struct shell *sh, int32_t argc, char *argv[]) { - if (a2dp_initied == 0) { - shell_print(sh, "need to register a2dp connection callbacks"); + if (check_cb_registration(sh) != 0) { return -ENOEXEC; } From 6f0b31c7091b3b203d27241f3eaa4903a9add1ff Mon Sep 17 00:00:00 2001 From: Mark Wang Date: Tue, 18 Nov 2025 15:50:32 +0800 Subject: [PATCH 0090/6328] bluetooth: shell: a2dp: improve a2dp shell cmds add abort req and rsp callbacks, improve register_ep cmd to support delay report, check buf tailroom for sending media, add get_conn cmd to test bt_a2dp_get_conn. Signed-off-by: Mark Wang --- subsys/bluetooth/host/classic/shell/a2dp.c | 73 +++++++++++++++++++++- 1 file changed, 70 insertions(+), 3 deletions(-) diff --git a/subsys/bluetooth/host/classic/shell/a2dp.c b/subsys/bluetooth/host/classic/shell/a2dp.c index e4d105a66f45..7d34e7b660c4 100644 --- a/subsys/bluetooth/host/classic/shell/a2dp.c +++ b/subsys/bluetooth/host/classic/shell/a2dp.c @@ -499,6 +499,22 @@ static void app_get_config_rsp(struct bt_a2dp_stream *stream, struct bt_a2dp_cod } } +static int app_abort_req(struct bt_a2dp_stream *stream, uint8_t *rsp_err_code) +{ + *rsp_err_code = 0; + bt_shell_print("receive requesting abort and accept"); + return 0; +} + +static void app_abort_rsp(struct bt_a2dp_stream *stream, uint8_t rsp_err_code) +{ + if (rsp_err_code == 0) { + bt_shell_print("success to abort"); + } else { + bt_shell_error("fail to abort"); + } +} + static struct bt_a2dp_cb a2dp_cb = { .connected = app_connected, .disconnected = app_disconnected, @@ -515,6 +531,8 @@ static struct bt_a2dp_cb a2dp_cb = { .reconfig_req = app_reconfig_req, .get_config_req = app_get_config_req, .get_config_rsp = app_get_config_rsp, + .abort_req = app_abort_req, + .abort_rsp = app_abort_rsp, #if defined(CONFIG_BT_A2DP_SOURCE) .delay_report_req = app_delay_report_req, #endif @@ -558,11 +576,24 @@ static int cmd_register_ep(const struct shell *sh, int32_t argc, char *argv[]) int err = -1; const char *type; const char *action; + bool delay_report; + bool set_delay_report = false; if (check_cb_registration(sh) != 0) { return -ENOEXEC; } + /* configure delay report */ + if (argc == 4) { + set_delay_report = true; + err = 0; + delay_report = shell_strtobool(argv[3], 10, &err); + if (err != 0) { + shell_help(sh); + return SHELL_CMD_HELP_PRINTED; + } + } + type = argv[1]; action = argv[2]; if (!strcmp(action, "sbc")) { @@ -571,6 +602,11 @@ static int cmd_register_ep(const struct shell *sh, int32_t argc, char *argv[]) a2dp_sink_sdp_registered = 1; bt_sdp_register_service(&a2dp_sink_rec); } + + if (set_delay_report) { + sink_sbc_endpoint.delay_report = delay_report; + } + err = bt_a2dp_register_ep(&sink_sbc_endpoint, BT_AVDTP_AUDIO, BT_AVDTP_SINK); if (!err) { @@ -582,6 +618,11 @@ static int cmd_register_ep(const struct shell *sh, int32_t argc, char *argv[]) a2dp_source_sdp_registered = 1; bt_sdp_register_service(&a2dp_source_rec); } + + if (set_delay_report) { + source_sbc_endpoint.delay_report = delay_report; + } + err = bt_a2dp_register_ep(&source_sbc_endpoint, BT_AVDTP_AUDIO, BT_AVDTP_SOURCE); if (!err) { @@ -813,6 +854,7 @@ static int cmd_send_media(const struct shell *sh, int32_t argc, char *argv[]) #if defined(CONFIG_BT_A2DP_SOURCE) struct net_buf *buf; int ret; + size_t data_len; if (check_cb_registration(sh) != 0) { return -ENOEXEC; @@ -824,9 +866,13 @@ static int cmd_send_media(const struct shell *sh, int32_t argc, char *argv[]) return -ENOEXEC; } + __ASSERT_NO_MSG(net_buf_tailroom(buf) >= sizeof(uint8_t)); /* num of frames is 1 */ net_buf_add_u8(buf, (uint8_t)BT_A2DP_SBC_MEDIA_HDR_ENCODE(1, 0, 0, 0)); - net_buf_add_mem(buf, media_data, sizeof(media_data)); + + data_len = min(min(sizeof(media_data), bt_a2dp_get_mtu(&sbc_stream)), + net_buf_tailroom(buf)); + net_buf_add_mem(buf, media_data, data_len); shell_print(sh, "num of frames: %d, data length: %d", 1U, sizeof(media_data)); shell_print(sh, "data: %d, %d, %d, %d, %d, %d ......", media_data[0], media_data[1], media_data[2], media_data[3], media_data[4], media_data[5]); @@ -870,13 +916,33 @@ static int cmd_get_config(const struct shell *sh, int32_t argc, char *argv[]) return 0; } +static int cmd_get_conn(const struct shell *sh, int32_t argc, char *argv[]) +{ + struct bt_conn *conn; + + if (check_cb_registration(sh) != 0) { + return -ENOEXEC; + } + + conn = bt_a2dp_get_conn(default_a2dp); + if (conn != NULL) { + shell_print(sh, "a2dp conn is: %p", conn); + bt_conn_unref(conn); + } else { + shell_print(sh, "a2dp conn is: NULL"); + } + + return 0; +} + #define HELP_NONE "[none]" SHELL_STATIC_SUBCMD_SET_CREATE(a2dp_cmds, SHELL_CMD_ARG(register_cb, NULL, "register a2dp connection callbacks", cmd_register_cb, 1, 0), - SHELL_CMD_ARG(register_ep, NULL, " ", - cmd_register_ep, 3, 0), + SHELL_CMD_ARG(register_ep, NULL, + " [delay report: true or false]", + cmd_register_ep, 3, 1), SHELL_CMD_ARG(connect, NULL, HELP_NONE, cmd_connect, 1, 0), SHELL_CMD_ARG(disconnect, NULL, HELP_NONE, cmd_disconnect, 1, 0), SHELL_CMD_ARG(discover_peer_eps, NULL, "", cmd_get_peer_eps, 2, 0), @@ -892,6 +958,7 @@ SHELL_STATIC_SUBCMD_SET_CREATE(a2dp_cmds, SHELL_CMD_ARG(send_delay_report, NULL, HELP_NONE, cmd_send_delay_report, 1, 0), #endif SHELL_CMD_ARG(get_config, NULL, HELP_NONE, cmd_get_config, 1, 0), + SHELL_CMD_ARG(get_conn, NULL, HELP_NONE, cmd_get_conn, 1, 0), SHELL_SUBCMD_SET_END ); From 37a048abefb59a1d8ebf757b7607781c9d331045 Mon Sep 17 00:00:00 2001 From: Mark Wang Date: Tue, 18 Nov 2025 15:52:45 +0800 Subject: [PATCH 0091/6328] doc: Bluetooth: shell: improve a2dp shell doc describe all the a2dp shell cmds. Signed-off-by: Mark Wang --- .../bluetooth/shell/classic/a2dp.rst | 163 ++++++++++++++---- 1 file changed, 133 insertions(+), 30 deletions(-) diff --git a/doc/connectivity/bluetooth/shell/classic/a2dp.rst b/doc/connectivity/bluetooth/shell/classic/a2dp.rst index 503214445ce7..48b1053487f5 100644 --- a/doc/connectivity/bluetooth/shell/classic/a2dp.rst +++ b/doc/connectivity/bluetooth/shell/classic/a2dp.rst @@ -5,33 +5,80 @@ The :code:`a2dp` command exposes parts of the A2DP API. The following examples assume that you have two devices already connected. -Here is a example connecting two devices: - * Source and Sink sides register a2dp callbacks. using :code:`a2dp register_cb`. - * Source and Sink sides register stream endpoints. using :code:`a2dp register_ep source sbc` and :code:`a2dp register_ep sink sbc`. - * Source establish A2dp connection. It will create the AVDTP Signaling and Media L2CAP channels. using :code:`a2dp connect`. - * Source and Sink side can discover remote device's stream endpoints. using :code:`a2dp discover_peer_eps` - * Source or Sink configure the stream to create the stream after discover remote's endpoints. using :code:`a2dp configure`. - * Source or Sink establish the stream. using :code:`a2dp establish`. - * Source or Sink start the media. using :code:`a2dp start`. - * Source test the media sending. using :code:`a2dp send_media` to send one test packet data. - * Source or Sink suspend the media. using :code:`a2dp suspend`. - * Source or Sink release the media. using :code:`a2dp release`. +.. _a2dp_conn_disconn: + +A2DP Connection +*************** + +Demonstrate the flow of creating an A2DP connection: + +* Both sides register A2DP callbacks using :code:`a2dp register_cb`. +* Either side establishes an A2DP connection, which will create the AVDTP Signaling channel, using :code:`a2dp connect`. +* Either side can get the ACL connection using :code:`a2dp get_conn`. +* Either side can disconnect the A2DP connection using :code:`a2dp disconnect`. .. tabs:: - .. group-tab:: Device A (Audio Source Side) + .. group-tab:: Device A (initiator) .. code-block:: console uart:~$ a2dp register_cb success - uart:~$ a2dp register_ep source sbc - SBC source endpoint is registered uart:~$ a2dp connect Bonded with XX:XX:XX:XX:XX:XX Security changed: XX:XX:XX:XX:XX:XX level 2 a2dp connected - uart:~$ a2dp discover_peer_eps + uart:~$ a2dp get_conn + a2dp conn is: 0xXXXXXXXX + uart:~$ a2dp disconnect + a2dp disconnected + + .. group-tab:: Device B (acceptor) + + .. code-block:: console + + uart:~$ a2dp register_cb + success + + Connected: XX:XX:XX:XX:XX:XX + Bonded with XX:XX:XX:XX:XX:XX + Security changed: XX:XX:XX:XX:XX:XX level 2 + a2dp connected + + a2dp disconnected + +.. _a2dp_basic_operations: + +Basic A2DP Operations +********************* + +Demonstrate the flow of basic A2DP operations: + +* Source and Sink sides register stream endpoints using :code:`a2dp register_ep source sbc` and :code:`a2dp register_ep sink sbc`. +* Create an A2DP connection based on :ref:`a2dp connection `. +* Initiator discovers remote device's stream endpoints using :code:`a2dp discover_peer_eps 0x0104`. +* Initiator configures the stream to create the stream after discovering remote endpoints using :code:`a2dp configure`. +* Initiator establishes the stream using :code:`a2dp establish`. +* Sink sends delay report using :code:`a2dp send_delay_report`. +* Initiator starts the media using :code:`a2dp start`. +* Source tests media sending using :code:`a2dp send_media` to send one test packet data. +* Initiator suspends the media using :code:`a2dp suspend`. +* Initiator releases the media using :code:`a2dp release`. + +.. note:: + The initiator is the A2DP source role and the acceptor is the A2DP sink role in the following logs. + The delay report can only be sent by the sink role. The media data can only be sent by the source role. + +.. tabs:: + + .. group-tab:: Device A (initiator) + + .. code-block:: console + + uart:~$ a2dp register_ep source sbc + SBC source endpoint is registered + uart:~$ a2dp discover_peer_eps 0x0104 endpoint id: 1, (sink), (idle): codec type: SBC sample frequency: @@ -54,6 +101,9 @@ Here is a example connecting two devices: uart:~$ a2dp establish success to establish stream established + + receive delay report and accept + received delay report: 1 1/10ms uart:~$ a2dp start success to start stream started @@ -67,36 +117,89 @@ Here is a example connecting two devices: success to release stream released - .. group-tab:: Device B (Audio Sink Side) + .. group-tab:: Device B (acceptor) .. code-block:: console - uart:~$ a2dp register_cb - success uart:~$ a2dp register_ep sink sbc SBC sink endpoint is registered - - Connected: XX:XX:XX:XX:XX:XX - Bonded with XX:XX:XX:XX:XX:XX - Security changed: XX:XX:XX:XX:XX:XX level 2 - a2dp connected - + receive requesting config and accept sample rate 44100Hz stream configured - + receive requesting establishment and accept stream established - + uart:~$ a2dp send_delay_report + success to send report delay + receive requesting start and accept stream started - + received, num of frames: 1, data length: 160 data: 1, 2, 3, 4, 5, 6 ...... - + receive requesting suspend and accept stream suspended - + receive requesting release and accept stream released - ... + +Abort Operation +*************** + +Demonstrate the abort operation: + +* Establish an A2DP stream based on :ref:`basic a2dp operations `. +* Initiator aborts the stream using :code:`a2dp abort`. + +.. tabs:: + + .. group-tab:: Device A (initiator) + + .. code-block:: console + + uart:~$ a2dp abort + success to abort + stream released + + .. group-tab:: Device B (acceptor) + + .. code-block:: console + + + receive requesting abort and accept + stream released + +Get Configuration and Reconfigure Operation +******************************************** + +Demonstrate the get configuration and reconfigure operations: + +* Establish an A2DP stream based on :ref:`basic a2dp operations `. +* Initiator gets configuration using :code:`a2dp get_config`. +* Initiator reconfigures the stream using :code:`a2dp reconfigure`. + +.. tabs:: + + .. group-tab:: Device A (initiator) + + .. code-block:: console + + uart:~$ a2dp get_config + get config result: 0 + sample rate 44100Hz + uart:~$ a2dp reconfigure + success to configure + stream configured + + .. group-tab:: Device B (acceptor) + + .. code-block:: console + + + receive get config request and accept + + receive requesting reconfig and accept + sample rate 44100Hz + stream configured From 36ab1ba154d5483b555fca935a5269b360dddb80 Mon Sep 17 00:00:00 2001 From: Mark Wang Date: Wed, 19 Nov 2025 14:45:51 +0800 Subject: [PATCH 0092/6328] Bluetooth: shell: a2dp: Update a2dp sdp profile version The newest a2dp spec set the profile version as 1.4. Signed-off-by: Mark Wang --- subsys/bluetooth/host/classic/shell/a2dp.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/subsys/bluetooth/host/classic/shell/a2dp.c b/subsys/bluetooth/host/classic/shell/a2dp.c index 7d34e7b660c4..2fae78c61896 100644 --- a/subsys/bluetooth/host/classic/shell/a2dp.c +++ b/subsys/bluetooth/host/classic/shell/a2dp.c @@ -61,6 +61,8 @@ NET_BUF_POOL_DEFINE(a2dp_tx_pool, CONFIG_BT_MAX_CONN, BT_L2CAP_BUF_SIZE(CONFIG_BT_L2CAP_TX_MTU), CONFIG_BT_CONN_TX_USER_DATA_SIZE, NULL); +#define A2DP_VERSION 0x0104U + static struct bt_sdp_attribute a2dp_sink_attrs[] = { BT_SDP_NEW_SERVICE, BT_SDP_LIST( @@ -118,7 +120,7 @@ static struct bt_sdp_attribute a2dp_sink_attrs[] = { }, { BT_SDP_TYPE_SIZE(BT_SDP_UINT16), /* 09 */ - BT_SDP_ARRAY_16(0x0103U) /* 01 03 */ + BT_SDP_ARRAY_16(A2DP_VERSION) /* 01 04 */ }, ) }, @@ -187,7 +189,7 @@ static struct bt_sdp_attribute a2dp_source_attrs[] = { }, { BT_SDP_TYPE_SIZE(BT_SDP_UINT16), - BT_SDP_ARRAY_16(0x0103U) + BT_SDP_ARRAY_16(A2DP_VERSION) }, ) }, From 313478b026c176ceb497ab0d6801bc34d0bec015 Mon Sep 17 00:00:00 2001 From: Mark Wang Date: Mon, 15 Dec 2025 17:09:43 +0800 Subject: [PATCH 0093/6328] bluetooth: shell: a2dp: use bt_shell_xxx instead of shell_xxx Replace all shell_print() and shell_error() calls with bt_shell_print() and bt_shell_error() respectively to use the common Bluetooth shell printing functions throughout the A2DP shell implementation. Signed-off-by: Mark Wang --- subsys/bluetooth/host/classic/shell/a2dp.c | 62 +++++++++++----------- 1 file changed, 31 insertions(+), 31 deletions(-) diff --git a/subsys/bluetooth/host/classic/shell/a2dp.c b/subsys/bluetooth/host/classic/shell/a2dp.c index 2fae78c61896..5f7133aec0d3 100644 --- a/subsys/bluetooth/host/classic/shell/a2dp.c +++ b/subsys/bluetooth/host/classic/shell/a2dp.c @@ -546,7 +546,7 @@ static struct bt_a2dp_cb a2dp_cb = { static int check_cb_registration(const struct shell *sh) { if (!a2dp_cb_registered) { - shell_print(sh, "need to register a2dp connection callbacks"); + bt_shell_print("need to register a2dp connection callbacks"); return -EIO; } @@ -562,12 +562,12 @@ static int cmd_register_cb(const struct shell *sh, int32_t argc, char *argv[]) err = bt_a2dp_register_cb(&a2dp_cb); if (!err) { - shell_print(sh, "success"); + bt_shell_print("success"); } else { - shell_print(sh, "fail"); + bt_shell_print("fail"); } } else { - shell_print(sh, "already registered"); + bt_shell_print("already registered"); } return 0; @@ -612,7 +612,7 @@ static int cmd_register_ep(const struct shell *sh, int32_t argc, char *argv[]) err = bt_a2dp_register_ep(&sink_sbc_endpoint, BT_AVDTP_AUDIO, BT_AVDTP_SINK); if (!err) { - shell_print(sh, "SBC sink endpoint is registered"); + bt_shell_print("SBC sink endpoint is registered"); registered_sbc_endpoint = &sink_sbc_endpoint; } } else if (!strcmp(type, "source")) { @@ -628,7 +628,7 @@ static int cmd_register_ep(const struct shell *sh, int32_t argc, char *argv[]) err = bt_a2dp_register_ep(&source_sbc_endpoint, BT_AVDTP_AUDIO, BT_AVDTP_SOURCE); if (!err) { - shell_print(sh, "SBC source endpoint is registered"); + bt_shell_print("SBC source endpoint is registered"); registered_sbc_endpoint = &source_sbc_endpoint; } } else { @@ -641,7 +641,7 @@ static int cmd_register_ep(const struct shell *sh, int32_t argc, char *argv[]) } if (err) { - shell_print(sh, "fail to register endpoint"); + bt_shell_print("fail to register endpoint"); } return 0; @@ -654,13 +654,13 @@ static int cmd_connect(const struct shell *sh, int32_t argc, char *argv[]) } if (!default_conn) { - shell_error(sh, "Not connected"); + bt_shell_error("Not connected"); return -ENOEXEC; } default_a2dp = bt_a2dp_connect(default_conn); if (NULL == default_a2dp) { - shell_error(sh, "fail to connect a2dp"); + bt_shell_error("fail to connect a2dp"); } return 0; } @@ -675,7 +675,7 @@ static int cmd_disconnect(const struct shell *sh, int32_t argc, char *argv[]) bt_a2dp_disconnect(default_a2dp); default_a2dp = NULL; } else { - shell_error(sh, "a2dp is not connected"); + bt_shell_error("a2dp is not connected"); } return 0; } @@ -706,12 +706,12 @@ static int cmd_configure(const struct shell *sh, int32_t argc, char *argv[]) if (default_a2dp != NULL) { if (registered_sbc_endpoint == NULL) { - shell_error(sh, "no endpoint"); + bt_shell_error("no endpoint"); return 0; } if (found_peer_sbc_endpoint == NULL) { - shell_error(sh, "don't find the peer sbc endpoint"); + bt_shell_error("don't find the peer sbc endpoint"); return 0; } @@ -721,10 +721,10 @@ static int cmd_configure(const struct shell *sh, int32_t argc, char *argv[]) registered_sbc_endpoint, found_peer_sbc_endpoint, &sbc_cfg_default); if (err) { - shell_error(sh, "fail to configure"); + bt_shell_error("fail to configure"); } } else { - shell_error(sh, "a2dp is not connected"); + bt_shell_error("a2dp is not connected"); } return 0; } @@ -736,7 +736,7 @@ static int cmd_reconfigure(const struct shell *sh, int32_t argc, char *argv[]) } if (bt_a2dp_stream_reconfig(&sbc_stream, &sbc_cfg_default) != 0) { - shell_print(sh, "fail"); + bt_shell_print("fail"); } return 0; } @@ -775,7 +775,7 @@ static int cmd_get_peer_eps(const struct shell *sh, int32_t argc, char *argv[]) if (default_a2dp != NULL) { discover_param.avdtp_version = (uint16_t)shell_strtoul(argv[1], 0, &err); if (err != 0) { - shell_error(sh, "failed to parse avdtp version: %d", err); + bt_shell_error("failed to parse avdtp version: %d", err); return -ENOEXEC; } @@ -783,10 +783,10 @@ static int cmd_get_peer_eps(const struct shell *sh, int32_t argc, char *argv[]) err = bt_a2dp_discover(default_a2dp, &discover_param); if (err) { - shell_error(sh, "discover fail"); + bt_shell_error("discover fail"); } } else { - shell_error(sh, "a2dp is not connected"); + bt_shell_error("a2dp is not connected"); } return 0; } @@ -798,7 +798,7 @@ static int cmd_establish(const struct shell *sh, int32_t argc, char *argv[]) } if (bt_a2dp_stream_establish(&sbc_stream) != 0) { - shell_print(sh, "fail"); + bt_shell_print("fail"); } return 0; } @@ -810,7 +810,7 @@ static int cmd_release(const struct shell *sh, int32_t argc, char *argv[]) } if (bt_a2dp_stream_release(&sbc_stream) != 0) { - shell_print(sh, "fail"); + bt_shell_print("fail"); } return 0; } @@ -822,7 +822,7 @@ static int cmd_start(const struct shell *sh, int32_t argc, char *argv[]) } if (bt_a2dp_stream_start(&sbc_stream) != 0) { - shell_print(sh, "fail"); + bt_shell_print("fail"); } return 0; } @@ -834,7 +834,7 @@ static int cmd_suspend(const struct shell *sh, int32_t argc, char *argv[]) } if (bt_a2dp_stream_suspend(&sbc_stream) != 0) { - shell_print(sh, "fail"); + bt_shell_print("fail"); } return 0; } @@ -846,7 +846,7 @@ static int cmd_abort(const struct shell *sh, int32_t argc, char *argv[]) } if (bt_a2dp_stream_abort(&sbc_stream) != 0) { - shell_print(sh, "fail"); + bt_shell_print("fail"); } return 0; } @@ -864,7 +864,7 @@ static int cmd_send_media(const struct shell *sh, int32_t argc, char *argv[]) buf = bt_a2dp_stream_create_pdu(&a2dp_tx_pool, K_FOREVER); if (buf == NULL) { - shell_error(sh, "fail to allocate buffer"); + bt_shell_error("fail to allocate buffer"); return -ENOEXEC; } @@ -875,8 +875,8 @@ static int cmd_send_media(const struct shell *sh, int32_t argc, char *argv[]) data_len = min(min(sizeof(media_data), bt_a2dp_get_mtu(&sbc_stream)), net_buf_tailroom(buf)); net_buf_add_mem(buf, media_data, data_len); - shell_print(sh, "num of frames: %d, data length: %d", 1U, sizeof(media_data)); - shell_print(sh, "data: %d, %d, %d, %d, %d, %d ......", media_data[0], + bt_shell_print("num of frames: %d, data length: %d", 1U, sizeof(media_data)); + bt_shell_print("data: %d, %d, %d, %d, %d, %d ......", media_data[0], media_data[1], media_data[2], media_data[3], media_data[4], media_data[5]); ret = bt_a2dp_stream_send(&sbc_stream, buf, 0U, 0U); @@ -899,7 +899,7 @@ static int cmd_send_delay_report(const struct shell *sh, int32_t argc, char *arg err = bt_a2dp_stream_delay_report(&sbc_stream, 1); if (err < 0) { - shell_print(sh, "fail to send delay report (%d)\n", err); + bt_shell_print("fail to send delay report (%d)\n", err); } return 0; @@ -913,7 +913,7 @@ static int cmd_get_config(const struct shell *sh, int32_t argc, char *argv[]) } if (bt_a2dp_stream_get_config(&sbc_stream) != 0) { - shell_error(sh, "fail"); + bt_shell_error("fail"); } return 0; } @@ -928,10 +928,10 @@ static int cmd_get_conn(const struct shell *sh, int32_t argc, char *argv[]) conn = bt_a2dp_get_conn(default_a2dp); if (conn != NULL) { - shell_print(sh, "a2dp conn is: %p", conn); + bt_shell_print("a2dp conn is: %p", conn); bt_conn_unref(conn); } else { - shell_print(sh, "a2dp conn is: NULL"); + bt_shell_print("a2dp conn is: NULL"); } return 0; @@ -972,7 +972,7 @@ static int cmd_a2dp(const struct shell *sh, size_t argc, char **argv) return 1; } - shell_error(sh, "%s unknown parameter: %s", argv[0], argv[1]); + bt_shell_error("%s unknown parameter: %s", argv[0], argv[1]); return -ENOEXEC; } From d8eb0ce5f4642394836cc28ccfe1116e772c3aa3 Mon Sep 17 00:00:00 2001 From: Mark Wang Date: Mon, 15 Dec 2025 17:15:51 +0800 Subject: [PATCH 0094/6328] bluetooth: shell: a2dp: use bt_shell_error for error messages Replace bt_shell_print() calls with bt_shell_error() for all error conditions and failure cases in the A2DP shell implementation to properly distinguish error messages from informational output. Signed-off-by: Mark Wang --- subsys/bluetooth/host/classic/shell/a2dp.c | 42 +++++++++++----------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/subsys/bluetooth/host/classic/shell/a2dp.c b/subsys/bluetooth/host/classic/shell/a2dp.c index 5f7133aec0d3..2dda7af9969c 100644 --- a/subsys/bluetooth/host/classic/shell/a2dp.c +++ b/subsys/bluetooth/host/classic/shell/a2dp.c @@ -295,7 +295,7 @@ static void app_connected(struct bt_a2dp *a2dp, int err) default_a2dp = a2dp; bt_shell_print("a2dp connected"); } else { - bt_shell_print("a2dp connecting fail"); + bt_shell_error("a2dp connecting fail"); } } @@ -342,7 +342,7 @@ static void app_config_rsp(struct bt_a2dp_stream *stream, uint8_t rsp_err_code) if (rsp_err_code == 0) { bt_shell_print("success to configure"); } else { - bt_shell_print("fail to configure"); + bt_shell_error("fail to configure"); } } @@ -358,7 +358,7 @@ static void app_establish_rsp(struct bt_a2dp_stream *stream, uint8_t rsp_err_cod if (rsp_err_code == 0) { bt_shell_print("success to establish"); } else { - bt_shell_print("fail to establish"); + bt_shell_error("fail to establish"); } } @@ -374,7 +374,7 @@ static void app_release_rsp(struct bt_a2dp_stream *stream, uint8_t rsp_err_code) if (rsp_err_code == 0) { bt_shell_print("success to release"); } else { - bt_shell_print("fail to release"); + bt_shell_error("fail to release"); } } @@ -390,7 +390,7 @@ static void app_start_rsp(struct bt_a2dp_stream *stream, uint8_t rsp_err_code) if (rsp_err_code == 0) { bt_shell_print("success to start"); } else { - bt_shell_print("fail to start"); + bt_shell_error("fail to start"); } } @@ -406,7 +406,7 @@ static void app_suspend_rsp(struct bt_a2dp_stream *stream, uint8_t rsp_err_code) if (rsp_err_code == 0) { bt_shell_print("success to suspend"); } else { - bt_shell_print("fail to suspend"); + bt_shell_error("fail to suspend"); } } @@ -462,7 +462,7 @@ static void app_delay_report_rsp(struct bt_a2dp_stream *stream, uint8_t rsp_err_ if (rsp_err_code == 0) { bt_shell_print("success to send report delay"); } else { - bt_shell_print("fail to send report delay"); + bt_shell_error("fail to send report delay"); } } #endif @@ -546,8 +546,8 @@ static struct bt_a2dp_cb a2dp_cb = { static int check_cb_registration(const struct shell *sh) { if (!a2dp_cb_registered) { - bt_shell_print("need to register a2dp connection callbacks"); - return -EIO; + bt_shell_error("need to register a2dp connection callbacks"); + return -ENOENT; } return 0; @@ -564,10 +564,10 @@ static int cmd_register_cb(const struct shell *sh, int32_t argc, char *argv[]) if (!err) { bt_shell_print("success"); } else { - bt_shell_print("fail"); + bt_shell_error("fail"); } } else { - bt_shell_print("already registered"); + bt_shell_error("already registered"); } return 0; @@ -641,7 +641,7 @@ static int cmd_register_ep(const struct shell *sh, int32_t argc, char *argv[]) } if (err) { - bt_shell_print("fail to register endpoint"); + bt_shell_error("fail to register endpoint"); } return 0; @@ -736,7 +736,7 @@ static int cmd_reconfigure(const struct shell *sh, int32_t argc, char *argv[]) } if (bt_a2dp_stream_reconfig(&sbc_stream, &sbc_cfg_default) != 0) { - bt_shell_print("fail"); + bt_shell_error("fail"); } return 0; } @@ -798,7 +798,7 @@ static int cmd_establish(const struct shell *sh, int32_t argc, char *argv[]) } if (bt_a2dp_stream_establish(&sbc_stream) != 0) { - bt_shell_print("fail"); + bt_shell_error("fail"); } return 0; } @@ -810,7 +810,7 @@ static int cmd_release(const struct shell *sh, int32_t argc, char *argv[]) } if (bt_a2dp_stream_release(&sbc_stream) != 0) { - bt_shell_print("fail"); + bt_shell_error("fail"); } return 0; } @@ -822,7 +822,7 @@ static int cmd_start(const struct shell *sh, int32_t argc, char *argv[]) } if (bt_a2dp_stream_start(&sbc_stream) != 0) { - bt_shell_print("fail"); + bt_shell_error("fail"); } return 0; } @@ -834,7 +834,7 @@ static int cmd_suspend(const struct shell *sh, int32_t argc, char *argv[]) } if (bt_a2dp_stream_suspend(&sbc_stream) != 0) { - bt_shell_print("fail"); + bt_shell_error("fail"); } return 0; } @@ -846,7 +846,7 @@ static int cmd_abort(const struct shell *sh, int32_t argc, char *argv[]) } if (bt_a2dp_stream_abort(&sbc_stream) != 0) { - bt_shell_print("fail"); + bt_shell_error("fail"); } return 0; } @@ -881,7 +881,7 @@ static int cmd_send_media(const struct shell *sh, int32_t argc, char *argv[]) ret = bt_a2dp_stream_send(&sbc_stream, buf, 0U, 0U); if (ret < 0) { - printk(" Failed to send SBC audio data on streams(%d)\n", ret); + bt_shell_error(" Failed to send SBC audio data on streams(%d)\n", ret); net_buf_unref(buf); } #endif @@ -899,7 +899,7 @@ static int cmd_send_delay_report(const struct shell *sh, int32_t argc, char *arg err = bt_a2dp_stream_delay_report(&sbc_stream, 1); if (err < 0) { - bt_shell_print("fail to send delay report (%d)\n", err); + bt_shell_error("fail to send delay report (%d)\n", err); } return 0; @@ -931,7 +931,7 @@ static int cmd_get_conn(const struct shell *sh, int32_t argc, char *argv[]) bt_shell_print("a2dp conn is: %p", conn); bt_conn_unref(conn); } else { - bt_shell_print("a2dp conn is: NULL"); + bt_shell_error("a2dp conn is: NULL"); } return 0; From f66ce9c251f93e12c1dde70cda22274a2867eba8 Mon Sep 17 00:00:00 2001 From: Mark Wang Date: Wed, 17 Dec 2025 13:40:18 +0800 Subject: [PATCH 0095/6328] bluetooth: shell: a2dp: include error code in failure messages Add error code parameter to all A2DP shell error messages to provide more detailed diagnostic information when operations fail. This applies to configure, establish, release, start, suspend, delay report, and abort response handlers. Signed-off-by: Mark Wang --- subsys/bluetooth/host/classic/shell/a2dp.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/subsys/bluetooth/host/classic/shell/a2dp.c b/subsys/bluetooth/host/classic/shell/a2dp.c index 2dda7af9969c..3e504926a338 100644 --- a/subsys/bluetooth/host/classic/shell/a2dp.c +++ b/subsys/bluetooth/host/classic/shell/a2dp.c @@ -342,7 +342,7 @@ static void app_config_rsp(struct bt_a2dp_stream *stream, uint8_t rsp_err_code) if (rsp_err_code == 0) { bt_shell_print("success to configure"); } else { - bt_shell_error("fail to configure"); + bt_shell_error("fail to configure (err code %u)", rsp_err_code); } } @@ -358,7 +358,7 @@ static void app_establish_rsp(struct bt_a2dp_stream *stream, uint8_t rsp_err_cod if (rsp_err_code == 0) { bt_shell_print("success to establish"); } else { - bt_shell_error("fail to establish"); + bt_shell_error("fail to establish (err code %u)", rsp_err_code); } } @@ -374,7 +374,7 @@ static void app_release_rsp(struct bt_a2dp_stream *stream, uint8_t rsp_err_code) if (rsp_err_code == 0) { bt_shell_print("success to release"); } else { - bt_shell_error("fail to release"); + bt_shell_error("fail to release (err code %u)", rsp_err_code); } } @@ -390,7 +390,7 @@ static void app_start_rsp(struct bt_a2dp_stream *stream, uint8_t rsp_err_code) if (rsp_err_code == 0) { bt_shell_print("success to start"); } else { - bt_shell_error("fail to start"); + bt_shell_error("fail to start (err code %u)", rsp_err_code); } } @@ -406,7 +406,7 @@ static void app_suspend_rsp(struct bt_a2dp_stream *stream, uint8_t rsp_err_code) if (rsp_err_code == 0) { bt_shell_print("success to suspend"); } else { - bt_shell_error("fail to suspend"); + bt_shell_error("fail to suspend (err code %u)", rsp_err_code); } } @@ -462,7 +462,7 @@ static void app_delay_report_rsp(struct bt_a2dp_stream *stream, uint8_t rsp_err_ if (rsp_err_code == 0) { bt_shell_print("success to send report delay"); } else { - bt_shell_error("fail to send report delay"); + bt_shell_error("fail to send report delay (err code %u)", rsp_err_code); } } #endif @@ -513,7 +513,7 @@ static void app_abort_rsp(struct bt_a2dp_stream *stream, uint8_t rsp_err_code) if (rsp_err_code == 0) { bt_shell_print("success to abort"); } else { - bt_shell_error("fail to abort"); + bt_shell_error("fail to abort (err code %u)", rsp_err_code); } } From 5e61c06c85fb6810d2e6923716d73e6db3d1e684 Mon Sep 17 00:00:00 2001 From: Ibrahim Abdalkader Date: Tue, 9 Dec 2025 17:25:29 +0100 Subject: [PATCH 0096/6328] drivers: i3c: Use kernel heap for allocations Use the kernel heap instead of the libc heap, improving security and consistency. Signed-off-by: Ibrahim Abdalkader --- drivers/i3c/Kconfig | 8 ++++++++ drivers/i3c/i3c_common.c | 5 +++-- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/drivers/i3c/Kconfig b/drivers/i3c/Kconfig index 3c08e726b886..a5dd8a253d1e 100644 --- a/drivers/i3c/Kconfig +++ b/drivers/i3c/Kconfig @@ -58,6 +58,14 @@ config I3C_TARGET_BUFFER_MODE help This is an option to enable buffer mode. +config HEAP_MEM_POOL_ADD_SIZE_I3C + int "Heap memory pool size for I3C" + default 48 + depends on I3C_CONTROLLER && I3C_TARGET + help + The size of the memory pool used by I3C. Used only for + DEFTGTS (Define List of Targets) CCC (Common Command Code). + menuconfig I3C_USE_IBI bool "Use In-Band Interrupt (IBI)" default y diff --git a/drivers/i3c/i3c_common.c b/drivers/i3c/i3c_common.c index ba543ec0a7a4..1a4ce9d3cc8c 100644 --- a/drivers/i3c/i3c_common.c +++ b/drivers/i3c/i3c_common.c @@ -7,6 +7,7 @@ #include #include +#include #include #include #include @@ -1327,7 +1328,7 @@ int i3c_bus_deftgts(const struct device *dev) } /* Allocate memory for the struct with enough space for the targets */ - deftgts = malloc(data_len); + deftgts = k_malloc(data_len); if (!deftgts) { return -ENOMEM; } @@ -1371,7 +1372,7 @@ int i3c_bus_deftgts(const struct device *dev) ret = i3c_ccc_do_deftgts_all(dev, deftgts); - free(deftgts); + k_free(deftgts); return ret; } From 2a432c65a2de9080e1c31d0e42c9eac47a55f379 Mon Sep 17 00:00:00 2001 From: Ibrahim Abdalkader Date: Tue, 2 Dec 2025 14:54:15 +0100 Subject: [PATCH 0097/6328] drivers: wifi: Use kernel heap for allocations Use the kernel heap instead of the libc heap, improving security and consistency. Signed-off-by: Ibrahim Abdalkader --- drivers/wifi/eswifi/eswifi_socket_offload.c | 14 +++++++------- drivers/wifi/simplelink/simplelink_sockets.c | 10 +++++----- samples/net/wifi/shell/prj.conf | 1 + tests/drivers/build_all/wifi/prj.conf | 1 + 4 files changed, 14 insertions(+), 12 deletions(-) diff --git a/drivers/wifi/eswifi/eswifi_socket_offload.c b/drivers/wifi/eswifi/eswifi_socket_offload.c index 0a527d116dd2..4cc3195f9c7b 100644 --- a/drivers/wifi/eswifi/eswifi_socket_offload.c +++ b/drivers/wifi/eswifi/eswifi_socket_offload.c @@ -701,7 +701,7 @@ static int eswifi_off_getaddrinfo(const char *node, const char *service, } /* Allocate out res (addrinfo) struct. Just one. */ - *res = calloc(1, sizeof(struct zsock_addrinfo)); + *res = k_calloc(1, sizeof(struct zsock_addrinfo)); ai = *res; if (!ai) { err = DNS_EAI_MEMORY; @@ -709,9 +709,9 @@ static int eswifi_off_getaddrinfo(const char *node, const char *service, } /* Now, alloc the embedded net_sockaddr struct: */ - ai_addr = calloc(1, sizeof(*ai_addr)); + ai_addr = k_calloc(1, sizeof(*ai_addr)); if (!ai_addr) { - free(*res); + k_free(*res); err = DNS_EAI_MEMORY; goto done_unlock; } @@ -724,8 +724,8 @@ static int eswifi_off_getaddrinfo(const char *node, const char *service, ai_addr->sin_port = net_htons(port); if (!net_ipaddr_parse(rsp, strlen(rsp), (struct net_sockaddr *)ai_addr)) { - free(ai_addr); - free(*res); + k_free(ai_addr); + k_free(*res); err = DNS_EAI_FAIL; goto done_unlock; } @@ -743,8 +743,8 @@ static void eswifi_off_freeaddrinfo(struct zsock_addrinfo *res) { __ASSERT_NO_MSG(res); - free(res->ai_addr); - free(res); + k_free(res->ai_addr); + k_free(res); } const struct socket_dns_offload eswifi_dns_ops = { diff --git a/drivers/wifi/simplelink/simplelink_sockets.c b/drivers/wifi/simplelink/simplelink_sockets.c index 7b031eed89a2..2066f9922177 100644 --- a/drivers/wifi/simplelink/simplelink_sockets.c +++ b/drivers/wifi/simplelink/simplelink_sockets.c @@ -996,16 +996,16 @@ static int set_addr_info(const struct SlNetUtil_addrInfo_t *sl_ai, struct net_sockaddr *ai_addr; int retval = 0; - ai = calloc(1, sizeof(struct zsock_addrinfo)); + ai = k_calloc(1, sizeof(struct zsock_addrinfo)); if (!ai) { retval = DNS_EAI_MEMORY; goto exit; } else { /* Now, alloc the embedded net_sockaddr struct: */ - ai_addr = calloc(1, sizeof(struct net_sockaddr)); + ai_addr = k_calloc(1, sizeof(struct net_sockaddr)); if (!ai_addr) { retval = DNS_EAI_MEMORY; - free(ai); + k_free(ai); goto exit; } } @@ -1130,8 +1130,8 @@ static void simplelink_freeaddrinfo(struct zsock_addrinfo *res) { __ASSERT_NO_MSG(res); - free(res->ai_addr); - free(res); + k_free(res->ai_addr); + k_free(res); } static int simplelink_fcntl(int sd, int cmd, va_list args) diff --git a/samples/net/wifi/shell/prj.conf b/samples/net/wifi/shell/prj.conf index e1a1b40a4098..ba3d9514ae04 100644 --- a/samples/net/wifi/shell/prj.conf +++ b/samples/net/wifi/shell/prj.conf @@ -36,3 +36,4 @@ CONFIG_NET_L2_WIFI_SHELL=y # environment. CONFIG_NET_MGMT_EVENT_QUEUE_TIMEOUT=5000 CONFIG_NET_MGMT_EVENT_QUEUE_SIZE=16 +CONFIG_HEAP_MEM_POOL_SIZE=2048 diff --git a/tests/drivers/build_all/wifi/prj.conf b/tests/drivers/build_all/wifi/prj.conf index 68df2c447211..4c44f089ef6c 100644 --- a/tests/drivers/build_all/wifi/prj.conf +++ b/tests/drivers/build_all/wifi/prj.conf @@ -4,3 +4,4 @@ CONFIG_WIFI=y CONFIG_GPIO=y CONFIG_NETWORKING=y CONFIG_NET_IPV4=y +CONFIG_HEAP_MEM_POOL_SIZE=2048 From afa47a276522902d6c07ded2c9e772067bdad138 Mon Sep 17 00:00:00 2001 From: Ibrahim Abdalkader Date: Tue, 2 Dec 2025 15:07:30 +0100 Subject: [PATCH 0098/6328] mgmt: mcumgr: grp: Use kernel heap for allocations Use the kernel heap instead of the libc heap, improving security and consistency. Signed-off-by: Ibrahim Abdalkader --- .../mgmt/mcumgr/grp/enum_mgmt/src/enum_mgmt.c | 6 ++--- subsys/mgmt/mcumgr/grp/settings_mgmt/Kconfig | 6 ++--- .../grp/settings_mgmt/src/settings_mgmt.c | 24 +++++++++---------- tests/subsys/mgmt/mcumgr/all_options/prj.conf | 1 + 4 files changed, 19 insertions(+), 18 deletions(-) diff --git a/subsys/mgmt/mcumgr/grp/enum_mgmt/src/enum_mgmt.c b/subsys/mgmt/mcumgr/grp/enum_mgmt/src/enum_mgmt.c index 31a93d94e3d3..574d24a4f308 100644 --- a/subsys/mgmt/mcumgr/grp/enum_mgmt/src/enum_mgmt.c +++ b/subsys/mgmt/mcumgr/grp/enum_mgmt/src/enum_mgmt.c @@ -351,7 +351,7 @@ static int enum_mgmt_details(struct smp_streamer *ctxt) if (entries > 0) { /* Return details on selected groups only */ #ifdef CONFIG_MCUMGR_GRP_ENUM_DETAILS_BUFFER_TYPE_HEAP - uint16_t *entry_list = malloc(sizeof(uint16_t) * entries); + uint16_t *entry_list = k_malloc(sizeof(uint16_t) * entries); #else uint16_t entry_list[CONFIG_MCUMGR_GRP_ENUM_DETAILS_BUFFER_TYPE_STACK_ENTRIES]; #endif @@ -375,7 +375,7 @@ static int enum_mgmt_details(struct smp_streamer *ctxt) if (!ok) { #ifdef CONFIG_MCUMGR_GRP_ENUM_DETAILS_BUFFER_TYPE_HEAP - free(entry_list); + k_free(entry_list); #endif return MGMT_ERR_EINVAL; @@ -392,7 +392,7 @@ static int enum_mgmt_details(struct smp_streamer *ctxt) cleanup: #ifdef CONFIG_MCUMGR_GRP_ENUM_DETAILS_BUFFER_TYPE_HEAP - free(entry_list); + k_free(entry_list); #endif if (!ok) { diff --git a/subsys/mgmt/mcumgr/grp/settings_mgmt/Kconfig b/subsys/mgmt/mcumgr/grp/settings_mgmt/Kconfig index c7d24062b6d2..c41fb63aa6b9 100644 --- a/subsys/mgmt/mcumgr/grp/settings_mgmt/Kconfig +++ b/subsys/mgmt/mcumgr/grp/settings_mgmt/Kconfig @@ -32,10 +32,10 @@ config MCUMGR_GRP_SETTINGS_BUFFER_TYPE_STACK config MCUMGR_GRP_SETTINGS_BUFFER_TYPE_HEAP bool "Heap (dynamic size)" - depends on COMMON_LIBC_MALLOC_ARENA_SIZE > 0 + depends on HEAP_MEM_POOL_SIZE > 0 help - Use dynamic heap memory allocation through malloc, if there is insufficient heap memory - for the allocation then the request will be rejected. + Use dynamic heap memory allocation through k_malloc, if there is insufficient heap + memory for the allocation then the request will be rejected. endchoice diff --git a/subsys/mgmt/mcumgr/grp/settings_mgmt/src/settings_mgmt.c b/subsys/mgmt/mcumgr/grp/settings_mgmt/src/settings_mgmt.c index bc14566927b1..cf252fc89001 100644 --- a/subsys/mgmt/mcumgr/grp/settings_mgmt/src/settings_mgmt.c +++ b/subsys/mgmt/mcumgr/grp/settings_mgmt/src/settings_mgmt.c @@ -75,12 +75,12 @@ static int settings_mgmt_read(struct smp_streamer *ctxt) } #ifdef CONFIG_MCUMGR_GRP_SETTINGS_BUFFER_TYPE_HEAP - key_name = (char *)malloc(key.len + 1); - data = (uint8_t *)malloc(max_size); + key_name = (char *)k_malloc(key.len + 1); + data = (uint8_t *)k_malloc(max_size); if (data == NULL || key_name == NULL) { if (key_name != NULL) { - free(key_name); + k_free(key_name); } return MGMT_ERR_ENOMEM; @@ -143,8 +143,8 @@ static int settings_mgmt_read(struct smp_streamer *ctxt) end: #ifdef CONFIG_MCUMGR_GRP_SETTINGS_BUFFER_TYPE_HEAP - free(key_name); - free(data); + k_free(key_name); + k_free(data); #endif return MGMT_RETURN_CHECK(ok); @@ -191,7 +191,7 @@ static int settings_mgmt_write(struct smp_streamer *ctxt) } #ifdef CONFIG_MCUMGR_GRP_SETTINGS_BUFFER_TYPE_HEAP - key_name = (char *)malloc(key.len + 1); + key_name = (char *)k_malloc(key.len + 1); if (key_name == NULL) { return MGMT_ERR_ENOMEM; @@ -247,7 +247,7 @@ static int settings_mgmt_write(struct smp_streamer *ctxt) end: #ifdef CONFIG_MCUMGR_GRP_SETTINGS_BUFFER_TYPE_HEAP - free(key_name); + k_free(key_name); #endif return MGMT_RETURN_CHECK(ok); @@ -292,7 +292,7 @@ static int settings_mgmt_delete(struct smp_streamer *ctxt) } #ifdef CONFIG_MCUMGR_GRP_SETTINGS_BUFFER_TYPE_HEAP - key_name = (char *)malloc(key.len + 1); + key_name = (char *)k_malloc(key.len + 1); if (key_name == NULL) { return MGMT_ERR_ENOMEM; @@ -331,7 +331,7 @@ static int settings_mgmt_delete(struct smp_streamer *ctxt) rc = settings_delete(key_name); #ifdef CONFIG_MCUMGR_GRP_SETTINGS_BUFFER_TYPE_HEAP - free(key_name); + k_free(key_name); #endif if (rc < 0) { @@ -476,7 +476,7 @@ static int settings_mgmt_save(struct smp_streamer *ctxt) } #ifdef CONFIG_MCUMGR_GRP_SETTINGS_BUFFER_TYPE_HEAP - key_name = (char *)malloc(key.len + 1); + key_name = (char *)k_malloc(key.len + 1); if (key_name == NULL) { return MGMT_ERR_ENOMEM; @@ -504,7 +504,7 @@ static int settings_mgmt_save(struct smp_streamer *ctxt) if (status != MGMT_CB_OK) { if (status == MGMT_CB_ERROR_RC) { #ifdef CONFIG_MCUMGR_GRP_SETTINGS_BUFFER_TYPE_HEAP - free(key_name); + k_free(key_name); #endif return ret_rc; } @@ -551,7 +551,7 @@ static int settings_mgmt_save(struct smp_streamer *ctxt) end: #ifdef CONFIG_MCUMGR_GRP_SETTINGS_BUFFER_TYPE_HEAP - free(key_name); + k_free(key_name); #endif return MGMT_RETURN_CHECK(ok); diff --git a/tests/subsys/mgmt/mcumgr/all_options/prj.conf b/tests/subsys/mgmt/mcumgr/all_options/prj.conf index 695cb6eb5cb4..b828c1761437 100644 --- a/tests/subsys/mgmt/mcumgr/all_options/prj.conf +++ b/tests/subsys/mgmt/mcumgr/all_options/prj.conf @@ -9,6 +9,7 @@ CONFIG_BASE64=y CONFIG_NET_BUF=y CONFIG_ZCBOR=y CONFIG_CRC=y +CONFIG_HEAP_MEM_POOL_SIZE=2048 CONFIG_FLASH=y CONFIG_FLASH_MAP=y CONFIG_STREAM_FLASH=y From 0c5e7a6a9530cf82b0a1551bac558a1a6418ae51 Mon Sep 17 00:00:00 2001 From: Ibrahim Abdalkader Date: Tue, 2 Dec 2025 15:37:44 +0100 Subject: [PATCH 0099/6328] sensing: sensor_mgmt: Use kernel heap for allocations Use the kernel heap instead of the libc heap, improving security and consistency. Signed-off-by: Ibrahim Abdalkader --- samples/subsys/sensing/simple/prj.conf | 1 + subsys/mgmt/mcumgr/grp/settings_mgmt/Kconfig | 2 +- subsys/sensing/sensor_mgmt.c | 4 ++-- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/samples/subsys/sensing/simple/prj.conf b/samples/subsys/sensing/simple/prj.conf index 1e935e973c76..3044bad5f3a8 100644 --- a/samples/subsys/sensing/simple/prj.conf +++ b/samples/subsys/sensing/simple/prj.conf @@ -1 +1,2 @@ CONFIG_LOG=y +CONFIG_HEAP_MEM_POOL_SIZE=2048 diff --git a/subsys/mgmt/mcumgr/grp/settings_mgmt/Kconfig b/subsys/mgmt/mcumgr/grp/settings_mgmt/Kconfig index c41fb63aa6b9..0cba22e2c35d 100644 --- a/subsys/mgmt/mcumgr/grp/settings_mgmt/Kconfig +++ b/subsys/mgmt/mcumgr/grp/settings_mgmt/Kconfig @@ -35,7 +35,7 @@ config MCUMGR_GRP_SETTINGS_BUFFER_TYPE_HEAP depends on HEAP_MEM_POOL_SIZE > 0 help Use dynamic heap memory allocation through k_malloc, if there is insufficient heap - memory for the allocation then the request will be rejected. + memory for the allocation then the request will be rejected. endchoice diff --git a/subsys/sensing/sensor_mgmt.c b/subsys/sensing/sensor_mgmt.c index 8b466fdae27f..955882361081 100644 --- a/subsys/sensing/sensor_mgmt.c +++ b/subsys/sensing/sensor_mgmt.c @@ -342,7 +342,7 @@ int open_sensor(struct sensing_sensor *sensor, struct sensing_connection **conn) } /* create connection from sensor to application(client = NULL) */ - tmp_conn = malloc(sizeof(*tmp_conn)); + tmp_conn = k_malloc(sizeof(*tmp_conn)); if (!tmp_conn) { return -ENOMEM; } @@ -371,7 +371,7 @@ int close_sensor(struct sensing_connection **conn) save_config_and_notify(tmp_conn->source); - free(*conn); + k_free(*conn); *conn = NULL; return 0; From 2acacec3f3f395e342fb5ba8241492a96ad39278 Mon Sep 17 00:00:00 2001 From: Dharun krithik k Date: Fri, 28 Nov 2025 12:54:00 +0530 Subject: [PATCH 0100/6328] dts: infineon: add watchdog node for PSoC4 Add the watchdog controller node to the PSoC4 SoC definition. Signed-off-by: Dharun krithik k Signed-off-by: Sayooj K Karun --- dts/arm/infineon/psoc4/psoc4100tp/psoc4100tp.dtsi | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/dts/arm/infineon/psoc4/psoc4100tp/psoc4100tp.dtsi b/dts/arm/infineon/psoc4/psoc4100tp/psoc4100tp.dtsi index ba02c71345c0..662c0e4f7969 100644 --- a/dts/arm/infineon/psoc4/psoc4100tp/psoc4100tp.dtsi +++ b/dts/arm/infineon/psoc4/psoc4100tp/psoc4100tp.dtsi @@ -128,6 +128,13 @@ status = "disabled"; }; + watchdog0: watchdog@40030000 { + compatible = "infineon,watchdog"; + reg = <0x40030000 0xf1c>; + interrupts = <5 0>; + status = "disabled"; + }; + tcpwm0: tcpwm0@40200000 { reg = <0x40200000 0x280>; #address-cells = <1>; From 8eec4c5fc46a798dfd46c558f62ae020b30b6df2 Mon Sep 17 00:00:00 2001 From: Dharun krithik k Date: Sat, 29 Nov 2025 04:02:43 +0530 Subject: [PATCH 0101/6328] boards: cy8cproto_041tp: enable watchdog Enable the watchdog0 node and add an alias for it on the CY8CPROTO-041TP board. Signed-off-by: Dharun krithik k Signed-off-by: Sayooj K Karun --- .../cy8cproto_041tp/cy8cproto_041tp_common.dtsi | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/boards/infineon/cy8cproto_041tp/cy8cproto_041tp_common.dtsi b/boards/infineon/cy8cproto_041tp/cy8cproto_041tp_common.dtsi index aebc94f0ce7c..e04a69d11ef2 100644 --- a/boards/infineon/cy8cproto_041tp/cy8cproto_041tp_common.dtsi +++ b/boards/infineon/cy8cproto_041tp/cy8cproto_041tp_common.dtsi @@ -8,6 +8,12 @@ #include #include "cy8cproto_041tp-pinctrl.dtsi" +/ { + aliases { + watchdog0 = &watchdog0; + }; +}; + uart0: &scb0 { compatible = "infineon,uart"; status = "okay"; @@ -71,3 +77,7 @@ uart0: &scb0 { status = "okay"; interrupts = <4 4>; }; + +&watchdog0 { + status = "okay"; +}; From 682493add902852b3c600d66c4667a96061afe10 Mon Sep 17 00:00:00 2001 From: Dharun krithik k Date: Sat, 29 Nov 2025 04:01:52 +0530 Subject: [PATCH 0102/6328] drivers: watchdog: infineon: add PSoC4 support Add support for the Infineon PSoC4 family to the infineon watchdog driver. PSoC4 specific ILO frequency and tick period definitions. Initialization and configuration logic specific to PSoC4. Signed-off-by: Dharun krithik k Signed-off-by: Sayooj K Karun --- drivers/watchdog/wdt_infineon.c | 115 ++++++++++++++++++++++++++++---- 1 file changed, 101 insertions(+), 14 deletions(-) diff --git a/drivers/watchdog/wdt_infineon.c b/drivers/watchdog/wdt_infineon.c index 7fdb7bc2b19b..8c2a80a05907 100644 --- a/drivers/watchdog/wdt_infineon.c +++ b/drivers/watchdog/wdt_infineon.c @@ -9,6 +9,7 @@ #define DT_DRV_COMPAT infineon_watchdog +#include #include "cy_wdt.h" #include "cy_sysclk.h" @@ -18,7 +19,7 @@ #include LOG_MODULE_REGISTER(wdt_infineon, CONFIG_WDT_LOG_LEVEL); -#define IFX_CAT1_WDT_IS_IRQ_EN DT_NODE_HAS_PROP(DT_DRV_INST(0), interrupts) +#define IFX_WDT_IS_IRQ_EN DT_NODE_HAS_PROP(DT_DRV_INST(0), interrupts) typedef struct { /* Minimum period in milliseconds that can be represented with this many ignored bits */ @@ -43,7 +44,7 @@ typedef struct { #else #define IFX_WDT_MATCH_BITS (32) #endif -#elif defined(COMPONENT_CAT1B) +#elif defined(COMPONENT_CAT1B) || defined(CY_IP_S8SRSSLT) #define IFX_WDT_MATCH_BITS (16) #else #error Unhandled device type @@ -78,6 +79,27 @@ static const wdt_ignore_bits_data_t ifx_wdt_ignore_data[] = { {1, 1}, /* 12 bit(s): min period: 1ms, max period: 1ms, round up from 1+ms */ }; #endif +#elif defined(CY_IP_S8SRSSLT) +#define IFX_WDT_MAX_TIMEOUT_MS 4915 +#define IFX_WDT_MAX_IGNORE_BITS 12 +/* Cy_SysClk_IloCompensate function execution time is always ~ 1ms */ +#define IFX_ILO_COMPENSATE_TIMEOUT_MS 2 + +static const wdt_ignore_bits_data_t ifx_wdt_ignore_data[] = { + {3072, 2305}, /* 0 bit(s): min period: 3072ms, max period: 4915ms, round up from 2305+ms */ + {1536, 1153}, /* 1 bit(s): min period: 1536ms, max period: 2458ms, round up from 1153+ms */ + {768, 577}, /* 2 bit(s): min period: 768ms, max period: 1229ms, round up from 577+ms */ + {384, 289}, /* 3 bit(s): min period: 384ms, max period: 614ms, round up from 289+ms */ + {192, 145}, /* 4 bit(s): min period: 192ms, max period: 307ms, round up from 145+ms */ + {96, 73}, /* 5 bit(s): min period: 96ms, max period: 154ms, round up from 73+ms */ + {48, 37}, /* 6 bit(s): min period: 48ms, max period: 77ms, round up from 37+ms */ + {24, 19}, /* 7 bit(s): min period: 24ms, max period: 38ms, round up from 19+ms */ + {12, 10}, /* 8 bit(s): min period: 12ms, max period: 19ms, round up from 10+ms */ + {6, 5}, /* 9 bit(s): min period: 6ms, max period: 10ms, round up from 5+ms */ + {3, 3}, /* 10 bit(s): min period: 3ms, max period: 5ms, round up from 3+ms */ + {2, 2}, /* 11 bit(s): min period: 2ms, max period: 2ms, round up from 2+ms */ + {1, 1}, /* 12 bit(s): min period: 1ms, max period: 1ms, round up from 1+ms */ +}; #elif (defined(CY_IP_MXS40SSRSS) || defined(CY_IP_MXS22SRSS)) && (IFX_WDT_MATCH_BITS == 22) /* ILO Frequency = 32768 Hz, ILO Period = 1 / 32768 Hz = .030518 ms */ #define IFX_WDT_MAX_TIMEOUT_MS 384000 @@ -195,25 +217,49 @@ struct ifx_cat1_wdt_data { uint32_t wdt_initial_timeout_ms; uint32_t wdt_rounded_timeout_ms; uint32_t wdt_ignore_bits; -#ifdef IFX_CAT1_WDT_IS_IRQ_EN +#ifdef IFX_WDT_IS_IRQ_EN wdt_callback_t callback; #endif uint32_t timeout; bool timeout_installed; +#if defined(CY_IP_S8SRSSLT) + uint32_t ilo_compensated_counts; +#endif }; static struct ifx_cat1_wdt_data wdt_data; +#if !defined(CY_IP_S8SRSSLT) #define IFX_DETERMINE_MATCH_BITS(bits) ((IFX_WDT_MAX_IGNORE_BITS) - (bits)) #define IFX_GET_COUNT_FROM_MATCH_BITS(bits) (2UL << IFX_DETERMINE_MATCH_BITS(bits)) +#endif -__STATIC_INLINE uint32_t ifx_wdt_timeout_to_match(uint32_t timeout_ms, uint32_t ignore_bits) +__STATIC_INLINE uint32_t ifx_wdt_timeout_to_match(uint32_t timeout_ms, uint32_t ignore_bits, + struct ifx_cat1_wdt_data *dev_data) { +#if defined(CY_IP_S8SRSSLT) + ARG_UNUSED(timeout_ms); + ARG_UNUSED(ignore_bits); + + uint32_t match_count; + + match_count = (Cy_WDT_GetMatch() + dev_data->ilo_compensated_counts); + + /* Ensure match count is within valid range for 16-bit WDT */ + if (match_count > UINT16_MAX) { + match_count = UINT16_MAX; + } + + return match_count; +#else + ARG_UNUSED(dev_data); + uint32_t wrap_count_for_ignore_bits = (IFX_GET_COUNT_FROM_MATCH_BITS(ignore_bits)); uint32_t timeout_count = ((timeout_ms * CY_SYSCLK_ILO_FREQ) / 1000UL); /* handle multiple possible wraps of WDT counter */ timeout_count = ((timeout_count + Cy_WDT_GetCount()) % wrap_count_for_ignore_bits); return timeout_count; +#endif } /* Rounds up *timeout_ms if it's outside of the valid timeout range (ifx_wdt_ignore_data) */ @@ -230,7 +276,7 @@ __STATIC_INLINE uint32_t ifx_wdt_timeout_to_ignore_bits(uint32_t *timeout_ms) return IFX_WDT_MAX_IGNORE_BITS; /* Ideally should never reach this */ } -#ifdef IFX_CAT1_WDT_IS_IRQ_EN +#ifdef IFX_WDT_IS_IRQ_EN static void ifx_cat1_wdt_isr_handler(const struct device *dev) { struct ifx_cat1_wdt_data *dev_data = dev->data; @@ -265,8 +311,39 @@ static int ifx_cat1_wdt_setup(const struct device *dev, uint8_t options) Cy_WDT_MaskInterrupt(); dev_data->wdt_initial_timeout_ms = dev_data->timeout; -#if defined(CY_IP_MXS40SRSS) && (CY_IP_MXS40SRSS_VERSION >= 2) - Cy_WDT_SetUpperLimit(ifx_wdt_timeout_to_match(dev_data->wdt_initial_timeout_ms)); + +#if defined(CY_IP_S8SRSSLT) + Cy_SysClk_IloStartMeasurement(); + + dev_data->wdt_ignore_bits = ifx_wdt_timeout_to_ignore_bits(&dev_data->timeout); + dev_data->wdt_rounded_timeout_ms = dev_data->timeout; + + uint32_t desired_delay_us = dev_data->wdt_rounded_timeout_ms * 1000UL; + cy_en_sysclk_status_t res; + + /* Add timeout to prevent infinite hang */ + uint32_t start = k_cycle_get_32(); + uint32_t timeout_cycles = k_ms_to_cyc_ceil32(IFX_ILO_COMPENSATE_TIMEOUT_MS); + + for (;;) { + res = Cy_SysClk_IloCompensate(desired_delay_us, &dev_data->ilo_compensated_counts); + if (res == CY_SYSCLK_SUCCESS) { + break; + } + if (res == CY_SYSCLK_BAD_PARAM || res == CY_SYSCLK_INVALID_STATE) { + return -EIO; + } + if ((k_cycle_get_32() - start) > timeout_cycles) { + return -ETIMEDOUT; + } + k_yield(); + } + + Cy_WDT_SetIgnoreBits(dev_data->wdt_ignore_bits); + Cy_WDT_SetMatch(dev_data->ilo_compensated_counts); +#elif defined(CY_IP_MXS40SRSS) && (CY_IP_MXS40SRSS_VERSION >= 2) + Cy_WDT_SetUpperLimit(ifx_wdt_timeout_to_match(dev_data->wdt_initial_timeout_ms, + dev_data->wdt_ignore_bits, dev_data)); Cy_WDT_SetUpperAction(CY_WDT_LOW_UPPER_LIMIT_ACTION_RESET); #else dev_data->wdt_ignore_bits = ifx_wdt_timeout_to_ignore_bits(&dev_data->timeout); @@ -289,9 +366,8 @@ static int ifx_cat1_wdt_setup(const struct device *dev, uint8_t options) /* Twice, as reading back after 1 reset gives same value as before single reset */ Cy_WDT_ResetCounter(); #endif - Cy_WDT_SetMatch(ifx_wdt_timeout_to_match(dev_data->wdt_rounded_timeout_ms, - dev_data->wdt_ignore_bits)); + dev_data->wdt_ignore_bits, dev_data)); #endif ifx_wdt_unlock(); @@ -304,7 +380,7 @@ static int ifx_cat1_wdt_setup(const struct device *dev, uint8_t options) return -ENOMSG; } -#ifdef IFX_CAT1_WDT_IS_IRQ_EN +#ifdef IFX_WDT_IS_IRQ_EN if (dev_data->callback) { Cy_WDT_UnmaskInterrupt(); irq_enable(DT_INST_IRQN(0)); @@ -318,11 +394,16 @@ static int ifx_cat1_wdt_disable(const struct device *dev) { struct ifx_cat1_wdt_data *dev_data = dev->data; -#ifdef IFX_CAT1_WDT_IS_IRQ_EN +#ifdef IFX_WDT_IS_IRQ_EN Cy_WDT_MaskInterrupt(); irq_disable(DT_INST_IRQN(0)); #endif +#if defined(CY_IP_S8SRSSLT) + Cy_SysClk_IloStopMeasurement(); + dev_data->ilo_compensated_counts = 0; +#endif + ifx_wdt_unlock(); Cy_WDT_Disable(); ifx_wdt_lock(); @@ -346,7 +427,7 @@ static int ifx_cat1_wdt_install_timeout(const struct device *dev, const struct w } if (cfg->callback) { -#ifndef IFX_CAT1_WDT_IS_IRQ_EN +#ifndef IFX_WDT_IS_IRQ_EN LOG_WRN("Interrupt is not configured, can't set a callback."); #else dev_data->callback = cfg->callback; @@ -374,8 +455,10 @@ static int ifx_cat1_wdt_feed(const struct device *dev, int channel_id) ifx_wdt_unlock(); Cy_WDT_ClearWatchdog(); /* Clear to prevent reset from WDT */ + Cy_WDT_SetMatch(ifx_wdt_timeout_to_match(data->wdt_rounded_timeout_ms, - data->wdt_ignore_bits)); + data->wdt_ignore_bits, data)); + ifx_wdt_lock(); return 0; @@ -384,7 +467,7 @@ static int ifx_cat1_wdt_feed(const struct device *dev, int channel_id) static int ifx_cat1_wdt_init(const struct device *dev) { struct ifx_cat1_wdt_data *data = dev->data; -#ifdef IFX_CAT1_WDT_IS_IRQ_EN +#ifdef IFX_WDT_IS_IRQ_EN /* Connect WDT interrupt to ISR */ IRQ_CONNECT(DT_INST_IRQN(0), DT_INST_IRQ(0, priority), ifx_cat1_wdt_isr_handler, DEVICE_DT_INST_GET(0), 0); @@ -394,6 +477,10 @@ static int ifx_cat1_wdt_init(const struct device *dev) data->wdt_initial_timeout_ms = 0; data->wdt_rounded_timeout_ms = 0; +#if defined(CY_IP_S8SRSSLT) + data->ilo_compensated_counts = 0; +#endif + return 0; } From 0777dbea02849c89d8089192dca96188b49f3dd3 Mon Sep 17 00:00:00 2001 From: Daniel Leung Date: Fri, 19 Dec 2025 11:09:13 -0800 Subject: [PATCH 0103/6328] xtensa: mmu: assert when L2 table allocation fails during dup Add an assertions to halt the system if L2 table allocation fails when we need to duplicate an existing L2 table, as it is a must-have and must-success operation. Signed-off-by: Daniel Leung --- arch/xtensa/core/ptables.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/arch/xtensa/core/ptables.c b/arch/xtensa/core/ptables.c index b9d5bf2dcda2..6bcf8c104562 100644 --- a/arch/xtensa/core/ptables.c +++ b/arch/xtensa/core/ptables.c @@ -968,8 +968,14 @@ static uint32_t *dup_l2_table(uint32_t *src_l2_table, enum dup_action action) uint32_t *l2_table; l2_table = alloc_l2_table(); + + /* Duplicating L2 tables is a must-have and must-success operation. + * If we are running out of free L2 tables to be allocated, we cannot + * continue. + */ + __ASSERT_NO_MSG(l2_table != NULL); if (l2_table == NULL) { - return NULL; + arch_system_halt(K_ERR_KERNEL_PANIC); } switch (action) { From 82b7d94d4526a2bd6fd0fe32950926fe423209d8 Mon Sep 17 00:00:00 2001 From: Daniel Leung Date: Fri, 19 Dec 2025 11:26:54 -0800 Subject: [PATCH 0104/6328] xtensa: mmu: add debug logs on page table allocations Adds some debug logs when we are allocating page tables. This provides a more visible way of seeing whether we need to have more free tables. Signed-off-by: Daniel Leung --- arch/xtensa/core/ptables.c | 39 +++++++++++++++++++++++++------------- 1 file changed, 26 insertions(+), 13 deletions(-) diff --git a/arch/xtensa/core/ptables.c b/arch/xtensa/core/ptables.c index 6bcf8c104562..0370bb3885ed 100644 --- a/arch/xtensa/core/ptables.c +++ b/arch/xtensa/core/ptables.c @@ -326,6 +326,26 @@ static void init_page_table(uint32_t *ptable, size_t num_entries, uint32_t val) } } +static void calc_l2_page_tables_usage(void) +{ +#ifdef CONFIG_XTENSA_MMU_PAGE_TABLE_STATS + uint32_t cur_l2_usage = 0; + + /* Calculate how many L2 page tables are being used now. */ + for (int idx = 0; idx < CONFIG_XTENSA_MMU_NUM_L2_TABLES; idx++) { + if (l2_page_tables_counter[idx] > 0) { + cur_l2_usage++; + } + } + + /* Store the bigger number. */ + l2_page_tables_max_usage = MAX(l2_page_tables_max_usage, cur_l2_usage); + + LOG_DBG("L2 page table usage %u/%u/%u", cur_l2_usage, l2_page_tables_max_usage, + CONFIG_XTENSA_MMU_NUM_L2_TABLES); +#endif /* CONFIG_XTENSA_MMU_PAGE_TABLE_STATS */ +} + /** * @brief Find the L2 table counter array index from L2 table pointer. * @@ -357,19 +377,7 @@ static inline uint32_t *alloc_l2_table(void) } } -#ifdef CONFIG_XTENSA_MMU_PAGE_TABLE_STATS - uint32_t cur_l2_usage = 0; - - /* Calculate how many L2 page tables are being used now. */ - for (idx = 0; idx < CONFIG_XTENSA_MMU_NUM_L2_TABLES; idx++) { - if (l2_page_tables_counter[idx] > 0) { - cur_l2_usage++; - } - } - - /* Store the bigger number. */ - l2_page_tables_max_usage = MAX(l2_page_tables_max_usage, cur_l2_usage); -#endif /* CONFIG_XTENSA_MMU_PAGE_TABLE_STATS */ + calc_l2_page_tables_usage(); k_spin_unlock(&xtensa_counter_lock, key); @@ -716,6 +724,8 @@ static void l2_page_table_unmap(uint32_t *l1_table, void *vaddr) K_SPINLOCK(&xtensa_counter_lock) { l2_page_tables_counter_dec(l2_table); + + calc_l2_page_tables_usage(); } end: @@ -946,6 +956,9 @@ static inline uint32_t *alloc_l1_table(void) /* Store the bigger number. */ l1_page_tables_max_usage = MAX(l1_page_tables_max_usage, cur_l1_usage); + + LOG_DBG("L1 page table usage %u/%u/%u", cur_l1_usage, l1_page_tables_max_usage, + CONFIG_XTENSA_MMU_NUM_L1_TABLES); #endif /* CONFIG_XTENSA_MMU_PAGE_TABLE_STATS */ return ret; From 50e980d9a8329832e74a5a1ffcce81f947c7cf41 Mon Sep 17 00:00:00 2001 From: Daniel Leung Date: Mon, 22 Dec 2025 11:57:10 -0800 Subject: [PATCH 0105/6328] xtensa: mmu: halt system if not enough L2 tables during boot If there are not enough free L2 tables to map all predefined memory regions at boot, halt the system in case assertion is not enabled. Without all the needed memory regions mapped, it is very unlikely that anything will run properly. Signed-off-by: Daniel Leung --- arch/xtensa/core/ptables.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/arch/xtensa/core/ptables.c b/arch/xtensa/core/ptables.c index 0370bb3885ed..3ec0bb672720 100644 --- a/arch/xtensa/core/ptables.c +++ b/arch/xtensa/core/ptables.c @@ -407,6 +407,15 @@ static void map_memory_range(const uint32_t start, const uint32_t end, __ASSERT(l2_table != NULL, "There is no l2 page table available to map 0x%08x\n", page); + if (l2_table == NULL) { + /* This function is called during boot. If this cannot + * properly map all predefined memory regions, it is very + * unlikely for anything to run correctly. So forcibly + * halt the system in case assertion has been turned off. + */ + arch_system_halt(K_ERR_KERNEL_PANIC); + } + init_page_table(l2_table, L2_PAGE_TABLE_NUM_ENTRIES, PTE_L2_ILLEGAL); xtensa_kernel_ptables[l1_pos] = From c5bc58e3bdbf00aeb0354040f8f36d9f373aeb53 Mon Sep 17 00:00:00 2001 From: Vinit Mehta Date: Wed, 7 Jan 2026 15:38:46 +0530 Subject: [PATCH 0106/6328] Samples: bluetooth: a2dp_sink: Audio support for 1060EVKC Add codec driver overlay file to enable audio rendering for A2DP sink sample application for 1060EVKC platform Signed-off-by: Vinit Mehta --- .../boards/mimxrt1060_evk_mimxrt1062_qspi_C.conf | 10 ++++++++++ .../mimxrt1060_evk_mimxrt1062_qspi_C.overlay | 15 +++++++++++++++ 2 files changed, 25 insertions(+) create mode 100644 samples/bluetooth/classic/a2dp_sink/boards/mimxrt1060_evk_mimxrt1062_qspi_C.conf create mode 100644 samples/bluetooth/classic/a2dp_sink/boards/mimxrt1060_evk_mimxrt1062_qspi_C.overlay diff --git a/samples/bluetooth/classic/a2dp_sink/boards/mimxrt1060_evk_mimxrt1062_qspi_C.conf b/samples/bluetooth/classic/a2dp_sink/boards/mimxrt1060_evk_mimxrt1062_qspi_C.conf new file mode 100644 index 000000000000..ae1b1ee9be0f --- /dev/null +++ b/samples/bluetooth/classic/a2dp_sink/boards/mimxrt1060_evk_mimxrt1062_qspi_C.conf @@ -0,0 +1,10 @@ +# +# Copyright 2026 NXP +# +# SPDX-License-Identifier: Apache-2.0 +# + +CONFIG_I2S=y +CONFIG_AUDIO=y +CONFIG_AUDIO_CODEC=y +CONFIG_DMA_TCD_QUEUE_SIZE=4 diff --git a/samples/bluetooth/classic/a2dp_sink/boards/mimxrt1060_evk_mimxrt1062_qspi_C.overlay b/samples/bluetooth/classic/a2dp_sink/boards/mimxrt1060_evk_mimxrt1062_qspi_C.overlay new file mode 100644 index 000000000000..b0aab45ba45a --- /dev/null +++ b/samples/bluetooth/classic/a2dp_sink/boards/mimxrt1060_evk_mimxrt1062_qspi_C.overlay @@ -0,0 +1,15 @@ +/* + * Copyright 2026 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +&sai1 { + mclk-output; + podf = <15>; + pll-clocks = <&anatop 0 0 0>, + <&anatop 0 0 30>, + <&anatop 0 0 1>, + <&anatop 0 0 106>, + <&anatop 0 0 1000>; +}; From 924874baefa93c0faaaf352b50e06fb7ca70bbf7 Mon Sep 17 00:00:00 2001 From: Peter Mitsis Date: Mon, 12 Jan 2026 15:33:08 -0800 Subject: [PATCH 0107/6328] kernel: Fix two k_condvar_wait() issues 1. When the timeout is K_NO_WAIT, the thread should not be added to the wait queue as that would otherwise cause to the thread to wait until the next tick (which is not a no-wait situation). 2. Threads that were added to the wait queue AND did not receive a signal before timing out should not lock the supplied mutex. Signed-off-by: Peter Mitsis --- kernel/condvar.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/kernel/condvar.c b/kernel/condvar.c index 42590839c863..640fd8ad2b64 100644 --- a/kernel/condvar.c +++ b/kernel/condvar.c @@ -115,15 +115,23 @@ int z_impl_k_condvar_wait(struct k_condvar *condvar, struct k_mutex *mutex, k_timeout_t timeout) { k_spinlock_key_t key; - int ret; + int ret = -EAGAIN; SYS_PORT_TRACING_OBJ_FUNC_ENTER(k_condvar, wait, condvar, timeout); + if (unlikely(K_TIMEOUT_EQ(timeout, K_NO_WAIT))) { + k_mutex_unlock(mutex); + SYS_PORT_TRACING_OBJ_FUNC_EXIT(k_condvar, wait, condvar, timeout, ret); + return ret; + } + key = k_spin_lock(&lock); k_mutex_unlock(mutex); ret = z_pend_curr(&lock, key, &condvar->wait_q, timeout); - k_mutex_lock(mutex, K_FOREVER); + if (ret == 0) { + k_mutex_lock(mutex, K_FOREVER); + } SYS_PORT_TRACING_OBJ_FUNC_EXIT(k_condvar, wait, condvar, timeout, ret); From 3944b0cfc7f9f7a9d31479f2a2bd5a89e6ca82a5 Mon Sep 17 00:00:00 2001 From: Peter Mitsis Date: Fri, 9 Jan 2026 13:42:26 -0800 Subject: [PATCH 0108/6328] kernel: Extend thread user_options to 16 bits Upgrades the thread user_options to 16 bits from an 8-bit value to provide more space for future values. Also, as the size of this field has changed, the values for the existing architecture specific thread options have also shifted from the upper end of the old 8-bit field, to the upper end of the new 16-bit field. Fixes #101034 Signed-off-by: Peter Mitsis --- arch/arc/core/thread.c | 4 ++-- arch/arm/core/cortex_a_r/swap_helper.S | 4 ++-- arch/riscv/core/switch.S | 2 +- arch/x86/core/ia32/float.c | 2 +- arch/x86/core/ia32/swap.S | 8 ++++---- include/zephyr/kernel.h | 6 +++--- include/zephyr/kernel/thread.h | 12 ++++-------- kernel/thread.c | 2 +- scripts/coredump/gdbstubs/gdbstub.py | 8 ++++---- 9 files changed, 22 insertions(+), 26 deletions(-) diff --git a/arch/arc/core/thread.c b/arch/arc/core/thread.c index 387f983780b9..38aee4912027 100644 --- a/arch/arc/core/thread.c +++ b/arch/arc/core/thread.c @@ -318,7 +318,7 @@ void arc_dsp_disable(struct k_thread *thread, unsigned int options) k_spinlock_key_t key = k_spin_lock(&lock); /* Disable DSP or AGU capabilities for the thread */ - thread->base.user_options &= ~(uint8_t)options; + thread->base.user_options &= ~(uint16_t)options; k_spin_unlock(&lock, key); } @@ -329,7 +329,7 @@ void arc_dsp_enable(struct k_thread *thread, unsigned int options) k_spinlock_key_t key = k_spin_lock(&lock); /* Enable dsp or agu capabilities for the thread */ - thread->base.user_options |= (uint8_t)options; + thread->base.user_options |= (uint16_t)options; k_spin_unlock(&lock, key); } diff --git a/arch/arm/core/cortex_a_r/swap_helper.S b/arch/arm/core/cortex_a_r/swap_helper.S index 04b19f0b046b..9417073f311c 100644 --- a/arch/arm/core/cortex_a_r/swap_helper.S +++ b/arch/arm/core/cortex_a_r/swap_helper.S @@ -69,7 +69,7 @@ SECTION_FUNC(TEXT, z_arm_do_swap) cps #MODE_SVC #if defined(CONFIG_FPU_SHARING) - ldrb r0, [r2, #_thread_offset_to_user_options] + ldrh r0, [r2, #_thread_offset_to_user_options] tst r0, #K_FP_REGS /* _current->base.user_options & K_FP_REGS */ beq out_fp_inactive @@ -151,7 +151,7 @@ out_fp_inactive: cps #MODE_SVC #if defined(CONFIG_FPU_SHARING) - ldrb r0, [r2, #_thread_offset_to_user_options] + ldrh r0, [r2, #_thread_offset_to_user_options] tst r0, #K_FP_REGS /* _current->base.user_options & K_FP_REGS */ beq in_fp_inactive diff --git a/arch/riscv/core/switch.S b/arch/riscv/core/switch.S index 81292748f838..b78289af68b6 100644 --- a/arch/riscv/core/switch.S +++ b/arch/riscv/core/switch.S @@ -73,7 +73,7 @@ SECTION_FUNC(TEXT, z_riscv_switch) * in effect while in m-mode. (it is done on every exception return * otherwise). */ - lb t0, _thread_offset_to_user_options(a0) + lh t0, _thread_offset_to_user_options(a0) andi t0, t0, K_USER beqz t0, not_user_task mv s0, a0 diff --git a/arch/x86/core/ia32/float.c b/arch/x86/core/ia32/float.c index 9b6f4daa18e0..8219dc7593b8 100644 --- a/arch/x86/core/ia32/float.c +++ b/arch/x86/core/ia32/float.c @@ -179,7 +179,7 @@ void z_float_enable(struct k_thread *thread, unsigned int options) /* Indicate thread requires floating point context saving */ - thread->base.user_options |= (uint8_t)options; + thread->base.user_options |= (uint16_t)options; /* * The current thread might not allow FP instructions, so clear CR0[TS] * so we can use them. (CR0[TS] gets restored later on, if necessary.) diff --git a/arch/x86/core/ia32/swap.S b/arch/x86/core/ia32/swap.S index 4baa0070b9b8..f3433bfd0f0a 100644 --- a/arch/x86/core/ia32/swap.S +++ b/arch/x86/core/ia32/swap.S @@ -175,7 +175,7 @@ SECTION_FUNC(PINNED_TEXT, arch_swap) * _and_ whether the thread was context switched out preemptively. */ - testb $_FP_USER_MASK, _thread_offset_to_user_options(%eax) + testw $_FP_USER_MASK, _thread_offset_to_user_options(%eax) je restoreContext_NoFloatSwap @@ -216,7 +216,7 @@ SECTION_FUNC(PINNED_TEXT, arch_swap) #ifdef CONFIG_X86_SSE - testb $K_SSE_REGS, _thread_offset_to_user_options(%ebx) + testw $K_SSE_REGS, _thread_offset_to_user_options(%ebx) je x87FloatSave /* @@ -255,7 +255,7 @@ restoreContext_NoFloatSave: je restoreContext_NoFloatRestore #ifdef CONFIG_X86_SSE - testb $K_SSE_REGS, _thread_offset_to_user_options(%eax) + testw $K_SSE_REGS, _thread_offset_to_user_options(%eax) je x87FloatRestore fxrstor _thread_offset_to_preempFloatReg(%eax) @@ -290,7 +290,7 @@ restoreContext_NoFloatSwap: * registers */ - testb $_FP_USER_MASK, _thread_offset_to_user_options(%eax) + testw $_FP_USER_MASK, _thread_offset_to_user_options(%eax) jne CROHandlingDone /* diff --git a/include/zephyr/kernel.h b/include/zephyr/kernel.h index a27a4049242f..bfde2db11006 100644 --- a/include/zephyr/kernel.h +++ b/include/zephyr/kernel.h @@ -322,7 +322,7 @@ void k_thread_foreach_unlocked_filter_by_cpu(unsigned int cpu, * restore the contents of these registers when scheduling the thread. * No effect if @kconfig{CONFIG_DSP_SHARING} is not enabled. */ -#define K_DSP_IDX 6 +#define K_DSP_IDX 13 #define K_DSP_REGS (BIT(K_DSP_IDX)) /** @@ -333,7 +333,7 @@ void k_thread_foreach_unlocked_filter_by_cpu(unsigned int cpu, * memory and DSP feature. Often used with @kconfig{CONFIG_ARC_AGU_SHARING}. * No effect if @kconfig{CONFIG_ARC_AGU_SHARING} is not enabled. */ -#define K_AGU_IDX 7 +#define K_AGU_IDX 14 #define K_AGU_REGS (BIT(K_AGU_IDX)) /** @@ -345,7 +345,7 @@ void k_thread_foreach_unlocked_filter_by_cpu(unsigned int cpu, * save and restore the contents of these registers when scheduling * the thread. No effect if @kconfig{CONFIG_X86_SSE} is not enabled. */ -#define K_SSE_REGS (BIT(7)) +#define K_SSE_REGS (BIT(15)) /* end - thread options */ diff --git a/include/zephyr/kernel/thread.h b/include/zephyr/kernel/thread.h index 3dd40355bc28..46d32a388d47 100644 --- a/include/zephyr/kernel/thread.h +++ b/include/zephyr/kernel/thread.h @@ -57,10 +57,7 @@ struct _thread_base { _wait_q_t *pended_on; /* user facing 'thread options'; values defined in include/zephyr/kernel.h */ - uint8_t user_options; - - /* thread state */ - uint8_t thread_state; + uint16_t user_options; /* * scheduler lock count and thread priority @@ -97,6 +94,9 @@ struct _thread_base { uint32_t order_key; #endif + /* thread state */ + uint8_t thread_state; + #ifdef CONFIG_SMP /* True for the per-CPU idle threads */ uint8_t is_idle; @@ -111,11 +111,7 @@ struct _thread_base { #ifdef CONFIG_SCHED_CPU_MASK /* "May run on" bits for each CPU */ -#if CONFIG_MP_MAX_NUM_CPUS <= 8 - uint8_t cpu_mask; -#else uint16_t cpu_mask; -#endif /* CONFIG_MP_MAX_NUM_CPUS */ #endif /* CONFIG_SCHED_CPU_MASK */ /* data returned by APIs */ diff --git a/kernel/thread.c b/kernel/thread.c index 97efd493c9cb..a9dc945a12ed 100644 --- a/kernel/thread.c +++ b/kernel/thread.c @@ -881,7 +881,7 @@ void z_init_thread_base(struct _thread_base *thread_base, int priority, { /* k_q_node is initialized upon first insertion in a list */ thread_base->pended_on = NULL; - thread_base->user_options = (uint8_t)options; + thread_base->user_options = (uint16_t)options; thread_base->thread_state = (uint8_t)initial_state; thread_base->prio = priority; diff --git a/scripts/coredump/gdbstubs/gdbstub.py b/scripts/coredump/gdbstubs/gdbstub.py index e5499607389d..b277bd2d163a 100644 --- a/scripts/coredump/gdbstubs/gdbstub.py +++ b/scripts/coredump/gdbstubs/gdbstub.py @@ -279,11 +279,11 @@ def handle_general_query_packet(self, pkt): t_user_options_offset = self.elffile.get_kernel_thread_info_offset( ThreadInfoOffset.THREAD_INFO_OFFSET_T_USER_OPTIONS ) - thread_user_options_byte = self.get_memory( - thread_ptr + t_user_options_offset, 1 + thread_user_options_halfword = self.get_memory( + thread_ptr + t_user_options_offset, 2 ) - if thread_user_options_byte is not None: - thread_user_options = int.from_bytes(thread_user_options_byte, "little") + if thread_user_options_halfword is not None: + thread_user_options = int.from_bytes(thread_user_options_halfword, "little") thread_info_bytes += b', user_options: ' + bytes( hex(thread_user_options), 'ascii' ) From fad7e5dfe62fd0671b2a0c5fdbb8fd99c207aae5 Mon Sep 17 00:00:00 2001 From: Camille BAUD Date: Thu, 15 Jan 2026 13:06:18 +0100 Subject: [PATCH 0109/6328] drivers: display: rename ssd1306/9fb to ssd1306/9 harmonize with other drivers, remove irrelevant suffix Signed-off-by: Camille BAUD --- .../01space/esp32c3_042_oled/esp32c3_042_oled.dts | 2 +- boards/adi/max32672fthr/max32672fthr.dts | 2 +- .../ttgo_lora32/ttgo_lora32_esp32_procpu.dts | 2 +- .../lilygo/ttgo_tbeam/ttgo_tbeam_esp32_procpu.dts | 2 +- .../mxchip/az3166_iotdevkit/az3166_iotdevkit.dts | 2 +- boards/nxp/mr_canhubk3/mr_canhubk3_common.dtsi | 2 +- .../adafruit_featherwing_128x32_oled.overlay | 2 +- .../seeed_xiao_expansion_board.overlay | 2 +- boards/shields/ssd1306/ssd1306_128x32.overlay | 2 +- boards/shields/ssd1306/ssd1306_128x64.overlay | 2 +- boards/shields/ssd1306/ssd1306_128x64_spi.overlay | 2 +- drivers/display/Kconfig.ssd1306 | 10 +++++----- drivers/display/ssd1306.c | 14 +++++++------- dts/bindings/display/sinowealth,sh1106-i2c.yaml | 2 +- dts/bindings/display/sinowealth,sh1106-spi.yaml | 2 +- ...6fb-common.yaml => solomon,ssd1306-common.yaml} | 0 ...ssd1306fb-i2c.yaml => solomon,ssd1306-i2c.yaml} | 4 ++-- ...ssd1306fb-spi.yaml => solomon,ssd1306-spi.yaml} | 4 ++-- ...ssd1309fb-i2c.yaml => solomon,ssd1309-i2c.yaml} | 4 ++-- ...ssd1309fb-spi.yaml => solomon,ssd1309-spi.yaml} | 4 ++-- tests/drivers/build_all/display/app.overlay | 2 +- 21 files changed, 34 insertions(+), 34 deletions(-) rename dts/bindings/display/{solomon,ssd1306fb-common.yaml => solomon,ssd1306-common.yaml} (100%) rename dts/bindings/display/{solomon,ssd1306fb-i2c.yaml => solomon,ssd1306-i2c.yaml} (71%) rename dts/bindings/display/{solomon,ssd1306fb-spi.yaml => solomon,ssd1306-spi.yaml} (78%) rename dts/bindings/display/{solomon,ssd1309fb-i2c.yaml => solomon,ssd1309-i2c.yaml} (71%) rename dts/bindings/display/{solomon,ssd1309fb-spi.yaml => solomon,ssd1309-spi.yaml} (78%) diff --git a/boards/01space/esp32c3_042_oled/esp32c3_042_oled.dts b/boards/01space/esp32c3_042_oled/esp32c3_042_oled.dts index 70f83f398e75..d7c3b0960373 100644 --- a/boards/01space/esp32c3_042_oled/esp32c3_042_oled.dts +++ b/boards/01space/esp32c3_042_oled/esp32c3_042_oled.dts @@ -48,7 +48,7 @@ pinctrl-names = "default"; eastrising_72x40: ssd1306@3c { - compatible = "solomon,ssd1306fb"; + compatible = "solomon,ssd1306"; reg = <0x3c>; width = <72>; diff --git a/boards/adi/max32672fthr/max32672fthr.dts b/boards/adi/max32672fthr/max32672fthr.dts index 397fb51a81ac..0ed07af00a13 100644 --- a/boards/adi/max32672fthr/max32672fthr.dts +++ b/boards/adi/max32672fthr/max32672fthr.dts @@ -130,7 +130,7 @@ status = "okay"; ssd1306: ssd1306@3d { - compatible = "solomon,ssd1306fb"; + compatible = "solomon,ssd1306"; reg = <0x3d>; width = <128>; height = <32>; diff --git a/boards/lilygo/ttgo_lora32/ttgo_lora32_esp32_procpu.dts b/boards/lilygo/ttgo_lora32/ttgo_lora32_esp32_procpu.dts index aaed6346e114..5dfd627b7fbb 100644 --- a/boards/lilygo/ttgo_lora32/ttgo_lora32_esp32_procpu.dts +++ b/boards/lilygo/ttgo_lora32/ttgo_lora32_esp32_procpu.dts @@ -68,7 +68,7 @@ pinctrl-names = "default"; ssd1306_128x64: ssd1306@3c { - compatible = "solomon,ssd1306fb"; + compatible = "solomon,ssd1306"; reg = <0x3c>; width = <128>; height = <64>; diff --git a/boards/lilygo/ttgo_tbeam/ttgo_tbeam_esp32_procpu.dts b/boards/lilygo/ttgo_tbeam/ttgo_tbeam_esp32_procpu.dts index fc524286776e..f0a924bae389 100644 --- a/boards/lilygo/ttgo_tbeam/ttgo_tbeam_esp32_procpu.dts +++ b/boards/lilygo/ttgo_tbeam/ttgo_tbeam_esp32_procpu.dts @@ -78,7 +78,7 @@ pinctrl-names = "default"; ssd1306_128x64: ssd1306@3c { - compatible = "solomon,ssd1306fb"; + compatible = "solomon,ssd1306"; reg = <0x3c>; width = <128>; height = <64>; diff --git a/boards/mxchip/az3166_iotdevkit/az3166_iotdevkit.dts b/boards/mxchip/az3166_iotdevkit/az3166_iotdevkit.dts index e01b8d52eff6..b24be56345b4 100644 --- a/boards/mxchip/az3166_iotdevkit/az3166_iotdevkit.dts +++ b/boards/mxchip/az3166_iotdevkit/az3166_iotdevkit.dts @@ -171,7 +171,7 @@ }; ssd1306: ssd1306@3c { - compatible = "solomon,ssd1306fb"; + compatible = "solomon,ssd1306"; reg = <0x3c>; width = <128>; height = <64>; diff --git a/boards/nxp/mr_canhubk3/mr_canhubk3_common.dtsi b/boards/nxp/mr_canhubk3/mr_canhubk3_common.dtsi index 6b2b5b3fb172..b2ec5a5e51c1 100644 --- a/boards/nxp/mr_canhubk3/mr_canhubk3_common.dtsi +++ b/boards/nxp/mr_canhubk3/mr_canhubk3_common.dtsi @@ -395,7 +395,7 @@ status = "okay"; ssd1306: ssd1306@3c { - compatible = "solomon,ssd1306fb"; + compatible = "solomon,ssd1306"; reg = <0x3c>; width = <128>; height = <32>; diff --git a/boards/shields/adafruit_featherwing_128x32_oled/adafruit_featherwing_128x32_oled.overlay b/boards/shields/adafruit_featherwing_128x32_oled/adafruit_featherwing_128x32_oled.overlay index 585d214847ea..6e90dd042d6b 100644 --- a/boards/shields/adafruit_featherwing_128x32_oled/adafruit_featherwing_128x32_oled.overlay +++ b/boards/shields/adafruit_featherwing_128x32_oled/adafruit_featherwing_128x32_oled.overlay @@ -39,7 +39,7 @@ &feather_i2c { ssd1306_ssd1306_128x32: ssd1306@3c { - compatible = "solomon,ssd1306fb"; + compatible = "solomon,ssd1306"; reg = <0x3c>; width = <128>; height = <32>; diff --git a/boards/shields/seeed_xiao_expansion_board/seeed_xiao_expansion_board.overlay b/boards/shields/seeed_xiao_expansion_board/seeed_xiao_expansion_board.overlay index a90a4b62c465..bbeaa0215058 100644 --- a/boards/shields/seeed_xiao_expansion_board/seeed_xiao_expansion_board.overlay +++ b/boards/shields/seeed_xiao_expansion_board/seeed_xiao_expansion_board.overlay @@ -31,7 +31,7 @@ status = "okay"; ssd1306_128x64: ssd1306@3c { - compatible = "solomon,ssd1306fb"; + compatible = "solomon,ssd1306"; reg = <0x3c>; width = <128>; height = <64>; diff --git a/boards/shields/ssd1306/ssd1306_128x32.overlay b/boards/shields/ssd1306/ssd1306_128x32.overlay index a8b53a2cfb9e..0689f270a758 100644 --- a/boards/shields/ssd1306/ssd1306_128x32.overlay +++ b/boards/shields/ssd1306/ssd1306_128x32.overlay @@ -14,7 +14,7 @@ status = "okay"; ssd1306_ssd1306_128x32: ssd1306@3c { - compatible = "solomon,ssd1306fb"; + compatible = "solomon,ssd1306"; reg = <0x3c>; width = <128>; height = <32>; diff --git a/boards/shields/ssd1306/ssd1306_128x64.overlay b/boards/shields/ssd1306/ssd1306_128x64.overlay index 2e9f1c320cc3..8d4ef9ededc2 100644 --- a/boards/shields/ssd1306/ssd1306_128x64.overlay +++ b/boards/shields/ssd1306/ssd1306_128x64.overlay @@ -14,7 +14,7 @@ status = "okay"; ssd1306_ssd1306_128x64: ssd1306@3c { - compatible = "solomon,ssd1306fb"; + compatible = "solomon,ssd1306"; reg = <0x3c>; width = <128>; height = <64>; diff --git a/boards/shields/ssd1306/ssd1306_128x64_spi.overlay b/boards/shields/ssd1306/ssd1306_128x64_spi.overlay index c9ee9e68563c..b7c416192805 100644 --- a/boards/shields/ssd1306/ssd1306_128x64_spi.overlay +++ b/boards/shields/ssd1306/ssd1306_128x64_spi.overlay @@ -16,7 +16,7 @@ status = "okay"; ssd1306_ssd1306_128x64_spi: ssd1306@0 { - compatible = "solomon,ssd1306fb"; + compatible = "solomon,ssd1306"; reg = <0x0>; spi-max-frequency = <10000000>; width = <128>; diff --git a/drivers/display/Kconfig.ssd1306 b/drivers/display/Kconfig.ssd1306 index f067f572371d..43a3bd6d72d7 100644 --- a/drivers/display/Kconfig.ssd1306 +++ b/drivers/display/Kconfig.ssd1306 @@ -6,11 +6,11 @@ menuconfig SSD1306 bool "SSD1306 display driver" default y - depends on DT_HAS_SOLOMON_SSD1306FB_ENABLED || DT_HAS_SOLOMON_SSD1309FB_ENABLED || DT_HAS_SINOWEALTH_SH1106_ENABLED - select I2C if $(dt_compat_on_bus,$(DT_COMPAT_SOLOMON_SSD1306FB),i2c) - select SPI if $(dt_compat_on_bus,$(DT_COMPAT_SOLOMON_SSD1306FB),spi) - select I2C if $(dt_compat_on_bus,$(DT_COMPAT_SOLOMON_SSD1309FB),i2c) - select SPI if $(dt_compat_on_bus,$(DT_COMPAT_SOLOMON_SSD1309FB),spi) + depends on DT_HAS_SOLOMON_SSD1306_ENABLED || DT_HAS_SOLOMON_SSD1309_ENABLED || DT_HAS_SINOWEALTH_SH1106_ENABLED + select I2C if $(dt_compat_on_bus,$(DT_COMPAT_SOLOMON_SSD1306),i2c) + select SPI if $(dt_compat_on_bus,$(DT_COMPAT_SOLOMON_SSD1306),spi) + select I2C if $(dt_compat_on_bus,$(DT_COMPAT_SOLOMON_SSD1309),i2c) + select SPI if $(dt_compat_on_bus,$(DT_COMPAT_SOLOMON_SSD1309),spi) select I2C if $(dt_compat_on_bus,$(DT_COMPAT_SINOWEALTH_SH1106),i2c) select SPI if $(dt_compat_on_bus,$(DT_COMPAT_SINOWEALTH_SH1106),spi) help diff --git a/drivers/display/ssd1306.c b/drivers/display/ssd1306.c index 04f6e7f2e7ec..322426d2dc5c 100644 --- a/drivers/display/ssd1306.c +++ b/drivers/display/ssd1306.c @@ -71,8 +71,8 @@ struct ssd1306_data { enum display_orientation orientation; }; -#if (DT_HAS_COMPAT_ON_BUS_STATUS_OKAY(solomon_ssd1306fb, i2c) || \ - DT_HAS_COMPAT_ON_BUS_STATUS_OKAY(solomon_ssd1309fb, i2c) || \ +#if (DT_HAS_COMPAT_ON_BUS_STATUS_OKAY(solomon_ssd1306, i2c) || \ + DT_HAS_COMPAT_ON_BUS_STATUS_OKAY(solomon_ssd1309, i2c) || \ DT_HAS_COMPAT_ON_BUS_STATUS_OKAY(sinowealth_sh1106, i2c)) static bool ssd1306_bus_ready_i2c(const struct device *dev) { @@ -99,8 +99,8 @@ static const char *ssd1306_bus_name_i2c(const struct device *dev) } #endif -#if (DT_HAS_COMPAT_ON_BUS_STATUS_OKAY(solomon_ssd1306fb, spi) || \ - DT_HAS_COMPAT_ON_BUS_STATUS_OKAY(solomon_ssd1309fb, spi) || \ +#if (DT_HAS_COMPAT_ON_BUS_STATUS_OKAY(solomon_ssd1306, spi) || \ + DT_HAS_COMPAT_ON_BUS_STATUS_OKAY(solomon_ssd1309, spi) || \ DT_HAS_COMPAT_ON_BUS_STATUS_OKAY(sinowealth_sh1106, spi)) static bool ssd1306_bus_ready_spi(const struct device *dev) { @@ -627,7 +627,7 @@ static DEVICE_API(display, ssd1306_driver_api) = { .com_sequential = DT_PROP(node_id, com_sequential), \ .prechargep = DT_PROP(node_id, prechargep), \ .color_inversion = DT_PROP(node_id, inversion_on), \ - .ssd1309_compatible = DT_NODE_HAS_COMPAT(node_id, solomon_ssd1309fb), \ + .ssd1309_compatible = DT_NODE_HAS_COMPAT(node_id, solomon_ssd1309), \ .sh1106_compatible = DT_NODE_HAS_COMPAT(node_id, sinowealth_sh1106), \ .ready_time_ms = DT_PROP(node_id, ready_time_ms), \ .use_internal_iref = DT_PROP(node_id, use_internal_iref), \ @@ -638,6 +638,6 @@ static DEVICE_API(display, ssd1306_driver_api) = { DEVICE_DT_DEFINE(node_id, ssd1306_init, NULL, &data##node_id, &config##node_id, \ POST_KERNEL, CONFIG_DISPLAY_INIT_PRIORITY, &ssd1306_driver_api); -DT_FOREACH_STATUS_OKAY(solomon_ssd1306fb, SSD1306_DEFINE) -DT_FOREACH_STATUS_OKAY(solomon_ssd1309fb, SSD1306_DEFINE) +DT_FOREACH_STATUS_OKAY(solomon_ssd1306, SSD1306_DEFINE) +DT_FOREACH_STATUS_OKAY(solomon_ssd1309, SSD1306_DEFINE) DT_FOREACH_STATUS_OKAY(sinowealth_sh1106, SSD1306_DEFINE) diff --git a/dts/bindings/display/sinowealth,sh1106-i2c.yaml b/dts/bindings/display/sinowealth,sh1106-i2c.yaml index f476f838bbfe..2106dde1a559 100644 --- a/dts/bindings/display/sinowealth,sh1106-i2c.yaml +++ b/dts/bindings/display/sinowealth,sh1106-i2c.yaml @@ -5,4 +5,4 @@ description: SH1106 128x64 dot-matrix display controller on I2C bus compatible: "sinowealth,sh1106" -include: ["solomon,ssd1306fb-common.yaml", "i2c-device.yaml"] +include: ["solomon,ssd1306-common.yaml", "i2c-device.yaml"] diff --git a/dts/bindings/display/sinowealth,sh1106-spi.yaml b/dts/bindings/display/sinowealth,sh1106-spi.yaml index 5bb843c365d7..068c9ad6c718 100644 --- a/dts/bindings/display/sinowealth,sh1106-spi.yaml +++ b/dts/bindings/display/sinowealth,sh1106-spi.yaml @@ -5,7 +5,7 @@ description: SH1106 128x64 dot-matrix display controller on SPI bus compatible: "sinowealth,sh1106" -include: ["solomon,ssd1306fb-common.yaml", "spi-device.yaml"] +include: ["solomon,ssd1306-common.yaml", "spi-device.yaml"] properties: data-cmd-gpios: diff --git a/dts/bindings/display/solomon,ssd1306fb-common.yaml b/dts/bindings/display/solomon,ssd1306-common.yaml similarity index 100% rename from dts/bindings/display/solomon,ssd1306fb-common.yaml rename to dts/bindings/display/solomon,ssd1306-common.yaml diff --git a/dts/bindings/display/solomon,ssd1306fb-i2c.yaml b/dts/bindings/display/solomon,ssd1306-i2c.yaml similarity index 71% rename from dts/bindings/display/solomon,ssd1306fb-i2c.yaml rename to dts/bindings/display/solomon,ssd1306-i2c.yaml index a2eee397c074..f270b2f4886c 100644 --- a/dts/bindings/display/solomon,ssd1306fb-i2c.yaml +++ b/dts/bindings/display/solomon,ssd1306-i2c.yaml @@ -7,6 +7,6 @@ description: | The Solomon SSD1306 is a monochrome OLED controller with a maximum 128x64 resolution. -compatible: "solomon,ssd1306fb" +compatible: "solomon,ssd1306" -include: ["solomon,ssd1306fb-common.yaml", "i2c-device.yaml"] +include: ["solomon,ssd1306-common.yaml", "i2c-device.yaml"] diff --git a/dts/bindings/display/solomon,ssd1306fb-spi.yaml b/dts/bindings/display/solomon,ssd1306-spi.yaml similarity index 78% rename from dts/bindings/display/solomon,ssd1306fb-spi.yaml rename to dts/bindings/display/solomon,ssd1306-spi.yaml index 1cd7a39e6962..c87ef810b43b 100644 --- a/dts/bindings/display/solomon,ssd1306fb-spi.yaml +++ b/dts/bindings/display/solomon,ssd1306-spi.yaml @@ -7,9 +7,9 @@ description: | The Solomon SSD1306 is a monochrome OLED controller with a maximum 128x64 resolution. -compatible: "solomon,ssd1306fb" +compatible: "solomon,ssd1306" -include: ["solomon,ssd1306fb-common.yaml", "spi-device.yaml"] +include: ["solomon,ssd1306-common.yaml", "spi-device.yaml"] properties: data-cmd-gpios: diff --git a/dts/bindings/display/solomon,ssd1309fb-i2c.yaml b/dts/bindings/display/solomon,ssd1309-i2c.yaml similarity index 71% rename from dts/bindings/display/solomon,ssd1309fb-i2c.yaml rename to dts/bindings/display/solomon,ssd1309-i2c.yaml index c47668b4df0b..968457861985 100644 --- a/dts/bindings/display/solomon,ssd1309fb-i2c.yaml +++ b/dts/bindings/display/solomon,ssd1309-i2c.yaml @@ -7,6 +7,6 @@ description: | The Solomon SSD1309 is a monochrome OLED controller with a maximum 128x64 resolution. -compatible: "solomon,ssd1309fb" +compatible: "solomon,ssd1309" -include: ["solomon,ssd1306fb-common.yaml", "i2c-device.yaml"] +include: ["solomon,ssd1306-common.yaml", "i2c-device.yaml"] diff --git a/dts/bindings/display/solomon,ssd1309fb-spi.yaml b/dts/bindings/display/solomon,ssd1309-spi.yaml similarity index 78% rename from dts/bindings/display/solomon,ssd1309fb-spi.yaml rename to dts/bindings/display/solomon,ssd1309-spi.yaml index d894a795d37e..35789e6a35f6 100644 --- a/dts/bindings/display/solomon,ssd1309fb-spi.yaml +++ b/dts/bindings/display/solomon,ssd1309-spi.yaml @@ -7,9 +7,9 @@ description: | The Solomon SSD1309 is a monochrome OLED controller with a maximum 128x64 resolution. -compatible: "solomon,ssd1309fb" +compatible: "solomon,ssd1309" -include: ["solomon,ssd1306fb-common.yaml", "spi-device.yaml"] +include: ["solomon,ssd1306-common.yaml", "spi-device.yaml"] properties: data-cmd-gpios: diff --git a/tests/drivers/build_all/display/app.overlay b/tests/drivers/build_all/display/app.overlay index 9f2c304e4809..e151f67c4450 100644 --- a/tests/drivers/build_all/display/app.overlay +++ b/tests/drivers/build_all/display/app.overlay @@ -643,7 +643,7 @@ }; test_ssd1306: ssd1306@1 { - compatible = "solomon,ssd1306fb"; + compatible = "solomon,ssd1306"; reg = <0x1>; width = <128>; height = <64>; From fa30e17ffa29ebbb9b07ae652a098fc34d3b1b51 Mon Sep 17 00:00:00 2001 From: Camille BAUD Date: Thu, 15 Jan 2026 13:14:17 +0100 Subject: [PATCH 0110/6328] doc: release: Notes about SSD1306/9 bindings Adds notes about SSD1306/9 bindings Signed-off-by: Camille BAUD --- doc/releases/migration-guide-4.4.rst | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/doc/releases/migration-guide-4.4.rst b/doc/releases/migration-guide-4.4.rst index 2b19fcdddd14..991c0625b109 100644 --- a/doc/releases/migration-guide-4.4.rst +++ b/doc/releases/migration-guide-4.4.rst @@ -360,6 +360,10 @@ Display * ``solomon,ssd1327fb`` devicetree compatible has been renamed :dtcompatible:`solomon,ssd1327` to harmonize with other display controllers and eliminate the zephyr-irrelevant ``fb`` suffix. +* ``solomon,ssd1306fb`` and ``solomon,ssd1309fb`` devicetree compatibles has been renamed + :dtcompatible:`solomon,ssd1306` and :dtcompatible:`solomon,ssd1309` respectively, + to harmonize with other display controllers and eliminate the zephyr-irrelevant ``fb`` suffix. + DMA === From 74975b0be5adbe198b453850d1bef06e8b7e831f Mon Sep 17 00:00:00 2001 From: Camille BAUD Date: Sat, 17 Jan 2026 23:44:27 +0100 Subject: [PATCH 0111/6328] drivers: display: ssd1306: move registers from header to main file standard self-containment Signed-off-by: Camille BAUD --- drivers/display/ssd1306.c | 111 ++++++++++++++++++++++++----- drivers/display/ssd1306_regs.h | 123 --------------------------------- 2 files changed, 95 insertions(+), 139 deletions(-) delete mode 100644 drivers/display/ssd1306_regs.h diff --git a/drivers/display/ssd1306.c b/drivers/display/ssd1306.c index 322426d2dc5c..f52dadcf366b 100644 --- a/drivers/display/ssd1306.c +++ b/drivers/display/ssd1306.c @@ -16,21 +16,100 @@ LOG_MODULE_REGISTER(ssd1306, CONFIG_DISPLAY_LOG_LEVEL); #include #include -#include "ssd1306_regs.h" +/* + * Commands + */ +#define SSD1306_SET_LOWER_COL_ADDRESS 0x00 /* No arguments, command is argument */ +#define SSD1306_SET_LOWER_COL_ADDRESS_END 0x0f /* Command as argument end */ +#define SSD1306_SET_HIGHER_COL_ADDRESS 0x10 /* No arguments, command is argument */ +#define SSD1306_SET_HIGHER_COL_ADDRESS_END 0x1f /* Command as argument end */ +#define SSD1306_SET_MEM_ADDRESSING_MODE 0x20 /* 1 byte args: A[1:0] Addressing mode */ +#define SSD1306_SET_COLUMN_ADDRESS 0x21 /* 2 bytes args: column address, start end */ +#define SSD1306_SET_PAGE_ADDRESS 0x22 /* 2 bytes args: page address, start end */ +#define SSD1306_SET_PUMP_VOLTAGE_64 0x30 /* No arguments, command is argument */ +#define SSD1306_SET_PUMP_VOLTAGE_74 0x31 /* No arguments, command is argument */ +#define SSD1306_SET_PUMP_VOLTAGE_80 0x32 /* No arguments, command is argument */ +#define SSD1306_SET_PUMP_VOLTAGE_90 0x33 /* No arguments, command is argument */ +#define SSD1306_SET_START_LINE 0x40 /* No arguments, command is argument */ +#define SSD1306_SET_START_LINE_END 0x7f /* Command as argument end */ +#define SSD1306_SET_CONTRAST_CTRL 0x81 /* 1 byte args: Constrast */ +#define SH1106_SET_DCDC_DISABLED 0x8a /* No arguments, command is argument */ +#define SH1106_SET_DCDC_ENABLED 0x8b /* No arguments, command is argument */ +#define SSD1306_SET_CHARGE_PUMP 0x8d /* 1 byte args: A[0]A[7] Volts A[2] Enable */ +#define SSD1306_SET_SEGMENT_MAP_NORMAL 0xa0 /* No arguments */ +#define SSD1306_SET_SEGMENT_MAP_REMAPED 0xa1 /* No arguments */ +#define SSD1306_SET_ENTIRE_DISPLAY_OFF 0xa4 /* No arguments */ +#define SSD1306_SET_ENTIRE_DISPLAY_ON 0xa5 /* No arguments */ +#define SSD1306_SET_NORMAL_DISPLAY 0xa6 /* No arguments */ +#define SSD1306_SET_REVERSE_DISPLAY 0xa7 /* No arguments */ +#define SSD1306_SET_MULTIPLEX_RATIO 0xa8 /* 1 byte args: A[5:0] Multiplex Ratio */ +#define SSD1306_SET_IREF_MODE 0xad /* 1 byte args: A[5:4] Iref configuration */ +#define SH1106_SET_DCDC_MODE 0xad /* No arguments */ +#define SSD1306_SET_DISPLAY_OFF 0xae /* No arguments */ +#define SSD1306_SET_DISPLAY_ON 0xaf /* No arguments */ +#define SSD1306_SET_PAGE_START_ADDRESS 0xb0 /* No arguments, command is argument */ +#define SSD1306_SET_PAGE_START_ADDRESS_END 0xb7 /* Command as argument end */ +#define SSD1306_SET_COM_OUTPUT_SCAN_NORMAL 0xc0 /* No arguments */ +#define SSD1306_SET_COM_OUTPUT_SCAN_FLIPPED 0xc8 /* No arguments */ +#define SSD1306_SET_DISPLAY_OFFSET 0xd3 /* 1 byte args: A[5:0] COM shift */ +#define SSD1306_SET_CLOCK_DIV_RATIO 0xd5 /* 1 byte args: A[3:0] dratio A[7:4] oscfreq */ +#define SSD1306_SET_CHARGE_PERIOD 0xd9 /* 1 byte args: A[3:0] Phase1 A[7:4] Phase2 */ +#define SSD1306_SET_PADS_HW_CONFIG 0xda /* 1 byte args: A[5:4] COM configuration */ +#define SSD1306_SET_VCOM_DESELECT_LEVEL 0xdb /* 1 byte args: A[5:4] Voltage */ -#define SSD1306_CLOCK_DIV_RATIO 0x0 -#define SSD1306_CLOCK_FREQUENCY 0x8 -#define SSD1306_PANEL_VCOM_DESEL_LEVEL 0x20 -#define SSD1306_PANEL_PUMP_VOLTAGE SSD1306_SET_PUMP_VOLTAGE_90 +/* + * Configuration Constants + */ +#define SSD1306_CLOCK_DIV_RATIO 0x0 +#define SSD1306_CLOCK_FREQUENCY 0x8 +#define SSD1306_PANEL_VCOM_DESEL_LEVEL 0x20 +#define SSD1306_PANEL_PUMP_VOLTAGE SSD1306_SET_PUMP_VOLTAGE_90 +#define SSD1306_MEM_ADDRESSING_HORIZONTAL 0x00 +#define SSD1306_MEM_ADDRESSING_VERTICAL 0x01 +#define SSD1306_MEM_ADDRESSING_PAGE 0x02 +#define SSD1306_PANEL_VCOM_DESEL_LEVEL_SSD1309 0x34 +#define SSD1306_PADS_HW_SEQUENTIAL 0x02 +#define SSD1306_PADS_HW_ALTERNATIVE 0x12 +#define SSD1306_PADS_HW_COM_FLIP_SEQUENTIAL 0x22 +#define SSD1306_PADS_HW_COM_FLIP_ALTERNATIVE 0x32 +#define SSD1306_IREF_MODE_INTERNAL_30UA 0x30 +#define SSD1306_IREF_MODE_INTERNAL_19UA 0x10 +#define SSD1306_IREF_MODE_EXTERNAL 0x00 +#define SSD1306_CHARGE_PUMP_DISABLED 0x10 +#define SSD1306_CHARGE_PUMP_ENABLED 0x14 -#define SSD1306_PANEL_VCOM_DESEL_LEVEL_SSD1309 0x34 +/* + * Code Constants + */ +/* All following bytes will contain commands */ +#define SSD1306_I2C_ALL_BYTES_CMD 0x00 +/* All following bytes will contain data */ +#define SSD1306_I2C_ALL_BYTES_DATA 0x40 +/* The next byte will contain a command */ +#define SSD1306_I2C_BYTE_CMD 0x80 +/* The next byte will contain data */ +#define SSD1306_I2C_BYTE_DATA 0xc0 + +#define SSD1306_RESET_DELAY 1 +#define SSD1306_SUPPLY_DELAY 20 #ifndef SSD1306_ADDRESSING_MODE -#define SSD1306_ADDRESSING_MODE (SSD1306_SET_MEM_ADDRESSING_HORIZONTAL) +#define SSD1306_ADDRESSING_MODE (SSD1306_MEM_ADDRESSING_HORIZONTAL) #endif #define SSD1306_PPB_SHIFT 3 +/* + * Fields + */ +#define SSD1306_READ_STATUS_MASK 0xc0 +#define SSD1306_READ_STATUS_BUSY 0x80 +#define SSD1306_READ_STATUS_ON 0x40 +#define SSD1306_SET_LOWER_COL_ADDRESS_MASK 0x0f +#define SSD1306_SET_HIGHER_COL_ADDRESS_MASK 0x0f +#define SSD1306_SET_START_LINE_MASK 0x3f +#define SSD1306_SET_PAGE_START_ADDRESS_MASK 0x07 + union ssd1306_bus { struct i2c_dt_spec i2c; struct spi_dt_spec spi; @@ -86,8 +165,8 @@ static int ssd1306_write_bus_i2c(const struct device *dev, uint8_t *buf, size_t const struct ssd1306_config *config = dev->config; return i2c_burst_write_dt(&config->bus.i2c, - command ? SSD1306_CONTROL_ALL_BYTES_CMD : - SSD1306_CONTROL_ALL_BYTES_DATA, + command ? SSD1306_I2C_ALL_BYTES_CMD : + SSD1306_I2C_ALL_BYTES_DATA, buf, len); } @@ -198,8 +277,8 @@ static inline int ssd1306_set_hardware_config(const struct device *dev) SSD1306_SET_DISPLAY_OFFSET, config->display_offset, SSD1306_SET_PADS_HW_CONFIG, - (config->com_sequential ? SSD1306_SET_PADS_HW_SEQUENTIAL - : SSD1306_SET_PADS_HW_ALTERNATIVE), + (config->com_sequential ? SSD1306_PADS_HW_SEQUENTIAL + : SSD1306_PADS_HW_ALTERNATIVE), SSD1306_SET_MULTIPLEX_RATIO, config->multiplex_ratio, }; @@ -211,9 +290,9 @@ static inline int ssd1306_set_charge_pump(const struct device *dev) { const struct ssd1306_config *config = dev->config; uint8_t cmd_buf[] = { - (config->sh1106_compatible ? SH1106_SET_DCDC_MODE : SSD1306_SET_CHARGE_PUMP_ON), + (config->sh1106_compatible ? SH1106_SET_DCDC_MODE : SSD1306_SET_CHARGE_PUMP), (config->sh1106_compatible ? SH1106_SET_DCDC_ENABLED - : SSD1306_SET_CHARGE_PUMP_ON_ENABLED), + : SSD1306_CHARGE_PUMP_ENABLED), SSD1306_PANEL_PUMP_VOLTAGE, }; @@ -226,7 +305,7 @@ static inline int ssd1306_set_iref_mode(const struct device *dev) const struct ssd1306_config *config = dev->config; uint8_t cmd_buf[] = { SSD1306_SET_IREF_MODE, - SSD1306_SET_IREF_MODE_INTERNAL, + SSD1306_IREF_MODE_INTERNAL_30UA, }; if (config->use_internal_iref) { @@ -240,7 +319,7 @@ static int ssd1306_resume(const struct device *dev) { const struct ssd1306_config *config = dev->config; uint8_t cmd_buf[] = { - SSD1306_DISPLAY_ON, + SSD1306_SET_DISPLAY_ON, }; /* Turn on supply if pin connected */ @@ -256,7 +335,7 @@ static int ssd1306_suspend(const struct device *dev) { const struct ssd1306_config *config = dev->config; uint8_t cmd_buf[] = { - SSD1306_DISPLAY_OFF, + SSD1306_SET_DISPLAY_OFF, }; /* Turn off supply if pin connected */ diff --git a/drivers/display/ssd1306_regs.h b/drivers/display/ssd1306_regs.h deleted file mode 100644 index 87dc3b6ba5b4..000000000000 --- a/drivers/display/ssd1306_regs.h +++ /dev/null @@ -1,123 +0,0 @@ -/* - * Copyright (c) 2018 Phytec Messtechnik GmbH - * - * SPDX-License-Identifier: Apache-2.0 - */ - - -#ifndef __SSD1306_REGS_H__ -#define __SSD1306_REGS_H__ - -/* All following bytes will contain commands */ -#define SSD1306_CONTROL_ALL_BYTES_CMD 0x00 -/* All following bytes will contain data */ -#define SSD1306_CONTROL_ALL_BYTES_DATA 0x40 -/* The next byte will contain a command */ -#define SSD1306_CONTROL_BYTE_CMD 0x80 -/* The next byte will contain data */ -#define SSD1306_CONTROL_BYTE_DATA 0xc0 -#define SSD1306_READ_STATUS_MASK 0xc0 -#define SSD1306_READ_STATUS_BUSY 0x80 -#define SSD1306_READ_STATUS_ON 0x40 - -/* - * Fundamental Command Table - */ -#define SSD1306_SET_CONTRAST_CTRL 0x81 /* double byte command */ - -#define SSD1306_SET_ENTIRE_DISPLAY_OFF 0xa4 -#define SSD1306_SET_ENTIRE_DISPLAY_ON 0xa5 - -/* RAM data of 1 indicates an "ON" pixel */ -#define SSD1306_SET_NORMAL_DISPLAY 0xa6 -/* RAM data of 0 indicates an "ON" pixel */ -#define SSD1306_SET_REVERSE_DISPLAY 0xa7 - -#define SSD1306_DISPLAY_OFF 0xae -#define SSD1306_DISPLAY_ON 0xaf - -/* - * Addressing Setting Command Table - */ -#define SSD1306_SET_LOWER_COL_ADDRESS 0x00 -#define SSD1306_SET_LOWER_COL_ADDRESS_MASK 0x0f - -#define SSD1306_SET_HIGHER_COL_ADDRESS 0x10 -#define SSD1306_SET_HIGHER_COL_ADDRESS_MASK 0x0f - -#define SSD1306_SET_MEM_ADDRESSING_MODE 0x20 /* double byte command */ -#define SSD1306_SET_MEM_ADDRESSING_HORIZONTAL 0x00 -#define SSD1306_SET_MEM_ADDRESSING_VERTICAL 0x01 -#define SSD1306_SET_MEM_ADDRESSING_PAGE 0x02 - -#define SSD1306_SET_COLUMN_ADDRESS 0x21 /* triple byte command */ - -#define SSD1306_SET_PAGE_ADDRESS 0x22 /* triple byte command */ - -#define SSD1306_SET_PAGE_START_ADDRESS 0xb0 -#define SSD1306_SET_PAGE_START_ADDRESS_MASK 0x07 - - -/* - * Hardware Configuration Command Table - */ -#define SSD1306_SET_START_LINE 0x40 -#define SSD1306_SET_START_LINE_MASK 0x3f - -#define SSD1306_SET_SEGMENT_MAP_NORMAL 0xa0 -#define SSD1306_SET_SEGMENT_MAP_REMAPED 0xa1 - -#define SSD1306_SET_MULTIPLEX_RATIO 0xa8 /* double byte command */ - -#define SSD1306_SET_COM_OUTPUT_SCAN_NORMAL 0xc0 -#define SSD1306_SET_COM_OUTPUT_SCAN_FLIPPED 0xc8 - -#define SSD1306_SET_DISPLAY_OFFSET 0xd3 /* double byte command */ - -#define SSD1306_SET_PADS_HW_CONFIG 0xda /* double byte command */ -#define SSD1306_SET_PADS_HW_SEQUENTIAL 0x02 -#define SSD1306_SET_PADS_HW_ALTERNATIVE 0x12 - -#define SSD1306_SET_IREF_MODE 0xad -#define SSD1306_SET_IREF_MODE_INTERNAL 0x30 -#define SSD1306_SET_IREF_MODE_EXTERNAL 0x00 - - -/* - * Timing and Driving Scheme Setting Command Table - */ -#define SSD1306_SET_CLOCK_DIV_RATIO 0xd5 /* double byte command */ - -#define SSD1306_SET_CHARGE_PERIOD 0xd9 /* double byte command */ - -#define SSD1306_SET_VCOM_DESELECT_LEVEL 0xdb /* double byte command */ - -#define SSD1306_NOP 0xe3 - -/* - * Charge Pump Command Table - */ -#define SSD1306_SET_CHARGE_PUMP_ON 0x8d /* double byte command */ -#define SSD1306_SET_CHARGE_PUMP_ON_DISABLED 0x10 -#define SSD1306_SET_CHARGE_PUMP_ON_ENABLED 0x14 - -#define SH1106_SET_DCDC_MODE 0xad /* double byte command */ -#define SH1106_SET_DCDC_DISABLED 0x8a -#define SH1106_SET_DCDC_ENABLED 0x8b - -#define SSD1306_SET_PUMP_VOLTAGE_64 0x30 -#define SSD1306_SET_PUMP_VOLTAGE_74 0x31 -#define SSD1306_SET_PUMP_VOLTAGE_80 0x32 -#define SSD1306_SET_PUMP_VOLTAGE_90 0x33 - -/* - * Read modify write - */ -#define SSD1306_READ_MODIFY_WRITE_START 0xe0 -#define SSD1306_READ_MODIFY_WRITE_END 0xee - -/* time constants in ms */ -#define SSD1306_RESET_DELAY 1 -#define SSD1306_SUPPLY_DELAY 20 - -#endif From a780587ccbff7420d9a2464af5327fad1b68a66e Mon Sep 17 00:00:00 2001 From: Camille BAUD Date: Tue, 20 Jan 2026 15:39:46 +0100 Subject: [PATCH 0112/6328] drivers: display: move ssd1306.c to display_ssd1306.c add missig prefix Signed-off-by: Camille BAUD --- drivers/display/CMakeLists.txt | 2 +- drivers/display/{ssd1306.c => display_ssd1306.c} | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename drivers/display/{ssd1306.c => display_ssd1306.c} (100%) diff --git a/drivers/display/CMakeLists.txt b/drivers/display/CMakeLists.txt index 135e0929dd5c..55ea2a4d521f 100644 --- a/drivers/display/CMakeLists.txt +++ b/drivers/display/CMakeLists.txt @@ -39,7 +39,7 @@ zephyr_library_sources_ifdef(CONFIG_RENESAS_RA_GLCDC display_renesas_ra.c) zephyr_library_sources_ifdef(CONFIG_RM67162 display_rm67162.c) zephyr_library_sources_ifdef(CONFIG_RM68200 display_rm68200.c) zephyr_library_sources_ifdef(CONFIG_SH1122 display_sh1122.c) -zephyr_library_sources_ifdef(CONFIG_SSD1306 ssd1306.c) +zephyr_library_sources_ifdef(CONFIG_SSD1306 display_ssd1306.c) zephyr_library_sources_ifdef(CONFIG_SSD1320 display_ssd1320.c) zephyr_library_sources_ifdef(CONFIG_SSD1322 ssd1322.c) zephyr_library_sources_ifdef(CONFIG_SSD1327_5 display_ssd1327_5.c) diff --git a/drivers/display/ssd1306.c b/drivers/display/display_ssd1306.c similarity index 100% rename from drivers/display/ssd1306.c rename to drivers/display/display_ssd1306.c From 0f046ac0de2f0bdb9337d8e9d249fd1cb5006da0 Mon Sep 17 00:00:00 2001 From: Gaetan Perrot Date: Fri, 16 Jan 2026 17:11:12 +0900 Subject: [PATCH 0113/6328] drivers: adc: adc_ambiq: check return value of adc power control Handle the return value of am_hal_adc_power_control() during ADC initialization. The previous code overwrote the return value before it was checked, which could silently ignore failures when powering on the ADC. Fix this by validating the return code and propagating an error if the operation fails. Signed-off-by: Gaetan Perrot --- drivers/adc/adc_ambiq.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/adc/adc_ambiq.c b/drivers/adc/adc_ambiq.c index a5b329019740..8e5068569335 100644 --- a/drivers/adc/adc_ambiq.c +++ b/drivers/adc/adc_ambiq.c @@ -437,6 +437,11 @@ static int adc_ambiq_init(const struct device *dev) /* power on ADC*/ ret = am_hal_adc_power_control(data->adcHandle, AM_HAL_SYSCTRL_WAKE, false); + if (ret != AM_HAL_STATUS_SUCCESS) { + LOG_ERR("Failed to power on ADC, code: %d", ret); + return -EIO; + } + ret = pinctrl_apply_state(cfg->pin_cfg, PINCTRL_STATE_DEFAULT); if (ret < 0) { return ret; From 981872e2030a8bf5b058e16d6f6a0cc0bf487216 Mon Sep 17 00:00:00 2001 From: Gaetan Perrot Date: Tue, 20 Jan 2026 01:52:34 +0900 Subject: [PATCH 0114/6328] drivers: ethernet: nxp_imx_netc: netc_blk: make ierb_init() void ierb_init() never reports an error and cannot fail in practice. Returning an int led to a dead error. Convert ierb_init() to a void function, drop the unused return value checks, and provide a no-op implementation for SoCs that do not require IERB initialization. This simplifies the control flow and removes an unnecessary error condition. Signed-off-by: Gaetan Perrot --- .../ethernet/nxp_imx_netc/eth_nxp_imx_netc_blk.c | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/drivers/ethernet/nxp_imx_netc/eth_nxp_imx_netc_blk.c b/drivers/ethernet/nxp_imx_netc/eth_nxp_imx_netc_blk.c index 84caf5e3795a..591b23537718 100644 --- a/drivers/ethernet/nxp_imx_netc/eth_nxp_imx_netc_blk.c +++ b/drivers/ethernet/nxp_imx_netc/eth_nxp_imx_netc_blk.c @@ -147,7 +147,7 @@ static int ierb_unlock(const struct device *dev) #ifdef CONFIG_SOC_MIMX9596 /* Set LDID */ -static int ierb_init(const struct device *dev) +static void ierb_init(const struct device *dev) { uintptr_t base = DEVICE_MMIO_NAMED_GET(dev, ierb); @@ -173,8 +173,6 @@ static int ierb_init(const struct device *dev) sys_write32(6, base + IERB_VFAUXR(5)); /* NETC TIMER */ sys_write32(7, base + IERB_T0FAUXR); - - return 0; } static int netcmix_init(const struct device *dev) @@ -190,9 +188,9 @@ static int netcmix_init(const struct device *dev) return 0; } #elif defined(CONFIG_SOC_MIMX94398) -static int ierb_init(const struct device *dev) +static void ierb_init(const struct device *dev) { - return 0; + ARG_UNUSED(dev); } @@ -240,10 +238,7 @@ static int eth_nxp_imx_netc_blk_init(const struct device *dev) } } - if (ierb_init(dev) != 0) { - LOG_ERR("Failed to initialize IERB"); - return -EIO; - } + ierb_init(dev); ret = ierb_lock(dev); if (ret) { From 50ba0244c1136b8bf11fda052e640a84d44bc691 Mon Sep 17 00:00:00 2001 From: Felix Wang Date: Tue, 20 Jan 2026 08:31:47 +0530 Subject: [PATCH 0115/6328] MAINTAINERS: add FelixWang47831 as counter collaborator Add FelixWang47831 as a collaborator for the counter driver. Signed-off-by: Felix Wang --- MAINTAINERS.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/MAINTAINERS.yml b/MAINTAINERS.yml index 6b231468d6ba..bf191bbf1ddc 100644 --- a/MAINTAINERS.yml +++ b/MAINTAINERS.yml @@ -1460,6 +1460,7 @@ Documentation Infrastructure: - nordic-krch collaborators: - Holt-Sun + - FelixWang47831 files: - drivers/counter/ - include/zephyr/drivers/counter.h From d9d46c0ce343a895ffcb7b37d8216c38821c7694 Mon Sep 17 00:00:00 2001 From: Yangbo Lu Date: Tue, 20 Jan 2026 09:54:05 +0800 Subject: [PATCH 0116/6328] net: dsa: make dsa_tag.h as common header file Moved dsa_tag.h to include folder as common header file. And we will support iterable section for vendor dsa tag protocol drivers registering. Signed-off-by: Yangbo Lu --- include/zephyr/net/dsa_tag.h | 67 +++++++++++++++++++++++++++ subsys/net/l2/ethernet/dsa/dsa_core.c | 6 +-- subsys/net/l2/ethernet/dsa/dsa_port.c | 5 +- subsys/net/l2/ethernet/dsa/dsa_tag.c | 5 +- subsys/net/l2/ethernet/dsa/dsa_tag.h | 18 ------- 5 files changed, 73 insertions(+), 28 deletions(-) create mode 100644 include/zephyr/net/dsa_tag.h delete mode 100644 subsys/net/l2/ethernet/dsa/dsa_tag.h diff --git a/include/zephyr/net/dsa_tag.h b/include/zephyr/net/dsa_tag.h new file mode 100644 index 000000000000..bd09353402bb --- /dev/null +++ b/include/zephyr/net/dsa_tag.h @@ -0,0 +1,67 @@ +/* + * SPDX-FileCopyrightText: Copyright 2025-2026 NXP + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @file + * @brief Definitions for DSA tag protocol + */ + +#ifndef ZEPHYR_INCLUDE_NET_DSA_TAG_H_ +#define ZEPHYR_INCLUDE_NET_DSA_TAG_H_ + +/** + * @brief Definitions for DSA tag protocol + * @defgroup dsa_tag DSA tag protocol + * @since 4.4 + * @version 0.8.0 + * @ingroup ethernet + * @{ + */ + +#include +#ifdef CONFIG_DSA_TAG_PROTOCOL_NETC +#include +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/** @cond INTERNAL_HIDDEN */ + +/* + * DSA tag protocol handles packet received by untagging + * + * param iface: Interface of DSA conduit port on which receives the packet + * param pkt: Network packet + * + * Returns: Interface of DSA user port to redirect + */ +struct net_if *dsa_tag_recv(struct net_if *iface, struct net_pkt *pkt); + +/* + * DSA tag protocol handles packet transmitted by tagging + * + * param iface: Interface of DSA user port to transmit + * param pkt: Network packet + * + * Returns: Network packet tagged + */ +struct net_pkt *dsa_tag_xmit(struct net_if *iface, struct net_pkt *pkt); + +/* + * Set up DSA tag protocol + * + * param dev_cpu: Device of DSA CPU port + */ +void dsa_tag_setup(const struct device *dev_cpu); + +/** @endcond */ + +/** + * @} + */ + +#endif /* ZEPHYR_INCLUDE_NET_DSA_TAG_H_ */ diff --git a/subsys/net/l2/ethernet/dsa/dsa_core.c b/subsys/net/l2/ethernet/dsa/dsa_core.c index 610f14e09dc6..f30f12078237 100644 --- a/subsys/net/l2/ethernet/dsa/dsa_core.c +++ b/subsys/net/l2/ethernet/dsa/dsa_core.c @@ -1,6 +1,5 @@ /* - * Copyright 2025 NXP - * + * SPDX-FileCopyrightText: Copyright 2025-2026 NXP * SPDX-License-Identifier: Apache-2.0 */ @@ -9,8 +8,7 @@ LOG_MODULE_REGISTER(net_dsa_core, CONFIG_NET_DSA_LOG_LEVEL); #include #include - -#include "dsa_tag.h" +#include struct net_if *dsa_recv(struct net_if *iface, struct net_pkt *pkt) { diff --git a/subsys/net/l2/ethernet/dsa/dsa_port.c b/subsys/net/l2/ethernet/dsa/dsa_port.c index 8e2dd65347ce..234671006e09 100644 --- a/subsys/net/l2/ethernet/dsa/dsa_port.c +++ b/subsys/net/l2/ethernet/dsa/dsa_port.c @@ -1,6 +1,5 @@ /* - * Copyright 2025 NXP - * + * SPDX-FileCopyrightText: Copyright 2025-2026 NXP * SPDX-License-Identifier: Apache-2.0 */ @@ -10,7 +9,7 @@ LOG_MODULE_REGISTER(net_dsa_port, CONFIG_NET_DSA_LOG_LEVEL); #include #include #include -#include "dsa_tag.h" +#include #if defined(CONFIG_NET_INTERFACE_NAME_LEN) #define INTERFACE_NAME_LEN CONFIG_NET_INTERFACE_NAME_LEN diff --git a/subsys/net/l2/ethernet/dsa/dsa_tag.c b/subsys/net/l2/ethernet/dsa/dsa_tag.c index 014b264642f0..fa7c803e69f4 100644 --- a/subsys/net/l2/ethernet/dsa/dsa_tag.c +++ b/subsys/net/l2/ethernet/dsa/dsa_tag.c @@ -1,6 +1,5 @@ /* - * Copyright 2025 NXP - * + * SPDX-FileCopyrightText: Copyright 2025-2026 NXP * SPDX-License-Identifier: Apache-2.0 */ @@ -9,7 +8,7 @@ LOG_MODULE_REGISTER(net_dsa_tag, CONFIG_NET_DSA_LOG_LEVEL); #include #include -#include "dsa_tag.h" +#include struct net_if *dsa_tag_recv(struct net_if *iface, struct net_pkt *pkt) { diff --git a/subsys/net/l2/ethernet/dsa/dsa_tag.h b/subsys/net/l2/ethernet/dsa/dsa_tag.h deleted file mode 100644 index 2b27bb4435bb..000000000000 --- a/subsys/net/l2/ethernet/dsa/dsa_tag.h +++ /dev/null @@ -1,18 +0,0 @@ -/* - * Copyright 2025 NXP - * - * SPDX-License-Identifier: Apache-2.0 - */ -#ifndef ZEPHYR_SUBSYS_DSA_TAG_PRIV_H_ -#define ZEPHYR_SUBSYS_DSA_TAG_PRIV_H_ - -#include -#ifdef CONFIG_DSA_TAG_PROTOCOL_NETC -#include -#endif - -struct net_if *dsa_tag_recv(struct net_if *iface, struct net_pkt *pkt); -struct net_pkt *dsa_tag_xmit(struct net_if *iface, struct net_pkt *pkt); -void dsa_tag_setup(const struct device *dev_cpu); - -#endif From 1b14cb18a213f9dc6c9b78c04772284945fcd32e Mon Sep 17 00:00:00 2001 From: Yangbo Lu Date: Tue, 20 Jan 2026 10:08:56 +0800 Subject: [PATCH 0117/6328] net: dsa: support dsa protocol registering with iterable section Supported dsa protocol registering with iterable section. Signed-off-by: Yangbo Lu --- cmake/linker_script/common/common-rom.cmake | 4 ++++ .../linker/common-rom/common-rom-net.ld | 4 ++++ include/zephyr/net/dsa_tag.h | 24 ++++++++++++++++--- include/zephyr/net/dsa_tag_netc.h | 5 +--- subsys/net/l2/ethernet/dsa/dsa_tag.c | 23 +++++++++--------- subsys/net/l2/ethernet/dsa/dsa_tag_netc.c | 6 +++-- 6 files changed, 45 insertions(+), 21 deletions(-) diff --git a/cmake/linker_script/common/common-rom.cmake b/cmake/linker_script/common/common-rom.cmake index 1a1c0f582b03..4e2ca9b84964 100644 --- a/cmake/linker_script/common/common-rom.cmake +++ b/cmake/linker_script/common/common-rom.cmake @@ -240,6 +240,10 @@ if(CONFIG_NET_SOCKETS_SERVICE) ) endif() +if(CONFIG_NET_DSA) + zephyr_iterable_section(NAME dsa_tag_register KVMA RAM_REGION GROUP RODATA_REGION) +endif() + if(CONFIG_INPUT) zephyr_iterable_section(NAME input_callback KVMA RAM_REGION GROUP RODATA_REGION) endif() diff --git a/include/zephyr/linker/common-rom/common-rom-net.ld b/include/zephyr/linker/common-rom/common-rom-net.ld index 2b779e469939..315b078c0c2c 100644 --- a/include/zephyr/linker/common-rom/common-rom-net.ld +++ b/include/zephyr/linker/common-rom/common-rom-net.ld @@ -33,3 +33,7 @@ #if defined(CONFIG_NET_SOCKETS_SERVICE) ITERABLE_SECTION_ROM(net_socket_service_desc, Z_LINK_ITERABLE_SUBALIGN) #endif + +#if defined(CONFIG_NET_DSA) + ITERABLE_SECTION_ROM(dsa_tag_register, Z_LINK_ITERABLE_SUBALIGN) +#endif diff --git a/include/zephyr/net/dsa_tag.h b/include/zephyr/net/dsa_tag.h index bd09353402bb..ac440a668448 100644 --- a/include/zephyr/net/dsa_tag.h +++ b/include/zephyr/net/dsa_tag.h @@ -21,14 +21,32 @@ */ #include -#ifdef CONFIG_DSA_TAG_PROTOCOL_NETC -#include -#endif #ifdef __cplusplus extern "C" { #endif +/** + * @brief Registration information for a dsa tag protocol + */ +struct dsa_tag_register { + /** Protocol ID */ + int proto; + + /** Received packet handler */ + struct net_if *(*recv)(struct net_if *iface, struct net_pkt *pkt); + + /** Transmit packet handler */ + struct net_pkt *(*xmit)(struct net_if *iface, struct net_pkt *pkt); +}; + +#define DSA_TAG_REGISTER(_proto, _recv, _xmit) \ + static const STRUCT_SECTION_ITERABLE(dsa_tag_register, __dsa_tag_register_##_proto) = { \ + .proto = _proto, \ + .recv = _recv, \ + .xmit = _xmit, \ + } + /** @cond INTERNAL_HIDDEN */ /* diff --git a/include/zephyr/net/dsa_tag_netc.h b/include/zephyr/net/dsa_tag_netc.h index 78f8e4a125ba..b9149041bb55 100644 --- a/include/zephyr/net/dsa_tag_netc.h +++ b/include/zephyr/net/dsa_tag_netc.h @@ -1,6 +1,5 @@ /* - * Copyright 2025 NXP - * + * SPDX-FileCopyrightText: Copyright 2025-2026 NXP * SPDX-License-Identifier: Apache-2.0 */ #ifndef ZEPHYR_SUBSYS_DSA_TAG_NETC_H_ @@ -13,6 +12,4 @@ struct dsa_tag_netc_data { #endif }; -struct net_if *dsa_tag_netc_recv(struct net_if *iface, struct net_pkt *pkt); -struct net_pkt *dsa_tag_netc_xmit(struct net_if *iface, struct net_pkt *pkt); #endif /* ZEPHYR_SUBSYS_DSA_TAG_NETC_H_ */ diff --git a/subsys/net/l2/ethernet/dsa/dsa_tag.c b/subsys/net/l2/ethernet/dsa/dsa_tag.c index fa7c803e69f4..7eb1435589a7 100644 --- a/subsys/net/l2/ethernet/dsa/dsa_tag.c +++ b/subsys/net/l2/ethernet/dsa/dsa_tag.c @@ -44,19 +44,18 @@ void dsa_tag_setup(const struct device *dev_cpu) { const struct dsa_port_config *cfg = dev_cpu->config; struct dsa_switch_context *dsa_switch_ctx = dev_cpu->data; + bool match = false; - switch (cfg->tag_proto) { -#ifdef CONFIG_DSA_TAG_PROTOCOL_NETC - case DSA_TAG_PROTO_NETC: - dsa_switch_ctx->dapi->recv = dsa_tag_netc_recv; - dsa_switch_ctx->dapi->xmit = dsa_tag_netc_xmit; - break; -#endif - case DSA_TAG_PROTO_NOTAG: - dsa_switch_ctx->dapi->recv = NULL; - dsa_switch_ctx->dapi->xmit = NULL; - break; - default: + STRUCT_SECTION_FOREACH(dsa_tag_register, tag) { + if (tag->proto == cfg->tag_proto) { + dsa_switch_ctx->dapi->recv = tag->recv; + dsa_switch_ctx->dapi->xmit = tag->xmit; + match = true; + break; + } + } + + if ((!match) && (cfg->tag_proto != DSA_TAG_PROTO_NOTAG)) { LOG_ERR("DSA tag protocol %d not supported", cfg->tag_proto); } diff --git a/subsys/net/l2/ethernet/dsa/dsa_tag_netc.c b/subsys/net/l2/ethernet/dsa/dsa_tag_netc.c index 1ddc31a595e8..0f9a23155519 100644 --- a/subsys/net/l2/ethernet/dsa/dsa_tag_netc.c +++ b/subsys/net/l2/ethernet/dsa/dsa_tag_netc.c @@ -1,6 +1,5 @@ /* - * Copyright 2025 NXP - * + * SPDX-FileCopyrightText: Copyright 2025-2026 NXP * SPDX-License-Identifier: Apache-2.0 */ @@ -9,6 +8,7 @@ LOG_MODULE_REGISTER(net_dsa_tag_netc, CONFIG_NET_DSA_LOG_LEVEL); #include #include +#include #include #include "fsl_netc_tag.h" @@ -157,3 +157,5 @@ struct net_pkt *dsa_tag_netc_xmit(struct net_if *iface, struct net_pkt *pkt) net_pkt_cursor_init(pkt); return pkt; } + +DSA_TAG_REGISTER(DSA_TAG_PROTO_NETC, dsa_tag_netc_recv, dsa_tag_netc_xmit); From cd5bc5caa5799b657426ba68730b6d9e19fec23f Mon Sep 17 00:00:00 2001 From: Yangbo Lu Date: Fri, 16 Jan 2026 12:06:35 +0800 Subject: [PATCH 0118/6328] drivers: ethernet: dsa: improve DSA_NXP_NETC_GCL_LEN Kconfig option Renamed DSA_NXP_NETC_GCL_LEN to DSA_NXP_IMX_NETC_GCL_LEN for naming consistency, and wrapped it in DSA_DRIVERS condition. Signed-off-by: Yangbo Lu --- drivers/ethernet/dsa/Kconfig | 12 ++++++------ drivers/ethernet/dsa/dsa_nxp_imx_netc.c | 11 +++++------ 2 files changed, 11 insertions(+), 12 deletions(-) diff --git a/drivers/ethernet/dsa/Kconfig b/drivers/ethernet/dsa/Kconfig index 721be58c2422..aa2597fd4ebc 100644 --- a/drivers/ethernet/dsa/Kconfig +++ b/drivers/ethernet/dsa/Kconfig @@ -75,13 +75,13 @@ config DSA_NXP_IMX_NETC help Add support for NXP i.MX NETC DSA device driver. -endif # DSA_DRIVERS - -config DSA_NXP_NETC_GCL_LEN - int "Gate control list length for i.MX NETC DSA" +config DSA_NXP_IMX_NETC_GCL_LEN + int "Gate control list length for i.MX NETC switch" default 64 range 1 256 depends on DSA_NXP_IMX_NETC && NET_QBV help - Amount of Gate control list to use, reduce to save RAM. - The Max of the value can be 64,128,256. + Amount of Gate control list to use. Small value saves RAM. + The Max of the value can be 64, 128, or 256. + +endif # DSA_DRIVERS diff --git a/drivers/ethernet/dsa/dsa_nxp_imx_netc.c b/drivers/ethernet/dsa/dsa_nxp_imx_netc.c index 4cd2e3952f8d..0829dc550c83 100644 --- a/drivers/ethernet/dsa/dsa_nxp_imx_netc.c +++ b/drivers/ethernet/dsa/dsa_nxp_imx_netc.c @@ -1,6 +1,5 @@ /* - * Copyright 2025 NXP - * + * SPDX-FileCopyrightText: Copyright 2025-2026 NXP * SPDX-License-Identifier: Apache-2.0 */ @@ -36,7 +35,7 @@ struct dsa_netc_config { #ifdef CONFIG_NET_QBV struct netc_qbv_config { netc_tb_tgs_gcl_t tgs_config; - netc_tgs_gate_entry_t gcList[CONFIG_DSA_NXP_NETC_GCL_LEN]; + netc_tgs_gate_entry_t gcList[CONFIG_DSA_NXP_IMX_NETC_GCL_LEN]; }; #endif @@ -105,7 +104,7 @@ static int dsa_netc_port_init(const struct device *dev) #ifdef CONFIG_NET_QBV memset(&(prv->qbv_config[cfg->port_idx].tgs_config), 0, sizeof(netc_tb_tgs_gcl_t)); memset(prv->qbv_config[cfg->port_idx].gcList, 0, - sizeof(netc_tgs_gate_entry_t) * CONFIG_DSA_NXP_NETC_GCL_LEN); + sizeof(netc_tgs_gate_entry_t) * CONFIG_DSA_NXP_IMX_NETC_GCL_LEN); prv->qbv_config[cfg->port_idx].tgs_config.entryID = cfg->port_idx; prv->qbv_config[cfg->port_idx].tgs_config.gcList = prv->qbv_config[cfg->port_idx].gcList; #endif @@ -388,7 +387,7 @@ static int dsa_netc_set_qbv(const struct device *dev, const struct ethernet_conf case ETHERNET_QBV_PARAM_TYPE_GATE_CONTROL_LIST: row = config->qbv_param.gate_control.row; gate_num = ((CONFIG_NET_TC_TX_COUNT) < 8 ? (CONFIG_NET_TC_TX_COUNT) : 8); - if (row > CONFIG_DSA_NXP_NETC_GCL_LEN) { + if (row > CONFIG_DSA_NXP_IMX_NETC_GCL_LEN) { LOG_ERR("The gate control list length exceeds the limit"); return -ENOTSUP; } @@ -451,7 +450,7 @@ static int dsa_netc_get_qbv(const struct device *dev, struct ethernet_config *co case ETHERNET_QBV_PARAM_TYPE_GATE_CONTROL_LIST: row = config->qbv_param.gate_control.row; gate_num = ((CONFIG_NET_TC_TX_COUNT) < 8 ? (CONFIG_NET_TC_TX_COUNT) : 8); - if (row > CONFIG_DSA_NXP_NETC_GCL_LEN) { + if (row > CONFIG_DSA_NXP_IMX_NETC_GCL_LEN) { LOG_ERR("The gate control list length exceeds the limit"); return -ENOTSUP; } From 05c1fecb5b2b0e316881ed1dac29f3463d482595 Mon Sep 17 00:00:00 2001 From: Yangbo Lu Date: Tue, 20 Jan 2026 10:26:19 +0800 Subject: [PATCH 0119/6328] drivers: ethernet: dsa: move dsa_tag_netc driver out of subsys Moved dsa_tag_netc driver out of subsys. Maintained it in drivers/ethernet/dsa as vendor driver. Signed-off-by: Yangbo Lu --- drivers/ethernet/dsa/CMakeLists.txt | 3 +++ drivers/ethernet/dsa/Kconfig | 13 +++++++++++++ drivers/ethernet/dsa/dsa_nxp_imx_netc.c | 2 +- .../net/l2 => drivers}/ethernet/dsa/dsa_tag_netc.c | 5 +++-- .../net => drivers/ethernet/dsa}/dsa_tag_netc.h | 6 +++--- subsys/net/l2/ethernet/dsa/CMakeLists.txt | 1 - subsys/net/l2/ethernet/dsa/Kconfig | 11 ----------- 7 files changed, 23 insertions(+), 18 deletions(-) rename {subsys/net/l2 => drivers}/ethernet/dsa/dsa_tag_netc.c (97%) rename {include/zephyr/net => drivers/ethernet/dsa}/dsa_tag_netc.h (68%) diff --git a/drivers/ethernet/dsa/CMakeLists.txt b/drivers/ethernet/dsa/CMakeLists.txt index 64f5a7f04659..d2ec2f99bfe7 100644 --- a/drivers/ethernet/dsa/CMakeLists.txt +++ b/drivers/ethernet/dsa/CMakeLists.txt @@ -2,3 +2,6 @@ zephyr_library_sources_ifdef(CONFIG_DSA_KSZ8XXX dsa_ksz8xxx.c) zephyr_library_sources_ifdef(CONFIG_DSA_NXP_IMX_NETC dsa_nxp_imx_netc.c) + +# DSA tag protocol drivers +zephyr_library_sources_ifdef(CONFIG_DSA_TAG_PROTOCOL_NETC dsa_tag_netc.c) diff --git a/drivers/ethernet/dsa/Kconfig b/drivers/ethernet/dsa/Kconfig index aa2597fd4ebc..9395622d3ef6 100644 --- a/drivers/ethernet/dsa/Kconfig +++ b/drivers/ethernet/dsa/Kconfig @@ -84,4 +84,17 @@ config DSA_NXP_IMX_NETC_GCL_LEN Amount of Gate control list to use. Small value saves RAM. The Max of the value can be 64, 128, or 256. +# DSA tag protocol drivers +# Tag protocol ID found in + +DSA_PORT_COMPAT := zephyr,dsa-port + +config DSA_TAG_PROTOCOL_NETC + bool "Tag protocol - NETC" + default y + select NET_PKT_CONTROL_BLOCK + depends on $(dt_compat_any_has_prop,$(DSA_PORT_COMPAT),dsa-tag-protocol,1) + help + NXP NETC tag protocol. + endif # DSA_DRIVERS diff --git a/drivers/ethernet/dsa/dsa_nxp_imx_netc.c b/drivers/ethernet/dsa/dsa_nxp_imx_netc.c index 0829dc550c83..815caaf6bda9 100644 --- a/drivers/ethernet/dsa/dsa_nxp_imx_netc.c +++ b/drivers/ethernet/dsa/dsa_nxp_imx_netc.c @@ -7,12 +7,12 @@ LOG_MODULE_REGISTER(dsa_netc, CONFIG_ETHERNET_LOG_LEVEL); #include -#include #include #include #include #include +#include "dsa_tag_netc.h" #include "../eth.h" #include "fsl_netc_switch.h" diff --git a/subsys/net/l2/ethernet/dsa/dsa_tag_netc.c b/drivers/ethernet/dsa/dsa_tag_netc.c similarity index 97% rename from subsys/net/l2/ethernet/dsa/dsa_tag_netc.c rename to drivers/ethernet/dsa/dsa_tag_netc.c index 0f9a23155519..f8582fe3d7b0 100644 --- a/subsys/net/l2/ethernet/dsa/dsa_tag_netc.c +++ b/drivers/ethernet/dsa/dsa_tag_netc.c @@ -4,12 +4,13 @@ */ #include -LOG_MODULE_REGISTER(net_dsa_tag_netc, CONFIG_NET_DSA_LOG_LEVEL); +LOG_MODULE_REGISTER(dsa_tag_netc, CONFIG_ETHERNET_LOG_LEVEL); #include #include #include -#include + +#include "dsa_tag_netc.h" #include "fsl_netc_tag.h" struct net_if *dsa_tag_netc_recv(struct net_if *iface, struct net_pkt *pkt) diff --git a/include/zephyr/net/dsa_tag_netc.h b/drivers/ethernet/dsa/dsa_tag_netc.h similarity index 68% rename from include/zephyr/net/dsa_tag_netc.h rename to drivers/ethernet/dsa/dsa_tag_netc.h index b9149041bb55..a869900673bf 100644 --- a/include/zephyr/net/dsa_tag_netc.h +++ b/drivers/ethernet/dsa/dsa_tag_netc.h @@ -2,8 +2,8 @@ * SPDX-FileCopyrightText: Copyright 2025-2026 NXP * SPDX-License-Identifier: Apache-2.0 */ -#ifndef ZEPHYR_SUBSYS_DSA_TAG_NETC_H_ -#define ZEPHYR_SUBSYS_DSA_TAG_NETC_H_ +#ifndef ZEPHYR_DRIVERS_DSA_TAG_NETC_H_ +#define ZEPHYR_DRIVERS_DSA_TAG_NETC_H_ struct dsa_tag_netc_data { #ifdef CONFIG_NET_L2_PTP @@ -12,4 +12,4 @@ struct dsa_tag_netc_data { #endif }; -#endif /* ZEPHYR_SUBSYS_DSA_TAG_NETC_H_ */ +#endif /* ZEPHYR_DRIVERS_DSA_TAG_NETC_H_ */ diff --git a/subsys/net/l2/ethernet/dsa/CMakeLists.txt b/subsys/net/l2/ethernet/dsa/CMakeLists.txt index d1fe3d015a10..7c5d26ebb2ec 100644 --- a/subsys/net/l2/ethernet/dsa/CMakeLists.txt +++ b/subsys/net/l2/ethernet/dsa/CMakeLists.txt @@ -8,5 +8,4 @@ zephyr_library_sources(dsa_core.c) zephyr_library_sources(dsa_port.c) zephyr_library_sources(dsa_user.c) zephyr_library_sources(dsa_tag.c) -zephyr_library_sources_ifdef(CONFIG_DSA_TAG_PROTOCOL_NETC dsa_tag_netc.c) endif() diff --git a/subsys/net/l2/ethernet/dsa/Kconfig b/subsys/net/l2/ethernet/dsa/Kconfig index e6f09fc71417..ed5e6b69d9e0 100644 --- a/subsys/net/l2/ethernet/dsa/Kconfig +++ b/subsys/net/l2/ethernet/dsa/Kconfig @@ -12,8 +12,6 @@ menuconfig NET_DSA if NET_DSA -DSA_PORT_COMPAT := zephyr,dsa-port - config NET_DSA_DEPRECATED bool "Distributed Switch Architecture support for legacy device" select DEPRECATED @@ -35,15 +33,6 @@ config DSA_TAG_SIZE help Set the DSA tag length in bytes. -# Tag protocol ID found in -config DSA_TAG_PROTOCOL_NETC - bool "Tag protocol - NETC" - default y - select NET_PKT_CONTROL_BLOCK - depends on $(dt_compat_any_has_prop,$(DSA_PORT_COMPAT),dsa-tag-protocol,1) - help - NXP NETC tag protocol. - module = NET_DSA module-dep = NET_LOG module-str = Log level for DSA From b2ac268a66ee191dae9d03a60ae094a33d1be16c Mon Sep 17 00:00:00 2001 From: Yangbo Lu Date: Tue, 20 Jan 2026 11:24:46 +0800 Subject: [PATCH 0120/6328] drivers: ethernet: dsa: make dsa_tag_netc driver native The DSA tag protocol driver should be native for packet tagging and untagging. There is possibility other vendors/IPs use it. So, just defined DSA tag structures in header file instead of using hal header file. Signed-off-by: Yangbo Lu --- drivers/ethernet/dsa/dsa_tag_netc.c | 62 +++++++++--------- drivers/ethernet/dsa/dsa_tag_netc.h | 97 ++++++++++++++++++++++++++++- 2 files changed, 126 insertions(+), 33 deletions(-) diff --git a/drivers/ethernet/dsa/dsa_tag_netc.c b/drivers/ethernet/dsa/dsa_tag_netc.c index f8582fe3d7b0..51f0927594a6 100644 --- a/drivers/ethernet/dsa/dsa_tag_netc.c +++ b/drivers/ethernet/dsa/dsa_tag_netc.c @@ -11,7 +11,6 @@ LOG_MODULE_REGISTER(dsa_tag_netc, CONFIG_ETHERNET_LOG_LEVEL); #include #include "dsa_tag_netc.h" -#include "fsl_netc_tag.h" struct net_if *dsa_tag_netc_recv(struct net_if *iface, struct net_pkt *pkt) { @@ -22,8 +21,8 @@ struct net_if *dsa_tag_netc_recv(struct net_if *iface, struct net_pkt *pkt) (struct dsa_tag_netc_data *)(dsa_switch_ctx->tagger_data); #endif void *header = pkt->frags->data; - uint16_t tag_len = sizeof(netc_swt_tag_host_t); - netc_swt_tag_common_t *tag_common; + uint16_t tag_len = sizeof(struct netc_switch_tag_host); + struct netc_switch_tag_common *tag_common; struct net_if *iface_dst = iface; uint8_t *ptr; @@ -34,26 +33,27 @@ struct net_if *dsa_tag_netc_recv(struct net_if *iface, struct net_pkt *pkt) } /* Handle tag type */ - tag_common = (netc_swt_tag_common_t *)((uintptr_t)pkt->frags->data + NET_ETH_ADDR_LEN * 2); - if (tag_common->type == kNETC_TagForward) { + tag_common = (struct netc_switch_tag_common *)((uintptr_t)pkt->frags->data + + NET_ETH_ADDR_LEN * 2); + if (tag_common->type == NETC_SWITCH_TAG_TYPE_FORWARD) { /* Update tag length per tag type */ - tag_len = sizeof(netc_swt_tag_forward_t); + tag_len = sizeof(struct netc_switch_tag_forward); - } else if (tag_common->type == kNETC_TagToHost) { + } else if (tag_common->type == NETC_SWITCH_TAG_TYPE_TO_HOST) { #ifdef CONFIG_NET_L2_PTP - netc_swt_tag_host_rx_ts_t *tag_rx_ts; - netc_swt_tag_host_tx_ts_t *tag_tx_ts; + struct netc_switch_tag_host_rx_ts *tag_rx_ts; + struct netc_switch_tag_host_tx_ts *tag_tx_ts; uint64_t ts; #endif /* Handle tag sub-type */ - switch (tag_common->subType) { - case kNETC_TagToHostNoTs: + switch (tag_common->subtype) { + case NETC_SWITCH_TAG_SUBTYPE_TO_HOST_NO_TS: /* Normal case */ break; - case kNETC_TagToHostRxTs: + case NETC_SWITCH_TAG_SUBTYPE_TO_HOST_RX_TS: #ifdef CONFIG_NET_L2_PTP - tag_rx_ts = (netc_swt_tag_host_rx_ts_t *)tag_common; + tag_rx_ts = (struct netc_switch_tag_host_rx_ts *)tag_common; ts = net_ntohll(tag_rx_ts->timestamp); /* Fill timestamp */ @@ -61,20 +61,20 @@ struct net_if *dsa_tag_netc_recv(struct net_if *iface, struct net_pkt *pkt) pkt->timestamp.second = ts / NSEC_PER_SEC; #endif /* Update tag length per tag type */ - tag_len = sizeof(netc_swt_tag_host_rx_ts_t); + tag_len = sizeof(struct netc_switch_tag_host_rx_ts); break; - case kNETC_TagToHostTxTs: + case NETC_SWITCH_TAG_SUBTYPE_TO_HOST_TX_TS: #ifdef CONFIG_NET_L2_PTP - tag_tx_ts = (netc_swt_tag_host_tx_ts_t *)tag_common; + tag_tx_ts = (struct netc_switch_tag_host_tx_ts *)tag_common; ts = net_ntohll(tag_tx_ts->timestamp); if (tagger_data->twostep_timestamp_handler != NULL) { tagger_data->twostep_timestamp_handler(dsa_switch_ctx, - tag_tx_ts->tsReqId, ts); + tag_tx_ts->ts_req_id, ts); } #endif /* Update tag length per tag type */ - tag_len = sizeof(netc_swt_tag_host_tx_ts_t); + tag_len = sizeof(struct netc_switch_tag_host_tx_ts); break; default: LOG_ERR("tag sub-type error"); @@ -102,14 +102,14 @@ struct net_pkt *dsa_tag_netc_xmit(struct net_if *iface, struct net_pkt *pkt) struct dsa_port_config *cfg = (struct dsa_port_config *)dev->config; struct net_buf *header_buf; size_t header_len = NET_ETH_ADDR_LEN * 2; - netc_swt_tag_common_t *tag_common; + struct netc_switch_tag_common *tag_common; void *tag; /* Tag is inserted after DMAC/SMAC fields. Decide header size per tag type. */ if (net_ntohs(NET_ETH_HDR(pkt)->type) == NET_ETH_PTYPE_PTP) { - header_len += sizeof(netc_swt_tag_port_two_step_ts_t); + header_len += sizeof(struct netc_switch_tag_port_two_step_ts); } else { - header_len += sizeof(netc_swt_tag_port_no_ts_t); + header_len += sizeof(struct netc_switch_tag_port_no_ts); } /* Allocate net_buf for header */ @@ -131,21 +131,21 @@ struct net_pkt *dsa_tag_netc_xmit(struct net_if *iface, struct net_pkt *pkt) if (net_ntohs(NET_ETH_HDR(pkt)->type) == NET_ETH_PTYPE_PTP) { /* Utilize control block for timestamp request ID */ - ((netc_swt_tag_port_two_step_ts_t *)tag)->tsReqId = pkt->cb.cb[0] & 0xf; + ((struct netc_switch_tag_port_two_step_ts *)tag)->ts_req_id = pkt->cb.cb[0] & 0xf; - tag_common = &((netc_swt_tag_port_two_step_ts_t *)tag)->comTag; - tag_common->subType = kNETC_TagToPortTwoStepTs; + tag_common = &((struct netc_switch_tag_port_two_step_ts *)tag)->common; + tag_common->subtype = NETC_SWITCH_TAG_SUBTYPE_TO_PORT_TWOSTEP_TS; } else { - tag_common = &((netc_swt_tag_port_no_ts_t *)tag)->comTag; - tag_common->subType = kNETC_TagToPortNoTs; + tag_common = &((struct netc_switch_tag_port_no_ts *)tag)->common; + tag_common->subtype = NETC_SWITCH_TAG_SUBTYPE_TO_PORT_NO_TS; } #else - tag_common = &((netc_swt_tag_port_no_ts_t *)tag)->comTag; - tag_common->subType = kNETC_TagToPortNoTs; + tag_common = &((struct netc_switch_tag_port_no_ts *)tag)->common; + tag_common->subtype = NETC_SWITCH_TAG_SUBTYPE_TO_PORT_NO_TS; #endif - tag_common->tpid = NETC_SWITCH_DEFAULT_ETHER_TYPE; - tag_common->type = kNETC_TagToPort; - tag_common->swtId = 1; + tag_common->tpid = NETC_SWITCH_ETHER_TYPE; + tag_common->type = NETC_SWITCH_TAG_TYPE_TO_PORT; + tag_common->swtid = 1; tag_common->port = cfg->port_idx; /* Drop DMAC/SMAC on original frag */ diff --git a/drivers/ethernet/dsa/dsa_tag_netc.h b/drivers/ethernet/dsa/dsa_tag_netc.h index a869900673bf..ca3c67c0417f 100644 --- a/drivers/ethernet/dsa/dsa_tag_netc.h +++ b/drivers/ethernet/dsa/dsa_tag_netc.h @@ -7,9 +7,102 @@ struct dsa_tag_netc_data { #ifdef CONFIG_NET_L2_PTP - void (*twostep_timestamp_handler)(const struct dsa_switch_context *ctx, - uint8_t ts_req_id, uint64_t ts); + void (*twostep_timestamp_handler)(const struct dsa_switch_context *ctx, uint8_t ts_req_id, + uint64_t ts); #endif }; +#define NETC_SWITCH_ETHER_TYPE 0x3AFD + +enum netc_switch_tag_type { + NETC_SWITCH_TAG_TYPE_FORWARD, + NETC_SWITCH_TAG_TYPE_TO_PORT, + NETC_SWITCH_TAG_TYPE_TO_HOST, +}; + +enum netc_switch_tag_subtype { + NETC_SWITCH_TAG_SUBTYPE_TO_PORT_NO_TS = 0, + NETC_SWITCH_TAG_SUBTYPE_TO_PORT_ONESTEP_TS, + NETC_SWITCH_TAG_SUBTYPE_TO_PORT_TWOSTEP_TS, + NETC_SWITCH_TAG_SUBTYPE_TO_PORT_ALL_TS, + + NETC_SWITCH_TAG_SUBTYPE_TO_HOST_NO_TS = 0, + NETC_SWITCH_TAG_SUBTYPE_TO_HOST_RX_TS, + NETC_SWITCH_TAG_SUBTYPE_TO_HOST_TX_TS, +}; + +#pragma pack(1) +/* Switch tag common part */ +struct netc_switch_tag_common { + uint16_t tpid; /* Tag Protocol Identifier to identify the tag as an NXP switch tag. */ + uint16_t subtype: 4; /* Specific feature is based on tag type. */ + uint16_t type: 4; /* Tag type. */ + uint16_t qv: 1; /* QoS Valid. */ + uint16_t: 1; /* Reserved. */ + uint16_t ipv: 3; /* Internal Priority Value. */ + uint16_t: 1; /* Reserved. */ + uint16_t dr: 2; /* Drop Resilience. */ + uint8_t swtid: 3; /* Switch ID. */ + uint8_t port: 5; /* Switch port. */ +}; + +/* Switch tag for forward */ +struct netc_switch_tag_forward { + struct netc_switch_tag_common common; + uint8_t pm: 1; /* Port Masquerading. */ + uint8_t: 7; +}; + +/* Switch tag for to_port without timestamp */ +struct netc_switch_tag_port_no_ts { + struct netc_switch_tag_common common; + uint8_t: 8; +}; + +/* Switch tag for to_port with one-step timestamp */ +struct netc_switch_tag_port_one_step_ts { + struct netc_switch_tag_common common; + uint8_t: 8; + uint32_t timestamp; +}; + +/* Switch tag for to_port without two-step timestamp */ +struct netc_switch_tag_port_two_step_ts { + struct netc_switch_tag_common common; + uint8_t ts_req_id: 4; + uint8_t: 4; +}; + +/* Switch tag for to_port with all timestamps */ +struct netc_switch_tag_port_all_ts { + struct netc_switch_tag_common common; + uint8_t ts_req_id: 4; + uint8_t: 4; + uint32_t timestamp; +}; + +/* Switch tag for to_host */ +struct netc_switch_tag_host { + struct netc_switch_tag_common common; + uint16_t: 4; + uint16_t host_reason: 4; +}; + +/* Switch tag for to_host with timestamp */ +struct netc_switch_tag_host_rx_ts { + struct netc_switch_tag_common common; + uint16_t: 4; + uint16_t host_reason: 4; + uint64_t timestamp; +}; + +/* Switch tag for to_host with timestamp */ +struct netc_switch_tag_host_tx_ts { + struct netc_switch_tag_common common; + uint16_t ts_req_id: 4; + uint16_t host_reason: 4; + uint64_t timestamp; +}; +#pragma pack() + #endif /* ZEPHYR_DRIVERS_DSA_TAG_NETC_H_ */ From 81fd57078de4609d7ada72a037120f5e44d68021 Mon Sep 17 00:00:00 2001 From: TOKITA Hiroshi Date: Tue, 20 Jan 2026 15:47:42 +0900 Subject: [PATCH 0121/6328] MAINTAINERS: Add area for QNX Hypervisor Add area for supporting QNX Hypervisor Virtual Machine. Signed-off-by: TOKITA Hiroshi --- MAINTAINERS.yml | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/MAINTAINERS.yml b/MAINTAINERS.yml index bf191bbf1ddc..1656a133f92d 100644 --- a/MAINTAINERS.yml +++ b/MAINTAINERS.yml @@ -4327,6 +4327,16 @@ Power management: tests: - pm +QNX Hypervisor Platforms: + status: maintained + maintainers: + - soburi + files: + - boards/blackberry/qnxhv_vm/ + - soc/blackberry/qnxhv_vm/ + labels: + - "platform: QNX Hypervisor" + "Quicklogic Platform": status: odd fixes files: From 33196ff3cdd973248c0a277fd99eb125dc53eece Mon Sep 17 00:00:00 2001 From: Camille BAUD Date: Fri, 31 Oct 2025 02:06:29 +0100 Subject: [PATCH 0122/6328] dts: adc: add bindings for bflb adc Adds the bindings for the GPADC Signed-off-by: Camille BAUD --- dts/bindings/adc/bflb,adc.yaml | 23 +++++++++++++++++++++++ dts/riscv/bflb/bl60x.dtsi | 15 ++++++++++++++- dts/riscv/bflb/bl61x.dtsi | 15 ++++++++++++++- dts/riscv/bflb/bl70x.dtsi | 15 ++++++++++++++- 4 files changed, 65 insertions(+), 3 deletions(-) create mode 100644 dts/bindings/adc/bflb,adc.yaml diff --git a/dts/bindings/adc/bflb,adc.yaml b/dts/bindings/adc/bflb,adc.yaml new file mode 100644 index 000000000000..b4a8388ece72 --- /dev/null +++ b/dts/bindings/adc/bflb,adc.yaml @@ -0,0 +1,23 @@ +# Copyright (c) 2025 MASSDRIVER EI (massdriver.space) +# +# SPDX-License-Identifier: Apache-2.0 + +description: | + Bouffalolab ADC + +compatible: "bflb,adc" + +include: [adc-controller.yaml, pinctrl-device.yaml] + +properties: + reg: + required: true + + interrupts: + required: true + + "#io-channel-cells": + const: 1 + +io-channel-cells: + - input diff --git a/dts/riscv/bflb/bl60x.dtsi b/dts/riscv/bflb/bl60x.dtsi index d6f8429c7987..4ab191e8d149 100644 --- a/dts/riscv/bflb/bl60x.dtsi +++ b/dts/riscv/bflb/bl60x.dtsi @@ -1,6 +1,6 @@ /* * Copyright (c) 2021-2025 ATL Electronics - * Copyright (c) 2024-2025 MASSDRIVER EI (massdriver.space) + * Copyright (c) 2024-2026 MASSDRIVER EI (massdriver.space) * * SPDX-License-Identifier: Apache-2.0 */ @@ -15,6 +15,7 @@ #include #include #include +#include / { #address-cells = <1>; @@ -145,6 +146,18 @@ "pll_120", "pll_48"; }; + adc0: adc@40002000 { + compatible = "bflb,adc"; + reg = <0x40002000 0x1000 0x4000F000 0x1000>; + #io-channel-cells = <1>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + + interrupts = <41 0>; + interrupt-parent = <&clic>; + }; + efuse: efuse@40007000 { compatible = "bflb,efuse"; reg = <0x40007000 0x1000>; diff --git a/dts/riscv/bflb/bl61x.dtsi b/dts/riscv/bflb/bl61x.dtsi index be944d11a907..f63d472ec28a 100644 --- a/dts/riscv/bflb/bl61x.dtsi +++ b/dts/riscv/bflb/bl61x.dtsi @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024-2025 MASSDRIVER EI (massdriver.space) + * Copyright (c) 2024-2026 MASSDRIVER EI (massdriver.space) * * SPDX-License-Identifier: Apache-2.0 */ @@ -14,6 +14,7 @@ #include #include #include +#include / { #address-cells = <1>; @@ -160,6 +161,18 @@ "root", "bclk", "flash"; }; + adc0: adc@20002000 { + compatible = "bflb,adc"; + reg = <0x20002000 0x400 0x2000F000 0x1000>; + #io-channel-cells = <1>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + + interrupts = <41 1>; + interrupt-parent = <&clic>; + }; + uart0: uart@2000a000 { compatible = "bflb,uart"; reg = <0x2000a000 0x100>; diff --git a/dts/riscv/bflb/bl70x.dtsi b/dts/riscv/bflb/bl70x.dtsi index 4956750ea14a..1e6aadac74cf 100644 --- a/dts/riscv/bflb/bl70x.dtsi +++ b/dts/riscv/bflb/bl70x.dtsi @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024-2025 MASSDRIVER EI (massdriver.space) + * Copyright (c) 2024-2026 MASSDRIVER EI (massdriver.space) * * SPDX-License-Identifier: Apache-2.0 */ @@ -14,6 +14,7 @@ #include #include #include +#include / { #address-cells = <1>; @@ -150,6 +151,18 @@ "dll_120", "dll_57"; }; + adc0: adc@40002000 { + compatible = "bflb,adc"; + reg = <0x40002000 0x1000 0x4000F000 0x1000>; + #io-channel-cells = <1>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + + interrupts = <41 0>; + interrupt-parent = <&clic>; + }; + efuse: efuse@40007000 { compatible = "bflb,efuse"; reg = <0x40007000 0x1000>; From bddaa08afd5d6077ee7970f121e13dba5d9a86cf Mon Sep 17 00:00:00 2001 From: Camille BAUD Date: Fri, 31 Oct 2025 02:06:58 +0100 Subject: [PATCH 0123/6328] drivers: adc: add bflb adc driver Adds a driver for the GPADC Signed-off-by: Camille BAUD --- drivers/adc/CMakeLists.txt | 1 + drivers/adc/Kconfig | 1 + drivers/adc/Kconfig.bflb | 10 + drivers/adc/adc_bflb.c | 702 +++++++++++++++++++++++++++++++++++++ 4 files changed, 714 insertions(+) create mode 100644 drivers/adc/Kconfig.bflb create mode 100644 drivers/adc/adc_bflb.c diff --git a/drivers/adc/CMakeLists.txt b/drivers/adc/CMakeLists.txt index 847cffd5514a..fee7e54a7639 100644 --- a/drivers/adc/CMakeLists.txt +++ b/drivers/adc/CMakeLists.txt @@ -22,6 +22,7 @@ zephyr_library_sources_ifdef(CONFIG_ADC_ADS1X1X adc_ads1x1x.c) zephyr_library_sources_ifdef(CONFIG_ADC_ADS1X4S0X adc_ads1x4s0x.c) zephyr_library_sources_ifdef(CONFIG_ADC_ADS7052 adc_ads7052.c) zephyr_library_sources_ifdef(CONFIG_ADC_AMBIQ adc_ambiq.c) +zephyr_library_sources_ifdef(CONFIG_ADC_BFLB adc_bflb.c) zephyr_library_sources_ifdef(CONFIG_ADC_CC13XX_CC26XX adc_cc13xx_cc26xx.c) zephyr_library_sources_ifdef(CONFIG_ADC_CC23X0 adc_cc23x0.c) zephyr_library_sources_ifdef(CONFIG_ADC_CC32XX adc_cc32xx.c) diff --git a/drivers/adc/Kconfig b/drivers/adc/Kconfig index 04e88d05c60d..d8b5d42b009c 100644 --- a/drivers/adc/Kconfig +++ b/drivers/adc/Kconfig @@ -88,6 +88,7 @@ source "drivers/adc/Kconfig.ads1x4s0x" source "drivers/adc/Kconfig.ads7052" source "drivers/adc/Kconfig.ambiq" source "drivers/adc/Kconfig.b91" +source "drivers/adc/Kconfig.bflb" source "drivers/adc/Kconfig.cc13xx_cc26xx" source "drivers/adc/Kconfig.cc23x0" source "drivers/adc/Kconfig.cc32xx" diff --git a/drivers/adc/Kconfig.bflb b/drivers/adc/Kconfig.bflb new file mode 100644 index 000000000000..3b0e5511b7c8 --- /dev/null +++ b/drivers/adc/Kconfig.bflb @@ -0,0 +1,10 @@ +# Copyright (c) 2024-2025 MASSDRIVER EI +# SPDX-License-Identifier: Apache-2.0 + +config ADC_BFLB + bool "Bouffalolab ADC driver" + default y + depends on DT_HAS_BFLB_ADC_ENABLED + select ADC_CONFIGURABLE_INPUTS + help + Enables the Bouffalolab ADC driver. diff --git a/drivers/adc/adc_bflb.c b/drivers/adc/adc_bflb.c new file mode 100644 index 000000000000..e649026fceaa --- /dev/null +++ b/drivers/adc/adc_bflb.c @@ -0,0 +1,702 @@ +/* + * Copyright (c) 2024-2025 MASSDRIVER EI (massdriver.space) + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT bflb_adc + +#include +#include +#include +#include + +#include +LOG_MODULE_REGISTER(adc_bflb, CONFIG_ADC_LOG_LEVEL); + +#include +#include +#include +#include +#include +#include + +#define ADC_CHAN_SELECT_PER_SCN 6 +#define ADC_CHAN_SELECT_SIZE_SCN 5 +#define ADC_CHAN_SELECT_MSK_SCN 0x1f +#define ADC_CHAN_COUNT 12 +#define ADC_CHAN_INPUT_COUNT 0x1f + +#define ADC_GAIN_1_ID 1 +#define ADC_GAIN_2_ID 2 +#define ADC_GAIN_4_ID 3 +#define ADC_GAIN_8_ID 4 +#define ADC_GAIN_16_ID 5 +#define ADC_GAIN_32_ID 6 + +#define ADC_GAIN_UNSET ADC_GAIN_128 + +#define ADC_RESOLUTION_12B_ID 0 +#define ADC_RESOLUTION_14B_ID 2 +#define ADC_RESOLUTION_16B_ID 4 + +#define ADC_INPUT_ID_HALF_VBAT 18 +#define ADC_INPUT_ID_GND 23 + +#define ADC_RESULT_POSITIVE_INPUT 0x3E00000 +#define ADC_RESULT_POSITIVE_INPUT_POS 21 +#define ADC_RESULT_NEGATIVE_INPUT 0x1F0000 +#define ADC_RESULT_NEGATIVE_INPUT_POS 16 +#define ADC_RESULT 0xFFFF + +#define ADC_WAIT_TIMEOUT_MS 500 + +#define ADC_CLK_DIV_32 7 + +struct adc_bflb_config { + uint32_t reg_GPIP; + uint32_t reg_AON; + const struct pinctrl_dev_config *pcfg; + void (*irq_config_func)(const struct device *dev); +}; + +struct adc_bflb_data { + uint8_t channel_count; + uint8_t channel_p[12]; + uint8_t channel_n[12]; + enum adc_gain gain; + bool differential; + float cal_coe; + uint16_t cal_off; +}; + +static void adc_bflb_channel_set_channel(const struct device *dev, uint8_t id, + uint8_t channel_number_n, uint8_t channel_number_p) +{ + const struct adc_bflb_config *const cfg = dev->config; + uint32_t offset_p = AON_GPADC_REG_SCN_POS1_OFFSET; + uint32_t offset_n = AON_GPADC_REG_SCN_NEG1_OFFSET; + uint32_t tmp; + + if (id >= ADC_CHAN_SELECT_PER_SCN) { + offset_p = AON_GPADC_REG_SCN_POS2_OFFSET; + offset_n = AON_GPADC_REG_SCN_NEG2_OFFSET; + } + + tmp = sys_read32(cfg->reg_AON + offset_p); + tmp &= ~(ADC_CHAN_SELECT_MSK_SCN + << ((id % ADC_CHAN_SELECT_PER_SCN) * ADC_CHAN_SELECT_SIZE_SCN)); + tmp |= channel_number_p << ((id % ADC_CHAN_SELECT_PER_SCN) * ADC_CHAN_SELECT_SIZE_SCN); + sys_write32(tmp, cfg->reg_AON + offset_p); + + tmp = sys_read32(cfg->reg_AON + offset_n); + tmp &= ~(ADC_CHAN_SELECT_MSK_SCN + << ((id % ADC_CHAN_SELECT_PER_SCN) * ADC_CHAN_SELECT_SIZE_SCN)); + tmp |= channel_number_n << ((id % ADC_CHAN_SELECT_PER_SCN) * ADC_CHAN_SELECT_SIZE_SCN); + sys_write32(tmp, cfg->reg_AON + offset_n); +} + +static int adc_bflb_channel_setup(const struct device *dev, + const struct adc_channel_cfg *channel_cfg) +{ + const struct adc_bflb_config *const cfg = dev->config; + struct adc_bflb_data *data = dev->data; + uint32_t tmp; + uint8_t channel_id = channel_cfg->channel_id; + uint8_t gain = ADC_GAIN_1_ID; + + if (data->channel_count > ADC_CHAN_COUNT) { + LOG_ERR("Too many channels"); + return -ENOTSUP; + } + if (channel_cfg->input_negative > ADC_CHAN_INPUT_COUNT + || channel_cfg->input_positive > ADC_CHAN_INPUT_COUNT) { + LOG_ERR("Bad channel number(s)"); + return -EINVAL; + } + + if (channel_id >= ADC_CHAN_COUNT) { + LOG_ERR("Bad channel ID"); + return -EINVAL; + } + + switch (channel_cfg->gain) { + case ADC_GAIN_1: + gain = ADC_GAIN_1_ID; + break; + case ADC_GAIN_2: + gain = ADC_GAIN_2_ID; + break; + case ADC_GAIN_4: + gain = ADC_GAIN_4_ID; + break; + case ADC_GAIN_8: + gain = ADC_GAIN_8_ID; + break; + case ADC_GAIN_16: + gain = ADC_GAIN_16_ID; + break; + case ADC_GAIN_32: + gain = ADC_GAIN_32_ID; + break; + default: + LOG_ERR("Gain must be between 1 and 32 (included), cannot be 3, 6, 12, 24"); + return -EINVAL; + } + + if (data->gain != ADC_GAIN_UNSET && data->gain != channel_cfg->gain) { + LOG_WRN("Gain does not match previously set gain, gain is global for this adc"); + } + data->gain = channel_cfg->gain; + + if (data->gain != ADC_GAIN_UNSET && data->differential != channel_cfg->differential) { + LOG_WRN("Differential mode does not match previously set mode, it is global"); + } + + if (channel_cfg->differential) { + data->channel_n[channel_id] = channel_cfg->input_negative; + } else { + data->channel_n[channel_id] = ADC_INPUT_ID_GND; + } + data->channel_p[channel_id] = channel_cfg->input_positive; + + if (data->channel_count == 0) { + tmp = sys_read32(cfg->reg_AON + AON_GPADC_REG_CONFIG1_OFFSET); + tmp |= AON_GPADC_CONT_CONV_EN; + tmp &= ~AON_GPADC_SCAN_EN; + tmp &= ~AON_GPADC_CLK_ANA_INV; + sys_write32(tmp, cfg->reg_AON + AON_GPADC_REG_CONFIG1_OFFSET); + + tmp = sys_read32(cfg->reg_AON + AON_GPADC_REG_CMD_OFFSET); + tmp &= ~AON_GPADC_POS_SEL_MASK; + tmp &= ~AON_GPADC_NEG_SEL_MASK; + if (channel_cfg->differential) { + tmp &= ~AON_GPADC_NEG_GND; + tmp |= channel_cfg->input_negative << AON_GPADC_NEG_SEL_SHIFT; + } else { + tmp |= AON_GPADC_NEG_GND; + /* GND channel */ + tmp |= ADC_INPUT_ID_GND << AON_GPADC_NEG_SEL_SHIFT; + } + tmp |= channel_cfg->input_positive << AON_GPADC_POS_SEL_SHIFT; + sys_write32(tmp, cfg->reg_AON + AON_GPADC_REG_CMD_OFFSET); + + adc_bflb_channel_set_channel(dev, 0, data->channel_n[channel_id], + data->channel_p[channel_id]); + } else { + tmp = sys_read32(cfg->reg_AON + AON_GPADC_REG_CONFIG1_OFFSET); + tmp &= ~AON_GPADC_CONT_CONV_EN; + tmp |= AON_GPADC_SCAN_EN; + tmp |= AON_GPADC_CLK_ANA_INV; + tmp &= ~AON_GPADC_SCAN_LENGTH_MASK; + tmp |= data->channel_count << AON_GPADC_SCAN_LENGTH_SHIFT; + sys_write32(tmp, cfg->reg_AON + AON_GPADC_REG_CONFIG1_OFFSET); + + tmp = sys_read32(cfg->reg_AON + AON_GPADC_REG_CMD_OFFSET); + tmp &= ~AON_GPADC_POS_SEL_MASK; + tmp &= ~AON_GPADC_NEG_SEL_MASK; + tmp |= AON_GPADC_NEG_GND; + sys_write32(tmp, cfg->reg_AON + AON_GPADC_REG_CMD_OFFSET); + + adc_bflb_channel_set_channel(dev, data->channel_count, data->channel_n[channel_id], + data->channel_p[channel_id]); + } + + tmp = sys_read32(cfg->reg_AON + AON_GPADC_REG_CONFIG2_OFFSET); + tmp |= (gain << AON_GPADC_PGA1_GAIN_SHIFT); + tmp |= (gain << AON_GPADC_PGA2_GAIN_SHIFT); + if (channel_cfg->differential) { + tmp |= AON_GPADC_DIFF_MODE; + } else { + tmp &= ~AON_GPADC_DIFF_MODE; + } + sys_write32(tmp, cfg->reg_AON + AON_GPADC_REG_CONFIG2_OFFSET); + + data->channel_count++; + + return 0; +} + +static uint32_t adc_bflb_read_one(const struct device *dev) +{ + const struct adc_bflb_config *const cfg = dev->config; + + while ((sys_read32(cfg->reg_GPIP + GPIP_GPADC_CONFIG_OFFSET) & + GPIP_GPADC_FIFO_DATA_COUNT_MASK) == 0) { + clock_bflb_settle(); + } + return sys_read32(cfg->reg_GPIP + GPIP_GPADC_DMA_RDATA_OFFSET) & GPIP_GPADC_DMA_RDATA_MASK; +} + +static void adc_bflb_trigger(const struct device *dev) +{ + const struct adc_bflb_config *const cfg = dev->config; + uint32_t tmp; + + tmp = sys_read32(cfg->reg_AON + AON_GPADC_REG_CMD_OFFSET); + tmp |= AON_GPADC_CONV_START; + sys_write32(tmp, cfg->reg_AON + AON_GPADC_REG_CMD_OFFSET); +} + +static void adc_bflb_detrigger(const struct device *dev) +{ + const struct adc_bflb_config *const cfg = dev->config; + uint32_t tmp; + + tmp = sys_read32(cfg->reg_AON + AON_GPADC_REG_CMD_OFFSET); + tmp &= ~AON_GPADC_CONV_START; + sys_write32(tmp, cfg->reg_AON + AON_GPADC_REG_CMD_OFFSET); +} + +static int adc_bflb_read(const struct device *dev, + const struct adc_sequence *sequence) +{ + struct adc_bflb_data *data = dev->data; + const struct adc_bflb_config *const cfg = dev->config; + uint32_t tmp; + uint8_t chan_nb = 0; + uint32_t nb_samples = 0; + uint8_t sample_chans[ADC_CHAN_COUNT] = {0}; + k_timepoint_t end_timeout = sys_timepoint_calc(K_MSEC(ADC_WAIT_TIMEOUT_MS)); + + for (uint8_t i = 0; i < ADC_CHAN_COUNT; i++) { + if ((sequence->channels >> i) & 0x1) { + sample_chans[chan_nb] = i; + chan_nb += 1; + } + } + + nb_samples = sequence->buffer_size / 2 / chan_nb; + if (nb_samples < 1) { + LOG_ERR("resolution 12 to 16 bits, buffer size invalid"); + return -EINVAL; + } + + tmp = sys_read32(cfg->reg_AON + AON_GPADC_REG_CONFIG1_OFFSET); + tmp &= ~AON_GPADC_RES_SEL_MASK; + + switch (sequence->resolution) { + case 12: + tmp |= ADC_RESOLUTION_12B_ID << AON_GPADC_RES_SEL_SHIFT; + break; + case 14: + tmp |= ADC_RESOLUTION_14B_ID << AON_GPADC_RES_SEL_SHIFT; + break; + case 16: + tmp |= ADC_RESOLUTION_16B_ID << AON_GPADC_RES_SEL_SHIFT; + break; + default: + LOG_ERR("resolution 12, 14 or 16 bits, resolution invalid"); + return -EINVAL; + } + sys_write32(tmp, cfg->reg_AON + AON_GPADC_REG_CONFIG1_OFFSET); + + tmp = sys_read32(cfg->reg_GPIP + GPIP_GPADC_CONFIG_OFFSET); + tmp |= GPIP_GPADC_FIFO_CLR; + sys_write32(tmp, cfg->reg_GPIP + GPIP_GPADC_CONFIG_OFFSET); + + adc_bflb_trigger(dev); + + for (int i = 0; i < nb_samples; i++) { + for (int j = 0; j < chan_nb; j++) { + tmp = adc_bflb_read_one(dev); + while (((tmp & ADC_RESULT_POSITIVE_INPUT) + >> ADC_RESULT_POSITIVE_INPUT_POS + != data->channel_p[sample_chans[j]] + || (tmp & ADC_RESULT_NEGATIVE_INPUT) + >> ADC_RESULT_NEGATIVE_INPUT_POS + != data->channel_n[sample_chans[j]]) + && !sys_timepoint_expired(end_timeout)) { + tmp = adc_bflb_read_one(dev); + } + ((uint16_t *)sequence->buffer)[i * chan_nb + j] = ((tmp & ADC_RESULT) + >> (16 - sequence->resolution)) / data->cal_coe - data->cal_off; + } + } + + if (sys_timepoint_expired(end_timeout)) { + return -ETIMEDOUT; + } + + adc_bflb_detrigger(dev); + + return 0; +} + +static void adc_bflb_isr(const struct device *dev) +{ + /* Do nothing */ +} + +#if defined(CONFIG_SOC_SERIES_BL60X) +static void adc_bflb_calibrate_dynamic(const struct device *dev) +{ + struct adc_bflb_data *data = dev->data; + const struct adc_bflb_config *const cfg = dev->config; + volatile uint32_t tmp; + volatile uint32_t offset = 0; + bool negative = false; + + tmp = sys_read32(cfg->reg_AON + AON_GPADC_REG_CONFIG1_OFFSET); + /* resolution 16-bits */ + tmp |= (ADC_RESOLUTION_16B_ID << AON_GPADC_RES_SEL_SHIFT); + /* continuous mode */ + tmp |= AON_GPADC_CONT_CONV_EN; + sys_write32(tmp, cfg->reg_AON + AON_GPADC_REG_CONFIG1_OFFSET); + + tmp = sys_read32(cfg->reg_AON + AON_GPADC_REG_CONFIG2_OFFSET); + tmp |= AON_GPADC_DIFF_MODE; + tmp |= AON_GPADC_VBAT_EN; + tmp &= ~AON_GPADC_VREF_SEL; + sys_write32(tmp, cfg->reg_AON + AON_GPADC_REG_CONFIG2_OFFSET); + + tmp = sys_read32(cfg->reg_AON + AON_GPADC_REG_CMD_OFFSET); + tmp &= ~AON_GPADC_NEG_GND; + tmp &= ~AON_GPADC_POS_SEL_MASK; + tmp &= ~AON_GPADC_NEG_SEL_MASK; + tmp |= (ADC_INPUT_ID_HALF_VBAT << AON_GPADC_POS_SEL_SHIFT); + tmp |= (ADC_INPUT_ID_HALF_VBAT << AON_GPADC_NEG_SEL_SHIFT); + sys_write32(tmp, cfg->reg_AON + AON_GPADC_REG_CMD_OFFSET); + + tmp = sys_read32(cfg->reg_GPIP + GPIP_GPADC_CONFIG_OFFSET); + tmp |= GPIP_GPADC_FIFO_CLR; + sys_write32(tmp, cfg->reg_GPIP + GPIP_GPADC_CONFIG_OFFSET); + + clock_bflb_settle(); + clock_bflb_settle(); + clock_bflb_settle(); + + adc_bflb_trigger(dev); + /* 10 samplings */ + for (uint8_t i = 0; i < 10; i++) { + tmp = adc_bflb_read_one(dev); + /* only consider samples after the first 5 */ + if (i > 4) { + if (tmp & 0x8000) { + negative = true; + tmp = ~tmp; + tmp += 1; + } + offset += (tmp & 0xffff); + } + } + + adc_bflb_detrigger(dev); + offset = offset / 5; + if (negative) { + data->cal_coe += (float)offset / 2048.0f; + } else { + data->cal_coe -= (float)offset / 2048.0f; + } +} +#endif + +static void adc_bflb_calibrate_gnd_offset(const struct device *dev) +{ + struct adc_bflb_data *data = dev->data; + const struct adc_bflb_config *const cfg = dev->config; + volatile uint32_t tmp; + volatile uint32_t offset = 0; + + tmp = sys_read32(cfg->reg_AON + AON_GPADC_REG_CONFIG1_OFFSET); + tmp |= (ADC_RESOLUTION_16B_ID << AON_GPADC_RES_SEL_SHIFT); + tmp |= AON_GPADC_CONT_CONV_EN; + tmp &= ~AON_GPADC_SCAN_EN; + tmp &= ~AON_GPADC_CLK_ANA_INV; + sys_write32(tmp, cfg->reg_AON + AON_GPADC_REG_CONFIG1_OFFSET); + + tmp = sys_read32(cfg->reg_AON + AON_GPADC_REG_CONFIG2_OFFSET); + tmp &= ~AON_GPADC_DIFF_MODE; + tmp &= ~AON_GPADC_VBAT_EN; + tmp &= ~AON_GPADC_VREF_SEL; + sys_write32(tmp, cfg->reg_AON + AON_GPADC_REG_CONFIG2_OFFSET); + + tmp = sys_read32(cfg->reg_AON + AON_GPADC_REG_CMD_OFFSET); + tmp |= AON_GPADC_NEG_GND; + tmp &= ~AON_GPADC_POS_SEL_MASK; + tmp &= ~AON_GPADC_NEG_SEL_MASK; + tmp |= (ADC_INPUT_ID_GND << AON_GPADC_POS_SEL_SHIFT); + tmp |= (ADC_INPUT_ID_GND << AON_GPADC_NEG_SEL_SHIFT); + sys_write32(tmp, cfg->reg_AON + AON_GPADC_REG_CMD_OFFSET); + + tmp = sys_read32(cfg->reg_GPIP + GPIP_GPADC_CONFIG_OFFSET); + tmp |= GPIP_GPADC_FIFO_CLR; + sys_write32(tmp, cfg->reg_GPIP + GPIP_GPADC_CONFIG_OFFSET); + + clock_bflb_settle(); + clock_bflb_settle(); + clock_bflb_settle(); + + adc_bflb_trigger(dev); + /* 10 samplings */ + for (uint8_t i = 0; i < 10; i++) { + tmp = adc_bflb_read_one(dev); + /* only consider samples after the first 5 */ + if (i > 4) { + offset += (tmp & ADC_RESULT); + } + } + + adc_bflb_detrigger(dev); + data->cal_off = offset / 5; +} + +#if defined(CONFIG_SOC_SERIES_BL70X) +static int adc_bflb_calibrate_efuse(const struct device *dev) +{ + struct adc_bflb_data *data = dev->data; + const struct device *efuse = DEVICE_DT_GET_ONE(bflb_efuse); + int ret; + uint32_t trim; + + ret = syscon_read_reg(efuse, 0x78, &trim); + if (ret < 0) { + LOG_ERR("Error: Couldn't read efuses: err: %d.\n", ret); + return -EINVAL; + } + if ((trim & 0x4000) == 0) { + LOG_ERR("Error: ADC calibration data not present"); + return -EINVAL; + } + trim = (trim & 0x1FFE) >> 1; + if (trim & 0x800) { + trim = ~trim; + trim += 1; + trim = trim & 0xfff; + data->cal_coe = ((float)1.0 + ((float)trim / (float)2048.0)); + } else { + data->cal_coe = ((float)1.0 - ((float)trim / (float)2048.0)); + } + return 0; +} +#elif defined(CONFIG_SOC_SERIES_BL61X) +static int adc_bflb_calibrate_efuse(const struct device *dev) +{ + struct adc_bflb_data *data = dev->data; + const struct device *efuse = DEVICE_DT_GET_ONE(bflb_efuse); + int ret; + uint32_t trim; + + ret = syscon_read_reg(efuse, 0xF0, &trim); + if (ret < 0) { + LOG_ERR("Error: Couldn't read efuses: err: %d.\n", ret); + return -EINVAL; + } + if ((trim & 0x4000000) == 0) { + LOG_ERR("Error: ADC calibration data not present"); + return -EINVAL; + } + trim = (trim & 0x3FFC000) >> 14; + if (trim & 0x800) { + trim = ~trim; + trim += 1; + trim = trim & 0xfff; + data->cal_coe = ((float)1.0 + ((float)trim / (float)2048.0)); + } else { + data->cal_coe = ((float)1.0 - ((float)trim / (float)2048.0)); + } + return 0; +} +#endif + +#if defined(CONFIG_SOC_SERIES_BL60X) || defined(CONFIG_SOC_SERIES_BL70X) +static void adc_bflb_init_clock(const struct device *dev) +{ + uint32_t tmp; + + /* clock pathing*/ + tmp = sys_read32(GLB_BASE + GLB_GPADC_32M_SRC_CTRL_OFFSET); + /* clock = XTAL or RC32M (32M) */ + tmp |= GLB_GPADC_32M_CLK_SEL_MSK; + /* div = 1 so ADC gets 32Mhz */ + tmp &= ~GLB_GPADC_32M_CLK_DIV_MSK; + /* enable */ + tmp |= GLB_GPADC_32M_DIV_EN_MSK; + sys_write32(tmp, GLB_BASE + GLB_GPADC_32M_SRC_CTRL_OFFSET); +} + +#elif defined(CONFIG_SOC_SERIES_BL61X) +static void adc_bflb_init_clock(const struct device *dev) +{ + uint32_t tmp; + + /* clock pathing*/ + tmp = sys_read32(GLB_BASE + GLB_ADC_CFG0_OFFSET); + /* clock = XTAL or RC32M (32M) */ + tmp |= GLB_GPADC_32M_CLK_SEL_MSK; + /* div = 1 so ADC gets 32Mhz */ + tmp &= ~GLB_GPADC_32M_CLK_DIV_MSK; + /* enable */ + tmp |= GLB_GPADC_32M_DIV_EN_MSK; + sys_write32(tmp, GLB_BASE + GLB_ADC_CFG0_OFFSET); +} +#else +#error Unsupported Platform +#endif + +static int adc_bflb_init(const struct device *dev) +{ + const struct adc_bflb_config *const cfg = dev->config; + uint32_t tmp; + int ret; + + ret = pinctrl_apply_state(cfg->pcfg, PINCTRL_STATE_DEFAULT); + if (ret < 0) { + return ret; + } + + adc_bflb_init_clock(dev); + + /* peripheral reset sequence */ + tmp = sys_read32(cfg->reg_AON + AON_GPADC_REG_CMD_OFFSET); + tmp &= ~AON_GPADC_GLOBAL_EN; + sys_write32(tmp, cfg->reg_AON + AON_GPADC_REG_CMD_OFFSET); + + tmp = sys_read32(cfg->reg_AON + AON_GPADC_REG_CMD_OFFSET); + tmp |= AON_GPADC_GLOBAL_EN; + sys_write32(tmp, cfg->reg_AON + AON_GPADC_REG_CMD_OFFSET); + + tmp = sys_read32(cfg->reg_AON + AON_GPADC_REG_CMD_OFFSET); + tmp |= AON_GPADC_SOFT_RST; + sys_write32(tmp, cfg->reg_AON + AON_GPADC_REG_CMD_OFFSET); + + clock_bflb_settle(); + clock_bflb_settle(); + clock_bflb_settle(); + + tmp = sys_read32(cfg->reg_AON + AON_GPADC_REG_CMD_OFFSET); + tmp &= ~AON_GPADC_CONV_START; + sys_write32(tmp, cfg->reg_AON + AON_GPADC_REG_CMD_OFFSET); + + tmp = sys_read32(cfg->reg_AON + AON_GPADC_REG_CMD_OFFSET); + tmp &= ~AON_GPADC_SOFT_RST; + sys_write32(tmp, cfg->reg_AON + AON_GPADC_REG_CMD_OFFSET); + + tmp = 0; + /* enable power to adc? */ + tmp |= (2 << AON_GPADC_V18_SEL_SHIFT); + tmp |= (1 << AON_GPADC_V11_SEL_SHIFT); + /* set internal clock divider to 32 */ + tmp |= (ADC_CLK_DIV_32 << AON_GPADC_CLK_DIV_RATIO_SHIFT); + /* default resolution (12-bits) */ + tmp |= (ADC_RESOLUTION_12B_ID << AON_GPADC_RES_SEL_SHIFT); + tmp &= ~AON_GPADC_CONT_CONV_EN; + tmp &= ~AON_GPADC_SCAN_EN; + sys_write32(tmp, cfg->reg_AON + AON_GPADC_REG_CONFIG1_OFFSET); + + clock_bflb_settle(); + clock_bflb_settle(); + clock_bflb_settle(); + + tmp = 0; + /* ""conversion speed"" */ + tmp |= (2 << AON_GPADC_DLY_SEL_SHIFT); + /* ""Vref AZ and chop on"" */ + tmp |= (2 << AON_GPADC_CHOP_MODE_SHIFT); + /* "gain 1" is 1 */ + tmp |= (1 << AON_GPADC_PGA1_GAIN_SHIFT); + /* "gain 2" is 1 */ + tmp |= (1 << AON_GPADC_PGA2_GAIN_SHIFT); + /* enable gain */ + tmp |= AON_GPADC_PGA_EN; + /* "offset calibration" value */ + tmp |= (8 << AON_GPADC_PGA_OS_CAL_SHIFT); + /* "VCM" is 1.2v */ + tmp |= (1 << AON_GPADC_PGA_VCM_SHIFT); + /* ADC reference (VREF channel) is 3v3 */ + tmp &= ~AON_GPADC_VREF_SEL; + sys_write32(tmp, cfg->reg_AON + AON_GPADC_REG_CONFIG2_OFFSET); + + tmp = sys_read32(cfg->reg_AON + AON_GPADC_REG_CMD_OFFSET); + /* "MIC2" differential mode enable */ + tmp |= AON_GPADC_MIC2_DIFF; + /* single ended mode is achieved by setting differential other end to ground */ + tmp |= AON_GPADC_NEG_GND; + sys_write32(tmp, cfg->reg_AON + AON_GPADC_REG_CMD_OFFSET); + + /* clear calibration */ + tmp = sys_read32(cfg->reg_AON + AON_GPADC_REG_DEFINE_OFFSET); + tmp &= ~AON_GPADC_OS_CAL_DATA_MASK; + sys_write32(tmp, cfg->reg_AON + AON_GPADC_REG_DEFINE_OFFSET); + + /* interrupts and status setup */ + tmp = sys_read32(cfg->reg_GPIP + GPIP_GPADC_CONFIG_OFFSET); + tmp |= (GPIP_GPADC_FIFO_UNDERRUN_MASK + | GPIP_GPADC_FIFO_OVERRUN_MASK + | GPIP_GPADC_RDY_MASK + | GPIP_GPADC_FIFO_UNDERRUN_CLR + | GPIP_GPADC_FIFO_OVERRUN_CLR + | GPIP_GPADC_RDY_CLR); +#ifdef CONFIG_SOC_SERIES_BL70X + tmp |= (GPIP_GPADC_FIFO_RDY_MASK | GPIP_GPADC_FIFO_RDY); +#endif + tmp |= GPIP_GPADC_FIFO_CLR; + tmp &= ~GPIP_GPADC_FIFO_THL_MASK; + tmp &= ~GPIP_GPADC_DMA_EN; + sys_write32(tmp, cfg->reg_GPIP + GPIP_GPADC_CONFIG_OFFSET); + + clock_bflb_settle(); + + tmp = sys_read32(cfg->reg_GPIP + GPIP_GPADC_CONFIG_OFFSET); + tmp &= ~(GPIP_GPADC_FIFO_UNDERRUN_CLR + | GPIP_GPADC_FIFO_OVERRUN_CLR + | GPIP_GPADC_RDY_CLR + | GPIP_GPADC_FIFO_CLR); + sys_write32(tmp, cfg->reg_GPIP + GPIP_GPADC_CONFIG_OFFSET); + + tmp = sys_read32(cfg->reg_AON + AON_GPADC_REG_ISR_OFFSET); + tmp |= AON_GPADC_NEG_SATUR_MASK; + tmp |= AON_GPADC_POS_SATUR_MASK; + sys_write32(tmp, cfg->reg_AON + AON_GPADC_REG_ISR_OFFSET); + +#if defined(CONFIG_SOC_SERIES_BL60X) + adc_bflb_calibrate_dynamic(dev); + adc_bflb_calibrate_gnd_offset(dev); +#else + ret = adc_bflb_calibrate_efuse(dev); + if (ret < 0) { + LOG_ERR("Couldn't calibrate via efuses"); + return ret; + } + adc_bflb_calibrate_gnd_offset(dev); +#endif + + cfg->irq_config_func(dev); + return 0; +} + +static DEVICE_API(adc, adc_bflb_api) = { + .channel_setup = adc_bflb_channel_setup, + .read = adc_bflb_read, + .ref_internal = 3200, +}; + +#define ADC_BFLB_DEVICE(n) \ + PINCTRL_DT_INST_DEFINE(n); \ + static void adc_bflb_irq_config_##n(const struct device *dev) \ + { \ + IRQ_CONNECT(DT_INST_IRQN(n), \ + DT_INST_IRQ(n, priority), \ + adc_bflb_isr, \ + DEVICE_DT_INST_GET(n), 0); \ + irq_enable(DT_INST_IRQN(n)); \ + } \ + static const struct adc_bflb_config adc_bflb_config_##n = { \ + .reg_GPIP = DT_INST_REG_ADDR_BY_IDX(n, 0), \ + .reg_AON = DT_INST_REG_ADDR_BY_IDX(n, 1), \ + .irq_config_func = &adc_bflb_irq_config_##n, \ + .pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(n), \ + }; \ + static struct adc_bflb_data adc_bflb_data_##n = { \ + .channel_count = 0, \ + .gain = ADC_GAIN_UNSET, \ + .cal_off = 0, \ + .cal_coe = 1.0f, \ + }; \ + DEVICE_DT_INST_DEFINE(n, adc_bflb_init, NULL, \ + &adc_bflb_data_##n, \ + &adc_bflb_config_##n, POST_KERNEL, \ + CONFIG_ADC_INIT_PRIORITY, \ + &adc_bflb_api); + +DT_INST_FOREACH_STATUS_OKAY(ADC_BFLB_DEVICE) From b8b2d2ed2187f1a9168ce9f040a6e53aa0a35771 Mon Sep 17 00:00:00 2001 From: Camille BAUD Date: Fri, 31 Oct 2025 02:14:01 +0100 Subject: [PATCH 0124/6328] samples: adc_dt: Add some bflb boards Add ADC sample overlays Signed-off-by: Camille BAUD --- .../adc/adc_dt/boards/ai_m61_32s_kit.overlay | 45 ++++++++++++++++++ .../adc_dt/boards/dt_xt_zb1_devkit.overlay | 47 +++++++++++++++++++ 2 files changed, 92 insertions(+) create mode 100644 samples/drivers/adc/adc_dt/boards/ai_m61_32s_kit.overlay create mode 100644 samples/drivers/adc/adc_dt/boards/dt_xt_zb1_devkit.overlay diff --git a/samples/drivers/adc/adc_dt/boards/ai_m61_32s_kit.overlay b/samples/drivers/adc/adc_dt/boards/ai_m61_32s_kit.overlay new file mode 100644 index 000000000000..96bd41ae6a8d --- /dev/null +++ b/samples/drivers/adc/adc_dt/boards/ai_m61_32s_kit.overlay @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2024-2026 MASSDRIVER EI (massdriver.space) + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + zephyr,user { + io-channels = <&adc0 0>, <&adc0 1>; + }; +}; + +&pinctrl { + adc0_default: adc0_default { + group1 { + pinmux = , + ; + }; + }; +}; + +&adc0 { + status = "okay"; + + pinctrl-0 = <&adc0_default>; + pinctrl-names = "default"; + + channel@0 { + reg = <0>; + zephyr,gain = "ADC_GAIN_1"; + zephyr,reference = "ADC_REF_INTERNAL"; + zephyr,acquisition-time = ; + zephyr,resolution = <16>; + zephyr,input-positive = <4>; + }; + + channel@1 { + reg = <1>; + zephyr,gain = "ADC_GAIN_1"; + zephyr,reference = "ADC_REF_INTERNAL"; + zephyr,acquisition-time = ; + zephyr,resolution = <16>; + zephyr,input-positive = <5>; + }; +}; diff --git a/samples/drivers/adc/adc_dt/boards/dt_xt_zb1_devkit.overlay b/samples/drivers/adc/adc_dt/boards/dt_xt_zb1_devkit.overlay new file mode 100644 index 000000000000..16b7f2e34af8 --- /dev/null +++ b/samples/drivers/adc/adc_dt/boards/dt_xt_zb1_devkit.overlay @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2024-2025 MASSDRIVER EI (massdriver.space) + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + zephyr,user { + io-channels = <&adc0 0>, <&adc0 1>; + }; +}; + +&pinctrl { + adc0_default: adc0_default { + group1 { + pinmux = , + ; + }; + }; +}; + +&adc0 { + status = "okay"; + #address-cells = <1>; + #size-cells = <0>; + + pinctrl-0 = <&adc0_default>; + pinctrl-names = "default"; + + channel@0 { + reg = <0>; + zephyr,gain = "ADC_GAIN_1"; + zephyr,reference = "ADC_REF_INTERNAL"; + zephyr,acquisition-time = ; + zephyr,resolution = <16>; + zephyr,input-positive = <6>; + }; + + channel@1 { + reg = <1>; + zephyr,gain = "ADC_GAIN_1"; + zephyr,reference = "ADC_REF_INTERNAL"; + zephyr,acquisition-time = ; + zephyr,resolution = <16>; + zephyr,input-positive = <0>; + }; +}; From 7ac12165dd1d908d1bab7fa850a57ec1f08be59b Mon Sep 17 00:00:00 2001 From: Camille BAUD Date: Fri, 31 Oct 2025 02:24:49 +0100 Subject: [PATCH 0125/6328] boards: bflb: Add ADC entry to boards with marked 'ADC' pins Adds adc entry so driver is built. Signed-off-by: Camille BAUD --- .../ai_m62_12f_kit-pinctrl.dtsi | 8 ++++++- .../ai_m62_12f_kit/ai_m62_12f_kit.dts | 22 ++++++++++++++++++- .../ai_m62_12f_kit/ai_m62_12f_kit.yaml | 1 + .../ai_wb2_12f_kit-pinctrl.dtsi | 8 ++++++- .../ai_wb2_12f_kit/ai_wb2_12f_kit.dts | 22 ++++++++++++++++++- .../ai_wb2_12f_kit/ai_wb2_12f_kit.yaml | 1 + 6 files changed, 58 insertions(+), 4 deletions(-) diff --git a/boards/aithinker/ai_m62_12f_kit/ai_m62_12f_kit-pinctrl.dtsi b/boards/aithinker/ai_m62_12f_kit/ai_m62_12f_kit-pinctrl.dtsi index 2ff265f2e2c5..9b4e0853fb60 100644 --- a/boards/aithinker/ai_m62_12f_kit/ai_m62_12f_kit-pinctrl.dtsi +++ b/boards/aithinker/ai_m62_12f_kit/ai_m62_12f_kit-pinctrl.dtsi @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024-2025 MASSDRIVER EI (massdriver.space) + * Copyright (c) 2024-2026 MASSDRIVER EI (massdriver.space) * * SPDX-License-Identifier: Apache-2.0 */ @@ -32,4 +32,10 @@ drive-strength = <1>; }; }; + + adc0_default: adc0_default { + group1 { + pinmux = ; + }; + }; }; diff --git a/boards/aithinker/ai_m62_12f_kit/ai_m62_12f_kit.dts b/boards/aithinker/ai_m62_12f_kit/ai_m62_12f_kit.dts index fc3a1c707233..9cc967abb9df 100644 --- a/boards/aithinker/ai_m62_12f_kit/ai_m62_12f_kit.dts +++ b/boards/aithinker/ai_m62_12f_kit/ai_m62_12f_kit.dts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024-2025 MASSDRIVER EI (massdriver.space) + * Copyright (c) 2024-2026 MASSDRIVER EI (massdriver.space) * * SPDX-License-Identifier: Apache-2.0 */ @@ -85,6 +85,10 @@ zephyr,code = ; }; }; + + zephyr,user { + io-channels = <&adc0 0>; + }; }; &i2c0 { @@ -101,3 +105,19 @@ pinctrl-0 = <&spi0_default>; pinctrl-names = "default"; }; + +&adc0 { + status = "okay"; + + pinctrl-0 = <&adc0_default>; + pinctrl-names = "default"; + + channel@0 { + reg = <0>; + zephyr,gain = "ADC_GAIN_1"; + zephyr,reference = "ADC_REF_INTERNAL"; + zephyr,acquisition-time = ; + zephyr,resolution = <16>; + zephyr,input-positive = <0>; + }; +}; diff --git a/boards/aithinker/ai_m62_12f_kit/ai_m62_12f_kit.yaml b/boards/aithinker/ai_m62_12f_kit/ai_m62_12f_kit.yaml index 9735f959fd14..a7bdae2167f1 100644 --- a/boards/aithinker/ai_m62_12f_kit/ai_m62_12f_kit.yaml +++ b/boards/aithinker/ai_m62_12f_kit/ai_m62_12f_kit.yaml @@ -23,4 +23,5 @@ supported: - flash - input - pwm + - adc vendor: bflb diff --git a/boards/aithinker/ai_wb2_12f_kit/ai_wb2_12f_kit-pinctrl.dtsi b/boards/aithinker/ai_wb2_12f_kit/ai_wb2_12f_kit-pinctrl.dtsi index acf2c447b815..ffe8585718f5 100644 --- a/boards/aithinker/ai_wb2_12f_kit/ai_wb2_12f_kit-pinctrl.dtsi +++ b/boards/aithinker/ai_wb2_12f_kit/ai_wb2_12f_kit-pinctrl.dtsi @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024-2025 MASSDRIVER EI (massdriver.space) + * Copyright (c) 2024-2026 MASSDRIVER EI (massdriver.space) * * SPDX-License-Identifier: Apache-2.0 */ @@ -32,4 +32,10 @@ drive-strength = <1>; }; }; + + adc0_default: adc0_default { + group1 { + pinmux = ; + }; + }; }; diff --git a/boards/aithinker/ai_wb2_12f_kit/ai_wb2_12f_kit.dts b/boards/aithinker/ai_wb2_12f_kit/ai_wb2_12f_kit.dts index 51ee647a2f4d..d58c3879cc6e 100644 --- a/boards/aithinker/ai_wb2_12f_kit/ai_wb2_12f_kit.dts +++ b/boards/aithinker/ai_wb2_12f_kit/ai_wb2_12f_kit.dts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024-2025 MASSDRIVER EI (massdriver.space) + * Copyright (c) 2024-2026 MASSDRIVER EI (massdriver.space) * * SPDX-License-Identifier: Apache-2.0 */ @@ -65,6 +65,10 @@ zephyr,code = ; }; }; + + zephyr,user { + io-channels = <&adc0 0>; + }; }; &i2c0 { @@ -81,3 +85,19 @@ pinctrl-0 = <&spi0_default>; pinctrl-names = "default"; }; + +&adc0 { + status = "okay"; + + pinctrl-0 = <&adc0_default>; + pinctrl-names = "default"; + + channel@0 { + reg = <0>; + zephyr,gain = "ADC_GAIN_1"; + zephyr,reference = "ADC_REF_INTERNAL"; + zephyr,acquisition-time = ; + zephyr,resolution = <16>; + zephyr,input-positive = <10>; + }; +}; diff --git a/boards/aithinker/ai_wb2_12f_kit/ai_wb2_12f_kit.yaml b/boards/aithinker/ai_wb2_12f_kit/ai_wb2_12f_kit.yaml index 77cf6f189871..e55219b611f5 100644 --- a/boards/aithinker/ai_wb2_12f_kit/ai_wb2_12f_kit.yaml +++ b/boards/aithinker/ai_wb2_12f_kit/ai_wb2_12f_kit.yaml @@ -23,4 +23,5 @@ supported: - flash - input - pwm + - adc vendor: bflb From dd8e364863ba8656891389e3956e1040c16b0ceb Mon Sep 17 00:00:00 2001 From: Lucien Zhao Date: Sun, 21 Dec 2025 12:05:18 +0800 Subject: [PATCH 0126/6328] boards: nxp: frdm_mcxe247: config flexio0 pinmux - configure flexio pwm default pinmux Signed-off-by: Lucien Zhao --- boards/nxp/frdm_mcxe247/frdm_mcxe247-pinctrl.dtsi | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/boards/nxp/frdm_mcxe247/frdm_mcxe247-pinctrl.dtsi b/boards/nxp/frdm_mcxe247/frdm_mcxe247-pinctrl.dtsi index 42aa5471decb..5cd0f8d6e254 100644 --- a/boards/nxp/frdm_mcxe247/frdm_mcxe247-pinctrl.dtsi +++ b/boards/nxp/frdm_mcxe247/frdm_mcxe247-pinctrl.dtsi @@ -84,4 +84,12 @@ input-enable; }; }; + + flexio_pwm_default: flexio_pwm_default { + group0 { + pinmux = ; + drive-strength = "low"; + slew-rate = "slow"; + }; + }; }; From f63b15ddd06222ccb5763e94409cc79768e88fac Mon Sep 17 00:00:00 2001 From: Lucien Zhao Date: Sun, 21 Dec 2025 12:07:40 +0800 Subject: [PATCH 0127/6328] tests: drivers: pwm: enable pwm_api case by using flexio0 - enable pwm_api case by using flexio function - record platform information in testcase.yaml Signed-off-by: Lucien Zhao --- .../boards/frdm_mcxe247_flexio_pwm.overlay | 29 +++++++++++++++++++ tests/drivers/pwm/pwm_api/testcase.yaml | 2 ++ 2 files changed, 31 insertions(+) create mode 100644 tests/drivers/pwm/pwm_api/boards/frdm_mcxe247_flexio_pwm.overlay diff --git a/tests/drivers/pwm/pwm_api/boards/frdm_mcxe247_flexio_pwm.overlay b/tests/drivers/pwm/pwm_api/boards/frdm_mcxe247_flexio_pwm.overlay new file mode 100644 index 000000000000..a0e2df1f375d --- /dev/null +++ b/tests/drivers/pwm/pwm_api/boards/frdm_mcxe247_flexio_pwm.overlay @@ -0,0 +1,29 @@ +/* + * Copyright 2025 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/* PWM signal is visible on J2-4. */ +/ { + aliases { + pwm-test = &flexio0_pwm; + }; +}; + +&flexio0 { + status = "okay"; + + flexio0_pwm: flexio0_pwm { + compatible = "nxp,flexio-pwm"; + #pwm-cells = <3>; + status = "okay"; + pinctrl-0 = <&flexio_pwm_default>; + pinctrl-names = "default"; + + pwm_0 { + pin-id = <7>; + prescaler = <1>; + }; + }; +}; diff --git a/tests/drivers/pwm/pwm_api/testcase.yaml b/tests/drivers/pwm/pwm_api/testcase.yaml index a88aaaca39f2..48658cdbd771 100644 --- a/tests/drivers/pwm/pwm_api/testcase.yaml +++ b/tests/drivers/pwm/pwm_api/testcase.yaml @@ -20,6 +20,7 @@ tests: - platform:mimxrt1180_evk/mimxrt1189/cm7:DTC_OVERLAY_FILE="boards/mimxrt1180_evk_flexio_pwm.overlay" - platform:frdm_mcxa366/mcxa366:DTC_OVERLAY_FILE="boards/frdm_mcxa366_flexio_pwm.overlay" - platform:frdm_mcxa266/mcxa266:DTC_OVERLAY_FILE="boards/frdm_mcxa266_flexio_pwm.overlay" + - platform:frdm_mcxe247/mcxe247:DTC_OVERLAY_FILE="boards/frdm_mcxe247_flexio_pwm.overlay" platform_allow: - frdm_ke17z - frdm_ke17z512 @@ -28,6 +29,7 @@ tests: - mimxrt1180_evk/mimxrt1189/cm7 - frdm_mcxa366/mcxa366 - frdm_mcxa266/mcxa266 + - frdm_mcxe247 filter: dt_alias_exists("pwm-test") and CONFIG_DT_HAS_NXP_FLEXIO_ENABLED and CONFIG_DT_HAS_NXP_FLEXIO_PWM_ENABLED depends_on: pwm From 0923d2cedff2a98f34b717935c6e75ae74102f78 Mon Sep 17 00:00:00 2001 From: The Nguyen Date: Thu, 18 Sep 2025 18:26:06 +0000 Subject: [PATCH 0128/6328] manifest: update revision of hal_renesas Update hal_renesas revision to add BSP code support Signed-off-by: The Nguyen --- west.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/west.yml b/west.yml index 9ab9b81e5ded..ff2f3230cbe4 100644 --- a/west.yml +++ b/west.yml @@ -231,7 +231,7 @@ manifest: - hal - name: hal_renesas path: modules/hal/renesas - revision: 56c35ce22bac062a9d6b1fc87f145b5d48571efb + revision: 14f3c2bdd307009eaf9520cdfda2cbabb81e8d10 groups: - hal - name: hal_rpi_pico From 9dd9132688c39b391ceab767fcf24b04ede67b83 Mon Sep 17 00:00:00 2001 From: The Nguyen Date: Thu, 18 Sep 2025 18:27:55 +0000 Subject: [PATCH 0129/6328] soc: renesas: ra: soc init hooks refactor This commit updates the source files for Renesas RA initialization: - The SoC reset/init now uses generic hooks from the "soc/renesas/ra/common" instead of SoC-specific initialization hooks. - Add soc_reset_hooks() to perform the early reset code. - Battery-backup domain initialization has been removed from soc_early_init() and reallocated to soc_reset_hooks(). Signed-off-by: The Nguyen Signed-off-by: Khoa Tran --- soc/renesas/ra/CMakeLists.txt | 5 +- soc/renesas/ra/Kconfig | 4 +- soc/renesas/ra/common/CMakeLists.txt | 26 ++++ .../ra/{common_fsp => common}/pinctrl_soc.h | 6 +- soc/renesas/ra/common/platform_init.ld | 8 ++ .../ra/{ra2l1 => common}/ram_sections.ld | 0 soc/renesas/ra/common/soc.c | 30 +++++ soc/renesas/ra/common/soc.h | 17 +++ .../ra/{common_fsp => common}/vector_data.h | 2 + soc/renesas/ra/common_fsp/CMakeLists.txt | 5 - soc/renesas/ra/common_fsp/battery_backup.c | 56 --------- soc/renesas/ra/common_fsp/battery_backup.h | 16 --- soc/renesas/ra/common_fsp/cold_start.c | 29 ----- soc/renesas/ra/common_fsp/cold_start.h | 17 --- soc/renesas/ra/ra2a1/CMakeLists.txt | 12 -- soc/renesas/ra/ra2a1/Kconfig | 1 - soc/renesas/ra/ra2a1/ram_sections.ld | 17 --- soc/renesas/ra/ra2a1/soc.c | 51 -------- soc/renesas/ra/ra2a1/soc.h | 16 --- soc/renesas/ra/ra2l1/CMakeLists.txt | 12 -- soc/renesas/ra/ra2l1/Kconfig | 1 - soc/renesas/ra/ra2l1/soc.c | 52 -------- soc/renesas/ra/ra2l1/soc.h | 17 --- soc/renesas/ra/ra4c1/CMakeLists.txt | 12 -- soc/renesas/ra/ra4c1/Kconfig | 1 - soc/renesas/ra/ra4c1/ram_sections.ld | 16 --- soc/renesas/ra/ra4c1/soc.c | 62 --------- soc/renesas/ra/ra4c1/soc.h | 16 --- soc/renesas/ra/ra4e1/CMakeLists.txt | 12 -- soc/renesas/ra/ra4e1/Kconfig | 1 - soc/renesas/ra/ra4e1/ram_sections.ld | 16 --- soc/renesas/ra/ra4e1/soc.c | 76 ----------- soc/renesas/ra/ra4e1/soc.h | 16 --- soc/renesas/ra/ra4e2/CMakeLists.txt | 7 -- soc/renesas/ra/ra4e2/Kconfig | 1 - soc/renesas/ra/ra4e2/ram_sections.ld | 16 --- soc/renesas/ra/ra4e2/soc.c | 76 ----------- soc/renesas/ra/ra4e2/soc.h | 16 --- soc/renesas/ra/ra4l1/CMakeLists.txt | 12 -- soc/renesas/ra/ra4l1/Kconfig | 1 - soc/renesas/ra/ra4l1/ram_sections.ld | 16 --- soc/renesas/ra/ra4l1/soc.c | 76 ----------- soc/renesas/ra/ra4l1/soc.h | 16 --- soc/renesas/ra/ra4m1/CMakeLists.txt | 12 -- soc/renesas/ra/ra4m1/Kconfig | 1 - soc/renesas/ra/ra4m1/ram_sections.ld | 17 --- soc/renesas/ra/ra4m1/soc.c | 72 ----------- soc/renesas/ra/ra4m1/soc.h | 16 --- soc/renesas/ra/ra4m2/CMakeLists.txt | 12 -- soc/renesas/ra/ra4m2/Kconfig | 1 - soc/renesas/ra/ra4m2/ram_sections.ld | 16 --- soc/renesas/ra/ra4m2/soc.c | 76 ----------- soc/renesas/ra/ra4m2/soc.h | 16 --- soc/renesas/ra/ra4m3/CMakeLists.txt | 12 -- soc/renesas/ra/ra4m3/Kconfig | 1 - soc/renesas/ra/ra4m3/ram_sections.ld | 16 --- soc/renesas/ra/ra4m3/soc.c | 76 ----------- soc/renesas/ra/ra4m3/soc.h | 16 --- soc/renesas/ra/ra4t1/CMakeLists.txt | 5 - soc/renesas/ra/ra4t1/Kconfig | 1 - soc/renesas/ra/ra4t1/ram_sections.ld | 16 --- soc/renesas/ra/ra4t1/soc.c | 76 ----------- soc/renesas/ra/ra4t1/soc.h | 16 --- soc/renesas/ra/ra4w1/CMakeLists.txt | 12 -- soc/renesas/ra/ra4w1/Kconfig | 1 - soc/renesas/ra/ra4w1/ram_sections.ld | 16 --- soc/renesas/ra/ra4w1/soc.c | 51 -------- soc/renesas/ra/ra4w1/soc.h | 16 --- soc/renesas/ra/ra6e1/CMakeLists.txt | 12 -- soc/renesas/ra/ra6e1/Kconfig | 1 - soc/renesas/ra/ra6e1/ram_sections.ld | 16 --- soc/renesas/ra/ra6e1/soc.c | 81 ------------ soc/renesas/ra/ra6e1/soc.h | 16 --- soc/renesas/ra/ra6e2/CMakeLists.txt | 12 -- soc/renesas/ra/ra6e2/Kconfig | 1 - soc/renesas/ra/ra6e2/ram_sections.ld | 16 --- soc/renesas/ra/ra6e2/soc.c | 81 ------------ soc/renesas/ra/ra6e2/soc.h | 16 --- soc/renesas/ra/ra6m1/CMakeLists.txt | 12 -- soc/renesas/ra/ra6m1/Kconfig | 1 - soc/renesas/ra/ra6m1/ram_sections.ld | 16 --- soc/renesas/ra/ra6m1/soc.c | 56 --------- soc/renesas/ra/ra6m1/soc.h | 16 --- soc/renesas/ra/ra6m2/CMakeLists.txt | 12 -- soc/renesas/ra/ra6m2/Kconfig | 1 - soc/renesas/ra/ra6m2/ram_sections.ld | 16 --- soc/renesas/ra/ra6m2/soc.c | 56 --------- soc/renesas/ra/ra6m2/soc.h | 16 --- soc/renesas/ra/ra6m3/CMakeLists.txt | 12 -- soc/renesas/ra/ra6m3/Kconfig | 1 - soc/renesas/ra/ra6m3/ram_sections.ld | 16 --- soc/renesas/ra/ra6m3/soc.c | 56 --------- soc/renesas/ra/ra6m3/soc.h | 16 --- soc/renesas/ra/ra6m4/CMakeLists.txt | 18 +-- soc/renesas/ra/ra6m4/Kconfig | 1 - soc/renesas/ra/ra6m4/ram_sections.ld | 16 --- soc/renesas/ra/ra6m4/soc.c | 81 ------------ soc/renesas/ra/ra6m4/soc.h | 16 --- soc/renesas/ra/ra6m5/CMakeLists.txt | 16 +-- soc/renesas/ra/ra6m5/Kconfig | 1 - soc/renesas/ra/ra6m5/ram_sections.ld | 16 --- soc/renesas/ra/ra6m5/soc.c | 88 ------------- soc/renesas/ra/ra6m5/soc.h | 16 --- soc/renesas/ra/ra8d1/CMakeLists.txt | 12 -- soc/renesas/ra/ra8d1/Kconfig | 1 - soc/renesas/ra/ra8d1/ram_sections.ld | 16 --- soc/renesas/ra/ra8d1/soc.c | 79 ------------ soc/renesas/ra/ra8d1/soc.h | 17 --- soc/renesas/ra/ra8d2/CMakeLists.txt | 12 -- soc/renesas/ra/ra8d2/Kconfig | 1 - soc/renesas/ra/ra8d2/ram_sections.ld | 16 --- soc/renesas/ra/ra8d2/soc.c | 106 ---------------- soc/renesas/ra/ra8m1/CMakeLists.txt | 12 -- soc/renesas/ra/ra8m1/Kconfig | 1 - soc/renesas/ra/ra8m1/ram_sections.ld | 16 --- soc/renesas/ra/ra8m1/soc.c | 52 -------- soc/renesas/ra/ra8m1/soc.h | 17 --- soc/renesas/ra/ra8m2/CMakeLists.txt | 12 -- soc/renesas/ra/ra8m2/Kconfig | 1 - soc/renesas/ra/ra8m2/ram_sections.ld | 16 --- soc/renesas/ra/ra8m2/soc.c | 106 ---------------- soc/renesas/ra/ra8m2/soc.h | 16 --- soc/renesas/ra/ra8p1/CMakeLists.txt | 10 -- soc/renesas/ra/ra8p1/Kconfig | 1 - soc/renesas/ra/ra8p1/ram_sections.ld | 16 --- soc/renesas/ra/ra8p1/soc.c | 119 ------------------ soc/renesas/ra/ra8p1/soc.h | 17 --- soc/renesas/ra/ra8t1/CMakeLists.txt | 12 -- soc/renesas/ra/ra8t1/Kconfig | 1 - soc/renesas/ra/ra8t1/ram_sections.ld | 16 --- soc/renesas/ra/ra8t1/soc.c | 50 -------- soc/renesas/ra/ra8t1/soc.h | 16 --- soc/renesas/ra/ra8t2/CMakeLists.txt | 12 -- soc/renesas/ra/ra8t2/Kconfig | 1 - soc/renesas/ra/ra8t2/ram_sections.ld | 16 --- soc/renesas/ra/ra8t2/soc.c | 93 -------------- soc/renesas/ra/ra8t2/soc.h | 16 --- 137 files changed, 98 insertions(+), 3066 deletions(-) create mode 100644 soc/renesas/ra/common/CMakeLists.txt rename soc/renesas/ra/{common_fsp => common}/pinctrl_soc.h (90%) create mode 100644 soc/renesas/ra/common/platform_init.ld rename soc/renesas/ra/{ra2l1 => common}/ram_sections.ld (100%) create mode 100644 soc/renesas/ra/common/soc.c create mode 100644 soc/renesas/ra/common/soc.h rename soc/renesas/ra/{common_fsp => common}/vector_data.h (84%) delete mode 100644 soc/renesas/ra/common_fsp/CMakeLists.txt delete mode 100644 soc/renesas/ra/common_fsp/battery_backup.c delete mode 100644 soc/renesas/ra/common_fsp/battery_backup.h delete mode 100644 soc/renesas/ra/common_fsp/cold_start.c delete mode 100644 soc/renesas/ra/common_fsp/cold_start.h delete mode 100644 soc/renesas/ra/ra2a1/ram_sections.ld delete mode 100644 soc/renesas/ra/ra2a1/soc.c delete mode 100644 soc/renesas/ra/ra2a1/soc.h delete mode 100644 soc/renesas/ra/ra2l1/soc.c delete mode 100644 soc/renesas/ra/ra2l1/soc.h delete mode 100644 soc/renesas/ra/ra4c1/ram_sections.ld delete mode 100644 soc/renesas/ra/ra4c1/soc.c delete mode 100644 soc/renesas/ra/ra4c1/soc.h delete mode 100644 soc/renesas/ra/ra4e1/ram_sections.ld delete mode 100644 soc/renesas/ra/ra4e1/soc.c delete mode 100644 soc/renesas/ra/ra4e1/soc.h delete mode 100644 soc/renesas/ra/ra4e2/ram_sections.ld delete mode 100644 soc/renesas/ra/ra4e2/soc.c delete mode 100644 soc/renesas/ra/ra4e2/soc.h delete mode 100644 soc/renesas/ra/ra4l1/ram_sections.ld delete mode 100644 soc/renesas/ra/ra4l1/soc.c delete mode 100644 soc/renesas/ra/ra4l1/soc.h delete mode 100644 soc/renesas/ra/ra4m1/ram_sections.ld delete mode 100644 soc/renesas/ra/ra4m1/soc.c delete mode 100644 soc/renesas/ra/ra4m1/soc.h delete mode 100644 soc/renesas/ra/ra4m2/ram_sections.ld delete mode 100644 soc/renesas/ra/ra4m2/soc.c delete mode 100644 soc/renesas/ra/ra4m2/soc.h delete mode 100644 soc/renesas/ra/ra4m3/ram_sections.ld delete mode 100644 soc/renesas/ra/ra4m3/soc.c delete mode 100644 soc/renesas/ra/ra4m3/soc.h delete mode 100644 soc/renesas/ra/ra4t1/ram_sections.ld delete mode 100644 soc/renesas/ra/ra4t1/soc.c delete mode 100644 soc/renesas/ra/ra4t1/soc.h delete mode 100644 soc/renesas/ra/ra4w1/ram_sections.ld delete mode 100644 soc/renesas/ra/ra4w1/soc.c delete mode 100644 soc/renesas/ra/ra4w1/soc.h delete mode 100644 soc/renesas/ra/ra6e1/ram_sections.ld delete mode 100644 soc/renesas/ra/ra6e1/soc.c delete mode 100644 soc/renesas/ra/ra6e1/soc.h delete mode 100644 soc/renesas/ra/ra6e2/ram_sections.ld delete mode 100644 soc/renesas/ra/ra6e2/soc.c delete mode 100644 soc/renesas/ra/ra6e2/soc.h delete mode 100644 soc/renesas/ra/ra6m1/ram_sections.ld delete mode 100644 soc/renesas/ra/ra6m1/soc.c delete mode 100644 soc/renesas/ra/ra6m1/soc.h delete mode 100644 soc/renesas/ra/ra6m2/ram_sections.ld delete mode 100644 soc/renesas/ra/ra6m2/soc.c delete mode 100644 soc/renesas/ra/ra6m2/soc.h delete mode 100644 soc/renesas/ra/ra6m3/ram_sections.ld delete mode 100644 soc/renesas/ra/ra6m3/soc.c delete mode 100644 soc/renesas/ra/ra6m3/soc.h delete mode 100644 soc/renesas/ra/ra6m4/ram_sections.ld delete mode 100644 soc/renesas/ra/ra6m4/soc.c delete mode 100644 soc/renesas/ra/ra6m4/soc.h delete mode 100644 soc/renesas/ra/ra6m5/ram_sections.ld delete mode 100644 soc/renesas/ra/ra6m5/soc.c delete mode 100644 soc/renesas/ra/ra6m5/soc.h delete mode 100644 soc/renesas/ra/ra8d1/ram_sections.ld delete mode 100644 soc/renesas/ra/ra8d1/soc.c delete mode 100644 soc/renesas/ra/ra8d1/soc.h delete mode 100644 soc/renesas/ra/ra8d2/ram_sections.ld delete mode 100644 soc/renesas/ra/ra8d2/soc.c delete mode 100644 soc/renesas/ra/ra8m1/ram_sections.ld delete mode 100644 soc/renesas/ra/ra8m1/soc.c delete mode 100644 soc/renesas/ra/ra8m1/soc.h delete mode 100644 soc/renesas/ra/ra8m2/ram_sections.ld delete mode 100644 soc/renesas/ra/ra8m2/soc.c delete mode 100644 soc/renesas/ra/ra8m2/soc.h delete mode 100644 soc/renesas/ra/ra8p1/ram_sections.ld delete mode 100644 soc/renesas/ra/ra8p1/soc.c delete mode 100644 soc/renesas/ra/ra8p1/soc.h delete mode 100644 soc/renesas/ra/ra8t1/ram_sections.ld delete mode 100644 soc/renesas/ra/ra8t1/soc.c delete mode 100644 soc/renesas/ra/ra8t1/soc.h delete mode 100644 soc/renesas/ra/ra8t2/ram_sections.ld delete mode 100644 soc/renesas/ra/ra8t2/soc.c delete mode 100644 soc/renesas/ra/ra8t2/soc.h diff --git a/soc/renesas/ra/CMakeLists.txt b/soc/renesas/ra/CMakeLists.txt index a7b5d2c2dc5b..0628ac50fe7f 100644 --- a/soc/renesas/ra/CMakeLists.txt +++ b/soc/renesas/ra/CMakeLists.txt @@ -2,8 +2,5 @@ # Copyright (c) 2024 Renesas Electronics Corporation # SPDX-License-Identifier: Apache-2.0 -zephyr_include_directories(common) -zephyr_include_directories_ifdef(CONFIG_HAS_RENESAS_RA_FSP common_fsp) - -add_subdirectory_ifdef(CONFIG_HAS_RENESAS_RA_FSP common_fsp) +add_subdirectory(common) add_subdirectory(${SOC_SERIES}) diff --git a/soc/renesas/ra/Kconfig b/soc/renesas/ra/Kconfig index ef0822de420a..9f571d9f66fc 100644 --- a/soc/renesas/ra/Kconfig +++ b/soc/renesas/ra/Kconfig @@ -2,6 +2,9 @@ # SPDX-License-Identifier: Apache-2.0 config SOC_FAMILY_RENESAS_RA + select SOC_RESET_HOOK + select SOC_EARLY_INIT_HOOK + select SOC_LATE_INIT_HOOK select HAS_SEGGER_RTT if ZEPHYR_SEGGER_MODULE if SOC_FAMILY_RENESAS_RA @@ -27,7 +30,6 @@ rsource "*/Kconfig" config SOC_RA_ENABLE_START_SECOND_CORE bool "Allows the primary core to start the secondary core" depends on ((RENESAS_PN_NUMBER_OF_CORES = 2) && CPU_CORTEX_M85) - select SOC_LATE_INIT_HOOK help Indicates the second core will be start in the soc_late_init_hook when enabled diff --git a/soc/renesas/ra/common/CMakeLists.txt b/soc/renesas/ra/common/CMakeLists.txt new file mode 100644 index 000000000000..c7aba54f21e4 --- /dev/null +++ b/soc/renesas/ra/common/CMakeLists.txt @@ -0,0 +1,26 @@ +# Copyright (c) 2025 Renesas Electronics Corporation +# SPDX-License-Identifier: Apache-2.0 + +zephyr_include_directories(.) + +# Let SystemInit() be called in place of soc_reset_hook() by default. +zephyr_linker_symbol(SYMBOL soc_reset_hook EXPR "@SystemInit@") + +# These files are used when the CMake linker script generator is disabled. +if(CONFIG_CMAKE_LINKER_GENERATOR) + if(CONFIG_USE_RA_FSP_DTC) + zephyr_linker_section(NAME .fsp_dtc_vector_table GROUP RAM) + zephyr_linker_section_configure(SECTION .fsp_dtc_vector_table KEEP INPUT ".fsp_dtc_vector_table*") + endif() + +elseif(CONFIG_LD_LINKER_TEMPLATE) + zephyr_linker_sources(SECTIONS platform_init.ld) + zephyr_linker_sources(SECTIONS ram_sections.ld) + +endif() + +zephyr_sources(soc.c) + +if(NOT CONFIG_ETH_RENESAS_RA_USE_NS_BUF) + set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "") +endif() diff --git a/soc/renesas/ra/common_fsp/pinctrl_soc.h b/soc/renesas/ra/common/pinctrl_soc.h similarity index 90% rename from soc/renesas/ra/common_fsp/pinctrl_soc.h rename to soc/renesas/ra/common/pinctrl_soc.h index ff345032f803..cbf667e1a557 100644 --- a/soc/renesas/ra/common_fsp/pinctrl_soc.h +++ b/soc/renesas/ra/common/pinctrl_soc.h @@ -54,10 +54,8 @@ typedef struct ra_pinctrl_soc_pin pinctrl_soc_pin_t; * @param prop Property name describing state pins. */ #define Z_PINCTRL_STATE_PINS_INIT(node_id, prop) \ - { \ - DT_FOREACH_CHILD_VARGS(DT_PHANDLE(node_id, prop), DT_FOREACH_PROP_ELEM, psels, \ - Z_PINCTRL_STATE_PIN_INIT) \ - } + {DT_FOREACH_CHILD_VARGS(DT_PHANDLE(node_id, prop), DT_FOREACH_PROP_ELEM, psels, \ + Z_PINCTRL_STATE_PIN_INIT)} #define RA_GET_PORT_NUM(pinctrl) (((pinctrl) >> RA_PORT_NUM_POS) & RA_PORT_NUM_MASK) #define RA_GET_PIN_NUM(pinctrl) (((pinctrl) >> RA_PIN_NUM_POS) & RA_PIN_NUM_MASK) diff --git a/soc/renesas/ra/common/platform_init.ld b/soc/renesas/ra/common/platform_init.ld new file mode 100644 index 000000000000..3cda23aa8554 --- /dev/null +++ b/soc/renesas/ra/common/platform_init.ld @@ -0,0 +1,8 @@ +/* + * Copyright (c) 2025 Renesas Electronics Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/* Let SystemInit() be called in place of soc_reset_hook() by default. */ +PROVIDE(soc_reset_hook = SystemInit); diff --git a/soc/renesas/ra/ra2l1/ram_sections.ld b/soc/renesas/ra/common/ram_sections.ld similarity index 100% rename from soc/renesas/ra/ra2l1/ram_sections.ld rename to soc/renesas/ra/common/ram_sections.ld diff --git a/soc/renesas/ra/common/soc.c b/soc/renesas/ra/common/soc.c new file mode 100644 index 000000000000..ed9d0582dd49 --- /dev/null +++ b/soc/renesas/ra/common/soc.c @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2024-2025 Renesas Electronics Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include + +extern void NMI_Handler(void); + +void soc_early_init_hook(void) +{ +#ifdef CONFIG_RUNTIME_NMI + z_arm_nmi_set_handler(NMI_Handler); +#endif /* CONFIG_RUNTIME_NMI */ + +#if defined(CONFIG_ICACHE) + /* Invalidate I-Cache after initializing the .ram_from_flash section. */ + sys_cache_instr_invd_all(); +#endif /* CONFIG_ICACHE */ +} + +void soc_late_init_hook(void) +{ +#ifdef CONFIG_SOC_RA_ENABLE_START_SECOND_CORE + R_BSP_SecondaryCoreStart(); +#endif /* CONFIG_SOC_RA_ENABLE_START_SECOND_CORE */ +} diff --git a/soc/renesas/ra/common/soc.h b/soc/renesas/ra/common/soc.h new file mode 100644 index 000000000000..e6096df8be93 --- /dev/null +++ b/soc/renesas/ra/common/soc.h @@ -0,0 +1,17 @@ +/* + * Copyright (c) 2024 TOKITA Hiroshi + * Copyright (c) 2025 Renesas Electronics Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @file SoC configuration macros for the Renesas RA family MCU + */ + +#ifndef ZEPHYR_SOC_RENESAS_RA_COMMON_SOC_H_ +#define ZEPHYR_SOC_RENESAS_RA_COMMON_SOC_H_ + +#include + +#endif /* ZEPHYR_SOC_RENESAS_RA_COMMON_SOC_H_ */ diff --git a/soc/renesas/ra/common_fsp/vector_data.h b/soc/renesas/ra/common/vector_data.h similarity index 84% rename from soc/renesas/ra/common_fsp/vector_data.h rename to soc/renesas/ra/common/vector_data.h index 91096f529054..036e9a9068fa 100644 --- a/soc/renesas/ra/common_fsp/vector_data.h +++ b/soc/renesas/ra/common/vector_data.h @@ -9,4 +9,6 @@ #ifndef ZEPHYR_SOC_RENESAS_RA_COMMON_VECTOR_DATA_H_ #define ZEPHYR_SOC_RENESAS_RA_COMMON_VECTOR_DATA_H_ +#define BSP_ICU_VECTOR_NUM_ENTRIES CONFIG_NUM_IRQS + #endif /* ZEPHYR_SOC_RENESAS_RA_COMMON_VECTOR_DATA_H_ */ diff --git a/soc/renesas/ra/common_fsp/CMakeLists.txt b/soc/renesas/ra/common_fsp/CMakeLists.txt deleted file mode 100644 index 5e407d6d50ea..000000000000 --- a/soc/renesas/ra/common_fsp/CMakeLists.txt +++ /dev/null @@ -1,5 +0,0 @@ -# Copyright (c) 2025 Renesas Electronics Corporation -# SPDX-License-Identifier: Apache-2.0 - -zephyr_sources_ifdef(CONFIG_RENESAS_RA_BATTERY_BACKUP_MANUAL_CONFIGURE battery_backup.c) -zephyr_sources(cold_start.c) diff --git a/soc/renesas/ra/common_fsp/battery_backup.c b/soc/renesas/ra/common_fsp/battery_backup.c deleted file mode 100644 index 741337a53953..000000000000 --- a/soc/renesas/ra/common_fsp/battery_backup.c +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright (c) 2025 Renesas Electronics Corporation - * - * SPDX-License-Identifier: Apache-2.0 - */ -#include "battery_backup.h" - -#define VCC_DROP_DETECTION_STABILIZATION_WAIT_TIME_US 20 -#define VBTBPSR_VBPORF_IS_SET BIT(0) -#define VBTBPCR2_VDETLVL_SETTING_NOT_USED 0x6 - -static uint8_t vbtbpsr_state_at_boot; - -bool is_backup_domain_reset_happen(void) -{ - return (vbtbpsr_state_at_boot & VBTBPSR_VBPORF_IS_SET); -} - -void battery_backup_init(void) -{ -#if DT_NODE_HAS_PROP(DT_NODELABEL(battery_backup), switch_threshold) - /* Check VBPORM bit. If VBPORM flag is 0, wait until it changes to 1 */ - while (R_SYSTEM->VBTBPSR_b.VBPORM == 0) { - } - vbtbpsr_state_at_boot = R_SYSTEM->VBTBPSR; - if (R_SYSTEM->VBTBPSR_b.VBPORF == 1) { - R_BSP_RegisterProtectDisable(BSP_REG_PROTECT_OM_LPC_BATT); - R_SYSTEM->VBTBPSR_b.VBPORF = 0; - R_SYSTEM->VBTBPCR2_b.VDETLVL = - DT_ENUM_IDX(DT_NODELABEL(battery_backup), switch_threshold); - R_BSP_SoftwareDelay(VCC_DROP_DETECTION_STABILIZATION_WAIT_TIME_US, - BSP_DELAY_UNITS_MICROSECONDS); - R_SYSTEM->VBTBPCR2_b.VDETE = 1; - R_BSP_RegisterProtectEnable(BSP_REG_PROTECT_OM_LPC_BATT); - } -#else - /* Set the BPWSWSTP bit to 1. The power supply switch is stopped */ - R_BSP_RegisterProtectDisable(BSP_REG_PROTECT_OM_LPC_BATT); - R_SYSTEM->VBTBPCR1_b.BPWSWSTP = 1; - - /* Check VBPORM flag. If VBPORM flag is 0, wait until it changes to 1 */ - while (R_SYSTEM->VBTBPSR_b.VBPORM == 0) { - } - vbtbpsr_state_at_boot = R_SYSTEM->VBTBPSR; - R_SYSTEM->VBTBPSR_b.VBPORF = 0; - R_SYSTEM->VBTBPCR2_b.VDETE = 0; - R_SYSTEM->VBTBPCR2_b.VDETLVL = DT_ENUM_IDX_OR( - DT_NODELABEL(battery_backup), switch_threshold, VBTBPCR2_VDETLVL_SETTING_NOT_USED); - R_BSP_RegisterProtectEnable(BSP_REG_PROTECT_OM_LPC_BATT); - - /* Set the SOSTP bit to 1 regardless of its value. Stop Sub-Clock Oscillator */ - R_BSP_RegisterProtectDisable(BSP_REG_PROTECT_CGC); - R_SYSTEM->SOSCCR_b.SOSTP = 1; - R_BSP_RegisterProtectEnable(BSP_REG_PROTECT_CGC); -#endif /* BATTERY_BACKUP_CONFIGURATION_NOT_USED */ -} diff --git a/soc/renesas/ra/common_fsp/battery_backup.h b/soc/renesas/ra/common_fsp/battery_backup.h deleted file mode 100644 index 2757a9d47a37..000000000000 --- a/soc/renesas/ra/common_fsp/battery_backup.h +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright (c) 2025 Renesas Electronics Corporation - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#ifndef ZEPHYR_SOC_RENESAS_RA_BATTERY_BACKUP_H_ -#define ZEPHYR_SOC_RENESAS_RA_BATTERY_BACKUP_H_ - -#include -#include - -bool is_backup_domain_reset_happen(void); -void battery_backup_init(void); - -#endif /* ZEPHYR_SOC_RENESAS_RA_BATTERY_BACKUP_H_ */ diff --git a/soc/renesas/ra/common_fsp/cold_start.c b/soc/renesas/ra/common_fsp/cold_start.c deleted file mode 100644 index a176e07805bf..000000000000 --- a/soc/renesas/ra/common_fsp/cold_start.c +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright (c) 2025 Renesas Electronics Corporation - * - * SPDX-License-Identifier: Apache-2.0 - */ -#include -#include -#include "cold_start.h" - -#define RSTSR2_CWSF_BIT_MASK BIT(0) - -static uint8_t rstsr2_state_at_boot; - -bool is_power_on_reset_happen(void) -{ - return ((rstsr2_state_at_boot & RSTSR2_CWSF_BIT_MASK) == 0); -} - -void cold_start_handler(void) -{ - /* Detect power on reset */ - rstsr2_state_at_boot = R_SYSTEM->RSTSR2; - if (R_SYSTEM->RSTSR2_b.CWSF == 0) { -#if defined(CONFIG_RENESAS_RA_BATTERY_BACKUP_MANUAL_CONFIGURE) - battery_backup_init(); -#endif /* CONFIG_RENESAS_RA_BATTERY_BACKUP_MANUAL_CONFIGURE */ - R_SYSTEM->RSTSR2_b.CWSF = 1; - } -} diff --git a/soc/renesas/ra/common_fsp/cold_start.h b/soc/renesas/ra/common_fsp/cold_start.h deleted file mode 100644 index 5b818b994182..000000000000 --- a/soc/renesas/ra/common_fsp/cold_start.h +++ /dev/null @@ -1,17 +0,0 @@ -/* - * Copyright (c) 2025 Renesas Electronics Corporation - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#ifndef ZEPHYR_SOC_RENESAS_RA_COLD_START_H_ -#define ZEPHYR_SOC_RENESAS_RA_COLD_START_H_ - -#include -#include -#include "battery_backup.h" - -bool is_power_on_reset_happen(void); -void cold_start_handler(void); - -#endif /* ZEPHYR_SOC_RENESAS_RA_COLD_START_H_ */ diff --git a/soc/renesas/ra/ra2a1/CMakeLists.txt b/soc/renesas/ra/ra2a1/CMakeLists.txt index 04f2ebbc433a..5c08e3ca2039 100644 --- a/soc/renesas/ra/ra2a1/CMakeLists.txt +++ b/soc/renesas/ra/ra2a1/CMakeLists.txt @@ -4,10 +4,6 @@ zephyr_include_directories(.) -zephyr_sources( - soc.c -) - if(CONFIG_CMAKE_LINKER_GENERATOR) dt_nodelabel(option_setting_ofs0 NODELABEL "option_setting_ofs0") dt_nodelabel(option_setting_ofs1 NODELABEL "option_setting_ofs1") @@ -21,11 +17,6 @@ if(CONFIG_CMAKE_LINKER_GENERATOR) dt_node_has_status(osis_status PATH ${option_setting_osis} STATUS okay) - if(CONFIG_USE_RA_FSP_DTC) - zephyr_linker_section(NAME .fsp_dtc_vector_table GROUP RAM) - zephyr_linker_section_configure(SECTION .fsp_dtc_vector_table KEEP INPUT ".fsp_dtc_vector_table*") - endif() - zephyr_linker_section(NAME .rom_padding GROUP ROM_REGION ADDRESS 0x000000C0) zephyr_linker_section_configure(SECTION .rom_padding KEEP INPUT ".rom_padding*") @@ -46,10 +37,7 @@ if(CONFIG_CMAKE_LINKER_GENERATOR) elseif(CONFIG_LD_LINKER_TEMPLATE) zephyr_linker_sources(ROM_START rom_start.ld) zephyr_linker_sources(SECTIONS sections.ld) - zephyr_linker_sources(RAM_SECTIONS ram_sections.ld) else() message(WARNING "Unsupported linker template.") endif() - -set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "") diff --git a/soc/renesas/ra/ra2a1/Kconfig b/soc/renesas/ra/ra2a1/Kconfig index e42ae36eac1c..9b3b2539efde 100644 --- a/soc/renesas/ra/ra2a1/Kconfig +++ b/soc/renesas/ra/ra2a1/Kconfig @@ -10,7 +10,6 @@ config SOC_SERIES_RA2A1 select HAS_SWO select XIP select HAS_RENESAS_RA_FSP - select SOC_EARLY_INIT_HOOK if SOC_SERIES_RA2A1 diff --git a/soc/renesas/ra/ra2a1/ram_sections.ld b/soc/renesas/ra/ra2a1/ram_sections.ld deleted file mode 100644 index ece8ea46fa47..000000000000 --- a/soc/renesas/ra/ra2a1/ram_sections.ld +++ /dev/null @@ -1,17 +0,0 @@ -/* - * Copyright (c) 2024 TOKITA Hiroshi - * Copyright (c) 2025 Renesas Electronics Corporation - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include - -#ifdef CONFIG_USE_RA_FSP_DTC -SECTION_DATA_PROLOGUE(.fsp_dtc_vector_table,(NOLOAD),) -{ - /* If DTC is used, put the DTC vector table at the start of SRAM. - This avoids memory holes due to 1K alignment required by it. */ - *(.fsp_dtc_vector_table) -} GROUP_DATA_LINK_IN(RAMABLE_REGION, RAMABLE_REGION) -#endif /* CONFIG_USE_RA_FSP_DTC */ diff --git a/soc/renesas/ra/ra2a1/soc.c b/soc/renesas/ra/ra2a1/soc.c deleted file mode 100644 index 5585eba6a6d7..000000000000 --- a/soc/renesas/ra/ra2a1/soc.c +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright (c) 2024 TOKITA Hiroshi - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/** - * @file - * @brief System/hardware module for Renesas RA2A1 family processor - */ - -#include -#include -#include -#include -#include -#include -#include -#include -LOG_MODULE_REGISTER(soc, CONFIG_SOC_LOG_LEVEL); - -#include - -uint32_t SystemCoreClock BSP_SECTION_EARLY_INIT; - -volatile uint32_t g_protect_pfswe_counter BSP_SECTION_EARLY_INIT; - -#ifdef CONFIG_RUNTIME_NMI -extern bsp_grp_irq_cb_t g_bsp_group_irq_sources[]; -extern void NMI_Handler(void); -#endif /* CONFIG_RUNTIME_NMI */ - -/** - * @brief Perform basic hardware initialization at boot. - * - * This needs to be run from the very beginning. - */ -void soc_early_init_hook(void) -{ - SystemCoreClock = BSP_MOCO_HZ; - g_protect_pfswe_counter = 0; - bsp_clock_init(); - -#ifdef CONFIG_RUNTIME_NMI - for (uint32_t i = 0; i < 16; i++) { - g_bsp_group_irq_sources[i] = 0; - } - - z_arm_nmi_set_handler(NMI_Handler); -#endif /* CONFIG_RUNTIME_NMI */ -} diff --git a/soc/renesas/ra/ra2a1/soc.h b/soc/renesas/ra/ra2a1/soc.h deleted file mode 100644 index 3dab874487bb..000000000000 --- a/soc/renesas/ra/ra2a1/soc.h +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright (c) 2024 TOKITA Hiroshi - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/** - * @file SoC configuration macros for the Renesas RA2A1 family MCU - */ - -#ifndef ZEPHYR_SOC_RENESAS_RA2A1_SOC_H_ -#define ZEPHYR_SOC_RENESAS_RA2A1_SOC_H_ - -#include - -#endif /* ZEPHYR_SOC_RENESAS_RA2A1_SOC_H_ */ diff --git a/soc/renesas/ra/ra2l1/CMakeLists.txt b/soc/renesas/ra/ra2l1/CMakeLists.txt index 1d8891f222cb..45c638e71cbd 100644 --- a/soc/renesas/ra/ra2l1/CMakeLists.txt +++ b/soc/renesas/ra/ra2l1/CMakeLists.txt @@ -4,10 +4,6 @@ zephyr_include_directories(.) -zephyr_sources( - soc.c -) - if(CONFIG_CMAKE_LINKER_GENERATOR) dt_nodelabel(option_setting_ofs0 NODELABEL "option_setting_ofs0") dt_nodelabel(option_setting_ofs1 NODELABEL "option_setting_ofs1") @@ -21,11 +17,6 @@ if(CONFIG_CMAKE_LINKER_GENERATOR) dt_node_has_status(osis_status PATH ${option_setting_osis} STATUS okay) - if(CONFIG_USE_RA_FSP_DTC) - zephyr_linker_section(NAME .fsp_dtc_vector_table GROUP RAM) - zephyr_linker_section_configure(SECTION .fsp_dtc_vector_table KEEP INPUT ".fsp_dtc_vector_table*") - endif() - zephyr_linker_section(NAME .rom_padding GROUP ROM_REGION ADDRESS 0x000000C0) zephyr_linker_section_configure(SECTION .rom_padding KEEP INPUT ".rom_padding*") @@ -46,10 +37,7 @@ if(CONFIG_CMAKE_LINKER_GENERATOR) elseif(CONFIG_LD_LINKER_TEMPLATE) zephyr_linker_sources(ROM_START rom_start.ld) zephyr_linker_sources(SECTIONS sections.ld) - zephyr_linker_sources(RAM_SECTIONS ram_sections.ld) else() message(WARNING "Unsupported linker template.") endif() - -set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "") diff --git a/soc/renesas/ra/ra2l1/Kconfig b/soc/renesas/ra/ra2l1/Kconfig index 6d781dc1f8f0..d4342e1432e0 100644 --- a/soc/renesas/ra/ra2l1/Kconfig +++ b/soc/renesas/ra/ra2l1/Kconfig @@ -11,7 +11,6 @@ config SOC_SERIES_RA2L1 select CPU_CORTEX_M_HAS_SYSTICK select CLOCK_CONTROL_RENESAS_RA_CGC if CLOCK_CONTROL select HAS_SWO - select SOC_EARLY_INIT_HOOK if SOC_SERIES_RA2L1 diff --git a/soc/renesas/ra/ra2l1/soc.c b/soc/renesas/ra/ra2l1/soc.c deleted file mode 100644 index 82a889c994ab..000000000000 --- a/soc/renesas/ra/ra2l1/soc.c +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright (c) 2023-2024 MUNIC SA - * Copyright (c) 2024 Renesas Electronics Corporation - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/** - * @file - * @brief System/hardware module for Renesas RA2L1 family processor - */ - -#include -#include -#include -#include -#include -#include -#include -#include -LOG_MODULE_REGISTER(soc, CONFIG_SOC_LOG_LEVEL); - -#include "bsp_cfg.h" -#include - -uint32_t SystemCoreClock BSP_SECTION_EARLY_INIT; - -volatile uint32_t g_protect_pfswe_counter BSP_SECTION_EARLY_INIT; - -#ifdef CONFIG_RUNTIME_NMI -extern bsp_grp_irq_cb_t g_bsp_group_irq_sources[]; -extern void NMI_Handler(void); -#endif /* CONFIG_RUNTIME_NMI */ - -/** - * @brief Perform basic hardware initialization at boot. - * - * This needs to be run from the very beginning. - */ -void soc_early_init_hook(void) -{ - SystemCoreClock = BSP_MOCO_HZ; - g_protect_pfswe_counter = 0; - -#ifdef CONFIG_RUNTIME_NMI - for (uint32_t i = 0; i < 16; i++) { - g_bsp_group_irq_sources[i] = 0; - } - - z_arm_nmi_set_handler(NMI_Handler); -#endif /* CONFIG_RUNTIME_NMI */ -} diff --git a/soc/renesas/ra/ra2l1/soc.h b/soc/renesas/ra/ra2l1/soc.h deleted file mode 100644 index 2fa588a6c0c3..000000000000 --- a/soc/renesas/ra/ra2l1/soc.h +++ /dev/null @@ -1,17 +0,0 @@ -/* - * Copyright (c) 2021-2024 MUNIC SA - * Copyright (c) 2024 Renesas Electronics Corporation - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/** - * @file SoC configuration macros for the Renesas RA2L1 family MCU - */ - -#ifndef ZEPHYR_SOC_RENESAS_RA2L1_SOC_H_ -#define ZEPHYR_SOC_RENESAS_RA2L1_SOC_H_ - -#include - -#endif /* ZEPHYR_SOC_RENESAS_RA2L1_SOC_H_ */ diff --git a/soc/renesas/ra/ra4c1/CMakeLists.txt b/soc/renesas/ra/ra4c1/CMakeLists.txt index 695c35a40947..6a32d2a8e0e0 100644 --- a/soc/renesas/ra/ra4c1/CMakeLists.txt +++ b/soc/renesas/ra/ra4c1/CMakeLists.txt @@ -3,10 +3,6 @@ zephyr_include_directories(.) -zephyr_sources( - soc.c -) - if(CONFIG_CMAKE_LINKER_GENERATOR) dt_nodelabel(option_setting_ofs0 NODELABEL "option_setting_ofs0") dt_nodelabel(option_setting_dualsel NODELABEL "option_setting_dualsel") @@ -38,11 +34,6 @@ if(CONFIG_CMAKE_LINKER_GENERATOR) dt_node_has_status(banksel_sel_status PATH ${option_setting_banksel_sel} STATUS okay) dt_node_has_status(bps_sel_status PATH ${option_setting_bps_sel} STATUS okay) - if(CONFIG_USE_RA_FSP_DTC) - zephyr_linker_section(NAME .fsp_dtc_vector_table GROUP RAM) - zephyr_linker_section_configure(SECTION .fsp_dtc_vector_table KEEP INPUT ".fsp_dtc_vector_table*") - endif() - if(${ofs0_status}) zephyr_linker_section(NAME .option_setting_ofs0 GROUP OFS_OFS0_MEMORY ADDRESS ${ofs0_addr}) zephyr_linker_section_configure(SECTION .option_setting_ofs0 KEEP INPUT ".option_setting_ofs0*") @@ -90,10 +81,7 @@ if(CONFIG_CMAKE_LINKER_GENERATOR) elseif(CONFIG_LD_LINKER_TEMPLATE) zephyr_linker_sources(SECTIONS sections.ld) - zephyr_linker_sources(RAM_SECTIONS ram_sections.ld) else() message(WARNING "Unsupported linker template.") endif() - -set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "") diff --git a/soc/renesas/ra/ra4c1/Kconfig b/soc/renesas/ra/ra4c1/Kconfig index 38075b3dd06a..a45c7b4b8e2c 100644 --- a/soc/renesas/ra/ra4c1/Kconfig +++ b/soc/renesas/ra/ra4c1/Kconfig @@ -13,7 +13,6 @@ config SOC_SERIES_RA4C1 select FPU select HAS_SWO select XIP - select SOC_EARLY_INIT_HOOK if SOC_SERIES_RA4C1 diff --git a/soc/renesas/ra/ra4c1/ram_sections.ld b/soc/renesas/ra/ra4c1/ram_sections.ld deleted file mode 100644 index 18be2a431de2..000000000000 --- a/soc/renesas/ra/ra4c1/ram_sections.ld +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright (c) 2025 Renesas Electronics Corporation - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include - -#ifdef CONFIG_USE_RA_FSP_DTC -SECTION_DATA_PROLOGUE(.fsp_dtc_vector_table,(NOLOAD),) -{ - /* If DTC is used, put the DTC vector table at the start of SRAM. - This avoids memory holes due to 1K alignment required by it. */ - *(.fsp_dtc_vector_table) -} GROUP_DATA_LINK_IN(RAMABLE_REGION, RAMABLE_REGION) -#endif /* CONFIG_USE_RA_FSP_DTC */ diff --git a/soc/renesas/ra/ra4c1/soc.c b/soc/renesas/ra/ra4c1/soc.c deleted file mode 100644 index f4921562c029..000000000000 --- a/soc/renesas/ra/ra4c1/soc.c +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright (c) 2025 Renesas Electronics Corporation - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/** - * @file - * @brief System/hardware module for Renesas RA4C1 family processor - */ - -#include -#include -#include -#include -#include -#include -#include -#include -LOG_MODULE_REGISTER(soc, CONFIG_SOC_LOG_LEVEL); - -#include "bsp_cfg.h" -#include - -uint32_t SystemCoreClock BSP_SECTION_EARLY_INIT; - -volatile uint32_t g_protect_pfswe_counter BSP_SECTION_EARLY_INIT; - -/** - * @brief Perform basic hardware initialization at boot. - * - * This needs to be run from the very beginning. - */ -void soc_early_init_hook(void) -{ - extern volatile uint16_t g_protect_counters[]; - - for (uint32_t i = 0; i < 5; i++) { - g_protect_counters[i] = 0; - } - -#if FSP_PRIV_TZ_USE_SECURE_REGS - /* Disable protection using PRCR register. */ - R_BSP_RegisterProtectDisable(BSP_REG_PROTECT_SAR); - - /* Initialize peripherals to secure mode for flat projects */ - R_PSCU->PSARB = 0; - R_PSCU->PSARC = 0; - R_PSCU->PSARD = 0; - R_PSCU->PSARE = 0; - - R_CPSCU->ICUSARC = 0; - R_CPSCU->ICUSARG = 0; - R_CPSCU->ICUSARH = 0; - - /* Enable protection using PRCR register. */ - R_BSP_RegisterProtectEnable(BSP_REG_PROTECT_SAR); -#endif - - SystemCoreClock = BSP_MOCO_HZ; - g_protect_pfswe_counter = 0; -} diff --git a/soc/renesas/ra/ra4c1/soc.h b/soc/renesas/ra/ra4c1/soc.h deleted file mode 100644 index 925b6a248fe0..000000000000 --- a/soc/renesas/ra/ra4c1/soc.h +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright (c) 2025 Renesas Electronics Corporation - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/** - * @file SoC configuration macros for the Renesas RA4C1 family MCU - */ - -#ifndef ZEPHYR_SOC_RENESAS_RA4C1_SOC_H_ -#define ZEPHYR_SOC_RENESAS_RA4C1_SOC_H_ - -#include - -#endif /* ZEPHYR_SOC_RENESAS_RA4C1_SOC_H_ */ diff --git a/soc/renesas/ra/ra4e1/CMakeLists.txt b/soc/renesas/ra/ra4e1/CMakeLists.txt index 82681b5184b3..b362cc3501a2 100644 --- a/soc/renesas/ra/ra4e1/CMakeLists.txt +++ b/soc/renesas/ra/ra4e1/CMakeLists.txt @@ -3,10 +3,6 @@ zephyr_include_directories(.) -zephyr_sources( - soc.c -) - if(CONFIG_CMAKE_LINKER_GENERATOR) dt_nodelabel(option_setting_ofs0 NODELABEL "option_setting_ofs0") dt_nodelabel(option_setting_ofs1_sec NODELABEL "option_setting_ofs1_sec") @@ -29,11 +25,6 @@ if(CONFIG_CMAKE_LINKER_GENERATOR) dt_node_has_status(ofs1_sel_status PATH ${option_setting_ofs1_sel} STATUS okay) dt_node_has_status(bps_sel_status PATH ${option_setting_bps_sel} STATUS okay) - if(CONFIG_USE_RA_FSP_DTC) - zephyr_linker_section(NAME .fsp_dtc_vector_table GROUP RAM) - zephyr_linker_section_configure(SECTION .fsp_dtc_vector_table KEEP INPUT ".fsp_dtc_vector_table*") - endif() - if(${ofs0_status}) zephyr_linker_section(NAME .option_setting_ofs0 GROUP OFS_OFS0_MEMORY ADDRESS ${ofs0_addr}) zephyr_linker_section_configure(SECTION .option_setting_ofs0 KEEP INPUT ".option_setting_ofs0*") @@ -66,10 +57,7 @@ if(CONFIG_CMAKE_LINKER_GENERATOR) elseif(CONFIG_LD_LINKER_TEMPLATE) zephyr_linker_sources(SECTIONS sections.ld) - zephyr_linker_sources(RAM_SECTIONS ram_sections.ld) else() message(WARNING "Unsupported linker template.") endif() - -set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "") diff --git a/soc/renesas/ra/ra4e1/Kconfig b/soc/renesas/ra/ra4e1/Kconfig index b48567294a7e..7424c449dd89 100644 --- a/soc/renesas/ra/ra4e1/Kconfig +++ b/soc/renesas/ra/ra4e1/Kconfig @@ -13,7 +13,6 @@ config SOC_SERIES_RA4E1 select FPU select HAS_SWO select XIP - select SOC_EARLY_INIT_HOOK select GPIO_RA_HAS_VBTICTLR if SOC_SERIES_RA4E1 diff --git a/soc/renesas/ra/ra4e1/ram_sections.ld b/soc/renesas/ra/ra4e1/ram_sections.ld deleted file mode 100644 index 18be2a431de2..000000000000 --- a/soc/renesas/ra/ra4e1/ram_sections.ld +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright (c) 2025 Renesas Electronics Corporation - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include - -#ifdef CONFIG_USE_RA_FSP_DTC -SECTION_DATA_PROLOGUE(.fsp_dtc_vector_table,(NOLOAD),) -{ - /* If DTC is used, put the DTC vector table at the start of SRAM. - This avoids memory holes due to 1K alignment required by it. */ - *(.fsp_dtc_vector_table) -} GROUP_DATA_LINK_IN(RAMABLE_REGION, RAMABLE_REGION) -#endif /* CONFIG_USE_RA_FSP_DTC */ diff --git a/soc/renesas/ra/ra4e1/soc.c b/soc/renesas/ra/ra4e1/soc.c deleted file mode 100644 index 011e53fd89ca..000000000000 --- a/soc/renesas/ra/ra4e1/soc.c +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright (c) 2025 Renesas Electronics Corporation - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/** - * @file - * @brief System/hardware module for Renesas RA4E1 family processor - */ - -#include -#include -#include -#include -#include -#include -#include -#include -LOG_MODULE_REGISTER(soc, CONFIG_SOC_LOG_LEVEL); - -#include "bsp_cfg.h" -#include - -uint32_t SystemCoreClock BSP_SECTION_EARLY_INIT; - -volatile uint32_t g_protect_pfswe_counter BSP_SECTION_EARLY_INIT; - -#ifdef CONFIG_RUNTIME_NMI -extern bsp_grp_irq_cb_t g_bsp_group_irq_sources[]; -extern void NMI_Handler(void); -#endif /* CONFIG_RUNTIME_NMI */ - -/** - * @brief Perform basic hardware initialization at boot. - * - * This needs to be run from the very beginning. - */ -void soc_early_init_hook(void) -{ - extern volatile uint16_t g_protect_counters[]; - - for (uint32_t i = 0; i < 5; i++) { - g_protect_counters[i] = 0; - } - -#if FSP_PRIV_TZ_USE_SECURE_REGS - /* Disable protection using PRCR register. */ - R_BSP_RegisterProtectDisable(BSP_REG_PROTECT_SAR); - - /* Initialize peripherals to secure mode for flat projects */ - R_PSCU->PSARB = 0; - R_PSCU->PSARC = 0; - R_PSCU->PSARD = 0; - R_PSCU->PSARE = 0; - - R_CPSCU->ICUSARC = 0; - R_CPSCU->ICUSARG = 0; - R_CPSCU->ICUSARH = 0; - R_CPSCU->ICUSARI = 0; - - /* Enable protection using PRCR register. */ - R_BSP_RegisterProtectEnable(BSP_REG_PROTECT_SAR); -#endif - - SystemCoreClock = BSP_MOCO_HZ; - g_protect_pfswe_counter = 0; - -#ifdef CONFIG_RUNTIME_NMI - for (uint32_t i = 0; i < 16; i++) { - g_bsp_group_irq_sources[i] = 0; - } - - z_arm_nmi_set_handler(NMI_Handler); -#endif /* CONFIG_RUNTIME_NMI */ -} diff --git a/soc/renesas/ra/ra4e1/soc.h b/soc/renesas/ra/ra4e1/soc.h deleted file mode 100644 index 704d430fecf5..000000000000 --- a/soc/renesas/ra/ra4e1/soc.h +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright (c) 2025 Renesas Electronics Corporation - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/** - * @file SoC configuration macros for the Renesas RA4E1 family MCU - */ - -#ifndef ZEPHYR_SOC_RENESAS_RA4E1_SOC_H_ -#define ZEPHYR_SOC_RENESAS_RA4E1_SOC_H_ - -#include - -#endif /* ZEPHYR_SOC_RENESAS_RA4E1_SOC_H_ */ diff --git a/soc/renesas/ra/ra4e2/CMakeLists.txt b/soc/renesas/ra/ra4e2/CMakeLists.txt index 4eea413d6825..8ceed38587d7 100644 --- a/soc/renesas/ra/ra4e2/CMakeLists.txt +++ b/soc/renesas/ra/ra4e2/CMakeLists.txt @@ -3,10 +3,6 @@ zephyr_include_directories(.) -zephyr_sources( - soc.c -) - if(CONFIG_CMAKE_LINKER_GENERATOR) dt_nodelabel(option_setting_ofs0 NODELABEL "option_setting_ofs0") dt_nodelabel(option_setting_osis NODELABEL "option_setting_osis") @@ -58,10 +54,7 @@ if(CONFIG_CMAKE_LINKER_GENERATOR) elseif(CONFIG_LD_LINKER_TEMPLATE) zephyr_linker_sources(SECTIONS sections.ld) - zephyr_linker_sources(RAM_SECTIONS ram_sections.ld) else() message(WARNING "Unsupported linker template.") endif() - -set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "") diff --git a/soc/renesas/ra/ra4e2/Kconfig b/soc/renesas/ra/ra4e2/Kconfig index 701c68a76631..f0331651a256 100644 --- a/soc/renesas/ra/ra4e2/Kconfig +++ b/soc/renesas/ra/ra4e2/Kconfig @@ -13,7 +13,6 @@ config SOC_SERIES_RA4E2 select FPU select HAS_SWO select XIP - select SOC_EARLY_INIT_HOOK if SOC_SERIES_RA4E2 diff --git a/soc/renesas/ra/ra4e2/ram_sections.ld b/soc/renesas/ra/ra4e2/ram_sections.ld deleted file mode 100644 index 18be2a431de2..000000000000 --- a/soc/renesas/ra/ra4e2/ram_sections.ld +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright (c) 2025 Renesas Electronics Corporation - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include - -#ifdef CONFIG_USE_RA_FSP_DTC -SECTION_DATA_PROLOGUE(.fsp_dtc_vector_table,(NOLOAD),) -{ - /* If DTC is used, put the DTC vector table at the start of SRAM. - This avoids memory holes due to 1K alignment required by it. */ - *(.fsp_dtc_vector_table) -} GROUP_DATA_LINK_IN(RAMABLE_REGION, RAMABLE_REGION) -#endif /* CONFIG_USE_RA_FSP_DTC */ diff --git a/soc/renesas/ra/ra4e2/soc.c b/soc/renesas/ra/ra4e2/soc.c deleted file mode 100644 index e2dfdbf2c996..000000000000 --- a/soc/renesas/ra/ra4e2/soc.c +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright (c) 2024 Renesas Electronics Corporation - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/** - * @file - * @brief System/hardware module for Renesas RA4E2 family processor - */ - -#include -#include -#include -#include -#include -#include -#include -#include -LOG_MODULE_REGISTER(soc, CONFIG_SOC_LOG_LEVEL); - -#include "bsp_cfg.h" -#include - -uint32_t SystemCoreClock BSP_SECTION_EARLY_INIT; - -volatile uint32_t g_protect_pfswe_counter BSP_SECTION_EARLY_INIT; - -#ifdef CONFIG_RUNTIME_NMI -extern bsp_grp_irq_cb_t g_bsp_group_irq_sources[]; -extern void NMI_Handler(void); -#endif /* CONFIG_RUNTIME_NMI */ - -/** - * @brief Perform basic hardware initialization at boot. - * - * This needs to be run from the very beginning. - */ -void soc_early_init_hook(void) -{ - extern volatile uint16_t g_protect_counters[]; - - for (uint32_t i = 0; i < 5; i++) { - g_protect_counters[i] = 0; - } - -#if FSP_PRIV_TZ_USE_SECURE_REGS - /* Disable protection using PRCR register. */ - R_BSP_RegisterProtectDisable(BSP_REG_PROTECT_SAR); - - /* Initialize peripherals to secure mode for flat projects */ - R_PSCU->PSARB = 0; - R_PSCU->PSARC = 0; - R_PSCU->PSARD = 0; - R_PSCU->PSARE = 0; - - R_CPSCU->ICUSARC = 0; - R_CPSCU->ICUSARG = 0; - R_CPSCU->ICUSARH = 0; - R_CPSCU->ICUSARI = 0; - - /* Enable protection using PRCR register. */ - R_BSP_RegisterProtectEnable(BSP_REG_PROTECT_SAR); -#endif - - SystemCoreClock = BSP_MOCO_HZ; - g_protect_pfswe_counter = 0; - -#ifdef CONFIG_RUNTIME_NMI - for (uint32_t i = 0; i < 16; i++) { - g_bsp_group_irq_sources[i] = 0; - } - - z_arm_nmi_set_handler(NMI_Handler); -#endif /* CONFIG_RUNTIME_NMI */ -} diff --git a/soc/renesas/ra/ra4e2/soc.h b/soc/renesas/ra/ra4e2/soc.h deleted file mode 100644 index cdf8331dac62..000000000000 --- a/soc/renesas/ra/ra4e2/soc.h +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright (c) 2024 Renesas Electronics Corporation - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/** - * @file SoC configuration macros for the Renesas RA4E2 family MCU - */ - -#ifndef ZEPHYR_SOC_RENESAS_RA4E2_SOC_H_ -#define ZEPHYR_SOC_RENESAS_RA4E2_SOC_H_ - -#include - -#endif /* ZEPHYR_SOC_RENESAS_RA4E2_SOC_H_ */ diff --git a/soc/renesas/ra/ra4l1/CMakeLists.txt b/soc/renesas/ra/ra4l1/CMakeLists.txt index 695c35a40947..6a32d2a8e0e0 100644 --- a/soc/renesas/ra/ra4l1/CMakeLists.txt +++ b/soc/renesas/ra/ra4l1/CMakeLists.txt @@ -3,10 +3,6 @@ zephyr_include_directories(.) -zephyr_sources( - soc.c -) - if(CONFIG_CMAKE_LINKER_GENERATOR) dt_nodelabel(option_setting_ofs0 NODELABEL "option_setting_ofs0") dt_nodelabel(option_setting_dualsel NODELABEL "option_setting_dualsel") @@ -38,11 +34,6 @@ if(CONFIG_CMAKE_LINKER_GENERATOR) dt_node_has_status(banksel_sel_status PATH ${option_setting_banksel_sel} STATUS okay) dt_node_has_status(bps_sel_status PATH ${option_setting_bps_sel} STATUS okay) - if(CONFIG_USE_RA_FSP_DTC) - zephyr_linker_section(NAME .fsp_dtc_vector_table GROUP RAM) - zephyr_linker_section_configure(SECTION .fsp_dtc_vector_table KEEP INPUT ".fsp_dtc_vector_table*") - endif() - if(${ofs0_status}) zephyr_linker_section(NAME .option_setting_ofs0 GROUP OFS_OFS0_MEMORY ADDRESS ${ofs0_addr}) zephyr_linker_section_configure(SECTION .option_setting_ofs0 KEEP INPUT ".option_setting_ofs0*") @@ -90,10 +81,7 @@ if(CONFIG_CMAKE_LINKER_GENERATOR) elseif(CONFIG_LD_LINKER_TEMPLATE) zephyr_linker_sources(SECTIONS sections.ld) - zephyr_linker_sources(RAM_SECTIONS ram_sections.ld) else() message(WARNING "Unsupported linker template.") endif() - -set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "") diff --git a/soc/renesas/ra/ra4l1/Kconfig b/soc/renesas/ra/ra4l1/Kconfig index 525f45693bbb..31eea255c1f5 100644 --- a/soc/renesas/ra/ra4l1/Kconfig +++ b/soc/renesas/ra/ra4l1/Kconfig @@ -13,7 +13,6 @@ config SOC_SERIES_RA4L1 select HAS_RENESAS_RA_FSP select CLOCK_CONTROL_RENESAS_RA_CGC if CLOCK_CONTROL select XIP - select SOC_EARLY_INIT_HOOK if SOC_SERIES_RA4L1 diff --git a/soc/renesas/ra/ra4l1/ram_sections.ld b/soc/renesas/ra/ra4l1/ram_sections.ld deleted file mode 100644 index 18be2a431de2..000000000000 --- a/soc/renesas/ra/ra4l1/ram_sections.ld +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright (c) 2025 Renesas Electronics Corporation - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include - -#ifdef CONFIG_USE_RA_FSP_DTC -SECTION_DATA_PROLOGUE(.fsp_dtc_vector_table,(NOLOAD),) -{ - /* If DTC is used, put the DTC vector table at the start of SRAM. - This avoids memory holes due to 1K alignment required by it. */ - *(.fsp_dtc_vector_table) -} GROUP_DATA_LINK_IN(RAMABLE_REGION, RAMABLE_REGION) -#endif /* CONFIG_USE_RA_FSP_DTC */ diff --git a/soc/renesas/ra/ra4l1/soc.c b/soc/renesas/ra/ra4l1/soc.c deleted file mode 100644 index 042d64aba7bc..000000000000 --- a/soc/renesas/ra/ra4l1/soc.c +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright (c) 2025 Renesas Electronics Corporation - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/** - * @file - * @brief System/hardware module for Renesas RA4L1 family processor - */ - -#include -#include -#include -#include -#include -#include -#include -#include -LOG_MODULE_REGISTER(soc, CONFIG_SOC_LOG_LEVEL); - -#include "bsp_cfg.h" -#include "bsp_api.h" - -uint32_t SystemCoreClock BSP_SECTION_EARLY_INIT; - -volatile uint32_t g_protect_pfswe_counter BSP_SECTION_EARLY_INIT; - -#ifdef CONFIG_RUNTIME_NMI -extern bsp_grp_irq_cb_t g_bsp_group_irq_sources[]; -extern void NMI_Handler(void); -#endif /* CONFIG_RUNTIME_NMI */ - -/** - * @brief Perform basic hardware initialization at boot. - * - * This needs to be run from the very beginning. - */ -void soc_early_init_hook(void) -{ - extern volatile uint16_t g_protect_counters[]; - - for (uint32_t i = 0; i < 5; i++) { - g_protect_counters[i] = 0; - } - -#if FSP_PRIV_TZ_USE_SECURE_REGS - /* Disable protection using PRCR register. */ - R_BSP_RegisterProtectDisable(BSP_REG_PROTECT_SAR); - - /* Initialize peripherals to secure mode for flat projects */ - R_PSCU->PSARB = 0; - R_PSCU->PSARC = 0; - R_PSCU->PSARD = 0; - R_PSCU->PSARE = 0; - - R_CPSCU->ICUSARC = 0; - R_CPSCU->ICUSARG = 0; - R_CPSCU->ICUSARH = 0; - R_CPSCU->ICUSARI = 0; - - /* Enable protection using PRCR register. */ - R_BSP_RegisterProtectEnable(BSP_REG_PROTECT_SAR); -#endif - - SystemCoreClock = BSP_MOCO_HZ; - g_protect_pfswe_counter = 0; - -#ifdef CONFIG_RUNTIME_NMI - for (uint32_t i = 0; i < 16; i++) { - g_bsp_group_irq_sources[i] = 0; - } - - z_arm_nmi_set_handler(NMI_Handler); -#endif /* CONFIG_RUNTIME_NMI */ -} diff --git a/soc/renesas/ra/ra4l1/soc.h b/soc/renesas/ra/ra4l1/soc.h deleted file mode 100644 index cf99273edd37..000000000000 --- a/soc/renesas/ra/ra4l1/soc.h +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright (c) 2025 Renesas Electronics Corporation - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/** - * @file SoC configuration macros for the Renesas RA4L1 family MCU - */ - -#ifndef ZEPHYR_SOC_RENESAS_RA4L1_SOC_H_ -#define ZEPHYR_SOC_RENESAS_RA4L1_SOC_H_ - -#include - -#endif /* ZEPHYR_SOC_RENESAS_RA4L1_SOC_H_ */ diff --git a/soc/renesas/ra/ra4m1/CMakeLists.txt b/soc/renesas/ra/ra4m1/CMakeLists.txt index 94e1769c22f4..916d369c34e0 100644 --- a/soc/renesas/ra/ra4m1/CMakeLists.txt +++ b/soc/renesas/ra/ra4m1/CMakeLists.txt @@ -4,10 +4,6 @@ zephyr_include_directories(.) -zephyr_sources( - soc.c -) - if(CONFIG_CMAKE_LINKER_GENERATOR) dt_nodelabel(option_setting_ofs0 NODELABEL "option_setting_ofs0") dt_nodelabel(option_setting_ofs1 NODELABEL "option_setting_ofs1") @@ -21,11 +17,6 @@ if(CONFIG_CMAKE_LINKER_GENERATOR) dt_node_has_status(osis_status PATH ${option_setting_osis} STATUS okay) - if(CONFIG_USE_RA_FSP_DTC) - zephyr_linker_section(NAME .fsp_dtc_vector_table GROUP RAM) - zephyr_linker_section_configure(SECTION .fsp_dtc_vector_table KEEP INPUT ".fsp_dtc_vector_table*") - endif() - zephyr_linker_section(NAME .rom_padding GROUP ROM_REGION ADDRESS 0x000000C0) zephyr_linker_section_configure(SECTION .rom_padding KEEP INPUT ".rom_padding*") @@ -46,10 +37,7 @@ if(CONFIG_CMAKE_LINKER_GENERATOR) elseif(CONFIG_LD_LINKER_TEMPLATE) zephyr_linker_sources(ROM_START rom_start.ld) zephyr_linker_sources(SECTIONS sections.ld) - zephyr_linker_sources(RAM_SECTIONS ram_sections.ld) else() message(WARNING "Unsupported linker template.") endif() - -set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "") diff --git a/soc/renesas/ra/ra4m1/Kconfig b/soc/renesas/ra/ra4m1/Kconfig index b5fa5e108bc6..844d6d99d281 100644 --- a/soc/renesas/ra/ra4m1/Kconfig +++ b/soc/renesas/ra/ra4m1/Kconfig @@ -12,7 +12,6 @@ config SOC_SERIES_RA4M1 select FPU select HAS_SWO select XIP - select SOC_EARLY_INIT_HOOK select GPIO_RA_HAS_VBTICTLR if SOC_SERIES_RA4M1 diff --git a/soc/renesas/ra/ra4m1/ram_sections.ld b/soc/renesas/ra/ra4m1/ram_sections.ld deleted file mode 100644 index ca4598c51305..000000000000 --- a/soc/renesas/ra/ra4m1/ram_sections.ld +++ /dev/null @@ -1,17 +0,0 @@ -/* - * Copyright (c) 2024 TOKITA Hiroshi - * Copyright (c) 2025 Renesas Electronics Corporation - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include - -#ifdef CONFIG_USE_RA_FSP_DTC -SECTION_DATA_PROLOGUE(.fsp_dtc_vector_table,(NOLOAD),) -{ - /* If DTC is used, put the DTC vector table at the start of SRAM. - This avoids memory holes due to 1K alignment required by it. */ - *(.fsp_dtc_vector_table) -} GROUP_DATA_LINK_IN(RAMABLE_REGION, RAMABLE_REGION) -#endif /* CONFIG_USE_RA_FSP_DTC */ diff --git a/soc/renesas/ra/ra4m1/soc.c b/soc/renesas/ra/ra4m1/soc.c deleted file mode 100644 index b2dbbd7aae40..000000000000 --- a/soc/renesas/ra/ra4m1/soc.c +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright (c) 2024 Ian Morris - * Copyright (c) 2024 TOKITA Hiroshi - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/** - * @file - * @brief System/hardware module for Renesas RA4M1 family processor - */ - -#include -#include -#include -#include -#include -#include -#include -#include -LOG_MODULE_REGISTER(soc, CONFIG_SOC_LOG_LEVEL); - -#include "bsp_cfg.h" -#include - -#define HOCO_FREQ DT_PROP(DT_PATH(clocks, clock_hoco), clock_frequency) - -#if HOCO_FREQ == MHZ(24) -#define OFS1_HOCO_FREQ 0 -#elif HOCO_FREQ == MHZ(32) -#define OFS1_HOCO_FREQ 2 -#elif HOCO_FREQ == MHZ(48) -#define OFS1_HOCO_FREQ 4 -#elif HOCO_FREQ == MHZ(64) -#define OFS1_HOCO_FREQ 5 -#else -#error "Unsupported HOCO frequency" -#endif - -uint32_t SystemCoreClock BSP_SECTION_EARLY_INIT; - -volatile uint32_t g_protect_pfswe_counter BSP_SECTION_EARLY_INIT; - -#ifdef CONFIG_RUNTIME_NMI -extern bsp_grp_irq_cb_t g_bsp_group_irq_sources[]; -extern void NMI_Handler(void); -#endif /* CONFIG_RUNTIME_NMI */ - -/** - * @brief Perform basic hardware initialization at boot. - * - * This needs to be run from the very beginning. - */ -void soc_early_init_hook(void) -{ - uint32_t key; - - key = irq_lock(); - - SystemCoreClock = BSP_MOCO_HZ; - g_protect_pfswe_counter = 0; - -#ifdef CONFIG_RUNTIME_NMI - for (uint32_t i = 0; i < 16; i++) { - g_bsp_group_irq_sources[i] = 0; - } - - z_arm_nmi_set_handler(NMI_Handler); -#endif /* CONFIG_RUNTIME_NMI */ - - irq_unlock(key); -} diff --git a/soc/renesas/ra/ra4m1/soc.h b/soc/renesas/ra/ra4m1/soc.h deleted file mode 100644 index 0476e2ba816a..000000000000 --- a/soc/renesas/ra/ra4m1/soc.h +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright (c) 2023 TOKITA Hiroshi - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/** - * @file SoC configuration macros for the Renesas RA4M1 family MCU - */ - -#ifndef ZEPHYR_SOC_RENESAS_RA4M1_SOC_H_ -#define ZEPHYR_SOC_RENESAS_RA4M1_SOC_H_ - -#include - -#endif /* ZEPHYR_SOC_RENESAS_RA4M1_SOC_H_ */ diff --git a/soc/renesas/ra/ra4m2/CMakeLists.txt b/soc/renesas/ra/ra4m2/CMakeLists.txt index 074db41fdceb..98482a648553 100644 --- a/soc/renesas/ra/ra4m2/CMakeLists.txt +++ b/soc/renesas/ra/ra4m2/CMakeLists.txt @@ -3,10 +3,6 @@ zephyr_include_directories(.) -zephyr_sources( - soc.c -) - if(CONFIG_CMAKE_LINKER_GENERATOR) dt_nodelabel(option_setting_ofs0 NODELABEL "option_setting_ofs0") dt_nodelabel(option_setting_ofs1_sec NODELABEL "option_setting_ofs1_sec") @@ -29,11 +25,6 @@ if(CONFIG_CMAKE_LINKER_GENERATOR) dt_node_has_status(ofs1_sel_status PATH ${option_setting_ofs1_sel} STATUS okay) dt_node_has_status(bps_sel_status PATH ${option_setting_bps_sel} STATUS okay) - if(CONFIG_USE_RA_FSP_DTC) - zephyr_linker_section(NAME .fsp_dtc_vector_table GROUP RAM) - zephyr_linker_section_configure(SECTION .fsp_dtc_vector_table KEEP INPUT ".fsp_dtc_vector_table*") - endif() - if(${ofs0_status}) zephyr_linker_section(NAME .option_setting_ofs0 GROUP OFS_OFS0_MEMORY ADDRESS ${ofs0_addr}) zephyr_linker_section_configure(SECTION .option_setting_ofs0 KEEP INPUT ".option_setting_ofs0*") @@ -66,10 +57,7 @@ if(CONFIG_CMAKE_LINKER_GENERATOR) elseif(CONFIG_LD_LINKER_TEMPLATE) zephyr_linker_sources(SECTIONS sections.ld) - zephyr_linker_sources(RAM_SECTIONS ram_sections.ld) else() message(WARNING "Unsupported linker template.") endif() - -set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "") diff --git a/soc/renesas/ra/ra4m2/Kconfig b/soc/renesas/ra/ra4m2/Kconfig index 0412eaaa63b7..bb9b510ebd39 100644 --- a/soc/renesas/ra/ra4m2/Kconfig +++ b/soc/renesas/ra/ra4m2/Kconfig @@ -13,7 +13,6 @@ config SOC_SERIES_RA4M2 select FPU select HAS_SWO select XIP - select SOC_EARLY_INIT_HOOK select GPIO_RA_HAS_VBTICTLR if SOC_SERIES_RA4M2 diff --git a/soc/renesas/ra/ra4m2/ram_sections.ld b/soc/renesas/ra/ra4m2/ram_sections.ld deleted file mode 100644 index 18be2a431de2..000000000000 --- a/soc/renesas/ra/ra4m2/ram_sections.ld +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright (c) 2025 Renesas Electronics Corporation - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include - -#ifdef CONFIG_USE_RA_FSP_DTC -SECTION_DATA_PROLOGUE(.fsp_dtc_vector_table,(NOLOAD),) -{ - /* If DTC is used, put the DTC vector table at the start of SRAM. - This avoids memory holes due to 1K alignment required by it. */ - *(.fsp_dtc_vector_table) -} GROUP_DATA_LINK_IN(RAMABLE_REGION, RAMABLE_REGION) -#endif /* CONFIG_USE_RA_FSP_DTC */ diff --git a/soc/renesas/ra/ra4m2/soc.c b/soc/renesas/ra/ra4m2/soc.c deleted file mode 100644 index 0f008fd4216e..000000000000 --- a/soc/renesas/ra/ra4m2/soc.c +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright (c) 2024 Renesas Electronics Corporation - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/** - * @file - * @brief System/hardware module for Renesas RA4M2 family processor - */ - -#include -#include -#include -#include -#include -#include -#include -#include -LOG_MODULE_REGISTER(soc, CONFIG_SOC_LOG_LEVEL); - -#include "bsp_cfg.h" -#include - -uint32_t SystemCoreClock BSP_SECTION_EARLY_INIT; - -volatile uint32_t g_protect_pfswe_counter BSP_SECTION_EARLY_INIT; - -#ifdef CONFIG_RUNTIME_NMI -extern bsp_grp_irq_cb_t g_bsp_group_irq_sources[]; -extern void NMI_Handler(void); -#endif /* CONFIG_RUNTIME_NMI */ - -/** - * @brief Perform basic hardware initialization at boot. - * - * This needs to be run from the very beginning. - */ -void soc_early_init_hook(void) -{ - extern volatile uint16_t g_protect_counters[]; - - for (uint32_t i = 0; i < 5; i++) { - g_protect_counters[i] = 0; - } - -#if FSP_PRIV_TZ_USE_SECURE_REGS - /* Disable protection using PRCR register. */ - R_BSP_RegisterProtectDisable(BSP_REG_PROTECT_SAR); - - /* Initialize peripherals to secure mode for flat projects */ - R_PSCU->PSARB = 0; - R_PSCU->PSARC = 0; - R_PSCU->PSARD = 0; - R_PSCU->PSARE = 0; - - R_CPSCU->ICUSARC = 0; - R_CPSCU->ICUSARG = 0; - R_CPSCU->ICUSARH = 0; - R_CPSCU->ICUSARI = 0; - - /* Enable protection using PRCR register. */ - R_BSP_RegisterProtectEnable(BSP_REG_PROTECT_SAR); -#endif - - SystemCoreClock = BSP_MOCO_HZ; - g_protect_pfswe_counter = 0; - -#ifdef CONFIG_RUNTIME_NMI - for (uint32_t i = 0; i < 16; i++) { - g_bsp_group_irq_sources[i] = 0; - } - - z_arm_nmi_set_handler(NMI_Handler); -#endif /* CONFIG_RUNTIME_NMI */ -} diff --git a/soc/renesas/ra/ra4m2/soc.h b/soc/renesas/ra/ra4m2/soc.h deleted file mode 100644 index 99cefaf34758..000000000000 --- a/soc/renesas/ra/ra4m2/soc.h +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright (c) 2024 Renesas Electronics Corporation - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/** - * @file SoC configuration macros for the Renesas RA4M2 family MCU - */ - -#ifndef ZEPHYR_SOC_RENESAS_RA4M2_SOC_H_ -#define ZEPHYR_SOC_RENESAS_RA4M2_SOC_H_ - -#include - -#endif /* ZEPHYR_SOC_RENESAS_RA4M2_SOC_H_ */ diff --git a/soc/renesas/ra/ra4m3/CMakeLists.txt b/soc/renesas/ra/ra4m3/CMakeLists.txt index 7f86249065cb..5013edd514dd 100644 --- a/soc/renesas/ra/ra4m3/CMakeLists.txt +++ b/soc/renesas/ra/ra4m3/CMakeLists.txt @@ -3,10 +3,6 @@ zephyr_include_directories(.) -zephyr_sources( - soc.c -) - if(CONFIG_CMAKE_LINKER_GENERATOR) dt_nodelabel(option_setting_ofs0 NODELABEL "option_setting_ofs0") dt_nodelabel(option_setting_ofs1_sec NODELABEL "option_setting_ofs1_sec") @@ -35,11 +31,6 @@ if(CONFIG_CMAKE_LINKER_GENERATOR) dt_node_has_status(banksel_sel_status PATH ${option_setting_banksel_sel} STATUS okay) dt_node_has_status(bps_sel_status PATH ${option_setting_bps_sel} STATUS okay) - if(CONFIG_USE_RA_FSP_DTC) - zephyr_linker_section(NAME .fsp_dtc_vector_table GROUP RAM) - zephyr_linker_section_configure(SECTION .fsp_dtc_vector_table KEEP INPUT ".fsp_dtc_vector_table*") - endif() - if(${ofs0_status}) zephyr_linker_section(NAME .option_setting_ofs0 GROUP OFS_OFS0_MEMORY ADDRESS ${ofs0_addr}) zephyr_linker_section_configure(SECTION .option_setting_ofs0 KEEP INPUT ".option_setting_ofs0*") @@ -82,10 +73,7 @@ if(CONFIG_CMAKE_LINKER_GENERATOR) elseif(CONFIG_LD_LINKER_TEMPLATE) zephyr_linker_sources(SECTIONS sections.ld) - zephyr_linker_sources(RAM_SECTIONS ram_sections.ld) else() message(WARNING "Unsupported linker template.") endif() - -set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "") diff --git a/soc/renesas/ra/ra4m3/Kconfig b/soc/renesas/ra/ra4m3/Kconfig index 379253245469..1a9c28821cb3 100644 --- a/soc/renesas/ra/ra4m3/Kconfig +++ b/soc/renesas/ra/ra4m3/Kconfig @@ -13,7 +13,6 @@ config SOC_SERIES_RA4M3 select FPU select HAS_SWO select XIP - select SOC_EARLY_INIT_HOOK select GPIO_RA_HAS_VBTICTLR if SOC_SERIES_RA4M3 diff --git a/soc/renesas/ra/ra4m3/ram_sections.ld b/soc/renesas/ra/ra4m3/ram_sections.ld deleted file mode 100644 index 18be2a431de2..000000000000 --- a/soc/renesas/ra/ra4m3/ram_sections.ld +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright (c) 2025 Renesas Electronics Corporation - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include - -#ifdef CONFIG_USE_RA_FSP_DTC -SECTION_DATA_PROLOGUE(.fsp_dtc_vector_table,(NOLOAD),) -{ - /* If DTC is used, put the DTC vector table at the start of SRAM. - This avoids memory holes due to 1K alignment required by it. */ - *(.fsp_dtc_vector_table) -} GROUP_DATA_LINK_IN(RAMABLE_REGION, RAMABLE_REGION) -#endif /* CONFIG_USE_RA_FSP_DTC */ diff --git a/soc/renesas/ra/ra4m3/soc.c b/soc/renesas/ra/ra4m3/soc.c deleted file mode 100644 index 9bb153a0d9db..000000000000 --- a/soc/renesas/ra/ra4m3/soc.c +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright (c) 2024 Renesas Electronics Corporation - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/** - * @file - * @brief System/hardware module for Renesas RA4M3 family processor - */ - -#include -#include -#include -#include -#include -#include -#include -#include -LOG_MODULE_REGISTER(soc, CONFIG_SOC_LOG_LEVEL); - -#include "bsp_cfg.h" -#include - -uint32_t SystemCoreClock BSP_SECTION_EARLY_INIT; - -volatile uint32_t g_protect_pfswe_counter BSP_SECTION_EARLY_INIT; - -#ifdef CONFIG_RUNTIME_NMI -extern bsp_grp_irq_cb_t g_bsp_group_irq_sources[]; -extern void NMI_Handler(void); -#endif /* CONFIG_RUNTIME_NMI */ - -/** - * @brief Perform basic hardware initialization at boot. - * - * This needs to be run from the very beginning. - */ -void soc_early_init_hook(void) -{ - extern volatile uint16_t g_protect_counters[]; - - for (uint32_t i = 0; i < 5; i++) { - g_protect_counters[i] = 0; - } - -#if FSP_PRIV_TZ_USE_SECURE_REGS - /* Disable protection using PRCR register. */ - R_BSP_RegisterProtectDisable(BSP_REG_PROTECT_SAR); - - /* Initialize peripherals to secure mode for flat projects */ - R_PSCU->PSARB = 0; - R_PSCU->PSARC = 0; - R_PSCU->PSARD = 0; - R_PSCU->PSARE = 0; - - R_CPSCU->ICUSARC = 0; - R_CPSCU->ICUSARG = 0; - R_CPSCU->ICUSARH = 0; - R_CPSCU->ICUSARI = 0; - - /* Enable protection using PRCR register. */ - R_BSP_RegisterProtectEnable(BSP_REG_PROTECT_SAR); -#endif - - SystemCoreClock = BSP_MOCO_HZ; - g_protect_pfswe_counter = 0; - -#ifdef CONFIG_RUNTIME_NMI - for (uint32_t i = 0; i < 16; i++) { - g_bsp_group_irq_sources[i] = 0; - } - - z_arm_nmi_set_handler(NMI_Handler); -#endif /* CONFIG_RUNTIME_NMI */ -} diff --git a/soc/renesas/ra/ra4m3/soc.h b/soc/renesas/ra/ra4m3/soc.h deleted file mode 100644 index 7910a06c96a7..000000000000 --- a/soc/renesas/ra/ra4m3/soc.h +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright (c) 2024 Renesas Electronics Corporation - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/** - * @file SoC configuration macros for the Renesas RA4M3 family MCU - */ - -#ifndef ZEPHYR_SOC_RENESAS_RA4M3_SOC_H_ -#define ZEPHYR_SOC_RENESAS_RA4M3_SOC_H_ - -#include - -#endif /* ZEPHYR_SOC_RENESAS_RA4M3_SOC_H_ */ diff --git a/soc/renesas/ra/ra4t1/CMakeLists.txt b/soc/renesas/ra/ra4t1/CMakeLists.txt index 1eccd63aa3a4..b54dc8312ffb 100644 --- a/soc/renesas/ra/ra4t1/CMakeLists.txt +++ b/soc/renesas/ra/ra4t1/CMakeLists.txt @@ -3,9 +3,4 @@ zephyr_include_directories(.) -zephyr_sources(soc.c) - zephyr_linker_sources(SECTIONS sections.ld) -zephyr_linker_sources(RAM_SECTIONS ram_sections.ld) - -set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "") diff --git a/soc/renesas/ra/ra4t1/Kconfig b/soc/renesas/ra/ra4t1/Kconfig index 5b2a50a95760..7c857cc373b4 100644 --- a/soc/renesas/ra/ra4t1/Kconfig +++ b/soc/renesas/ra/ra4t1/Kconfig @@ -12,7 +12,6 @@ config SOC_SERIES_RA4T1 select CPU_HAS_FPU select FPU select XIP - select SOC_EARLY_INIT_HOOK if SOC_SERIES_RA4T1 diff --git a/soc/renesas/ra/ra4t1/ram_sections.ld b/soc/renesas/ra/ra4t1/ram_sections.ld deleted file mode 100644 index 18be2a431de2..000000000000 --- a/soc/renesas/ra/ra4t1/ram_sections.ld +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright (c) 2025 Renesas Electronics Corporation - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include - -#ifdef CONFIG_USE_RA_FSP_DTC -SECTION_DATA_PROLOGUE(.fsp_dtc_vector_table,(NOLOAD),) -{ - /* If DTC is used, put the DTC vector table at the start of SRAM. - This avoids memory holes due to 1K alignment required by it. */ - *(.fsp_dtc_vector_table) -} GROUP_DATA_LINK_IN(RAMABLE_REGION, RAMABLE_REGION) -#endif /* CONFIG_USE_RA_FSP_DTC */ diff --git a/soc/renesas/ra/ra4t1/soc.c b/soc/renesas/ra/ra4t1/soc.c deleted file mode 100644 index ff3cfbfd08db..000000000000 --- a/soc/renesas/ra/ra4t1/soc.c +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright (c) 2025 Renesas Electronics Corporation - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/** - * @file - * @brief System/hardware module for Renesas RA4E2 family processor - */ - -#include -#include -#include -#include -#include -#include -#include -#include -LOG_MODULE_REGISTER(soc, CONFIG_SOC_LOG_LEVEL); - -#include -#include "soc.h" - -uint32_t SystemCoreClock BSP_SECTION_EARLY_INIT; - -volatile uint32_t g_protect_pfswe_counter BSP_SECTION_EARLY_INIT; - -#ifdef CONFIG_RUNTIME_NMI -extern bsp_grp_irq_cb_t g_bsp_group_irq_sources[]; -extern void NMI_Handler(void); -#endif /* CONFIG_RUNTIME_NMI */ - -/** - * @brief Perform basic hardware initialization at boot. - * - * This needs to be run from the very beginning. - */ -void soc_early_init_hook(void) -{ - extern volatile uint16_t g_protect_counters[]; - - for (uint32_t i = 0; i < 5; i++) { - g_protect_counters[i] = 0; - } - -#if FSP_PRIV_TZ_USE_SECURE_REGS - /* Disable protection using PRCR register. */ - R_BSP_RegisterProtectDisable(BSP_REG_PROTECT_SAR); - - /* Initialize peripherals to secure mode for flat projects */ - R_PSCU->PSARB = 0; - R_PSCU->PSARC = 0; - R_PSCU->PSARD = 0; - R_PSCU->PSARE = 0; - - R_CPSCU->ICUSARC = 0; - R_CPSCU->ICUSARG = 0; - R_CPSCU->ICUSARH = 0; - R_CPSCU->ICUSARI = 0; - - /* Enable protection using PRCR register. */ - R_BSP_RegisterProtectEnable(BSP_REG_PROTECT_SAR); -#endif - - SystemCoreClock = BSP_MOCO_HZ; - g_protect_pfswe_counter = 0; - -#ifdef CONFIG_RUNTIME_NMI - for (uint32_t i = 0; i < 16; i++) { - g_bsp_group_irq_sources[i] = 0; - } - - z_arm_nmi_set_handler(NMI_Handler); -#endif /* CONFIG_RUNTIME_NMI */ -} diff --git a/soc/renesas/ra/ra4t1/soc.h b/soc/renesas/ra/ra4t1/soc.h deleted file mode 100644 index 979040422a73..000000000000 --- a/soc/renesas/ra/ra4t1/soc.h +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright (c) 2025 Renesas Electronics Corporation - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/** - * @file SoC configuration macros for the Renesas RA4T1 family MCU - */ - -#ifndef ZEPHYR_SOC_RENESAS_RA4T1_SOC_H_ -#define ZEPHYR_SOC_RENESAS_RA4T1_SOC_H_ - -#include - -#endif /* ZEPHYR_SOC_RENESAS_RA4T1_SOC_H_ */ diff --git a/soc/renesas/ra/ra4w1/CMakeLists.txt b/soc/renesas/ra/ra4w1/CMakeLists.txt index ffb74974499d..d4d4d8e512e6 100644 --- a/soc/renesas/ra/ra4w1/CMakeLists.txt +++ b/soc/renesas/ra/ra4w1/CMakeLists.txt @@ -3,10 +3,6 @@ zephyr_include_directories(.) -zephyr_sources( - soc.c -) - if(CONFIG_CMAKE_LINKER_GENERATOR) dt_nodelabel(option_setting_ofs0 NODELABEL "option_setting_ofs0") dt_nodelabel(option_setting_ofs1 NODELABEL "option_setting_ofs1") @@ -20,11 +16,6 @@ if(CONFIG_CMAKE_LINKER_GENERATOR) dt_node_has_status(osis_status PATH ${option_setting_osis} STATUS okay) - if(CONFIG_USE_RA_FSP_DTC) - zephyr_linker_section(NAME .fsp_dtc_vector_table GROUP RAM) - zephyr_linker_section_configure(SECTION .fsp_dtc_vector_table KEEP INPUT ".fsp_dtc_vector_table*") - endif() - zephyr_linker_section(NAME .rom_padding GROUP ROM_REGION ADDRESS 0x000000C0) zephyr_linker_section_configure(SECTION .rom_padding KEEP INPUT ".rom_padding*") @@ -45,10 +36,7 @@ if(CONFIG_CMAKE_LINKER_GENERATOR) elseif(CONFIG_LD_LINKER_TEMPLATE) zephyr_linker_sources(ROM_START rom_start.ld) zephyr_linker_sources(SECTIONS sections.ld) - zephyr_linker_sources(RAM_SECTIONS ram_sections.ld) else() message(WARNING "Unsupported linker template.") endif() - -set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "") diff --git a/soc/renesas/ra/ra4w1/Kconfig b/soc/renesas/ra/ra4w1/Kconfig index 34f44bf6d074..32eb9f1ceeb3 100644 --- a/soc/renesas/ra/ra4w1/Kconfig +++ b/soc/renesas/ra/ra4w1/Kconfig @@ -12,5 +12,4 @@ config SOC_SERIES_RA4W1 select FPU select HAS_SWO select XIP - select SOC_EARLY_INIT_HOOK select GPIO_RA_HAS_VBTICTLR diff --git a/soc/renesas/ra/ra4w1/ram_sections.ld b/soc/renesas/ra/ra4w1/ram_sections.ld deleted file mode 100644 index 18be2a431de2..000000000000 --- a/soc/renesas/ra/ra4w1/ram_sections.ld +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright (c) 2025 Renesas Electronics Corporation - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include - -#ifdef CONFIG_USE_RA_FSP_DTC -SECTION_DATA_PROLOGUE(.fsp_dtc_vector_table,(NOLOAD),) -{ - /* If DTC is used, put the DTC vector table at the start of SRAM. - This avoids memory holes due to 1K alignment required by it. */ - *(.fsp_dtc_vector_table) -} GROUP_DATA_LINK_IN(RAMABLE_REGION, RAMABLE_REGION) -#endif /* CONFIG_USE_RA_FSP_DTC */ diff --git a/soc/renesas/ra/ra4w1/soc.c b/soc/renesas/ra/ra4w1/soc.c deleted file mode 100644 index c62592e320c2..000000000000 --- a/soc/renesas/ra/ra4w1/soc.c +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright (c) 2024 Renesas Electronics Corporation - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/** - * @file - * @brief System/hardware module for Renesas RA4W1 family processor - */ - -#include -#include -#include -#include -#include -#include -#include -#include -LOG_MODULE_REGISTER(soc, CONFIG_SOC_LOG_LEVEL); - -#include "bsp_cfg.h" -#include - -uint32_t SystemCoreClock BSP_SECTION_EARLY_INIT; - -volatile uint32_t g_protect_pfswe_counter BSP_SECTION_EARLY_INIT; - -#ifdef CONFIG_RUNTIME_NMI -extern bsp_grp_irq_cb_t g_bsp_group_irq_sources[]; -extern void NMI_Handler(void); -#endif /* CONFIG_RUNTIME_NMI */ - -/** - * @brief Perform basic hardware initialization at boot. - * - * This needs to be run from the very beginning. - */ -void soc_early_init_hook(void) -{ - SystemCoreClock = BSP_MOCO_HZ; - g_protect_pfswe_counter = 0; - -#ifdef CONFIG_RUNTIME_NMI - for (uint32_t i = 0; i < 16; i++) { - g_bsp_group_irq_sources[i] = 0; - } - - z_arm_nmi_set_handler(NMI_Handler); -#endif /* CONFIG_RUNTIME_NMI */ -} diff --git a/soc/renesas/ra/ra4w1/soc.h b/soc/renesas/ra/ra4w1/soc.h deleted file mode 100644 index 7646360c58bb..000000000000 --- a/soc/renesas/ra/ra4w1/soc.h +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright (c) 2024 Renesas Electronics Corporation - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/** - * @file SoC configuration macros for the Renesas RA4W1 family MCU - */ - -#ifndef ZEPHYR_SOC_RENESAS_RA4W1_SOC_H_ -#define ZEPHYR_SOC_RENESAS_RA4W1_SOC_H_ - -#include - -#endif /* ZEPHYR_SOC_RENESAS_RA4W1_SOC_H_ */ diff --git a/soc/renesas/ra/ra6e1/CMakeLists.txt b/soc/renesas/ra/ra6e1/CMakeLists.txt index 0459d4214b8d..50a1a19272ba 100644 --- a/soc/renesas/ra/ra6e1/CMakeLists.txt +++ b/soc/renesas/ra/ra6e1/CMakeLists.txt @@ -3,10 +3,6 @@ zephyr_include_directories(.) -zephyr_sources( - soc.c -) - if(CONFIG_CMAKE_LINKER_GENERATOR) dt_nodelabel(option_setting_ofs0 NODELABEL "option_setting_ofs0") dt_nodelabel(option_setting_dualsel NODELABEL "option_setting_dualsel") @@ -38,11 +34,6 @@ if(CONFIG_CMAKE_LINKER_GENERATOR) dt_node_has_status(banksel_sel_status PATH ${option_setting_banksel_sel} STATUS okay) dt_node_has_status(bps_sel_status PATH ${option_setting_bps_sel} STATUS okay) - if(CONFIG_USE_RA_FSP_DTC) - zephyr_linker_section(NAME .fsp_dtc_vector_table GROUP RAM) - zephyr_linker_section_configure(SECTION .fsp_dtc_vector_table KEEP INPUT ".fsp_dtc_vector_table*") - endif() - if(${ofs0_status}) zephyr_linker_section(NAME .option_setting_ofs0 GROUP OFS_OFS0_MEMORY ADDRESS ${ofs0_addr}) zephyr_linker_section_configure(SECTION .option_setting_ofs0 KEEP INPUT ".option_setting_ofs0*") @@ -90,10 +81,7 @@ if(CONFIG_CMAKE_LINKER_GENERATOR) elseif(CONFIG_LD_LINKER_TEMPLATE) zephyr_linker_sources(SECTIONS sections.ld) - zephyr_linker_sources(RAM_SECTIONS ram_sections.ld) else() message(WARNING "Unsupported linker template.") endif() - -set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "") diff --git a/soc/renesas/ra/ra6e1/Kconfig b/soc/renesas/ra/ra6e1/Kconfig index b93d85a76ffd..5e171c26a112 100644 --- a/soc/renesas/ra/ra6e1/Kconfig +++ b/soc/renesas/ra/ra6e1/Kconfig @@ -13,7 +13,6 @@ config SOC_SERIES_RA6E1 select FPU select HAS_SWO select XIP - select SOC_EARLY_INIT_HOOK select GPIO_RA_HAS_VBTICTLR if SOC_SERIES_RA6E1 diff --git a/soc/renesas/ra/ra6e1/ram_sections.ld b/soc/renesas/ra/ra6e1/ram_sections.ld deleted file mode 100644 index 18be2a431de2..000000000000 --- a/soc/renesas/ra/ra6e1/ram_sections.ld +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright (c) 2025 Renesas Electronics Corporation - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include - -#ifdef CONFIG_USE_RA_FSP_DTC -SECTION_DATA_PROLOGUE(.fsp_dtc_vector_table,(NOLOAD),) -{ - /* If DTC is used, put the DTC vector table at the start of SRAM. - This avoids memory holes due to 1K alignment required by it. */ - *(.fsp_dtc_vector_table) -} GROUP_DATA_LINK_IN(RAMABLE_REGION, RAMABLE_REGION) -#endif /* CONFIG_USE_RA_FSP_DTC */ diff --git a/soc/renesas/ra/ra6e1/soc.c b/soc/renesas/ra/ra6e1/soc.c deleted file mode 100644 index b8bf0463c7d6..000000000000 --- a/soc/renesas/ra/ra6e1/soc.c +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright (c) 2024 Renesas Electronics Corporation - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/** - * @file - * @brief System/hardware module for Renesas RA6E1 family processor - */ - -#include -#include -#include -#include -#include -#include -#include -LOG_MODULE_REGISTER(soc, CONFIG_SOC_LOG_LEVEL); - -#include "bsp_cfg.h" -#include - -uint32_t SystemCoreClock BSP_SECTION_EARLY_INIT; - -volatile uint32_t g_protect_pfswe_counter BSP_SECTION_EARLY_INIT; - -#ifdef CONFIG_RUNTIME_NMI -extern bsp_grp_irq_cb_t g_bsp_group_irq_sources[]; -extern void NMI_Handler(void); -#endif /* CONFIG_RUNTIME_NMI */ - -/** - * @brief Perform basic hardware initialization at boot. - * - * This needs to be run from the very beginning. - */ -void soc_early_init_hook(void) -{ - uint32_t key; - - extern volatile uint16_t g_protect_counters[]; - - for (uint32_t i = 0; i < 5; i++) { - g_protect_counters[i] = 0; - } - -#if FSP_PRIV_TZ_USE_SECURE_REGS - /* Disable protection using PRCR register. */ - R_BSP_RegisterProtectDisable(BSP_REG_PROTECT_SAR); - - /* Initialize peripherals to secure mode for flat projects */ - R_PSCU->PSARB = 0; - R_PSCU->PSARC = 0; - R_PSCU->PSARD = 0; - R_PSCU->PSARE = 0; - - R_CPSCU->ICUSARC = 0; - R_CPSCU->ICUSARG = 0; - R_CPSCU->ICUSARH = 0; - R_CPSCU->ICUSARI = 0; - - /* Enable protection using PRCR register. */ - R_BSP_RegisterProtectEnable(BSP_REG_PROTECT_SAR); -#endif - - key = irq_lock(); - - SystemCoreClock = BSP_MOCO_HZ; - g_protect_pfswe_counter = 0; - -#ifdef CONFIG_RUNTIME_NMI - for (uint32_t i = 0; i < 16; i++) { - g_bsp_group_irq_sources[i] = 0; - } - - z_arm_nmi_set_handler(NMI_Handler); -#endif /* CONFIG_RUNTIME_NMI */ - - irq_unlock(key); -} diff --git a/soc/renesas/ra/ra6e1/soc.h b/soc/renesas/ra/ra6e1/soc.h deleted file mode 100644 index 0d3eb2c16fcc..000000000000 --- a/soc/renesas/ra/ra6e1/soc.h +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright (c) 2024 Renesas Electronics Corporation - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/** - * @file SoC configuration macros for the Renesas RA6E1 family MCU - */ - -#ifndef ZEPHYR_SOC_RENESAS_RA6E1_SOC_H_ -#define ZEPHYR_SOC_RENESAS_RA6E1_SOC_H_ - -#include - -#endif /* ZEPHYR_SOC_RENESAS_RA6E1_SOC_H_ */ diff --git a/soc/renesas/ra/ra6e2/CMakeLists.txt b/soc/renesas/ra/ra6e2/CMakeLists.txt index 4eea413d6825..5ac3de6b8848 100644 --- a/soc/renesas/ra/ra6e2/CMakeLists.txt +++ b/soc/renesas/ra/ra6e2/CMakeLists.txt @@ -3,10 +3,6 @@ zephyr_include_directories(.) -zephyr_sources( - soc.c -) - if(CONFIG_CMAKE_LINKER_GENERATOR) dt_nodelabel(option_setting_ofs0 NODELABEL "option_setting_ofs0") dt_nodelabel(option_setting_osis NODELABEL "option_setting_osis") @@ -26,11 +22,6 @@ if(CONFIG_CMAKE_LINKER_GENERATOR) dt_node_has_status(bps_sec_status PATH ${option_setting_bps_sec} STATUS okay) dt_node_has_status(pbps_sec_status PATH ${option_setting_pbps_sec} STATUS okay) - if(CONFIG_USE_RA_FSP_DTC) - zephyr_linker_section(NAME .fsp_dtc_vector_table GROUP RAM) - zephyr_linker_section_configure(SECTION .fsp_dtc_vector_table KEEP INPUT ".fsp_dtc_vector_table*") - endif() - if(${ofs0_status}) zephyr_linker_section(NAME .option_setting_ofs0 GROUP OFS_OFS0_MEMORY ADDRESS ${ofs0_addr}) zephyr_linker_section_configure(SECTION .option_setting_ofs0 KEEP INPUT ".option_setting_ofs0*") @@ -58,10 +49,7 @@ if(CONFIG_CMAKE_LINKER_GENERATOR) elseif(CONFIG_LD_LINKER_TEMPLATE) zephyr_linker_sources(SECTIONS sections.ld) - zephyr_linker_sources(RAM_SECTIONS ram_sections.ld) else() message(WARNING "Unsupported linker template.") endif() - -set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "") diff --git a/soc/renesas/ra/ra6e2/Kconfig b/soc/renesas/ra/ra6e2/Kconfig index 841bafe2fcd9..bfba13e86797 100644 --- a/soc/renesas/ra/ra6e2/Kconfig +++ b/soc/renesas/ra/ra6e2/Kconfig @@ -13,7 +13,6 @@ config SOC_SERIES_RA6E2 select FPU select HAS_SWO select XIP - select SOC_EARLY_INIT_HOOK if SOC_SERIES_RA6E2 diff --git a/soc/renesas/ra/ra6e2/ram_sections.ld b/soc/renesas/ra/ra6e2/ram_sections.ld deleted file mode 100644 index 18be2a431de2..000000000000 --- a/soc/renesas/ra/ra6e2/ram_sections.ld +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright (c) 2025 Renesas Electronics Corporation - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include - -#ifdef CONFIG_USE_RA_FSP_DTC -SECTION_DATA_PROLOGUE(.fsp_dtc_vector_table,(NOLOAD),) -{ - /* If DTC is used, put the DTC vector table at the start of SRAM. - This avoids memory holes due to 1K alignment required by it. */ - *(.fsp_dtc_vector_table) -} GROUP_DATA_LINK_IN(RAMABLE_REGION, RAMABLE_REGION) -#endif /* CONFIG_USE_RA_FSP_DTC */ diff --git a/soc/renesas/ra/ra6e2/soc.c b/soc/renesas/ra/ra6e2/soc.c deleted file mode 100644 index c68fc9880ab9..000000000000 --- a/soc/renesas/ra/ra6e2/soc.c +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright (c) 2024 Renesas Electronics Corporation - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/** - * @file - * @brief System/hardware module for Renesas RA6E2 family processor - */ - -#include -#include -#include -#include -#include -#include -#include -LOG_MODULE_REGISTER(soc, CONFIG_SOC_LOG_LEVEL); - -#include "bsp_cfg.h" -#include - -uint32_t SystemCoreClock BSP_SECTION_EARLY_INIT; - -volatile uint32_t g_protect_pfswe_counter BSP_SECTION_EARLY_INIT; - -#ifdef CONFIG_RUNTIME_NMI -extern bsp_grp_irq_cb_t g_bsp_group_irq_sources[]; -extern void NMI_Handler(void); -#endif /* CONFIG_RUNTIME_NMI */ - -/** - * @brief Perform basic hardware initialization at boot. - * - * This needs to be run from the very beginning. - */ -void soc_early_init_hook(void) -{ - uint32_t key; - - key = irq_lock(); - - extern volatile uint16_t g_protect_counters[]; - - for (uint32_t i = 0; i < 5; i++) { - g_protect_counters[i] = 0; - } - -#if FSP_PRIV_TZ_USE_SECURE_REGS - /* Disable protection using PRCR register. */ - R_BSP_RegisterProtectDisable(BSP_REG_PROTECT_SAR); - - /* Initialize peripherals to secure mode for flat projects */ - R_PSCU->PSARB = 0; - R_PSCU->PSARC = 0; - R_PSCU->PSARD = 0; - R_PSCU->PSARE = 0; - - R_CPSCU->ICUSARC = 0; - R_CPSCU->ICUSARG = 0; - R_CPSCU->ICUSARH = 0; - R_CPSCU->ICUSARI = 0; - - /* Enable protection using PRCR register. */ - R_BSP_RegisterProtectEnable(BSP_REG_PROTECT_SAR); -#endif - - SystemCoreClock = BSP_MOCO_HZ; - g_protect_pfswe_counter = 0; - -#ifdef CONFIG_RUNTIME_NMI - for (uint32_t i = 0; i < 16; i++) { - g_bsp_group_irq_sources[i] = 0; - } - - z_arm_nmi_set_handler(NMI_Handler); -#endif /* CONFIG_RUNTIME_NMI */ - - irq_unlock(key); -} diff --git a/soc/renesas/ra/ra6e2/soc.h b/soc/renesas/ra/ra6e2/soc.h deleted file mode 100644 index a40324087cdb..000000000000 --- a/soc/renesas/ra/ra6e2/soc.h +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright (c) 2024 Renesas Electronics Corporation - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/** - * @file SoC configuration macros for the Renesas RA6E2 family MCU - */ - -#ifndef ZEPHYR_SOC_RENESAS_RA6E2_SOC_H_ -#define ZEPHYR_SOC_RENESAS_RA6E2_SOC_H_ - -#include - -#endif /* ZEPHYR_SOC_RENESAS_RA6E2_SOC_H_ */ diff --git a/soc/renesas/ra/ra6m1/CMakeLists.txt b/soc/renesas/ra/ra6m1/CMakeLists.txt index f13469eb33c6..ff0cadb478c9 100644 --- a/soc/renesas/ra/ra6m1/CMakeLists.txt +++ b/soc/renesas/ra/ra6m1/CMakeLists.txt @@ -3,10 +3,6 @@ zephyr_include_directories(.) -zephyr_sources( - soc.c -) - if(CONFIG_CMAKE_LINKER_GENERATOR) dt_nodelabel(option_setting_ofs0 NODELABEL "option_setting_ofs0") dt_nodelabel(option_setting_ofs1 NODELABEL "option_setting_ofs1") @@ -20,11 +16,6 @@ if(CONFIG_CMAKE_LINKER_GENERATOR) dt_node_has_status(osis_status PATH ${option_setting_osis} STATUS okay) - if(CONFIG_USE_RA_FSP_DTC) - zephyr_linker_section(NAME .fsp_dtc_vector_table GROUP RAM) - zephyr_linker_section_configure(SECTION .fsp_dtc_vector_table KEEP INPUT ".fsp_dtc_vector_table*") - endif() - zephyr_linker_section(NAME .rom_padding GROUP ROM_REGION ADDRESS 0x000001C0) zephyr_linker_section_configure(SECTION .rom_padding KEEP INPUT ".rom_padding*") @@ -45,10 +36,7 @@ if(CONFIG_CMAKE_LINKER_GENERATOR) elseif(CONFIG_LD_LINKER_TEMPLATE) zephyr_linker_sources(ROM_START rom_start.ld) zephyr_linker_sources(SECTIONS sections.ld) - zephyr_linker_sources(RAM_SECTIONS ram_sections.ld) else() message(WARNING "Unsupported linker template.") endif() - -set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "") diff --git a/soc/renesas/ra/ra6m1/Kconfig b/soc/renesas/ra/ra6m1/Kconfig index d637b0aaf1ca..8d87148cd68e 100644 --- a/soc/renesas/ra/ra6m1/Kconfig +++ b/soc/renesas/ra/ra6m1/Kconfig @@ -12,7 +12,6 @@ config SOC_SERIES_RA6M1 select FPU select HAS_SWO select XIP - select SOC_EARLY_INIT_HOOK select GPIO_RA_HAS_VBTICTLR if SOC_SERIES_RA6M1 diff --git a/soc/renesas/ra/ra6m1/ram_sections.ld b/soc/renesas/ra/ra6m1/ram_sections.ld deleted file mode 100644 index 18be2a431de2..000000000000 --- a/soc/renesas/ra/ra6m1/ram_sections.ld +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright (c) 2025 Renesas Electronics Corporation - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include - -#ifdef CONFIG_USE_RA_FSP_DTC -SECTION_DATA_PROLOGUE(.fsp_dtc_vector_table,(NOLOAD),) -{ - /* If DTC is used, put the DTC vector table at the start of SRAM. - This avoids memory holes due to 1K alignment required by it. */ - *(.fsp_dtc_vector_table) -} GROUP_DATA_LINK_IN(RAMABLE_REGION, RAMABLE_REGION) -#endif /* CONFIG_USE_RA_FSP_DTC */ diff --git a/soc/renesas/ra/ra6m1/soc.c b/soc/renesas/ra/ra6m1/soc.c deleted file mode 100644 index 1986da3ec8c4..000000000000 --- a/soc/renesas/ra/ra6m1/soc.c +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright (c) 2024 Renesas Electronics Corporation - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/** - * @file - * @brief System/hardware module for Renesas RA6M1 family processor - */ - -#include -#include -#include -#include -#include -#include -#include -LOG_MODULE_REGISTER(soc, CONFIG_SOC_LOG_LEVEL); - -#include "bsp_cfg.h" -#include - -uint32_t SystemCoreClock BSP_SECTION_EARLY_INIT; - -volatile uint32_t g_protect_pfswe_counter BSP_SECTION_EARLY_INIT; - -#ifdef CONFIG_RUNTIME_NMI -extern bsp_grp_irq_cb_t g_bsp_group_irq_sources[]; -extern void NMI_Handler(void); -#endif /* CONFIG_RUNTIME_NMI */ - -/** - * @brief Perform basic hardware initialization at boot. - * - * This needs to be run from the very beginning. - */ -void soc_early_init_hook(void) -{ - uint32_t key; - - key = irq_lock(); - - SystemCoreClock = BSP_MOCO_HZ; - g_protect_pfswe_counter = 0; - -#ifdef CONFIG_RUNTIME_NMI - for (uint32_t i = 0; i < 16; i++) { - g_bsp_group_irq_sources[i] = 0; - } - - z_arm_nmi_set_handler(NMI_Handler); -#endif /* CONFIG_RUNTIME_NMI */ - - irq_unlock(key); -} diff --git a/soc/renesas/ra/ra6m1/soc.h b/soc/renesas/ra/ra6m1/soc.h deleted file mode 100644 index b341280870ec..000000000000 --- a/soc/renesas/ra/ra6m1/soc.h +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright (c) 2024 Renesas Electronics Corporation - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/** - * @file SoC configuration macros for the Renesas RA6M1 family MCU - */ - -#ifndef ZEPHYR_SOC_RENESAS_RA6M1_SOC_H_ -#define ZEPHYR_SOC_RENESAS_RA6M1_SOC_H_ - -#include - -#endif /* ZEPHYR_SOC_RENESAS_RA6M1_SOC_H_ */ diff --git a/soc/renesas/ra/ra6m2/CMakeLists.txt b/soc/renesas/ra/ra6m2/CMakeLists.txt index f13469eb33c6..ff0cadb478c9 100644 --- a/soc/renesas/ra/ra6m2/CMakeLists.txt +++ b/soc/renesas/ra/ra6m2/CMakeLists.txt @@ -3,10 +3,6 @@ zephyr_include_directories(.) -zephyr_sources( - soc.c -) - if(CONFIG_CMAKE_LINKER_GENERATOR) dt_nodelabel(option_setting_ofs0 NODELABEL "option_setting_ofs0") dt_nodelabel(option_setting_ofs1 NODELABEL "option_setting_ofs1") @@ -20,11 +16,6 @@ if(CONFIG_CMAKE_LINKER_GENERATOR) dt_node_has_status(osis_status PATH ${option_setting_osis} STATUS okay) - if(CONFIG_USE_RA_FSP_DTC) - zephyr_linker_section(NAME .fsp_dtc_vector_table GROUP RAM) - zephyr_linker_section_configure(SECTION .fsp_dtc_vector_table KEEP INPUT ".fsp_dtc_vector_table*") - endif() - zephyr_linker_section(NAME .rom_padding GROUP ROM_REGION ADDRESS 0x000001C0) zephyr_linker_section_configure(SECTION .rom_padding KEEP INPUT ".rom_padding*") @@ -45,10 +36,7 @@ if(CONFIG_CMAKE_LINKER_GENERATOR) elseif(CONFIG_LD_LINKER_TEMPLATE) zephyr_linker_sources(ROM_START rom_start.ld) zephyr_linker_sources(SECTIONS sections.ld) - zephyr_linker_sources(RAM_SECTIONS ram_sections.ld) else() message(WARNING "Unsupported linker template.") endif() - -set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "") diff --git a/soc/renesas/ra/ra6m2/Kconfig b/soc/renesas/ra/ra6m2/Kconfig index 3946ee6bdd99..19881efdd6f9 100644 --- a/soc/renesas/ra/ra6m2/Kconfig +++ b/soc/renesas/ra/ra6m2/Kconfig @@ -12,7 +12,6 @@ config SOC_SERIES_RA6M2 select FPU select HAS_SWO select XIP - select SOC_EARLY_INIT_HOOK select GPIO_RA_HAS_VBTICTLR if SOC_SERIES_RA6M2 diff --git a/soc/renesas/ra/ra6m2/ram_sections.ld b/soc/renesas/ra/ra6m2/ram_sections.ld deleted file mode 100644 index 18be2a431de2..000000000000 --- a/soc/renesas/ra/ra6m2/ram_sections.ld +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright (c) 2025 Renesas Electronics Corporation - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include - -#ifdef CONFIG_USE_RA_FSP_DTC -SECTION_DATA_PROLOGUE(.fsp_dtc_vector_table,(NOLOAD),) -{ - /* If DTC is used, put the DTC vector table at the start of SRAM. - This avoids memory holes due to 1K alignment required by it. */ - *(.fsp_dtc_vector_table) -} GROUP_DATA_LINK_IN(RAMABLE_REGION, RAMABLE_REGION) -#endif /* CONFIG_USE_RA_FSP_DTC */ diff --git a/soc/renesas/ra/ra6m2/soc.c b/soc/renesas/ra/ra6m2/soc.c deleted file mode 100644 index 90d7cd7fad1d..000000000000 --- a/soc/renesas/ra/ra6m2/soc.c +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright (c) 2024 Renesas Electronics Corporation - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/** - * @file - * @brief System/hardware module for Renesas RA6M2 family processor - */ - -#include -#include -#include -#include -#include -#include -#include -LOG_MODULE_REGISTER(soc, CONFIG_SOC_LOG_LEVEL); - -#include "bsp_cfg.h" -#include - -uint32_t SystemCoreClock BSP_SECTION_EARLY_INIT; - -volatile uint32_t g_protect_pfswe_counter BSP_SECTION_EARLY_INIT; - -#ifdef CONFIG_RUNTIME_NMI -extern bsp_grp_irq_cb_t g_bsp_group_irq_sources[]; -extern void NMI_Handler(void); -#endif /* CONFIG_RUNTIME_NMI */ - -/** - * @brief Perform basic hardware initialization at boot. - * - * This needs to be run from the very beginning. - */ -void soc_early_init_hook(void) -{ - uint32_t key; - - key = irq_lock(); - - SystemCoreClock = BSP_MOCO_HZ; - g_protect_pfswe_counter = 0; - -#ifdef CONFIG_RUNTIME_NMI - for (uint32_t i = 0; i < 16; i++) { - g_bsp_group_irq_sources[i] = 0; - } - - z_arm_nmi_set_handler(NMI_Handler); -#endif /* CONFIG_RUNTIME_NMI */ - - irq_unlock(key); -} diff --git a/soc/renesas/ra/ra6m2/soc.h b/soc/renesas/ra/ra6m2/soc.h deleted file mode 100644 index 8ad75a1efea5..000000000000 --- a/soc/renesas/ra/ra6m2/soc.h +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright (c) 2024 Renesas Electronics Corporation - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/** - * @file SoC configuration macros for the Renesas RA6M2 family MCU - */ - -#ifndef ZEPHYR_SOC_RENESAS_RA6M2_SOC_H_ -#define ZEPHYR_SOC_RENESAS_RA6M2_SOC_H_ - -#include - -#endif /* ZEPHYR_SOC_RENESAS_RA6M2_SOC_H_ */ diff --git a/soc/renesas/ra/ra6m3/CMakeLists.txt b/soc/renesas/ra/ra6m3/CMakeLists.txt index f13469eb33c6..ff0cadb478c9 100644 --- a/soc/renesas/ra/ra6m3/CMakeLists.txt +++ b/soc/renesas/ra/ra6m3/CMakeLists.txt @@ -3,10 +3,6 @@ zephyr_include_directories(.) -zephyr_sources( - soc.c -) - if(CONFIG_CMAKE_LINKER_GENERATOR) dt_nodelabel(option_setting_ofs0 NODELABEL "option_setting_ofs0") dt_nodelabel(option_setting_ofs1 NODELABEL "option_setting_ofs1") @@ -20,11 +16,6 @@ if(CONFIG_CMAKE_LINKER_GENERATOR) dt_node_has_status(osis_status PATH ${option_setting_osis} STATUS okay) - if(CONFIG_USE_RA_FSP_DTC) - zephyr_linker_section(NAME .fsp_dtc_vector_table GROUP RAM) - zephyr_linker_section_configure(SECTION .fsp_dtc_vector_table KEEP INPUT ".fsp_dtc_vector_table*") - endif() - zephyr_linker_section(NAME .rom_padding GROUP ROM_REGION ADDRESS 0x000001C0) zephyr_linker_section_configure(SECTION .rom_padding KEEP INPUT ".rom_padding*") @@ -45,10 +36,7 @@ if(CONFIG_CMAKE_LINKER_GENERATOR) elseif(CONFIG_LD_LINKER_TEMPLATE) zephyr_linker_sources(ROM_START rom_start.ld) zephyr_linker_sources(SECTIONS sections.ld) - zephyr_linker_sources(RAM_SECTIONS ram_sections.ld) else() message(WARNING "Unsupported linker template.") endif() - -set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "") diff --git a/soc/renesas/ra/ra6m3/Kconfig b/soc/renesas/ra/ra6m3/Kconfig index 21fe71c4a48a..a223f07f8728 100644 --- a/soc/renesas/ra/ra6m3/Kconfig +++ b/soc/renesas/ra/ra6m3/Kconfig @@ -12,7 +12,6 @@ config SOC_SERIES_RA6M3 select FPU select HAS_SWO select XIP - select SOC_EARLY_INIT_HOOK select GPIO_RA_HAS_VBTICTLR if SOC_SERIES_RA6M3 diff --git a/soc/renesas/ra/ra6m3/ram_sections.ld b/soc/renesas/ra/ra6m3/ram_sections.ld deleted file mode 100644 index 18be2a431de2..000000000000 --- a/soc/renesas/ra/ra6m3/ram_sections.ld +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright (c) 2025 Renesas Electronics Corporation - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include - -#ifdef CONFIG_USE_RA_FSP_DTC -SECTION_DATA_PROLOGUE(.fsp_dtc_vector_table,(NOLOAD),) -{ - /* If DTC is used, put the DTC vector table at the start of SRAM. - This avoids memory holes due to 1K alignment required by it. */ - *(.fsp_dtc_vector_table) -} GROUP_DATA_LINK_IN(RAMABLE_REGION, RAMABLE_REGION) -#endif /* CONFIG_USE_RA_FSP_DTC */ diff --git a/soc/renesas/ra/ra6m3/soc.c b/soc/renesas/ra/ra6m3/soc.c deleted file mode 100644 index 9c520b99e3a1..000000000000 --- a/soc/renesas/ra/ra6m3/soc.c +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright (c) 2024 Renesas Electronics Corporation - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/** - * @file - * @brief System/hardware module for Renesas RA6M3 family processor - */ - -#include -#include -#include -#include -#include -#include -#include -LOG_MODULE_REGISTER(soc, CONFIG_SOC_LOG_LEVEL); - -#include "bsp_cfg.h" -#include - -uint32_t SystemCoreClock BSP_SECTION_EARLY_INIT; - -volatile uint32_t g_protect_pfswe_counter BSP_SECTION_EARLY_INIT; - -#ifdef CONFIG_RUNTIME_NMI -extern bsp_grp_irq_cb_t g_bsp_group_irq_sources[]; -extern void NMI_Handler(void); -#endif /* CONFIG_RUNTIME_NMI */ - -/** - * @brief Perform basic hardware initialization at boot. - * - * This needs to be run from the very beginning. - */ -void soc_early_init_hook(void) -{ - uint32_t key; - - key = irq_lock(); - - SystemCoreClock = BSP_MOCO_HZ; - g_protect_pfswe_counter = 0; - -#ifdef CONFIG_RUNTIME_NMI - for (uint32_t i = 0; i < 16; i++) { - g_bsp_group_irq_sources[i] = 0; - } - - z_arm_nmi_set_handler(NMI_Handler); -#endif - - irq_unlock(key); -} diff --git a/soc/renesas/ra/ra6m3/soc.h b/soc/renesas/ra/ra6m3/soc.h deleted file mode 100644 index 9fa414f0b647..000000000000 --- a/soc/renesas/ra/ra6m3/soc.h +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright (c) 2024 Renesas Electronics Corporation - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/** - * @file SoC configuration macros for the Renesas RA6M3 family MCU - */ - -#ifndef ZEPHYR_SOC_RENESAS_RA6M3_SOC_H_ -#define ZEPHYR_SOC_RENESAS_RA6M3_SOC_H_ - -#include - -#endif /* ZEPHYR_SOC_RENESAS_RA6M3_SOC_H_ */ diff --git a/soc/renesas/ra/ra6m4/CMakeLists.txt b/soc/renesas/ra/ra6m4/CMakeLists.txt index 4ecf42a5fc63..d65792c0f5a6 100644 --- a/soc/renesas/ra/ra6m4/CMakeLists.txt +++ b/soc/renesas/ra/ra6m4/CMakeLists.txt @@ -3,10 +3,6 @@ zephyr_include_directories(.) -zephyr_sources( - soc.c -) - if(CONFIG_CMAKE_LINKER_GENERATOR) dt_nodelabel(option_setting_ofs0 NODELABEL "option_setting_ofs0") dt_nodelabel(option_setting_dualsel NODELABEL "option_setting_dualsel") @@ -38,11 +34,6 @@ if(CONFIG_CMAKE_LINKER_GENERATOR) dt_node_has_status(banksel_sel_status PATH ${option_setting_banksel_sel} STATUS okay) dt_node_has_status(bps_sel_status PATH ${option_setting_bps_sel} STATUS okay) - if(CONFIG_USE_RA_FSP_DTC) - zephyr_linker_section(NAME .fsp_dtc_vector_table GROUP RAM) - zephyr_linker_section_configure(SECTION .fsp_dtc_vector_table KEEP INPUT ".fsp_dtc_vector_table*") - endif() - if(${ofs0_status}) zephyr_linker_section(NAME .option_setting_ofs0 GROUP OFS_OFS0_MEMORY ADDRESS ${ofs0_addr}) zephyr_linker_section_configure(SECTION .option_setting_ofs0 KEEP INPUT ".option_setting_ofs0*") @@ -88,9 +79,12 @@ if(CONFIG_CMAKE_LINKER_GENERATOR) zephyr_linker_section_configure(SECTION .option_setting_bps_sel KEEP INPUT ".option_setting_bps_sel*") endif() + if(CONFIG_ETH_RENESAS_RA_USE_NS_BUF) + message(WARNING "Configure ETHERNET non-secure buffer with CMAKE_LINKER_GENERATOR is not supported.") + endif() + elseif(CONFIG_LD_LINKER_TEMPLATE) zephyr_linker_sources(SECTIONS sections.ld) - zephyr_linker_sources(RAM_SECTIONS ram_sections.ld) else() message(WARNING "Unsupported linker template.") @@ -109,8 +103,6 @@ if(CONFIG_ETH_RENESAS_RA_USE_NS_BUF) --output-rpd ${PROJECT_BINARY_DIR}/${CONFIG_KERNEL_BIN_NAME}.rpd $<$:--verbose> WORKING_DIRECTORY ${PROJECT_BINARY_DIR} - ) + ) endif() -else() - set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "") endif() diff --git a/soc/renesas/ra/ra6m4/Kconfig b/soc/renesas/ra/ra6m4/Kconfig index 50af68b81788..4bc5d96bfba1 100644 --- a/soc/renesas/ra/ra6m4/Kconfig +++ b/soc/renesas/ra/ra6m4/Kconfig @@ -14,7 +14,6 @@ config SOC_SERIES_RA6M4 select FPU select HAS_SWO select XIP - select SOC_EARLY_INIT_HOOK select GPIO_RA_HAS_VBTICTLR select OUTPUT_RPD if ETH_RENESAS_RA diff --git a/soc/renesas/ra/ra6m4/ram_sections.ld b/soc/renesas/ra/ra6m4/ram_sections.ld deleted file mode 100644 index 18be2a431de2..000000000000 --- a/soc/renesas/ra/ra6m4/ram_sections.ld +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright (c) 2025 Renesas Electronics Corporation - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include - -#ifdef CONFIG_USE_RA_FSP_DTC -SECTION_DATA_PROLOGUE(.fsp_dtc_vector_table,(NOLOAD),) -{ - /* If DTC is used, put the DTC vector table at the start of SRAM. - This avoids memory holes due to 1K alignment required by it. */ - *(.fsp_dtc_vector_table) -} GROUP_DATA_LINK_IN(RAMABLE_REGION, RAMABLE_REGION) -#endif /* CONFIG_USE_RA_FSP_DTC */ diff --git a/soc/renesas/ra/ra6m4/soc.c b/soc/renesas/ra/ra6m4/soc.c deleted file mode 100644 index 11342effb0da..000000000000 --- a/soc/renesas/ra/ra6m4/soc.c +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright (c) 2024 Renesas Electronics Corporation - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/** - * @file - * @brief System/hardware module for Renesas RA6M4 family processor - */ - -#include -#include -#include -#include -#include -#include -#include -LOG_MODULE_REGISTER(soc, CONFIG_SOC_LOG_LEVEL); - -#include "bsp_cfg.h" -#include - -uint32_t SystemCoreClock BSP_SECTION_EARLY_INIT; - -volatile uint32_t g_protect_pfswe_counter BSP_SECTION_EARLY_INIT; - -#ifdef CONFIG_RUNTIME_NMI -extern bsp_grp_irq_cb_t g_bsp_group_irq_sources[]; -extern void NMI_Handler(void); -#endif /* CONFIG_RUNTIME_NMI */ - -/** - * @brief Perform basic hardware initialization at boot. - * - * This needs to be run from the very beginning. - */ -void soc_early_init_hook(void) -{ - uint32_t key; - - key = irq_lock(); - - extern volatile uint16_t g_protect_counters[]; - - for (uint32_t i = 0; i < 5; i++) { - g_protect_counters[i] = 0; - } - -#if FSP_PRIV_TZ_USE_SECURE_REGS - /* Disable protection using PRCR register. */ - R_BSP_RegisterProtectDisable(BSP_REG_PROTECT_SAR); - - /* Initialize peripherals to secure mode for flat projects */ - R_PSCU->PSARB = 0; - R_PSCU->PSARC = 0; - R_PSCU->PSARD = 0; - R_PSCU->PSARE = 0; - - R_CPSCU->ICUSARC = 0; - R_CPSCU->ICUSARG = 0; - R_CPSCU->ICUSARH = 0; - R_CPSCU->ICUSARI = 0; - - /* Enable protection using PRCR register. */ - R_BSP_RegisterProtectEnable(BSP_REG_PROTECT_SAR); -#endif - - SystemCoreClock = BSP_MOCO_HZ; - g_protect_pfswe_counter = 0; - -#ifdef CONFIG_RUNTIME_NMI - for (uint32_t i = 0; i < 16; i++) { - g_bsp_group_irq_sources[i] = 0; - } - - z_arm_nmi_set_handler(NMI_Handler); -#endif - - irq_unlock(key); -} diff --git a/soc/renesas/ra/ra6m4/soc.h b/soc/renesas/ra/ra6m4/soc.h deleted file mode 100644 index 13344b76e84a..000000000000 --- a/soc/renesas/ra/ra6m4/soc.h +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright (c) 2024 Renesas Electronics Corporation - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/** - * @file SoC configuration macros for the Renesas RA6M4 family MCU - */ - -#ifndef ZEPHYR_SOC_RENESAS_RA6M4_SOC_H_ -#define ZEPHYR_SOC_RENESAS_RA6M4_SOC_H_ - -#include - -#endif /* ZEPHYR_SOC_RENESAS_RA6M4_SOC_H_ */ diff --git a/soc/renesas/ra/ra6m5/CMakeLists.txt b/soc/renesas/ra/ra6m5/CMakeLists.txt index b1b8a9d88f15..4f2bdb036687 100644 --- a/soc/renesas/ra/ra6m5/CMakeLists.txt +++ b/soc/renesas/ra/ra6m5/CMakeLists.txt @@ -3,10 +3,6 @@ zephyr_include_directories(.) -zephyr_sources( - soc.c -) - if(CONFIG_CMAKE_LINKER_GENERATOR) dt_nodelabel(option_setting_ofs0 NODELABEL "option_setting_ofs0") dt_nodelabel(option_setting_dualsel NODELABEL "option_setting_dualsel") @@ -38,11 +34,6 @@ if(CONFIG_CMAKE_LINKER_GENERATOR) dt_node_has_status(banksel_sel_status PATH ${option_setting_banksel_sel} STATUS okay) dt_node_has_status(bps_sel_status PATH ${option_setting_bps_sel} STATUS okay) - if(CONFIG_USE_RA_FSP_DTC) - zephyr_linker_section(NAME .fsp_dtc_vector_table GROUP RAM) - zephyr_linker_section_configure(SECTION .fsp_dtc_vector_table KEEP INPUT ".fsp_dtc_vector_table*") - endif() - if(${ofs0_status}) zephyr_linker_section(NAME .option_setting_ofs0 GROUP OFS_OFS0_MEMORY ADDRESS ${ofs0_addr}) zephyr_linker_section_configure(SECTION .option_setting_ofs0 KEEP INPUT ".option_setting_ofs0*") @@ -88,9 +79,12 @@ if(CONFIG_CMAKE_LINKER_GENERATOR) zephyr_linker_section_configure(SECTION .option_setting_bps_sel KEEP INPUT ".option_setting_bps_sel*") endif() + if(CONFIG_ETH_RENESAS_RA_USE_NS_BUF) + message(WARNING "Configure ETHERNET non-secure buffer with CMAKE_LINKER_GENERATOR is not supported.") + endif() + elseif(CONFIG_LD_LINKER_TEMPLATE) zephyr_linker_sources(SECTIONS sections.ld) - zephyr_linker_sources(RAM_SECTIONS ram_sections.ld) else() message(WARNING "Unsupported linker template.") @@ -111,6 +105,4 @@ if(CONFIG_ETH_RENESAS_RA_USE_NS_BUF) WORKING_DIRECTORY ${PROJECT_BINARY_DIR} ) endif() -else() - set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "") endif() diff --git a/soc/renesas/ra/ra6m5/Kconfig b/soc/renesas/ra/ra6m5/Kconfig index c7d645907272..93e4bd1c93fb 100644 --- a/soc/renesas/ra/ra6m5/Kconfig +++ b/soc/renesas/ra/ra6m5/Kconfig @@ -14,7 +14,6 @@ config SOC_SERIES_RA6M5 select FPU select HAS_SWO select XIP - select SOC_EARLY_INIT_HOOK select GPIO_RA_HAS_VBTICTLR select OUTPUT_RPD if ETH_RENESAS_RA diff --git a/soc/renesas/ra/ra6m5/ram_sections.ld b/soc/renesas/ra/ra6m5/ram_sections.ld deleted file mode 100644 index 18be2a431de2..000000000000 --- a/soc/renesas/ra/ra6m5/ram_sections.ld +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright (c) 2025 Renesas Electronics Corporation - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include - -#ifdef CONFIG_USE_RA_FSP_DTC -SECTION_DATA_PROLOGUE(.fsp_dtc_vector_table,(NOLOAD),) -{ - /* If DTC is used, put the DTC vector table at the start of SRAM. - This avoids memory holes due to 1K alignment required by it. */ - *(.fsp_dtc_vector_table) -} GROUP_DATA_LINK_IN(RAMABLE_REGION, RAMABLE_REGION) -#endif /* CONFIG_USE_RA_FSP_DTC */ diff --git a/soc/renesas/ra/ra6m5/soc.c b/soc/renesas/ra/ra6m5/soc.c deleted file mode 100644 index bba626f25b25..000000000000 --- a/soc/renesas/ra/ra6m5/soc.c +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Copyright (c) 2024 Renesas Electronics Corporation - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/** - * @file - * @brief System/hardware module for Renesas RA6M5 family processor - */ - -#include -#include -#include -#include -#include -#include -#include -LOG_MODULE_REGISTER(soc, CONFIG_SOC_LOG_LEVEL); - -#include "bsp_cfg.h" -#include - -uint32_t SystemCoreClock BSP_SECTION_EARLY_INIT; - -volatile uint32_t g_protect_pfswe_counter BSP_SECTION_EARLY_INIT; - -#ifdef CONFIG_RUNTIME_NMI -extern bsp_grp_irq_cb_t g_bsp_group_irq_sources[]; -extern void NMI_Handler(void); -#endif /* CONFIG_RUNTIME_NMI */ - -/** - * @brief Perform basic hardware initialization at boot. - * - * This needs to be run from the very beginning. - */ -void soc_early_init_hook(void) -{ - uint32_t key; - - key = irq_lock(); - - extern volatile uint16_t g_protect_counters[]; - - for (uint32_t i = 0; i < 5; i++) { - g_protect_counters[i] = 0; - } - -#if FSP_PRIV_TZ_USE_SECURE_REGS - /* Disable protection using PRCR register. */ - R_BSP_RegisterProtectDisable(BSP_REG_PROTECT_SAR); - - /* Initialize peripherals to secure mode for flat projects */ - R_PSCU->PSARB = 0; - R_PSCU->PSARC = 0; - R_PSCU->PSARD = 0; - R_PSCU->PSARE = 0; - R_CPSCU->ICUSARC = 0; - - /* The secure Attribute managed within the ARM CPU NVIC must match the - * security attribution of IELSEn registers (Reference section 13.2.9 - * in the RA6M4 manual R01UH0890EJ0050). - */ - uint32_t volatile *p_icusarg = &R_CPSCU->ICUSARG; - - for (int i = 0; i < BSP_ICU_VECTOR_MAX_ENTRIES / NUM_BITS(uint32_t); i++) { - p_icusarg[i] = 0; - NVIC->ITNS[i] = 0; - } - - /* Enable protection using PRCR register. */ - R_BSP_RegisterProtectEnable(BSP_REG_PROTECT_SAR); -#endif - - SystemCoreClock = BSP_MOCO_HZ; - g_protect_pfswe_counter = 0; - -#ifdef CONFIG_RUNTIME_NMI - for (uint32_t i = 0; i < 16; i++) { - g_bsp_group_irq_sources[i] = 0; - } - - z_arm_nmi_set_handler(NMI_Handler); -#endif - - irq_unlock(key); -} diff --git a/soc/renesas/ra/ra6m5/soc.h b/soc/renesas/ra/ra6m5/soc.h deleted file mode 100644 index 2774723147c1..000000000000 --- a/soc/renesas/ra/ra6m5/soc.h +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright (c) 2024 Renesas Electronics Corporation - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/** - * @file SoC configuration macros for the Renesas RA6M5 family MCU - */ - -#ifndef ZEPHYR_SOC_RENESAS_RA6M5_SOC_H_ -#define ZEPHYR_SOC_RENESAS_RA6M5_SOC_H_ - -#include - -#endif /* ZEPHYR_SOC_RENESAS_RA6M5_SOC_H_ */ diff --git a/soc/renesas/ra/ra8d1/CMakeLists.txt b/soc/renesas/ra/ra8d1/CMakeLists.txt index b0b66d221709..c1d1aea9a03e 100644 --- a/soc/renesas/ra/ra8d1/CMakeLists.txt +++ b/soc/renesas/ra/ra8d1/CMakeLists.txt @@ -3,10 +3,6 @@ zephyr_include_directories(.) -zephyr_sources( - soc.c -) - zephyr_sources_ifdef(CONFIG_PM power.c ) @@ -45,11 +41,6 @@ if(CONFIG_CMAKE_LINKER_GENERATOR) dt_node_has_status(banksel_sel_status PATH ${option_setting_banksel_sel} STATUS okay) dt_node_has_status(bps_sel_status PATH ${option_setting_bps_sel} STATUS okay) - if(CONFIG_USE_RA_FSP_DTC) - zephyr_linker_section(NAME .fsp_dtc_vector_table GROUP RAM) - zephyr_linker_section_configure(SECTION .fsp_dtc_vector_table KEEP INPUT ".fsp_dtc_vector_table*") - endif() - if(${ofs0_status}) zephyr_linker_section(NAME .option_setting_ofs0 GROUP OFS_OFS0_MEMORY ADDRESS ${ofs0_addr}) zephyr_linker_section_configure(SECTION .option_setting_ofs0 KEEP INPUT ".option_setting_ofs0*") @@ -102,10 +93,7 @@ if(CONFIG_CMAKE_LINKER_GENERATOR) elseif(CONFIG_LD_LINKER_TEMPLATE) zephyr_linker_sources(SECTIONS sections.ld) - zephyr_linker_sources(RAM_SECTIONS ram_sections.ld) else() message(WARNING "Unsupported linker template.") endif() - -set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "") diff --git a/soc/renesas/ra/ra8d1/Kconfig b/soc/renesas/ra/ra8d1/Kconfig index bf456b39ff11..ee5fd5ee7389 100644 --- a/soc/renesas/ra/ra8d1/Kconfig +++ b/soc/renesas/ra/ra8d1/Kconfig @@ -13,7 +13,6 @@ config SOC_SERIES_RA8D1 select XIP select CLOCK_CONTROL_RENESAS_RA_CGC if CLOCK_CONTROL select HAS_RENESAS_RA_FSP - select SOC_EARLY_INIT_HOOK select GPIO_RA_HAS_VBTICTLR select HAS_PM diff --git a/soc/renesas/ra/ra8d1/ram_sections.ld b/soc/renesas/ra/ra8d1/ram_sections.ld deleted file mode 100644 index 18be2a431de2..000000000000 --- a/soc/renesas/ra/ra8d1/ram_sections.ld +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright (c) 2025 Renesas Electronics Corporation - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include - -#ifdef CONFIG_USE_RA_FSP_DTC -SECTION_DATA_PROLOGUE(.fsp_dtc_vector_table,(NOLOAD),) -{ - /* If DTC is used, put the DTC vector table at the start of SRAM. - This avoids memory holes due to 1K alignment required by it. */ - *(.fsp_dtc_vector_table) -} GROUP_DATA_LINK_IN(RAMABLE_REGION, RAMABLE_REGION) -#endif /* CONFIG_USE_RA_FSP_DTC */ diff --git a/soc/renesas/ra/ra8d1/soc.c b/soc/renesas/ra/ra8d1/soc.c deleted file mode 100644 index fea9ddd312e4..000000000000 --- a/soc/renesas/ra/ra8d1/soc.c +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright (c) 2024 Renesas Electronics Corporation - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/** - * @file - * @brief System/hardware module for Renesas RA8D1 family processor - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -LOG_MODULE_REGISTER(soc, CONFIG_SOC_LOG_LEVEL); - -#include - -#define CCR_CACHE_ENABLE (SCB_CCR_IC_Msk | SCB_CCR_BP_Msk | SCB_CCR_LOB_Msk) - -uint32_t SystemCoreClock BSP_SECTION_EARLY_INIT; - -volatile uint32_t g_protect_pfswe_counter BSP_SECTION_EARLY_INIT; - -#ifdef CONFIG_RUNTIME_NMI -extern bsp_grp_irq_cb_t g_bsp_group_irq_sources[]; -extern void NMI_Handler(void); -#endif /* CONFIG_RUNTIME_NMI */ - -/** - * @brief Perform basic hardware initialization at boot. - * - * This needs to be run from the very beginning. - */ -void soc_early_init_hook(void) -{ - SystemCoreClock = BSP_MOCO_HZ; - g_protect_pfswe_counter = 0; - -#ifdef CONFIG_ICACHE - SCB->CCR = (uint32_t)CCR_CACHE_ENABLE; - barrier_dsync_fence_full(); - barrier_isync_fence_full(); -#endif -#if defined(CONFIG_DCACHE) && defined(CONFIG_CACHE_MANAGEMENT) - /* Apply Arm Cortex-M85 errata workarounds for D-Cache - * Attributing all cacheable memory as write-through set FORCEWT bit in MSCR register. - * Set bit 16 in ACTLR to 1. - * See erratum 3175626 and 3190818 in the Cortex-M85 AT640 and Cortex-M85 with FPU AT641 - * Software Developer Errata Notice (Date of issue: March 07, 2024, Document version: 13.0, - * Document ID: SDEN-2236668). - */ - MEMSYSCTL->MSCR |= MEMSYSCTL_MSCR_FORCEWT_Msk; - barrier_dsync_fence_full(); - barrier_isync_fence_full(); - ICB->ACTLR |= (1U << 16U); - barrier_dsync_fence_full(); - barrier_isync_fence_full(); - - sys_cache_data_enable(); -#endif - -#ifdef CONFIG_RUNTIME_NMI - for (uint32_t i = 0; i < 16; i++) { - g_bsp_group_irq_sources[i] = 0; - } - - z_arm_nmi_set_handler(NMI_Handler); -#endif /* CONFIG_RUNTIME_NMI */ - - cold_start_handler(); -} diff --git a/soc/renesas/ra/ra8d1/soc.h b/soc/renesas/ra/ra8d1/soc.h deleted file mode 100644 index b878fe60a3ae..000000000000 --- a/soc/renesas/ra/ra8d1/soc.h +++ /dev/null @@ -1,17 +0,0 @@ -/* - * Copyright (c) 2024-2025 Renesas Electronics Corporation - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/** - * @file SoC configuration macros for the Renesas RA8D1 family MCU - */ - -#ifndef ZEPHYR_SOC_RENESAS_RA8D1_SOC_H_ -#define ZEPHYR_SOC_RENESAS_RA8D1_SOC_H_ - -#include -#include - -#endif /* ZEPHYR_SOC_RENESAS_RA8D1_SOC_H_ */ diff --git a/soc/renesas/ra/ra8d2/CMakeLists.txt b/soc/renesas/ra/ra8d2/CMakeLists.txt index 2e8d68f94cd9..1542927b73be 100644 --- a/soc/renesas/ra/ra8d2/CMakeLists.txt +++ b/soc/renesas/ra/ra8d2/CMakeLists.txt @@ -3,20 +3,11 @@ zephyr_include_directories(.) -zephyr_sources( - soc.c -) - zephyr_sources_ifdef(CONFIG_PM power.c ) if(CONFIG_CMAKE_LINKER_GENERATOR) - if(CONFIG_USE_RA_FSP_DTC) - zephyr_linker_section(NAME .fsp_dtc_vector_table GROUP RAM) - zephyr_linker_section_configure(SECTION .fsp_dtc_vector_table KEEP INPUT ".fsp_dtc_vector_table*") - endif() - if((NOT CONFIG_BOOTLOADER_MCUBOOT) AND (NOT CONFIG_SOC_RA_SECOND_CORE_BUILD)) dt_nodelabel(option_setting_ofs0 NODELABEL "option_setting_ofs0") dt_nodelabel(option_setting_ofs2 NODELABEL "option_setting_ofs2") @@ -98,10 +89,7 @@ elseif(CONFIG_LD_LINKER_TEMPLATE) if((NOT CONFIG_BOOTLOADER_MCUBOOT) AND (NOT CONFIG_SOC_RA_SECOND_CORE_BUILD)) zephyr_linker_sources(SECTIONS sections.ld) endif() - zephyr_linker_sources(RAM_SECTIONS ram_sections.ld) else() message(WARNING "Unsupported linker template.") endif() - -set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "") diff --git a/soc/renesas/ra/ra8d2/Kconfig b/soc/renesas/ra/ra8d2/Kconfig index 581d925133d8..5883dfefe522 100644 --- a/soc/renesas/ra/ra8d2/Kconfig +++ b/soc/renesas/ra/ra8d2/Kconfig @@ -13,7 +13,6 @@ config SOC_SERIES_RA8D2 select XIP select CLOCK_CONTROL_RENESAS_RA_CGC if CLOCK_CONTROL select HAS_RENESAS_RA_FSP - select SOC_EARLY_INIT_HOOK select HAS_PM config SOC_R7KA8D2KFLCAC_CM85 diff --git a/soc/renesas/ra/ra8d2/ram_sections.ld b/soc/renesas/ra/ra8d2/ram_sections.ld deleted file mode 100644 index 18be2a431de2..000000000000 --- a/soc/renesas/ra/ra8d2/ram_sections.ld +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright (c) 2025 Renesas Electronics Corporation - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include - -#ifdef CONFIG_USE_RA_FSP_DTC -SECTION_DATA_PROLOGUE(.fsp_dtc_vector_table,(NOLOAD),) -{ - /* If DTC is used, put the DTC vector table at the start of SRAM. - This avoids memory holes due to 1K alignment required by it. */ - *(.fsp_dtc_vector_table) -} GROUP_DATA_LINK_IN(RAMABLE_REGION, RAMABLE_REGION) -#endif /* CONFIG_USE_RA_FSP_DTC */ diff --git a/soc/renesas/ra/ra8d2/soc.c b/soc/renesas/ra/ra8d2/soc.c deleted file mode 100644 index 497d94f0150b..000000000000 --- a/soc/renesas/ra/ra8d2/soc.c +++ /dev/null @@ -1,106 +0,0 @@ -/* - * Copyright (c) 2025 Renesas Electronics Corporation - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/** - * @file - * @brief System/hardware module for Renesas RA8P1 family processor - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -LOG_MODULE_REGISTER(soc, CONFIG_SOC_LOG_LEVEL); - -#include "soc.h" - -#define CCR_CACHE_ENABLE (SCB_CCR_IC_Msk | SCB_CCR_BP_Msk | SCB_CCR_LOB_Msk) - -uint32_t SystemCoreClock BSP_SECTION_EARLY_INIT; - -volatile uint32_t g_protect_pfswe_counter BSP_SECTION_EARLY_INIT; - -#ifdef CONFIG_RUNTIME_NMI -extern bsp_grp_irq_cb_t g_bsp_group_irq_sources[]; -extern void NMI_Handler(void); -#endif /* CONFIG_RUNTIME_NMI */ - -/** - * @brief Perform basic hardware initialization at boot. - * - * This needs to be run from the very beginning. - */ -void soc_early_init_hook(void) -{ - SystemCoreClock = BSP_MOCO_HZ; - g_protect_pfswe_counter = 0; - - extern volatile uint16_t g_protect_counters[]; - - for (uint32_t i = 0; i < 5; i++) { - g_protect_counters[i] = 0; - } - - SystemCoreClock = BSP_MOCO_HZ; - -#ifdef CONFIG_RUNTIME_NMI - for (uint32_t i = 0; i < 16; i++) { - g_bsp_group_irq_sources[i] = 0; - } - - z_arm_nmi_set_handler(NMI_Handler); -#endif /* CONFIG_RUNTIME_NMI */ - -#ifdef CONFIG_CPU_CORTEX_M85 -#ifdef CONFIG_ICACHE - SCB->CCR = (uint32_t)CCR_CACHE_ENABLE; - barrier_dsync_fence_full(); - barrier_isync_fence_full(); -#endif -#if defined(CONFIG_DCACHE) && defined(CONFIG_CACHE_MANAGEMENT) - /* Apply Arm Cortex-M85 errata workarounds for D-Cache - * Attributing all cacheable memory as write-through set FORCEWT bit in MSCR register. - * Set bit 16 in ACTLR to 1. - * See erratum 3175626 and 3190818 in the Cortex-M85 AT640 and Cortex-M85 with FPU AT641 - * Software Developer Errata Notice (Date of issue: March 07, 2024, Document version: 13.0, - * Document ID: SDEN-2236668). - */ - MEMSYSCTL->MSCR |= MEMSYSCTL_MSCR_FORCEWT_Msk; - barrier_dsync_fence_full(); - barrier_isync_fence_full(); - ICB->ACTLR |= (1U << 16U); - barrier_dsync_fence_full(); - barrier_isync_fence_full(); - - sys_cache_data_enable(); -#endif -#endif /*CONFIG_CPU_CORTEX_M85*/ - -#ifdef CONFIG_CPU_CORTEX_M33 -#if FSP_PRIV_TZ_USE_SECURE_REGS - /* Disable protection using PRCR register. */ - R_BSP_RegisterProtectDisable(BSP_REG_PROTECT_SAR); - - /* Initialize peripherals to secure mode for flat projects */ - R_PSCU->PSARB = 0; - R_PSCU->PSARC = 0; - R_PSCU->PSARD = 0; - R_PSCU->PSARE = 0; - - R_CPSCU->ICUSARG = 0; - R_CPSCU->ICUSARH = 0; - R_CPSCU->ICUSARI = 0; - - /* Enable protection using PRCR register. */ - R_BSP_RegisterProtectEnable(BSP_REG_PROTECT_SAR); -#endif -#endif /*CONFIG_CPU_CORTEX_M33*/ -} diff --git a/soc/renesas/ra/ra8m1/CMakeLists.txt b/soc/renesas/ra/ra8m1/CMakeLists.txt index 8550175d0e02..c4f9ce84c8ae 100644 --- a/soc/renesas/ra/ra8m1/CMakeLists.txt +++ b/soc/renesas/ra/ra8m1/CMakeLists.txt @@ -3,10 +3,6 @@ zephyr_include_directories(.) -zephyr_sources( - soc.c -) - zephyr_sources_ifdef(CONFIG_PM power.c ) @@ -45,11 +41,6 @@ if(CONFIG_CMAKE_LINKER_GENERATOR) dt_node_has_status(banksel_sel_status PATH ${option_setting_banksel_sel} STATUS okay) dt_node_has_status(bps_sel_status PATH ${option_setting_bps_sel} STATUS okay) - if(CONFIG_USE_RA_FSP_DTC) - zephyr_linker_section(NAME .fsp_dtc_vector_table GROUP RAM) - zephyr_linker_section_configure(SECTION .fsp_dtc_vector_table KEEP INPUT ".fsp_dtc_vector_table*") - endif() - if(${ofs0_status}) zephyr_linker_section(NAME .option_setting_ofs0 GROUP OFS_OFS0_MEMORY ADDRESS ${ofs0_addr}) zephyr_linker_section_configure(SECTION .option_setting_ofs0 KEEP INPUT ".option_setting_ofs0*") @@ -102,10 +93,7 @@ if(CONFIG_CMAKE_LINKER_GENERATOR) elseif(CONFIG_LD_LINKER_TEMPLATE) zephyr_linker_sources(SECTIONS sections.ld) - zephyr_linker_sources(RAM_SECTIONS ram_sections.ld) else() message(WARNING "Unsupported linker template.") endif() - -set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "") diff --git a/soc/renesas/ra/ra8m1/Kconfig b/soc/renesas/ra/ra8m1/Kconfig index 2b6813522a9d..32c46cba64e9 100644 --- a/soc/renesas/ra/ra8m1/Kconfig +++ b/soc/renesas/ra/ra8m1/Kconfig @@ -13,7 +13,6 @@ config SOC_SERIES_RA8M1 select XIP select CLOCK_CONTROL_RENESAS_RA_CGC if CLOCK_CONTROL select HAS_RENESAS_RA_FSP - select SOC_EARLY_INIT_HOOK select GPIO_RA_HAS_VBTICTLR select HAS_PM help diff --git a/soc/renesas/ra/ra8m1/ram_sections.ld b/soc/renesas/ra/ra8m1/ram_sections.ld deleted file mode 100644 index 18be2a431de2..000000000000 --- a/soc/renesas/ra/ra8m1/ram_sections.ld +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright (c) 2025 Renesas Electronics Corporation - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include - -#ifdef CONFIG_USE_RA_FSP_DTC -SECTION_DATA_PROLOGUE(.fsp_dtc_vector_table,(NOLOAD),) -{ - /* If DTC is used, put the DTC vector table at the start of SRAM. - This avoids memory holes due to 1K alignment required by it. */ - *(.fsp_dtc_vector_table) -} GROUP_DATA_LINK_IN(RAMABLE_REGION, RAMABLE_REGION) -#endif /* CONFIG_USE_RA_FSP_DTC */ diff --git a/soc/renesas/ra/ra8m1/soc.c b/soc/renesas/ra/ra8m1/soc.c deleted file mode 100644 index 35bafdbdfafd..000000000000 --- a/soc/renesas/ra/ra8m1/soc.c +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright (c) 2024 Renesas Electronics Corporation - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/** - * @file - * @brief System/hardware module for Renesas RA8M1 family processor - */ - -#include -#include -#include -#include -#include -#include -#include -#include -LOG_MODULE_REGISTER(soc, CONFIG_SOC_LOG_LEVEL); - -#include - -uint32_t SystemCoreClock BSP_SECTION_EARLY_INIT; - -volatile uint32_t g_protect_pfswe_counter BSP_SECTION_EARLY_INIT; - -#ifdef CONFIG_RUNTIME_NMI -extern bsp_grp_irq_cb_t g_bsp_group_irq_sources[]; -extern void NMI_Handler(void); -#endif /* CONFIG_RUNTIME_NMI */ - -/** - * @brief Perform basic hardware initialization at boot. - * - * This needs to be run from the very beginning. - */ -void soc_early_init_hook(void) -{ - SystemCoreClock = BSP_MOCO_HZ; - g_protect_pfswe_counter = 0; - -#ifdef CONFIG_RUNTIME_NMI - for (uint32_t i = 0; i < 16; i++) { - g_bsp_group_irq_sources[i] = 0; - } - - z_arm_nmi_set_handler(NMI_Handler); -#endif /* CONFIG_RUNTIME_NMI */ - - cold_start_handler(); -} diff --git a/soc/renesas/ra/ra8m1/soc.h b/soc/renesas/ra/ra8m1/soc.h deleted file mode 100644 index 1d817c563dc9..000000000000 --- a/soc/renesas/ra/ra8m1/soc.h +++ /dev/null @@ -1,17 +0,0 @@ -/* - * Copyright (c) 2024-2025 Renesas Electronics Corporation - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/** - * @file SoC configuration macros for the Renesas RA8M1 family MCU - */ - -#ifndef ZEPHYR_SOC_RENESAS_RA8M1_SOC_H_ -#define ZEPHYR_SOC_RENESAS_RA8M1_SOC_H_ - -#include -#include - -#endif /* ZEPHYR_SOC_RENESAS_RA8M1_SOC_H_ */ diff --git a/soc/renesas/ra/ra8m2/CMakeLists.txt b/soc/renesas/ra/ra8m2/CMakeLists.txt index 2e8d68f94cd9..1542927b73be 100644 --- a/soc/renesas/ra/ra8m2/CMakeLists.txt +++ b/soc/renesas/ra/ra8m2/CMakeLists.txt @@ -3,20 +3,11 @@ zephyr_include_directories(.) -zephyr_sources( - soc.c -) - zephyr_sources_ifdef(CONFIG_PM power.c ) if(CONFIG_CMAKE_LINKER_GENERATOR) - if(CONFIG_USE_RA_FSP_DTC) - zephyr_linker_section(NAME .fsp_dtc_vector_table GROUP RAM) - zephyr_linker_section_configure(SECTION .fsp_dtc_vector_table KEEP INPUT ".fsp_dtc_vector_table*") - endif() - if((NOT CONFIG_BOOTLOADER_MCUBOOT) AND (NOT CONFIG_SOC_RA_SECOND_CORE_BUILD)) dt_nodelabel(option_setting_ofs0 NODELABEL "option_setting_ofs0") dt_nodelabel(option_setting_ofs2 NODELABEL "option_setting_ofs2") @@ -98,10 +89,7 @@ elseif(CONFIG_LD_LINKER_TEMPLATE) if((NOT CONFIG_BOOTLOADER_MCUBOOT) AND (NOT CONFIG_SOC_RA_SECOND_CORE_BUILD)) zephyr_linker_sources(SECTIONS sections.ld) endif() - zephyr_linker_sources(RAM_SECTIONS ram_sections.ld) else() message(WARNING "Unsupported linker template.") endif() - -set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "") diff --git a/soc/renesas/ra/ra8m2/Kconfig b/soc/renesas/ra/ra8m2/Kconfig index 8a22472a6755..f98f8bed1fe0 100644 --- a/soc/renesas/ra/ra8m2/Kconfig +++ b/soc/renesas/ra/ra8m2/Kconfig @@ -13,7 +13,6 @@ config SOC_SERIES_RA8M2 select XIP select CLOCK_CONTROL_RENESAS_RA_CGC if CLOCK_CONTROL select HAS_RENESAS_RA_FSP - select SOC_EARLY_INIT_HOOK select HAS_PM config SOC_R7KA8M2JFLCAC_CM85 diff --git a/soc/renesas/ra/ra8m2/ram_sections.ld b/soc/renesas/ra/ra8m2/ram_sections.ld deleted file mode 100644 index 18be2a431de2..000000000000 --- a/soc/renesas/ra/ra8m2/ram_sections.ld +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright (c) 2025 Renesas Electronics Corporation - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include - -#ifdef CONFIG_USE_RA_FSP_DTC -SECTION_DATA_PROLOGUE(.fsp_dtc_vector_table,(NOLOAD),) -{ - /* If DTC is used, put the DTC vector table at the start of SRAM. - This avoids memory holes due to 1K alignment required by it. */ - *(.fsp_dtc_vector_table) -} GROUP_DATA_LINK_IN(RAMABLE_REGION, RAMABLE_REGION) -#endif /* CONFIG_USE_RA_FSP_DTC */ diff --git a/soc/renesas/ra/ra8m2/soc.c b/soc/renesas/ra/ra8m2/soc.c deleted file mode 100644 index db67c004f9e3..000000000000 --- a/soc/renesas/ra/ra8m2/soc.c +++ /dev/null @@ -1,106 +0,0 @@ -/* - * Copyright (c) 2025 Renesas Electronics Corporation - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/** - * @file - * @brief System/hardware module for Renesas RA8M2 family processor - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -LOG_MODULE_REGISTER(soc, CONFIG_SOC_LOG_LEVEL); - -#include "soc.h" - -#define CCR_CACHE_ENABLE (SCB_CCR_IC_Msk | SCB_CCR_BP_Msk | SCB_CCR_LOB_Msk) - -uint32_t SystemCoreClock BSP_SECTION_EARLY_INIT; - -volatile uint32_t g_protect_pfswe_counter BSP_SECTION_EARLY_INIT; - -#ifdef CONFIG_RUNTIME_NMI -extern bsp_grp_irq_cb_t g_bsp_group_irq_sources[]; -extern void NMI_Handler(void); -#endif /* CONFIG_RUNTIME_NMI */ - -/** - * @brief Perform basic hardware initialization at boot. - * - * This needs to be run from the very beginning. - */ -void soc_early_init_hook(void) -{ - SystemCoreClock = BSP_MOCO_HZ; - g_protect_pfswe_counter = 0; - - extern volatile uint16_t g_protect_counters[]; - - for (uint32_t i = 0; i < 5; i++) { - g_protect_counters[i] = 0; - } - - SystemCoreClock = BSP_MOCO_HZ; - -#ifdef CONFIG_RUNTIME_NMI - for (uint32_t i = 0; i < 16; i++) { - g_bsp_group_irq_sources[i] = 0; - } - - z_arm_nmi_set_handler(NMI_Handler); -#endif /* CONFIG_RUNTIME_NMI */ - -#ifdef CONFIG_CPU_CORTEX_M85 -#ifdef CONFIG_ICACHE - SCB->CCR = (uint32_t)CCR_CACHE_ENABLE; - barrier_dsync_fence_full(); - barrier_isync_fence_full(); -#endif -#if defined(CONFIG_DCACHE) && defined(CONFIG_CACHE_MANAGEMENT) - /* Apply Arm Cortex-M85 errata workarounds for D-Cache - * Attributing all cacheable memory as write-through set FORCEWT bit in MSCR register. - * Set bit 16 in ACTLR to 1. - * See erratum 3175626 and 3190818 in the Cortex-M85 AT640 and Cortex-M85 with FPU AT641 - * Software Developer Errata Notice (Date of issue: March 07, 2024, Document version: 13.0, - * Document ID: SDEN-2236668). - */ - MEMSYSCTL->MSCR |= MEMSYSCTL_MSCR_FORCEWT_Msk; - barrier_dsync_fence_full(); - barrier_isync_fence_full(); - ICB->ACTLR |= (1U << 16U); - barrier_dsync_fence_full(); - barrier_isync_fence_full(); - - sys_cache_data_enable(); -#endif -#endif /*CONFIG_CPU_CORTEX_M85*/ - -#ifdef CONFIG_CPU_CORTEX_M33 -#if FSP_PRIV_TZ_USE_SECURE_REGS - /* Disable protection using PRCR register. */ - R_BSP_RegisterProtectDisable(BSP_REG_PROTECT_SAR); - - /* Initialize peripherals to secure mode for flat projects */ - R_PSCU->PSARB = 0; - R_PSCU->PSARC = 0; - R_PSCU->PSARD = 0; - R_PSCU->PSARE = 0; - - R_CPSCU->ICUSARG = 0; - R_CPSCU->ICUSARH = 0; - R_CPSCU->ICUSARI = 0; - - /* Enable protection using PRCR register. */ - R_BSP_RegisterProtectEnable(BSP_REG_PROTECT_SAR); -#endif -#endif /*CONFIG_CPU_CORTEX_M33*/ -} diff --git a/soc/renesas/ra/ra8m2/soc.h b/soc/renesas/ra/ra8m2/soc.h deleted file mode 100644 index a494b8509f69..000000000000 --- a/soc/renesas/ra/ra8m2/soc.h +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright (c) 2025 Renesas Electronics Corporation - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/** - * @file SoC configuration macros for the Renesas RA8M2 family MCU - */ - -#ifndef ZEPHYR_SOC_RENESAS_RA8M2_SOC_H_ -#define ZEPHYR_SOC_RENESAS_RA8M2_SOC_H_ - -#include - -#endif /* ZEPHYR_SOC_RENESAS_RA8M2_SOC_H_ */ diff --git a/soc/renesas/ra/ra8p1/CMakeLists.txt b/soc/renesas/ra/ra8p1/CMakeLists.txt index 2e8d68f94cd9..0a65a484afac 100644 --- a/soc/renesas/ra/ra8p1/CMakeLists.txt +++ b/soc/renesas/ra/ra8p1/CMakeLists.txt @@ -3,20 +3,11 @@ zephyr_include_directories(.) -zephyr_sources( - soc.c -) - zephyr_sources_ifdef(CONFIG_PM power.c ) if(CONFIG_CMAKE_LINKER_GENERATOR) - if(CONFIG_USE_RA_FSP_DTC) - zephyr_linker_section(NAME .fsp_dtc_vector_table GROUP RAM) - zephyr_linker_section_configure(SECTION .fsp_dtc_vector_table KEEP INPUT ".fsp_dtc_vector_table*") - endif() - if((NOT CONFIG_BOOTLOADER_MCUBOOT) AND (NOT CONFIG_SOC_RA_SECOND_CORE_BUILD)) dt_nodelabel(option_setting_ofs0 NODELABEL "option_setting_ofs0") dt_nodelabel(option_setting_ofs2 NODELABEL "option_setting_ofs2") @@ -98,7 +89,6 @@ elseif(CONFIG_LD_LINKER_TEMPLATE) if((NOT CONFIG_BOOTLOADER_MCUBOOT) AND (NOT CONFIG_SOC_RA_SECOND_CORE_BUILD)) zephyr_linker_sources(SECTIONS sections.ld) endif() - zephyr_linker_sources(RAM_SECTIONS ram_sections.ld) else() message(WARNING "Unsupported linker template.") diff --git a/soc/renesas/ra/ra8p1/Kconfig b/soc/renesas/ra/ra8p1/Kconfig index 9ecd8df9ab95..1e2f7a503c70 100644 --- a/soc/renesas/ra/ra8p1/Kconfig +++ b/soc/renesas/ra/ra8p1/Kconfig @@ -14,7 +14,6 @@ config SOC_SERIES_RA8P1 select XIP select CLOCK_CONTROL_RENESAS_RA_CGC if CLOCK_CONTROL select HAS_RENESAS_RA_FSP - select SOC_EARLY_INIT_HOOK select HAS_PM config SOC_R7KA8P1KFLCAC_CM85 diff --git a/soc/renesas/ra/ra8p1/ram_sections.ld b/soc/renesas/ra/ra8p1/ram_sections.ld deleted file mode 100644 index 18be2a431de2..000000000000 --- a/soc/renesas/ra/ra8p1/ram_sections.ld +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright (c) 2025 Renesas Electronics Corporation - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include - -#ifdef CONFIG_USE_RA_FSP_DTC -SECTION_DATA_PROLOGUE(.fsp_dtc_vector_table,(NOLOAD),) -{ - /* If DTC is used, put the DTC vector table at the start of SRAM. - This avoids memory holes due to 1K alignment required by it. */ - *(.fsp_dtc_vector_table) -} GROUP_DATA_LINK_IN(RAMABLE_REGION, RAMABLE_REGION) -#endif /* CONFIG_USE_RA_FSP_DTC */ diff --git a/soc/renesas/ra/ra8p1/soc.c b/soc/renesas/ra/ra8p1/soc.c deleted file mode 100644 index d0589daba0e4..000000000000 --- a/soc/renesas/ra/ra8p1/soc.c +++ /dev/null @@ -1,119 +0,0 @@ -/* - * Copyright (c) 2025 Renesas Electronics Corporation - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/** - * @file - * @brief System/hardware module for Renesas RA8P1 family processor - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -LOG_MODULE_REGISTER(soc, CONFIG_SOC_LOG_LEVEL); - -#include - -#define CCR_CACHE_ENABLE (SCB_CCR_IC_Msk | SCB_CCR_BP_Msk | SCB_CCR_LOB_Msk) - -uint32_t SystemCoreClock BSP_SECTION_EARLY_INIT; - -volatile uint32_t g_protect_pfswe_counter BSP_SECTION_EARLY_INIT; - -#ifdef CONFIG_RUNTIME_NMI -extern bsp_grp_irq_cb_t g_bsp_group_irq_sources[]; -extern void NMI_Handler(void); -#endif /* CONFIG_RUNTIME_NMI */ - -extern void cold_start_handler(void); - -/** - * @brief Perform basic hardware initialization at boot. - * - * This needs to be run from the very beginning. - */ -void soc_early_init_hook(void) -{ - SystemCoreClock = BSP_MOCO_HZ; - g_protect_pfswe_counter = 0; - - extern volatile uint16_t g_protect_counters[]; - - for (uint32_t i = 0; i < 5; i++) { - g_protect_counters[i] = 0; - } - - SystemCoreClock = BSP_MOCO_HZ; - -#ifdef CONFIG_CPU_CORTEX_M85 -#ifdef CONFIG_ICACHE - SCB->CCR = (uint32_t)CCR_CACHE_ENABLE; - barrier_dsync_fence_full(); - barrier_isync_fence_full(); -#endif -#if defined(CONFIG_DCACHE) && defined(CONFIG_CACHE_MANAGEMENT) - /* Apply Arm Cortex-M85 errata workarounds for D-Cache - * Attributing all cacheable memory as write-through set FORCEWT bit in MSCR register. - * Set bit 16 in ACTLR to 1. - * See erratum 3175626 and 3190818 in the Cortex-M85 AT640 and Cortex-M85 with FPU AT641 - * Software Developer Errata Notice (Date of issue: March 07, 2024, Document version: 13.0, - * Document ID: SDEN-2236668). - */ - MEMSYSCTL->MSCR |= MEMSYSCTL_MSCR_FORCEWT_Msk; - barrier_dsync_fence_full(); - barrier_isync_fence_full(); - ICB->ACTLR |= (1U << 16U); - barrier_dsync_fence_full(); - barrier_isync_fence_full(); - - sys_cache_data_enable(); -#endif - -#endif /*CONFIG_CPU_CORTEX_M85*/ - -#ifdef CONFIG_CPU_CORTEX_M33 -#if FSP_PRIV_TZ_USE_SECURE_REGS - /* Disable protection using PRCR register. */ - R_BSP_RegisterProtectDisable(BSP_REG_PROTECT_SAR); - - /* Initialize peripherals to secure mode for flat projects */ - R_PSCU->PSARB = 0; - R_PSCU->PSARC = 0; - R_PSCU->PSARD = 0; - R_PSCU->PSARE = 0; - - R_CPSCU->ICUSARG = 0; - R_CPSCU->ICUSARH = 0; - R_CPSCU->ICUSARI = 0; - - /* Enable protection using PRCR register. */ - R_BSP_RegisterProtectEnable(BSP_REG_PROTECT_SAR); -#endif -#endif /*CONFIG_CPU_CORTEX_M33*/ -#ifdef CONFIG_RUNTIME_NMI - for (uint32_t i = 0; i < 16; i++) { - g_bsp_group_irq_sources[i] = 0; - } - - z_arm_nmi_set_handler(NMI_Handler); -#endif /* CONFIG_RUNTIME_NMI */ - - cold_start_handler(); -} - -#ifdef CONFIG_SOC_LATE_INIT_HOOK -void soc_late_init_hook(void) -{ -#ifdef CONFIG_SOC_RA_ENABLE_START_SECOND_CORE - R_BSP_SecondaryCoreStart(); -#endif /* CONFIG_SOC_RA_ENABLE_START_SECOND_CORE */ -} -#endif /* CONFIG_SOC_LATE_INIT_HOOK */ diff --git a/soc/renesas/ra/ra8p1/soc.h b/soc/renesas/ra/ra8p1/soc.h deleted file mode 100644 index 56172f7de5a0..000000000000 --- a/soc/renesas/ra/ra8p1/soc.h +++ /dev/null @@ -1,17 +0,0 @@ -/* - * Copyright (c) 2025 Renesas Electronics Corporation - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/** - * @file SoC configuration macros for the Renesas RA8P1 family MCU - */ - -#ifndef ZEPHYR_SOC_RENESAS_RA8P1_SOC_H_ -#define ZEPHYR_SOC_RENESAS_RA8P1_SOC_H_ - -#include -#include - -#endif /* ZEPHYR_SOC_RENESAS_RA8P1_SOC_H_ */ diff --git a/soc/renesas/ra/ra8t1/CMakeLists.txt b/soc/renesas/ra/ra8t1/CMakeLists.txt index 8550175d0e02..c4f9ce84c8ae 100644 --- a/soc/renesas/ra/ra8t1/CMakeLists.txt +++ b/soc/renesas/ra/ra8t1/CMakeLists.txt @@ -3,10 +3,6 @@ zephyr_include_directories(.) -zephyr_sources( - soc.c -) - zephyr_sources_ifdef(CONFIG_PM power.c ) @@ -45,11 +41,6 @@ if(CONFIG_CMAKE_LINKER_GENERATOR) dt_node_has_status(banksel_sel_status PATH ${option_setting_banksel_sel} STATUS okay) dt_node_has_status(bps_sel_status PATH ${option_setting_bps_sel} STATUS okay) - if(CONFIG_USE_RA_FSP_DTC) - zephyr_linker_section(NAME .fsp_dtc_vector_table GROUP RAM) - zephyr_linker_section_configure(SECTION .fsp_dtc_vector_table KEEP INPUT ".fsp_dtc_vector_table*") - endif() - if(${ofs0_status}) zephyr_linker_section(NAME .option_setting_ofs0 GROUP OFS_OFS0_MEMORY ADDRESS ${ofs0_addr}) zephyr_linker_section_configure(SECTION .option_setting_ofs0 KEEP INPUT ".option_setting_ofs0*") @@ -102,10 +93,7 @@ if(CONFIG_CMAKE_LINKER_GENERATOR) elseif(CONFIG_LD_LINKER_TEMPLATE) zephyr_linker_sources(SECTIONS sections.ld) - zephyr_linker_sources(RAM_SECTIONS ram_sections.ld) else() message(WARNING "Unsupported linker template.") endif() - -set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "") diff --git a/soc/renesas/ra/ra8t1/Kconfig b/soc/renesas/ra/ra8t1/Kconfig index ba1825598171..d84b81bf8172 100644 --- a/soc/renesas/ra/ra8t1/Kconfig +++ b/soc/renesas/ra/ra8t1/Kconfig @@ -13,7 +13,6 @@ config SOC_SERIES_RA8T1 select XIP select CLOCK_CONTROL_RENESAS_RA_CGC if CLOCK_CONTROL select HAS_RENESAS_RA_FSP - select SOC_EARLY_INIT_HOOK select GPIO_RA_HAS_VBTICTLR select HAS_PM diff --git a/soc/renesas/ra/ra8t1/ram_sections.ld b/soc/renesas/ra/ra8t1/ram_sections.ld deleted file mode 100644 index 18be2a431de2..000000000000 --- a/soc/renesas/ra/ra8t1/ram_sections.ld +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright (c) 2025 Renesas Electronics Corporation - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include - -#ifdef CONFIG_USE_RA_FSP_DTC -SECTION_DATA_PROLOGUE(.fsp_dtc_vector_table,(NOLOAD),) -{ - /* If DTC is used, put the DTC vector table at the start of SRAM. - This avoids memory holes due to 1K alignment required by it. */ - *(.fsp_dtc_vector_table) -} GROUP_DATA_LINK_IN(RAMABLE_REGION, RAMABLE_REGION) -#endif /* CONFIG_USE_RA_FSP_DTC */ diff --git a/soc/renesas/ra/ra8t1/soc.c b/soc/renesas/ra/ra8t1/soc.c deleted file mode 100644 index 3c02a1cae0bb..000000000000 --- a/soc/renesas/ra/ra8t1/soc.c +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright (c) 2024 Renesas Electronics Corporation - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/** - * @file - * @brief System/hardware module for Renesas RA8T1 family processor - */ - -#include -#include -#include -#include -#include -#include -#include -#include -LOG_MODULE_REGISTER(soc, CONFIG_SOC_LOG_LEVEL); - -#include - -uint32_t SystemCoreClock BSP_SECTION_EARLY_INIT; - -volatile uint32_t g_protect_pfswe_counter BSP_SECTION_EARLY_INIT; - -#ifdef CONFIG_RUNTIME_NMI -extern bsp_grp_irq_cb_t g_bsp_group_irq_sources[]; -extern void NMI_Handler(void); -#endif /* CONFIG_RUNTIME_NMI */ - -/** - * @brief Perform basic hardware initialization at boot. - * - * This needs to be run from the very beginning. - */ -void soc_early_init_hook(void) -{ - SystemCoreClock = BSP_MOCO_HZ; - g_protect_pfswe_counter = 0; - -#ifdef CONFIG_RUNTIME_NMI - for (uint32_t i = 0; i < 16; i++) { - g_bsp_group_irq_sources[i] = 0; - } - - z_arm_nmi_set_handler(NMI_Handler); -#endif /* CONFIG_RUNTIME_NMI */ -} diff --git a/soc/renesas/ra/ra8t1/soc.h b/soc/renesas/ra/ra8t1/soc.h deleted file mode 100644 index 3160d3eb80bc..000000000000 --- a/soc/renesas/ra/ra8t1/soc.h +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright (c) 2024 Renesas Electronics Corporation - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/** - * @file SoC configuration macros for the Renesas RA8T1 family MCU - */ - -#ifndef ZEPHYR_SOC_RENESAS_RA8T1_SOC_H_ -#define ZEPHYR_SOC_RENESAS_RA8T1_SOC_H_ - -#include - -#endif /* ZEPHYR_SOC_RENESAS_RA8T1_SOC_H_ */ diff --git a/soc/renesas/ra/ra8t2/CMakeLists.txt b/soc/renesas/ra/ra8t2/CMakeLists.txt index 2e8d68f94cd9..1542927b73be 100644 --- a/soc/renesas/ra/ra8t2/CMakeLists.txt +++ b/soc/renesas/ra/ra8t2/CMakeLists.txt @@ -3,20 +3,11 @@ zephyr_include_directories(.) -zephyr_sources( - soc.c -) - zephyr_sources_ifdef(CONFIG_PM power.c ) if(CONFIG_CMAKE_LINKER_GENERATOR) - if(CONFIG_USE_RA_FSP_DTC) - zephyr_linker_section(NAME .fsp_dtc_vector_table GROUP RAM) - zephyr_linker_section_configure(SECTION .fsp_dtc_vector_table KEEP INPUT ".fsp_dtc_vector_table*") - endif() - if((NOT CONFIG_BOOTLOADER_MCUBOOT) AND (NOT CONFIG_SOC_RA_SECOND_CORE_BUILD)) dt_nodelabel(option_setting_ofs0 NODELABEL "option_setting_ofs0") dt_nodelabel(option_setting_ofs2 NODELABEL "option_setting_ofs2") @@ -98,10 +89,7 @@ elseif(CONFIG_LD_LINKER_TEMPLATE) if((NOT CONFIG_BOOTLOADER_MCUBOOT) AND (NOT CONFIG_SOC_RA_SECOND_CORE_BUILD)) zephyr_linker_sources(SECTIONS sections.ld) endif() - zephyr_linker_sources(RAM_SECTIONS ram_sections.ld) else() message(WARNING "Unsupported linker template.") endif() - -set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "") diff --git a/soc/renesas/ra/ra8t2/Kconfig b/soc/renesas/ra/ra8t2/Kconfig index ae5d44d29a1a..af68f3e14b28 100644 --- a/soc/renesas/ra/ra8t2/Kconfig +++ b/soc/renesas/ra/ra8t2/Kconfig @@ -13,7 +13,6 @@ config SOC_SERIES_RA8T2 select XIP select CLOCK_CONTROL_RENESAS_RA_CGC if CLOCK_CONTROL select HAS_RENESAS_RA_FSP - select SOC_EARLY_INIT_HOOK select HAS_PM config SOC_R7KA8T2LFLCAC_CM85 diff --git a/soc/renesas/ra/ra8t2/ram_sections.ld b/soc/renesas/ra/ra8t2/ram_sections.ld deleted file mode 100644 index 18be2a431de2..000000000000 --- a/soc/renesas/ra/ra8t2/ram_sections.ld +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright (c) 2025 Renesas Electronics Corporation - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include - -#ifdef CONFIG_USE_RA_FSP_DTC -SECTION_DATA_PROLOGUE(.fsp_dtc_vector_table,(NOLOAD),) -{ - /* If DTC is used, put the DTC vector table at the start of SRAM. - This avoids memory holes due to 1K alignment required by it. */ - *(.fsp_dtc_vector_table) -} GROUP_DATA_LINK_IN(RAMABLE_REGION, RAMABLE_REGION) -#endif /* CONFIG_USE_RA_FSP_DTC */ diff --git a/soc/renesas/ra/ra8t2/soc.c b/soc/renesas/ra/ra8t2/soc.c deleted file mode 100644 index bff383e9585d..000000000000 --- a/soc/renesas/ra/ra8t2/soc.c +++ /dev/null @@ -1,93 +0,0 @@ -/* - * Copyright (c) 2025 Renesas Electronics Corporation - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/** - * @file - * @brief System/hardware module for Renesas RA8T2 family processor - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -LOG_MODULE_REGISTER(soc, CONFIG_SOC_LOG_LEVEL); - -#include "soc.h" - -#define CCR_CACHE_ENABLE (SCB_CCR_IC_Msk | SCB_CCR_BP_Msk | SCB_CCR_LOB_Msk) - -uint32_t SystemCoreClock BSP_SECTION_EARLY_INIT; - -volatile uint32_t g_protect_pfswe_counter BSP_SECTION_EARLY_INIT; - -/** - * @brief Perform basic hardware initialization at boot. - * - * This needs to be run from the very beginning. - */ -void soc_early_init_hook(void) -{ - SystemCoreClock = BSP_MOCO_HZ; - g_protect_pfswe_counter = 0; - - extern volatile uint16_t g_protect_counters[]; - - for (uint32_t i = 0; i < 5; i++) { - g_protect_counters[i] = 0; - } - - SystemCoreClock = BSP_MOCO_HZ; - -#ifdef CONFIG_CPU_CORTEX_M85 -#ifdef CONFIG_ICACHE - SCB->CCR = (uint32_t)CCR_CACHE_ENABLE; - barrier_dsync_fence_full(); - barrier_isync_fence_full(); -#endif -#if defined(CONFIG_DCACHE) && defined(CONFIG_CACHE_MANAGEMENT) - /* Apply Arm Cortex-M85 errata workarounds for D-Cache - * Attributing all cacheable memory as write-through set FORCEWT bit in MSCR register. - * Set bit 16 in ACTLR to 1. - * See erratum 3175626 and 3190818 in the Cortex-M85 AT640 and Cortex-M85 with FPU AT641 - * Software Developer Errata Notice (Date of issue: March 07, 2024, Document version: 13.0, - * Document ID: SDEN-2236668). - */ - MEMSYSCTL->MSCR |= MEMSYSCTL_MSCR_FORCEWT_Msk; - barrier_dsync_fence_full(); - barrier_isync_fence_full(); - ICB->ACTLR |= (1U << 16U); - barrier_dsync_fence_full(); - barrier_isync_fence_full(); - - sys_cache_data_enable(); -#endif -#endif /*CONFIG_CPU_CORTEX_M85*/ - -#ifdef CONFIG_CPU_CORTEX_M33 -#if FSP_PRIV_TZ_USE_SECURE_REGS - /* Disable protection using PRCR register. */ - R_BSP_RegisterProtectDisable(BSP_REG_PROTECT_SAR); - - /* Initialize peripherals to secure mode for flat projects */ - R_PSCU->PSARB = 0; - R_PSCU->PSARC = 0; - R_PSCU->PSARD = 0; - R_PSCU->PSARE = 0; - - R_CPSCU->ICUSARG = 0; - R_CPSCU->ICUSARH = 0; - R_CPSCU->ICUSARI = 0; - - /* Enable protection using PRCR register. */ - R_BSP_RegisterProtectEnable(BSP_REG_PROTECT_SAR); -#endif -#endif /*CONFIG_CPU_CORTEX_M33*/ -} diff --git a/soc/renesas/ra/ra8t2/soc.h b/soc/renesas/ra/ra8t2/soc.h deleted file mode 100644 index 86e5781b6a15..000000000000 --- a/soc/renesas/ra/ra8t2/soc.h +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright (c) 2025 Renesas Electronics Corporation - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/** - * @file SoC configuration macros for the Renesas RA8P1 family MCU - */ - -#ifndef ZEPHYR_SOC_RENESAS_RA8T2_SOC_H_ -#define ZEPHYR_SOC_RENESAS_RA8T2_SOC_H_ - -#include - -#endif /* ZEPHYR_SOC_RENESAS_RA8T2_SOC_H_ */ From d8c1333295f9913d7361f71d55e4a3b3c4a75eea Mon Sep 17 00:00:00 2001 From: Khoa Tran Date: Thu, 27 Nov 2025 13:55:45 +0700 Subject: [PATCH 0130/6328] boards: renesas: Disable sub-clock for boards lacking a crystal This commit disables the sub-clock node for boards without a populated onboard crystal. Signed-off-by: Khoa Tran --- boards/renesas/ek_ra4w1/ek_ra4w1.dts | 4 ---- boards/renesas/fpb_ra6e1/fpb_ra6e1.dts | 4 ---- boards/renesas/mck_ra8t1/mck_ra8t1.dts | 4 ---- boards/renesas/mck_ra8t2/mck_ra8t2.dtsi | 4 ---- 4 files changed, 16 deletions(-) diff --git a/boards/renesas/ek_ra4w1/ek_ra4w1.dts b/boards/renesas/ek_ra4w1/ek_ra4w1.dts index 856d0e983dfc..9b3d6cff463b 100644 --- a/boards/renesas/ek_ra4w1/ek_ra4w1.dts +++ b/boards/renesas/ek_ra4w1/ek_ra4w1.dts @@ -56,10 +56,6 @@ }; }; -&subclk { - status = "okay"; -}; - &sci0 { pinctrl-0 = <&sci0_default>; pinctrl-names = "default"; diff --git a/boards/renesas/fpb_ra6e1/fpb_ra6e1.dts b/boards/renesas/fpb_ra6e1/fpb_ra6e1.dts index 61a1bc73235c..9e28a6925ff0 100644 --- a/boards/renesas/fpb_ra6e1/fpb_ra6e1.dts +++ b/boards/renesas/fpb_ra6e1/fpb_ra6e1.dts @@ -93,10 +93,6 @@ status = "okay"; }; -&subclk { - status = "okay"; -}; - &pll { clocks = <&hoco>; div = <2>; diff --git a/boards/renesas/mck_ra8t1/mck_ra8t1.dts b/boards/renesas/mck_ra8t1/mck_ra8t1.dts index 90528485d355..f3a1bb84f21a 100644 --- a/boards/renesas/mck_ra8t1/mck_ra8t1.dts +++ b/boards/renesas/mck_ra8t1/mck_ra8t1.dts @@ -63,10 +63,6 @@ status = "okay"; }; -&subclk { - status = "okay"; -}; - &pll { status = "okay"; diff --git a/boards/renesas/mck_ra8t2/mck_ra8t2.dtsi b/boards/renesas/mck_ra8t2/mck_ra8t2.dtsi index 31a12eac7840..161dbe0d6546 100644 --- a/boards/renesas/mck_ra8t2/mck_ra8t2.dtsi +++ b/boards/renesas/mck_ra8t2/mck_ra8t2.dtsi @@ -51,10 +51,6 @@ status = "okay"; }; -&subclk { - status = "okay"; -}; - &pll { status = "okay"; From cb47fb2706f1c9676704d6adb6cd671cac00d754 Mon Sep 17 00:00:00 2001 From: The Nguyen Date: Thu, 18 Sep 2025 18:28:37 +0000 Subject: [PATCH 0131/6328] drivers: clock_control: remove clock early init for Renesas RA Remove the root clock control early initialization because it has already been done in the soc_reset_hooks() Signed-off-by: The Nguyen --- .../clock_control_renesas_ra_cgc.c | 30 ++----------------- soc/renesas/ra/Kconfig | 8 ----- 2 files changed, 2 insertions(+), 36 deletions(-) diff --git a/drivers/clock_control/clock_control_renesas_ra_cgc.c b/drivers/clock_control/clock_control_renesas_ra_cgc.c index 878b32232fe2..4b62bcc52fc5 100644 --- a/drivers/clock_control/clock_control_renesas_ra_cgc.c +++ b/drivers/clock_control/clock_control_renesas_ra_cgc.c @@ -91,29 +91,6 @@ static int clock_control_renesas_ra_get_rate(const struct device *dev, clock_con return 0; } -/** - * @brief Initializes a peripheral clock device driver - */ -static int clock_control_ra_init_pclk(const struct device *dev) -{ - ARG_UNUSED(dev); - - return 0; -} - -static int clock_control_ra_init(const struct device *dev) -{ - ARG_UNUSED(dev); - /* Call to HAL layer to initialize system clock and peripheral clock */ -#ifdef CONFIG_SOC_RA_SKIP_CLOCK_INIT - bsp_clock_freq_var_init(); - SystemCoreClockUpdate(); -#else - bsp_clock_init(); -#endif /* CONFIG_SOC_RA_SKIP_CLOCK_INIT */ - return 0; -} - static DEVICE_API(clock_control, clock_control_renesas_ra_api) = { .on = clock_control_renesas_ra_on, .off = clock_control_renesas_ra_off, @@ -127,13 +104,10 @@ static DEVICE_API(clock_control, clock_control_renesas_ra_api) = { DT_NODE_HAS_PROP(node_id, clocks), \ (RA_CGC_CLK_SRC(DT_CLOCKS_CTLR(node_id))), \ (RA_CGC_CLK_SRC(DT_CLOCKS_CTLR(DT_PARENT(node_id))))), \ - .clk_div = DT_PROP(node_id, div)}; \ - DEVICE_DT_DEFINE(node_id, &clock_control_ra_init_pclk, NULL, NULL, \ + .clk_div = DT_PROP(node_id, div)}; \ + DEVICE_DT_DEFINE(node_id, NULL, NULL, NULL, \ &node_id##_cfg, PRE_KERNEL_1, \ CONFIG_KERNEL_INIT_PRIORITY_OBJECTS, \ &clock_control_renesas_ra_api))); -DEVICE_DT_DEFINE(DT_NODELABEL(pclkblock), &clock_control_ra_init, NULL, NULL, NULL, PRE_KERNEL_1, - CONFIG_KERNEL_INIT_PRIORITY_OBJECTS, NULL); - DT_FOREACH_CHILD_STATUS_OKAY(DT_NODELABEL(pclkblock), INIT_PCLK); diff --git a/soc/renesas/ra/Kconfig b/soc/renesas/ra/Kconfig index 9f571d9f66fc..574e1db8c853 100644 --- a/soc/renesas/ra/Kconfig +++ b/soc/renesas/ra/Kconfig @@ -38,14 +38,6 @@ config SOC_RA_SECOND_CORE_BUILD help Indicates the image is built for the secondary core when enabled -config SOC_RA_SKIP_CLOCK_INIT - bool "Skip clock frequency configuration in system initialization" - depends on SOC_RA_SECOND_CORE_BUILD - default y - help - With this option, the CPU clock frequency is not set during system - initialization. - config RENESAS_RA_BATTERY_BACKUP_MANUAL_CONFIGURE bool "VBAT switching manual" default y From 0a37e1f43fc8433077a7b6ed6632022ae0c927dd Mon Sep 17 00:00:00 2001 From: Khoa Tran Date: Fri, 24 Oct 2025 09:23:26 +0700 Subject: [PATCH 0132/6328] drivers: display: update GLCDC device init flow Remove power domain on for GLCDC controller inside driver code due to it has already been done by soc_reset_hooks() Signed-off-by: Khoa Tran Signed-off-by: The Nguyen --- drivers/display/display_renesas_ra.c | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/drivers/display/display_renesas_ra.c b/drivers/display/display_renesas_ra.c index 98a79b09b6e3..39bf4085e4a7 100644 --- a/drivers/display/display_renesas_ra.c +++ b/drivers/display/display_renesas_ra.c @@ -368,20 +368,6 @@ static int display_init(const struct device *dev) struct display_ra_data *data = dev->data; int err; -#if BSP_FEATURE_BSP_HAS_GRAPHICS_DOMAIN - - R_BSP_RegisterProtectDisable(BSP_REG_PROTECT_OM_LPC_BATT); - FSP_HARDWARE_REGISTER_WAIT( - (R_SYSTEM->PDCTRGD & (R_SYSTEM_PDCTRGD_PDCSF_Msk | R_SYSTEM_PDCTRGD_PDPGSF_Msk)), - R_SYSTEM_PDCTRGD_PDPGSF_Msk); - R_SYSTEM->PDCTRGD = 0; - FSP_HARDWARE_REGISTER_WAIT( - (R_SYSTEM->PDCTRGD & (R_SYSTEM_PDCTRGD_PDCSF_Msk | R_SYSTEM_PDCTRGD_PDPGSF_Msk)), - 0); - R_BSP_RegisterProtectEnable(BSP_REG_PROTECT_OM_LPC_BATT); - -#endif - if (config->pincfg != NULL) { err = pinctrl_apply_state(config->pincfg, PINCTRL_STATE_DEFAULT); if (err) { From caf40f2581d8051d20e3227ae5721a97e48f5121 Mon Sep 17 00:00:00 2001 From: Khoa Tran Date: Wed, 29 Oct 2025 12:55:23 +0700 Subject: [PATCH 0133/6328] drivers: misc: update Renesas RA ethos_u init flow Remove the NPU power domain enabling inside ethos_u code due to it has already been done by soc_reset_hooks() Signed-off-by: Khoa Tran Signed-off-by: The Nguyen --- drivers/misc/ethos_u/ethos_u_renesas.c | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/drivers/misc/ethos_u/ethos_u_renesas.c b/drivers/misc/ethos_u/ethos_u_renesas.c index c57efc4280e4..b07819462603 100644 --- a/drivers/misc/ethos_u/ethos_u_renesas.c +++ b/drivers/misc/ethos_u/ethos_u_renesas.c @@ -55,21 +55,6 @@ static int ethos_u_renesas_ra_init(const struct device *dev) return err; } - if ((((0 == R_SYSTEM->PGCSAR_b.NONSEC2) && FSP_PRIV_TZ_USE_SECURE_REGS) || - ((1 == R_SYSTEM->PGCSAR_b.NONSEC2) && BSP_TZ_NONSECURE_BUILD)) && - (0 != R_SYSTEM->PDCTRNPU)) { - /* Turn on NPU power domain */ - R_BSP_RegisterProtectDisable(BSP_REG_PROTECT_OM_LPC_BATT); - FSP_HARDWARE_REGISTER_WAIT((R_SYSTEM->PDCTRNPU & (R_SYSTEM_PDCTRNPU_PDCSF_Msk | - R_SYSTEM_PDCTRGD_PDPGSF_Msk)), - R_SYSTEM_PDCTRGD_PDPGSF_Msk); - R_SYSTEM->PDCTRNPU = 0; - FSP_HARDWARE_REGISTER_WAIT((R_SYSTEM->PDCTRNPU & (R_SYSTEM_PDCTRNPU_PDCSF_Msk | - R_SYSTEM_PDCTRGD_PDPGSF_Msk)), - 0); - R_BSP_RegisterProtectEnable(BSP_REG_PROTECT_OM_LPC_BATT); - } - LOG_DBG("Ethos-U DTS info. base_address=0x%p, secure_enable=%u, privilege_enable=%u", ethosu_dts_info.base_addr, ethosu_dts_info.secure_enable, ethosu_dts_info.privilege_enable); From ca8e82532a34054fe73fb6d19511125144de044f Mon Sep 17 00:00:00 2001 From: Khoa Tran Date: Wed, 29 Oct 2025 12:50:52 +0700 Subject: [PATCH 0134/6328] drivers: rtc: Add update to use with new battery backup inplementation Update Renesas RTC driver to use with the new battery backup inplementation Signed-off-by: Khoa Tran --- drivers/rtc/rtc_renesas_ra.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/rtc/rtc_renesas_ra.c b/drivers/rtc/rtc_renesas_ra.c index 8993949630b3..e4a1ec0486a7 100644 --- a/drivers/rtc/rtc_renesas_ra.c +++ b/drivers/rtc/rtc_renesas_ra.c @@ -13,7 +13,7 @@ #include #include #include -#include +#include #include #include @@ -156,11 +156,11 @@ static int rtc_renesas_ra_init(const struct device *dev) } #if defined(CONFIG_RENESAS_RA_BATTERY_BACKUP_MANUAL_CONFIGURE) - if (is_backup_domain_reset_happen()) { + if (R_BSP_ResetStatusGet() & BSP_RESET_TYPE_VBATPOR) { R_RTC_ClockSourceSet(&data->fsp_ctrl); } #else - if (is_power_on_reset_happen()) { + if (R_BSP_ResetStatusGet() & BSP_RESET_TYPE_POR) { R_RTC_ClockSourceSet(&data->fsp_ctrl); } #endif /* CONFIG_RENESAS_RA_BATTERY_BACKUP_MANUAL_CONFIGURE */ From 77d603a5e00abeb1a3249c9612bd77bb78ae651f Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Fri, 9 Jan 2026 15:38:13 +0100 Subject: [PATCH 0135/6328] storage: flash_map: remove legacy Mbed TLS crypto for integrity check Remove Kconfig and code related to legacy Mbed TLS crypto for SHA-256. This was used for the integrity check functionality as alternative to PSA Crypto API. This support was already deprecated and now it's removed in order to prepare for the next Mbed TLS 4.0 release where legacy crypto won't be available anymore. Signed-off-by: Valerio Setti --- subsys/storage/flash_map/Kconfig | 27 +---------- .../storage/flash_map/flash_map_integrity.c | 47 +++---------------- 2 files changed, 8 insertions(+), 66 deletions(-) diff --git a/subsys/storage/flash_map/Kconfig b/subsys/storage/flash_map/Kconfig index 83d2f2713695..cc18b5d0f353 100644 --- a/subsys/storage/flash_map/Kconfig +++ b/subsys/storage/flash_map/Kconfig @@ -31,6 +31,8 @@ config FLASH_MAP_CUSTOM config FLASH_AREA_CHECK_INTEGRITY bool "Flash check functions" + select PSA_CRYPTO + select PSA_WANT_ALG_SHA_256 help If enabled, there will be available the backend to check flash integrity using SHA-256 verification algorithm. @@ -42,29 +44,4 @@ config FLASH_MAP_LABELS at runtime. The available labels will also be displayed in the flash_map list shell command. -if FLASH_AREA_CHECK_INTEGRITY - -choice FLASH_AREA_CHECK_INTEGRITY_BACKEND - prompt "Crypto backend for the flash check functions" - default FLASH_AREA_CHECK_INTEGRITY_PSA - -config FLASH_AREA_CHECK_INTEGRITY_PSA - bool "Use PSA" - select PSA_WANT_ALG_SHA_256 - select PSA_CRYPTO - help - Use the PSA API to perform the integrity check. - -config FLASH_AREA_CHECK_INTEGRITY_MBEDTLS - bool "Use Mbed TLS [DEPRECATED]" - select MBEDTLS - select MBEDTLS_SHA256 - select DEPRECATED - help - Use the Mbed TLS library to perform the integrity check. - -endchoice - -endif # FLASH_AREA_CHECK_INTEGRITY - endif diff --git a/subsys/storage/flash_map/flash_map_integrity.c b/subsys/storage/flash_map/flash_map_integrity.c index 7e512e759db2..feefc2761d8b 100644 --- a/subsys/storage/flash_map/flash_map_integrity.c +++ b/subsys/storage/flash_map/flash_map_integrity.c @@ -18,25 +18,14 @@ #include "flash_map_priv.h" #include #include - -#define SHA256_DIGEST_SIZE 32 -#if defined(CONFIG_FLASH_AREA_CHECK_INTEGRITY_PSA) #include -#define SUCCESS_VALUE PSA_SUCCESS -#else -#include -#define SUCCESS_VALUE 0 -#endif int flash_area_check_int_sha256(const struct flash_area *fa, const struct flash_area_check *fac) { - unsigned char hash[SHA256_DIGEST_SIZE]; -#if defined(CONFIG_FLASH_AREA_CHECK_INTEGRITY_PSA) + unsigned char hash[PSA_HASH_LENGTH(PSA_ALG_SHA_256)]; psa_hash_operation_t hash_ctx; -#else /* CONFIG_FLASH_AREA_CHECK_INTEGRITY_MBEDTLS */ - mbedtls_sha256_context hash_ctx; -#endif + size_t hash_len; int to_read; int pos; int rc; @@ -50,14 +39,9 @@ int flash_area_check_int_sha256(const struct flash_area *fa, return -EINVAL; } -#if defined(CONFIG_FLASH_AREA_CHECK_INTEGRITY_PSA) hash_ctx = psa_hash_operation_init(); rc = psa_hash_setup(&hash_ctx, PSA_ALG_SHA_256); -#else /* CONFIG_FLASH_AREA_CHECK_INTEGRITY_MBEDTLS */ - mbedtls_sha256_init(&hash_ctx); - rc = mbedtls_sha256_starts(&hash_ctx, false); -#endif - if (rc != SUCCESS_VALUE) { + if (rc != PSA_SUCCESS) { return -ESRCH; } @@ -74,44 +58,25 @@ int flash_area_check_int_sha256(const struct flash_area *fa, goto error; } -#if defined(CONFIG_FLASH_AREA_CHECK_INTEGRITY_PSA) rc = psa_hash_update(&hash_ctx, fac->rbuf, to_read); -#else /* CONFIG_FLASH_AREA_CHECK_INTEGRITY_MBEDTLS */ - rc = mbedtls_sha256_update(&hash_ctx, fac->rbuf, to_read); -#endif - if (rc != SUCCESS_VALUE) { + if (rc != PSA_SUCCESS) { rc = -ESRCH; goto error; } } -#if defined(CONFIG_FLASH_AREA_CHECK_INTEGRITY_PSA) - size_t hash_len; - rc = psa_hash_finish(&hash_ctx, hash, sizeof(hash), &hash_len); -#else /* CONFIG_FLASH_AREA_CHECK_INTEGRITY_MBEDTLS */ - rc = mbedtls_sha256_finish(&hash_ctx, hash); -#endif - if (rc != SUCCESS_VALUE) { + if (rc != PSA_SUCCESS) { rc = -ESRCH; goto error; } - if (memcmp(hash, fac->match, SHA256_DIGEST_SIZE)) { -#if defined(CONFIG_FLASH_AREA_CHECK_INTEGRITY_PSA) + if (memcmp(hash, fac->match, sizeof(hash))) { /* The operation has already been terminated. */ return -EILSEQ; -#else /* CONFIG_FLASH_AREA_CHECK_INTEGRITY_MBEDTLS */ - rc = -EILSEQ; - goto error; -#endif } error: -#if defined(CONFIG_FLASH_AREA_CHECK_INTEGRITY_PSA) psa_hash_abort(&hash_ctx); -#else /* CONFIG_FLASH_AREA_CHECK_INTEGRITY_MBEDTLS */ - mbedtls_sha256_free(&hash_ctx); -#endif return rc; } From 74740148b4296df7cea58ed062f53bdaf047ac39 Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Fri, 9 Jan 2026 15:45:17 +0100 Subject: [PATCH 0136/6328] tests: storage: flash_map: remove testing of legacy Mbed TLS crypto Following the removal of legacy Mbed TLS crypto for SHA-256 in the subsys, this commit updates the related sample. "overlay-mbedtls.conf" is removed as no more necessary and the corresponding test case is removed from "testcase.yaml". "overlay-psa.conf" is updated removing unnecessary Kconfig selections. Signed-off-by: Valerio Setti --- .../subsys/storage/flash_map/overlay-mbedtls.conf | 2 -- tests/subsys/storage/flash_map/overlay-psa.conf | 3 --- tests/subsys/storage/flash_map/testcase.yaml | 15 --------------- 3 files changed, 20 deletions(-) delete mode 100644 tests/subsys/storage/flash_map/overlay-mbedtls.conf diff --git a/tests/subsys/storage/flash_map/overlay-mbedtls.conf b/tests/subsys/storage/flash_map/overlay-mbedtls.conf deleted file mode 100644 index 2b8aef9e908d..000000000000 --- a/tests/subsys/storage/flash_map/overlay-mbedtls.conf +++ /dev/null @@ -1,2 +0,0 @@ -CONFIG_FLASH_AREA_CHECK_INTEGRITY=y -CONFIG_FLASH_AREA_CHECK_INTEGRITY_MBEDTLS=y diff --git a/tests/subsys/storage/flash_map/overlay-psa.conf b/tests/subsys/storage/flash_map/overlay-psa.conf index 03d88c4b5305..4a6f3846fdb3 100644 --- a/tests/subsys/storage/flash_map/overlay-psa.conf +++ b/tests/subsys/storage/flash_map/overlay-psa.conf @@ -1,5 +1,2 @@ CONFIG_FLASH_AREA_CHECK_INTEGRITY=y -CONFIG_FLASH_AREA_CHECK_INTEGRITY_PSA=y -CONFIG_MBEDTLS=y -CONFIG_MBEDTLS_PSA_CRYPTO_C=y CONFIG_TEST_RANDOM_GENERATOR=y diff --git a/tests/subsys/storage/flash_map/testcase.yaml b/tests/subsys/storage/flash_map/testcase.yaml index c25f657cbb05..3097f0de0cbb 100644 --- a/tests/subsys/storage/flash_map/testcase.yaml +++ b/tests/subsys/storage/flash_map/testcase.yaml @@ -27,21 +27,6 @@ tests: integration_platforms: - nrf52840dk/nrf52840 tags: flash_map - storage.flash_map_sha.mbedtls: - extra_args: EXTRA_CONF_FILE=overlay-mbedtls.conf - platform_allow: - - nrf51dk/nrf51822 - - qemu_x86 - - native_sim - - native_sim/native/64 - - mr_canhubk3 - - s32z2xxdc2/s32z270/rtu0 - - s32z2xxdc2/s32z270/rtu1 - - s32z2xxdc2@D/s32z270/rtu0 - - s32z2xxdc2@D/s32z270/rtu1 - tags: flash_map - integration_platforms: - - native_sim storage.flash_map_sha.psa: extra_args: EXTRA_CONF_FILE=overlay-psa.conf platform_allow: From 484fb7d7fca819658e214b62300f145434a490ef Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Fri, 9 Jan 2026 15:48:35 +0100 Subject: [PATCH 0137/6328] tests: storage: flash_map: rename conf file for integrity check Since now there is a single backend for crypto, i.e. the PSA Crypto API one, it's better to rename corresponding test case and related configuration file so that instead of mentioning "psa" they mention "integrity-check". Signed-off-by: Valerio Setti --- .../{overlay-psa.conf => overlay-integrity-check.conf} | 0 tests/subsys/storage/flash_map/testcase.yaml | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) rename tests/subsys/storage/flash_map/{overlay-psa.conf => overlay-integrity-check.conf} (100%) diff --git a/tests/subsys/storage/flash_map/overlay-psa.conf b/tests/subsys/storage/flash_map/overlay-integrity-check.conf similarity index 100% rename from tests/subsys/storage/flash_map/overlay-psa.conf rename to tests/subsys/storage/flash_map/overlay-integrity-check.conf diff --git a/tests/subsys/storage/flash_map/testcase.yaml b/tests/subsys/storage/flash_map/testcase.yaml index 3097f0de0cbb..5b1dc014cf33 100644 --- a/tests/subsys/storage/flash_map/testcase.yaml +++ b/tests/subsys/storage/flash_map/testcase.yaml @@ -28,7 +28,7 @@ tests: - nrf52840dk/nrf52840 tags: flash_map storage.flash_map_sha.psa: - extra_args: EXTRA_CONF_FILE=overlay-psa.conf + extra_args: EXTRA_CONF_FILE=overlay-integrity-check.conf platform_allow: - nrf51dk/nrf51822 - native_sim From 647f68cb2c0a6369d67918b29c6a9bc78d0fdd34 Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Fri, 9 Jan 2026 15:52:58 +0100 Subject: [PATCH 0138/6328] doc: migration-guide: add notes for changes in flash_map's integrity check Add notes about changes in flash_map's Kconfig for what concerns the crypto libraries used for integrity check. Signed-off-by: Valerio Setti --- doc/releases/migration-guide-4.4.rst | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/doc/releases/migration-guide-4.4.rst b/doc/releases/migration-guide-4.4.rst index 991c0625b109..50ff539a76e6 100644 --- a/doc/releases/migration-guide-4.4.rst +++ b/doc/releases/migration-guide-4.4.rst @@ -751,6 +751,15 @@ Other subsystems * Use :kconfig:option:`CONFIG_CACHE_HAS_MIRRORED_MEMORY_REGIONS` instead of :kconfig:option:`CONFIG_CACHE_DOUBLEMAP` as the former is more descriptive of the feature. +Flash +===== + +* Previously deprecated ``CONFIG_FLASH_AREA_CHECK_INTEGRITY_MBEDTLS`` is now + removed. + +* ``CONFIG_FLASH_AREA_CHECK_INTEGRITY_PSA`` is also removed since there is + now no alternative for the crypto library backend. + JWT === From fc7fae6090f4443485eef5f9974a30cfbba888e8 Mon Sep 17 00:00:00 2001 From: Nicola Vetrini Date: Fri, 16 Jan 2026 14:46:41 +0100 Subject: [PATCH 0139/6328] sca: ECLAIR: update configuration for ECLAIR 3.14.0 This is the version of the tool that Zephyr infrastructure uses, and the configuration needs to be adjusted accordingly. Setting *_ALIASES variables is not necessary anymore. Signed-off-by: Nicola Vetrini --- cmake/sca/eclair/ECL/deviations.ecl | 10 +++++----- cmake/sca/eclair/eclair.template | 5 ----- 2 files changed, 5 insertions(+), 10 deletions(-) diff --git a/cmake/sca/eclair/ECL/deviations.ecl b/cmake/sca/eclair/ECL/deviations.ecl index f2e143ad5cfe..af1d37c380b4 100644 --- a/cmake/sca/eclair/ECL/deviations.ecl +++ b/cmake/sca/eclair/ECL/deviations.ecl @@ -329,7 +329,7 @@ safe." -doc_end -doc_begin="Switch statements having a controlling expression of enum type deliberately do not have a default case: gcc -Wall enables -Wswitch which warns (and breaks the build as we use -Werror) if one of the enum labels is missing from the switch." --config=MC3A2.R16.4,reports+={deliberate,'any_area(kind(context)&&^.* has no `default.*$&&stmt(node(switch_stmt)&&child(cond,skip(__non_syntactic_paren_stmts,type(canonical(enum_underlying_type(any())))))))'} +-config=MC3A2.R16.4,reports+={deliberate,"any_area(kind(context)&&^.* has no `default.*$&&stmt(node(switch_stmt)&&child(cond,skip(__non_syntactic_paren_stmts,ref(enum_underlying_type(any()))))))"} -doc_end -doc_begin="A switch statement with a single switch clause and no default label may be used in place of an equivalent if statement if it is considered to improve readability." @@ -382,10 +382,10 @@ in assignments; (5) as initializers, possibly designated, in initalizer lists; -config=MC3A2.R20.7,expansion_context= {safe, "context(__call_expr_arg_contexts)"}, {safe, "left_right(^[(,\\[]$,^[),\\]]$)"}, -{safe, "context(skip_to(__expr_non_syntactic_contexts, stmt_child(node(array_subscript_expr), subscript)))"}, -{safe, "context(skip_to(__expr_non_syntactic_contexts, stmt_child(operator(assign), lhs)))"}, -{safe, "context(skip_to(__expr_non_syntactic_contexts, stmt_child(node(init_list_expr||designated_init_expr), init)))"}, -{safe, "context(skip_to(__expr_non_syntactic_contexts, stmt_child(node(case_stmt), lower||upper)))"} +{safe, "context(skip(parent(__expr_non_syntactic_contexts), is(subscript)&&parent(node(array_subscript_expr))))"}, +{safe, "context(skip(parent(__expr_non_syntactic_contexts), is(lhs)&&parent(stmt(operator(assign)))))"}, +{safe, "context(skip(parent(__expr_non_syntactic_contexts), is(init)&&parent(node(init_list_expr||designated_init_expr))))"}, +{safe, "context(skip(parent(__expr_non_syntactic_contexts), is(lower||upper)&&parent(node(case_stmt))))"} -doc_end -doc_begin="Violations involving the __config_enabled macros cannot be fixed without diff --git a/cmake/sca/eclair/eclair.template b/cmake/sca/eclair/eclair.template index d82824edb870..ffd3f87a76d5 100644 --- a/cmake/sca/eclair/eclair.template +++ b/cmake/sca/eclair/eclair.template @@ -28,11 +28,6 @@ execute_process( COMMAND @CMAKE_COMMAND@ -E env ECLAIR_DIAGNOSTICS_OUTPUT=@ECLAIR_DIAGNOSTICS_OUTPUT@ ECLAIR_DATA_DIR=@ECLAIR_ANALYSIS_DATA_DIR@ - CC_ALIASES=@CC_ALIASES@ - CXX_ALIASES=@CXX_ALIASES@ - AS_ALIASES=@AS_ALIASES@ - LD_ALIASES=@LD_ALIASES@ - AR_ALIASES=@AR_ALIASES@ @ECLAIR_ENV@ ${ECLAIR_ARGS} -- ${ZEPHYR_COMPILER_CALL} COMMAND_ERROR_IS_FATAL ANY ) From ff864b3cd31c49ca4ce0d3b1f2415b99e03a8246 Mon Sep 17 00:00:00 2001 From: Gatien Chevallier Date: Wed, 15 Oct 2025 15:21:08 +0200 Subject: [PATCH 0140/6328] drivers: otp: add stm32 BSEC driver Introduce the Boot and SECurity(BSEC) control driver. The BSEC peripheral manages the accesses to an embedded one time programmable(OTP) array of fuses. Those fuses are used to store on-chip, non-volatile data like boot and security parameters (e.g: secret keys, non-volatile counters, etc...). Signed-off-by: Gatien Chevallier --- drivers/otp/CMakeLists.txt | 1 + drivers/otp/Kconfig | 1 + drivers/otp/Kconfig.stm32 | 10 ++ drivers/otp/otp_bsec_stm32.c | 165 ++++++++++++++++++++++++++++ dts/bindings/otp/st,stm32-bsec.yaml | 59 ++++++++++ 5 files changed, 236 insertions(+) create mode 100644 drivers/otp/Kconfig.stm32 create mode 100644 drivers/otp/otp_bsec_stm32.c create mode 100644 dts/bindings/otp/st,stm32-bsec.yaml diff --git a/drivers/otp/CMakeLists.txt b/drivers/otp/CMakeLists.txt index 72b7ec78eb81..8c29247a5061 100644 --- a/drivers/otp/CMakeLists.txt +++ b/drivers/otp/CMakeLists.txt @@ -3,3 +3,4 @@ zephyr_library() zephyr_library_sources_ifdef(CONFIG_OTP_EMULATOR otp_emulator.c) +zephyr_library_sources_ifdef(CONFIG_OTP_STM32_BSEC otp_bsec_stm32.c) diff --git a/drivers/otp/Kconfig b/drivers/otp/Kconfig index 5e587c823af2..1d14f8934370 100644 --- a/drivers/otp/Kconfig +++ b/drivers/otp/Kconfig @@ -19,6 +19,7 @@ module-str = otp source "subsys/logging/Kconfig.template.log_config" source "drivers/otp/Kconfig.emu" +source "drivers/otp/Kconfig.stm32" config OTP_INIT_PRIORITY int "OTP init priority" diff --git a/drivers/otp/Kconfig.stm32 b/drivers/otp/Kconfig.stm32 new file mode 100644 index 000000000000..996395c4da5c --- /dev/null +++ b/drivers/otp/Kconfig.stm32 @@ -0,0 +1,10 @@ +# Copyright (c) 2026 STMicroelectronics +# SPDX-License-Identifier: Apache-2.0 + +config OTP_STM32_BSEC + bool "STM32 BSEC driver" + default y + select USE_STM32_HAL_BSEC + depends on DT_HAS_ST_STM32_BSEC_ENABLED + help + Enable OTP fuse access for STM32 SoCs embedding a BSEC peripheral. diff --git a/drivers/otp/otp_bsec_stm32.c b/drivers/otp/otp_bsec_stm32.c new file mode 100644 index 000000000000..403053704992 --- /dev/null +++ b/drivers/otp/otp_bsec_stm32.c @@ -0,0 +1,165 @@ +/* + * Copyright (c) 2026 STMicroelectronics + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include +#include + +#define DT_DRV_COMPAT st_stm32_bsec + +LOG_MODULE_REGISTER(otp_bsec_stm32); + +#define BSEC_WORD_SIZE 4 + +static K_MUTEX_DEFINE(lock); + +struct bsec_stm32_config { + BSEC_TypeDef *base; + unsigned int upper_fuse_limit; +}; + +static int otp_bsec_stm32_check_accessible(BSEC_HandleTypeDef *handle, + const struct bsec_stm32_config *config, off_t offset, + unsigned int nb_fuse) +{ + uint32_t fuse_idx = offset / BSEC_WORD_SIZE; + HAL_StatusTypeDef hal_ret; + uint32_t bsec_state = 0; + + if (nb_fuse == 0) { + return -EINVAL; + } + + hal_ret = HAL_BSEC_GetDeviceLifeCycleState(handle, &bsec_state); + if (hal_ret != HAL_OK) { + return -EACCES; + } + + /* Upper fuses are only accessible when the BSEC is in closed locked state */ + if (((fuse_idx + nb_fuse) > config->upper_fuse_limit) && + (bsec_state != HAL_BSEC_CLOSED_STATE)) { + return -EACCES; + } + + return 0; +} + +#if defined(CONFIG_OTP_PROGRAM) +static int otp_bsec_stm32_program(const struct device *dev, off_t offset, const void *buf, + size_t len) +{ + const struct bsec_stm32_config *config = dev->config; + BSEC_HandleTypeDef handle = { .Instance = config->base }; + HAL_StatusTypeDef hal_ret; + unsigned int nb_fuse; + unsigned int i; + int ret; + + /* Allow programming of 4bytes words only */ + if (!IS_ALIGNED(len, BSEC_WORD_SIZE)) { + LOG_ERR("Invalid length to program OTP: %zu", len); + return -EINVAL; + } + + /* Allow programming only at the beginning of a new word */ + if (!IS_ALIGNED(offset, BSEC_WORD_SIZE)) { + LOG_ERR("Programmed data not aligned on an OTP word"); + return -EINVAL; + } + + nb_fuse = len / BSEC_WORD_SIZE; + + ret = otp_bsec_stm32_check_accessible(&handle, config, offset, nb_fuse); + if (ret != 0) { + return ret; + } + + k_mutex_lock(&lock, K_FOREVER); + + for (i = 0; i < nb_fuse; i++) { + uint32_t prog_data = 0; + + LOG_DBG("Programming Fuse %lu", (offset / BSEC_WORD_SIZE) + i); + + prog_data = UNALIGNED_GET((uint32_t *)((uint8_t *)buf + i * BSEC_WORD_SIZE)); + + hal_ret = HAL_BSEC_OTP_Program(&handle, (offset / BSEC_WORD_SIZE) + i, prog_data, + 0); + if (hal_ret != HAL_OK) { + k_mutex_unlock(&lock); + return -EACCES; + } + } + + k_mutex_unlock(&lock); + + return 0; +} +#endif /* CONFIG_OTP_PROGRAM */ + +static int otp_bsec_stm32_read(const struct device *dev, off_t offset, void *buf, size_t len) +{ + const struct bsec_stm32_config *config = dev->config; + BSEC_HandleTypeDef handle = { .Instance = config->base }; + uint8_t *dest = (uint8_t *)buf; + HAL_StatusTypeDef hal_ret; + size_t bytes_left = len; + unsigned int nb_fuse; + unsigned int i; + int ret; + + /* Allow intra-word and spanned reads but not 0-sized reads */ + nb_fuse = len != 0 ? DIV_ROUND_UP(offset % BSEC_WORD_SIZE + len, BSEC_WORD_SIZE) : 0; + + ret = otp_bsec_stm32_check_accessible(&handle, config, offset, nb_fuse); + if (ret != 0) { + return ret; + } + + k_mutex_lock(&lock, K_FOREVER); + + for (i = 0; i < nb_fuse; i++) { + size_t first_offset = (i == 0) ? offset % BSEC_WORD_SIZE : 0; + size_t read_sz = MIN(BSEC_WORD_SIZE - first_offset, bytes_left); + uint32_t fuse_data = 0; + + LOG_DBG("Reading Fuse %lu", (offset / BSEC_WORD_SIZE) + i); + + hal_ret = HAL_BSEC_OTP_Read(&handle, (offset / BSEC_WORD_SIZE) + i, &fuse_data); + if (hal_ret != HAL_OK) { + k_mutex_unlock(&lock); + return -EACCES; + } + + memcpy(dest, ((uint8_t *)&fuse_data) + first_offset, read_sz); + dest += read_sz; + bytes_left -= read_sz; + if (bytes_left == 0) { + break; + } + } + + k_mutex_unlock(&lock); + + return 0; +} + +static const struct bsec_stm32_config bsec_config = { + .base = (void *)DT_INST_REG_ADDR(0), + .upper_fuse_limit = DT_INST_PROP(0, st_upper_fuse_limit), +}; + +static DEVICE_API(otp, otp_bsec_stm32_api) = { +#if defined(CONFIG_OTP_PROGRAM) + .program = otp_bsec_stm32_program, +#endif + .read = otp_bsec_stm32_read, +}; + +DEVICE_DT_INST_DEFINE(0, NULL, NULL, NULL, &bsec_config, PRE_KERNEL_1, + CONFIG_OTP_INIT_PRIORITY, &otp_bsec_stm32_api); diff --git a/dts/bindings/otp/st,stm32-bsec.yaml b/dts/bindings/otp/st,stm32-bsec.yaml new file mode 100644 index 000000000000..196aa31305c0 --- /dev/null +++ b/dts/bindings/otp/st,stm32-bsec.yaml @@ -0,0 +1,59 @@ +# Copyright (c) 2026 STMicroelectronics +# SPDX-License-Identifier: Apache-2.0 + +title: STM32 Boot and security control (BSEC) + +description: | + The boot and security control (BSEC) peripheral manages the accesses to an + embedded one time programmable (OTP) array of fuses. Those fuses are used to + store on-chip, non-volatile data like boot and security parameters. + Embedded non-volatile secrets are stored in BSEC upper area that is only + accessible while BSEC is operating in its BSEC-closed state. When the BSEC + state is BSEC-open, those non-volatile secrets are permanently hidden. + + Configuration example at SoC level: + + bsec: efuse@56009000 { + compatible = "st,stm32-bsec"; + reg = <0x56009000 0x1000>; + st,upper-fuse-limit = <256>; + + nvmem-layout { + compatible = "fixed-layout"; + #address-cells = <1>; + #size-cells = <1>; + + bootrom_cfg1: bootrom-cfg1@20 { + reg = <0x20 0x4>; + #nvmem-cell-cells = <0>; + }; + + mac_address0: mac-address@2a4 { + reg = <0x2a4 0x6>; + #nvmem-cell-cells = <0>; + }; + }; + }; + + Configuration example at board level: + + &bsec { + nvmem-layout { + mac_address2: mac-address@2fc { + reg = <0x2fc 0x6>; + #nvmem-cell-cells = <0>; + }; + }; + }; + +compatible: "st,stm32-bsec" + +include: base.yaml + +properties: + st,upper-fuse-limit: + type: int + required: true + description: | + Start fuse (32bit OTP word) index of the upper fuse region of the BSEC. + This region requires a particular SoC state to be accessed. From 84dc3270841874f9fb731e4a9a14909ac371d928 Mon Sep 17 00:00:00 2001 From: Gatien Chevallier Date: Wed, 22 Oct 2025 11:06:28 +0200 Subject: [PATCH 0141/6328] drivers: ethernet: stm32: handle MAC address with net_eth_mac_load() This new API handles if the MAC address should be fetched from NVMEM, is static or be randomly generated. Use it so that the driver can fetch the MAC address from the OTP fuses, when possible. Signed-off-by: Gatien Chevallier --- drivers/ethernet/Kconfig.stm32_hal | 1 + drivers/ethernet/eth_stm32_hal_common.c | 71 +++++++++++++------------ drivers/ethernet/eth_stm32_hal_priv.h | 1 + 3 files changed, 40 insertions(+), 33 deletions(-) diff --git a/drivers/ethernet/Kconfig.stm32_hal b/drivers/ethernet/Kconfig.stm32_hal index 00100dc5f0b6..3916ec639c6c 100644 --- a/drivers/ethernet/Kconfig.stm32_hal +++ b/drivers/ethernet/Kconfig.stm32_hal @@ -13,6 +13,7 @@ menuconfig ETH_STM32_HAL select HWINFO select ETH_DSA_SUPPORT_DEPRECATED select PINCTRL + imply NVMEM if $(dt_compat_any_has_prop,$(DT_COMPAT_ST_STM32_ETHERNET),nvmem-cells) imply CRC help Enable STM32 HAL based Ethernet driver. It is available for diff --git a/drivers/ethernet/eth_stm32_hal_common.c b/drivers/ethernet/eth_stm32_hal_common.c index ccdb586d8435..243d0325cf7a 100644 --- a/drivers/ethernet/eth_stm32_hal_common.c +++ b/drivers/ethernet/eth_stm32_hal_common.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -109,38 +110,6 @@ void HAL_ETH_RxCpltCallback(ETH_HandleTypeDef *heth_handle) k_sem_give(&dev_data->rx_int_sem); } -static void generate_mac(uint8_t *mac_addr) -{ -#if defined(ETH_STM32_RANDOM_MAC) - /* "zephyr,random-mac-address" is set, generate a random mac address */ - gen_random_mac(mac_addr, ST_OUI_B0, ST_OUI_B1, ST_OUI_B2); -#else /* Use user defined mac address */ - mac_addr[0] = ST_OUI_B0; - mac_addr[1] = ST_OUI_B1; - mac_addr[2] = ST_OUI_B2; -#if NODE_HAS_VALID_MAC_ADDR(DT_DRV_INST(0)) - mac_addr[3] = NODE_MAC_ADDR_OCTET(DT_DRV_INST(0), 3); - mac_addr[4] = NODE_MAC_ADDR_OCTET(DT_DRV_INST(0), 4); - mac_addr[5] = NODE_MAC_ADDR_OCTET(DT_DRV_INST(0), 5); -#else - uint8_t unique_device_ID_12_bytes[12]; - uint32_t result_mac_32_bits; - - /* Nothing defined by the user, use device id */ - hwinfo_get_device_id(unique_device_ID_12_bytes, 12); - result_mac_32_bits = crc32_ieee((uint8_t *)unique_device_ID_12_bytes, 12); - memcpy(&mac_addr[3], &result_mac_32_bits, 3); - - /** - * Set MAC address locally administered bit (LAA) as this is not assigned by the - * manufacturer - */ - mac_addr[0] |= 0x02; - -#endif /* NODE_HAS_VALID_MAC_ADDR(DT_DRV_INST(0))) */ -#endif -} - static int eth_initialize(const struct device *dev) { struct eth_stm32_hal_dev_data *dev_data = dev->data; @@ -177,7 +146,42 @@ static int eth_initialize(const struct device *dev) return ret; } - generate_mac(dev_data->mac_addr); + if (cfg->mac_cfg.type != NET_ETH_MAC_NVMEM) { +#if defined(ETH_STM32_RANDOM_MAC) + /* "zephyr,random-mac-address" is set, generate a random mac address */ + gen_random_mac(dev_data->mac_addr, ST_OUI_B0, ST_OUI_B1, ST_OUI_B2); +#else /* Use user defined mac address */ + dev_data->mac_addr[0] = ST_OUI_B0; + dev_data->mac_addr[1] = ST_OUI_B1; + dev_data->mac_addr[2] = ST_OUI_B2; +#if NODE_HAS_VALID_MAC_ADDR(DT_DRV_INST(0)) + dev_data->mac_addr[3] = NODE_MAC_ADDR_OCTET(DT_DRV_INST(0), 3); + dev_data->mac_addr[4] = NODE_MAC_ADDR_OCTET(DT_DRV_INST(0), 4); + dev_data->mac_addr[5] = NODE_MAC_ADDR_OCTET(DT_DRV_INST(0), 5); +#else + uint8_t unique_device_ID_12_bytes[12]; + uint32_t result_mac_32_bits; + + /* Nothing defined by the user, use device id */ + hwinfo_get_device_id(unique_device_ID_12_bytes, 12); + result_mac_32_bits = crc32_ieee((uint8_t *)unique_device_ID_12_bytes, 12); + memcpy(&dev_data->mac_addr[3], &result_mac_32_bits, 3); + + /** + * Set MAC address locally administered bit (LAA) as this is not assigned by the + * manufacturer + */ + dev_data->mac_addr[0] |= 0x02; + +#endif /* NODE_HAS_VALID_MAC_ADDR(DT_DRV_INST(0))) */ +#endif + } else { + ret = net_eth_mac_load(&cfg->mac_cfg, dev_data->mac_addr); + if (ret < 0) { + LOG_ERR("Failed to load MAC (%d)", ret); + return ret; + } + } heth->Init.MACAddr = dev_data->mac_addr; @@ -408,6 +412,7 @@ static const struct eth_stm32_hal_dev_cfg eth0_config = { (mac_clk_ptp), (stm_eth))), #endif .pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(0), + .mac_cfg = NET_ETH_MAC_DT_INST_CONFIG_INIT(0), }; BUILD_ASSERT(DT_INST_ENUM_HAS_VALUE(0, phy_connection_type, mii) diff --git a/drivers/ethernet/eth_stm32_hal_priv.h b/drivers/ethernet/eth_stm32_hal_priv.h index da63b1f2ac6c..02297f9bab07 100644 --- a/drivers/ethernet/eth_stm32_hal_priv.h +++ b/drivers/ethernet/eth_stm32_hal_priv.h @@ -113,6 +113,7 @@ struct eth_stm32_hal_dev_cfg { uint8_t rate_pclken_idx; #endif const struct pinctrl_dev_config *pcfg; + const struct net_eth_mac_config mac_cfg; }; /* Device run time data */ From 28a988cc1048f548f83940ba45e870e1e899e27a Mon Sep 17 00:00:00 2001 From: Gatien Chevallier Date: Wed, 22 Oct 2025 11:15:03 +0200 Subject: [PATCH 0142/6328] dts: arm: st: n6: Add BSEC node for OTP handling The STM32N6 has a BSEC peripheral for the OTP management, add it to the SoC device tree file. Moreover, there are 4 OTP words dedicated for Ethernet MAC addresses, describe them in the NVMEM layout. Signed-off-by: Gatien Chevallier --- dts/arm/st/n6/stm32n6.dtsi | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/dts/arm/st/n6/stm32n6.dtsi b/dts/arm/st/n6/stm32n6.dtsi index 298c5b56335a..2facbb234784 100644 --- a/dts/arm/st/n6/stm32n6.dtsi +++ b/dts/arm/st/n6/stm32n6.dtsi @@ -746,6 +746,29 @@ status = "disabled"; }; + bsec: efuse@56009000 { + compatible = "st,stm32-bsec"; + reg = <0x56009000 0x1000>; + st,upper-fuse-limit = <256>; + status = "disabled"; + + nvmem-layout { + compatible = "fixed-layout"; + #address-cells = <1>; + #size-cells = <1>; + + mac_address0: mac-address@2a4 { + reg = <0x2a4 0x6>; + #nvmem-cell-cells = <0>; + }; + + mac_address1: mac-address@2ac { + reg = <0x2ac 0x6>; + #nvmem-cell-cells = <0>; + }; + }; + }; + dcmipp: dcmipp@58002000 { compatible = "st,stm32-dcmipp"; reg = <0x58002000 0x1000>; From 40c98c82d7219821d0cb3734ddf97afa335e4343 Mon Sep 17 00:00:00 2001 From: Gatien Chevallier Date: Wed, 22 Oct 2025 11:18:46 +0200 Subject: [PATCH 0143/6328] boards: st: stm32n6570_dk: read the MAC address from the OTP fuses On STM32N6x SoCs, secrets and persistent information such as Ethernet MAC addresses are stored in the BSEC OTP fuses. Therefore, default enable OTP support if NET_L2_ETHERNET and NVMEM are enabled so that the MAC address can be read from the BSEC OTP fuses through the NVMEM API. Use the "mac_address0" NVMEM cell to be able to read the ethernet MAC address from the OTP fuses. Signed-off-by: Gatien Chevallier --- boards/st/stm32n6570_dk/Kconfig.defconfig | 3 +++ boards/st/stm32n6570_dk/stm32n6570_dk_common.dtsi | 6 ++++++ 2 files changed, 9 insertions(+) diff --git a/boards/st/stm32n6570_dk/Kconfig.defconfig b/boards/st/stm32n6570_dk/Kconfig.defconfig index b078ade8a6af..26bc6d813d95 100644 --- a/boards/st/stm32n6570_dk/Kconfig.defconfig +++ b/boards/st/stm32n6570_dk/Kconfig.defconfig @@ -8,6 +8,9 @@ if BOARD_STM32N6570_DK configdefault NET_L2_ETHERNET default y +configdefault OTP + default y if NET_L2_ETHERNET && NVMEM + if DISPLAY || VIDEO # MEMC needs to be enabled in order to store # display frame buffer and video buffer pool to external PSRAM diff --git a/boards/st/stm32n6570_dk/stm32n6570_dk_common.dtsi b/boards/st/stm32n6570_dk/stm32n6570_dk_common.dtsi index 42a9447a3027..0486b278fe5a 100644 --- a/boards/st/stm32n6570_dk/stm32n6570_dk_common.dtsi +++ b/boards/st/stm32n6570_dk/stm32n6570_dk_common.dtsi @@ -439,6 +439,10 @@ zephyr_udc0: &usbotg_hs1 { }; }; +&bsec { + status = "okay"; +}; + /** * Per the RGMII specification, the Tx clock signal must be skewed * from the Tx data signals by 1~2 ns. On this board, the SoC must @@ -467,6 +471,8 @@ zephyr_udc0: &usbotg_hs1 { pinctrl-names = "default"; phy-connection-type = "rgmii"; phy-handle = <ð_phy>; + nvmem-cells = <&mac_address0>; + nvmem-cell-names = "mac-address"; }; &mdio { From 49de45225de7a15f02cb559aa0316fe99ee17ef6 Mon Sep 17 00:00:00 2001 From: Gaetan Perrot Date: Tue, 20 Jan 2026 14:45:13 +0900 Subject: [PATCH 0144/6328] drivers: clock_control: litex: make litex_clk_dts_clkouts_read void litex_clk_dts_clkouts_read() never reports errors and always returns 0. The error check at the call site is therefore dead code. Make the function void and drop the unused error handling. Signed-off-by: Gaetan Perrot --- drivers/clock_control/clock_control_litex.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/drivers/clock_control/clock_control_litex.c b/drivers/clock_control/clock_control_litex.c index ea1a4d7d6fda..1436249e538a 100644 --- a/drivers/clock_control/clock_control_litex.c +++ b/drivers/clock_control/clock_control_litex.c @@ -1637,7 +1637,7 @@ static int litex_clk_dts_timeout_read(struct litex_clk_timeout *timeout) return 0; } -static int litex_clk_dts_clkouts_read(void) +static void litex_clk_dts_clkouts_read(void) { struct litex_clk_range clkout_div; struct litex_clk_clkout *lcko; @@ -1665,7 +1665,6 @@ static int litex_clk_dts_clkouts_read(void) #if CLKOUT_EXIST(6) == 1 CLKOUT_INIT(6) #endif - return 0; } static void litex_clk_init_clkouts(void) @@ -1756,10 +1755,7 @@ static int litex_clk_init(const struct device *dev) return ret; } - ret = litex_clk_dts_clkouts_read(); - if (ret != 0) { - return ret; - } + litex_clk_dts_clkouts_read(); litex_clk_init_clkouts(); From 27be4443fc0bab8f06535df0792802dd30eb2c30 Mon Sep 17 00:00:00 2001 From: Gaetan Perrot Date: Tue, 20 Jan 2026 14:49:27 +0900 Subject: [PATCH 0145/6328] drivers: clock_control: litex: remove redundant initialization Local variables are initialized but always overwritten before being read or return. Drop the redundant initialization. No functional change intended. Signed-off-by: Gaetan Perrot --- drivers/clock_control/clock_control_litex.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/clock_control/clock_control_litex.c b/drivers/clock_control/clock_control_litex.c index 1436249e538a..f1a4bdaf4f0b 100644 --- a/drivers/clock_control/clock_control_litex.c +++ b/drivers/clock_control/clock_control_litex.c @@ -1248,7 +1248,7 @@ static int litex_clk_calc_clkout_params(struct litex_clk_clkout *lcko, uint64_t vco_freq) { int delta_f; - uint64_t m, clk_freq = 0; + uint64_t m, clk_freq; uint32_t d, margin = 1; if (lcko->margin.exp) { @@ -1311,13 +1311,13 @@ static int litex_clk_calc_all_clkout_params(uint64_t vco_freq) static int litex_clk_calc_all_params(void) { uint32_t div, mul; - uint64_t vco_freq = 0; + uint64_t vco_freq; for (div = ldev->divclk.min; div <= ldev->divclk.max; div++) { ldev->ts_g_config.div = div; for (mul = ldev->clkfbout.max; mul >= ldev->clkfbout.min; mul--) { - int below, above, all_valid = true; + int below, above, all_valid; vco_freq = CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC * (uint64_t)mul; vco_freq /= div; From 40d79b1f64309f3b1fa52f4e8fdbcd7368b75912 Mon Sep 17 00:00:00 2001 From: Peter van der Perk Date: Tue, 20 Jan 2026 09:27:09 +0100 Subject: [PATCH 0146/6328] sensor: bmm150: fix init when no trigger is selected When no trigger was chosen case statement fell through to default which causes the return code to -ENOTSUPP Signed-off-by: Peter van der Perk --- drivers/sensor/bosch/bmm150/bmm150.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/sensor/bosch/bmm150/bmm150.c b/drivers/sensor/bosch/bmm150/bmm150.c index 9db0f5553157..46109e19503f 100644 --- a/drivers/sensor/bosch/bmm150/bmm150.c +++ b/drivers/sensor/bosch/bmm150/bmm150.c @@ -651,8 +651,8 @@ static int pm_action(const struct device *dev, enum pm_device_action action) else { ret = bmm150_trigger_mode_power_ctrl(dev, true); } - break; #endif + break; #ifdef CONFIG_PM_DEVICE case PM_DEVICE_ACTION_SUSPEND: ret = bmm150_power_control(dev, 0); /* Suspend */ From 0b1b0991969ed054b8ef8af7ff5d134eb9d4a81a Mon Sep 17 00:00:00 2001 From: Vinayak Kariappa Chettimada Date: Wed, 19 Nov 2025 23:25:50 +0100 Subject: [PATCH 0147/6328] Bluetooth: Controller: Fix PAST sync_offset_us calculation Fix the missing use of remainder value in the sync_offset_us calculations. Also, Periodic Sync reception is relative to Peripheral event hence ticks_anchor does not require the ticker margin and event jitter to be subtracted. Signed-off-by: Vinayak Kariappa Chettimada --- subsys/bluetooth/controller/ll_sw/ull_conn.c | 9 ++++++--- subsys/bluetooth/controller/ll_sw/ull_llcp.c | 11 +++++------ subsys/bluetooth/controller/ll_sw/ull_sync.c | 10 ++++------ .../controller/ctrl_periodic_sync/src/main.c | 16 ++++++++-------- .../audio/test_scripts/bap_bass_client_sync.sh | 2 +- 5 files changed, 24 insertions(+), 24 deletions(-) diff --git a/subsys/bluetooth/controller/ll_sw/ull_conn.c b/subsys/bluetooth/controller/ll_sw/ull_conn.c index 3e6908417b0a..1c1f7d598abb 100644 --- a/subsys/bluetooth/controller/ll_sw/ull_conn.c +++ b/subsys/bluetooth/controller/ll_sw/ull_conn.c @@ -2849,7 +2849,7 @@ static void ticker_get_offset_op_cb(uint32_t status, void *param) *((uint32_t volatile *)param) = status; } -static uint32_t get_ticker_offset(uint8_t ticker_id, uint16_t *lazy) +static uint32_t get_ticker_offset(const struct ll_conn *conn, uint8_t ticker_id, uint16_t *lazy) { uint32_t volatile ret_cb; uint32_t ticks_to_expire; @@ -2888,6 +2888,7 @@ static uint32_t get_ticker_offset(uint8_t ticker_id, uint16_t *lazy) /* Add a tick for negative remainder and return positive remainder * value. */ + remainder = conn->llcp.prep.remainder; hal_ticker_add_jitter(&ticks_to_expire, &remainder); start_us = remainder; @@ -2921,7 +2922,8 @@ static void mfy_past_sender_offset_get(void *param) LL_ASSERT_DBG(adv_sync); - ticker_offset_us = get_ticker_offset(TICKER_ID_ADV_SYNC_BASE + adv_sync_handle, + ticker_offset_us = get_ticker_offset(conn, + (TICKER_ID_ADV_SYNC_BASE + adv_sync_handle), &lazy); pa_event_counter = adv_sync->lll.event_counter; @@ -2933,7 +2935,8 @@ static void mfy_past_sender_offset_get(void *param) LL_ASSERT_DBG(sync); - ticker_offset_us = get_ticker_offset(TICKER_ID_SCAN_SYNC_BASE + sync_handle, + ticker_offset_us = get_ticker_offset(conn, + (TICKER_ID_SCAN_SYNC_BASE + sync_handle), &lazy); if (lazy && ticker_offset_us > interval_us) { diff --git a/subsys/bluetooth/controller/ll_sw/ull_llcp.c b/subsys/bluetooth/controller/ll_sw/ull_llcp.c index f40e98ad96c7..2c0e852bafc7 100644 --- a/subsys/bluetooth/controller/ll_sw/ull_llcp.c +++ b/subsys/bluetooth/controller/ll_sw/ull_llcp.c @@ -1552,20 +1552,19 @@ void ull_lp_past_offset_calc_reply(struct ll_conn *conn, uint32_t offset_us, /* Update offset_us */ offset_us = offset_us - (conn_event_offset * conn_interval_us); - - ctx->data.periodic_sync.conn_event_count = ull_conn_event_counter(conn) + - conn_event_offset; } llcp_pdu_fill_sync_info_offset(&ctx->data.periodic_sync.sync_info, offset_us); + #if defined(CONFIG_BT_PERIPHERAL) /* Save the result for later use */ ctx->data.periodic_sync.offset_us = offset_us; #endif /* CONFIG_BT_PERIPHERAL */ - ctx->data.periodic_sync.sync_conn_event_count = ull_conn_event_counter(conn); - ctx->data.periodic_sync.conn_event_count = ull_conn_event_counter(conn) + - conn_event_offset; + ctx->data.periodic_sync.sync_conn_event_count = + ull_conn_event_counter_at_prepare(conn) - 1U; + ctx->data.periodic_sync.conn_event_count = + ull_conn_event_counter_at_prepare(conn) + conn_event_offset - 1U; ctx->data.periodic_sync.sync_info.evt_cntr = pa_event_counter; diff --git a/subsys/bluetooth/controller/ll_sw/ull_sync.c b/subsys/bluetooth/controller/ll_sw/ull_sync.c index dbca3e77c7a4..53a53c38a36c 100644 --- a/subsys/bluetooth/controller/ll_sw/ull_sync.c +++ b/subsys/bluetooth/controller/ll_sw/ull_sync.c @@ -274,6 +274,8 @@ void ull_sync_setup_from_sync_transfer(struct ll_conn *conn, uint16_t service_da if (sync->skip > skip_max) { sync->skip = skip_max; } + } else { + sync->skip = 0U; } sync->sync_expire = CONN_ESTAB_COUNTDOWN; @@ -321,14 +323,9 @@ void ull_sync_setup_from_sync_transfer(struct ll_conn *conn, uint16_t service_da conn_interval_us = conn->lll.interval * CONN_INT_UNIT_US; /* Calculate offset and schedule sync radio events */ - ready_delay_us = lll_radio_rx_ready_delay_get(lll->phy, PHY_FLAGS_S8); - sync_offset_us = PDU_ADV_SYNC_INFO_OFFSET_GET(si) * lll->window_size_event_us; /* offs_adjust may be 1 only if sync setup by LL_PERIODIC_SYNC_IND */ sync_offset_us += (PDU_ADV_SYNC_INFO_OFFS_ADJUST_GET(si) ? OFFS_ADJUST_US : 0U); - sync_offset_us -= EVENT_TICKER_RES_MARGIN_US; - sync_offset_us -= EVENT_JITTER_US; - sync_offset_us -= ready_delay_us; if (conn_evt_offset) { int64_t conn_offset_us = (int64_t)conn_evt_offset * conn_interval_us; @@ -386,6 +383,7 @@ void ull_sync_setup_from_sync_transfer(struct ll_conn *conn, uint16_t service_da /* Calculate event time reservation */ slot_us = PDU_AC_MAX_US(PDU_AC_EXT_PAYLOAD_RX_SIZE, lll->phy); + ready_delay_us = lll_radio_rx_ready_delay_get(lll->phy, PHY_FLAGS_S8); slot_us += ready_delay_us; /* Add implementation defined radio event overheads */ @@ -410,7 +408,7 @@ void ull_sync_setup_from_sync_transfer(struct ll_conn *conn, uint16_t service_da #if defined(CONFIG_BT_PERIPHERAL) if (conn->lll.role == BT_HCI_ROLE_PERIPHERAL) { /* Compensate for window widening */ - ticks_anchor += HAL_TICKER_US_TO_TICKS(conn->lll.periph.window_widening_event_us); + sync_offset_us += conn->lll.periph.window_widening_event_us; } #endif /* CONFIG_BT_PERIPHERAL */ diff --git a/tests/bluetooth/controller/ctrl_periodic_sync/src/main.c b/tests/bluetooth/controller/ctrl_periodic_sync/src/main.c index 38ddbccb88cd..68803a41b454 100644 --- a/tests/bluetooth/controller/ctrl_periodic_sync/src/main.c +++ b/tests/bluetooth/controller/ctrl_periodic_sync/src/main.c @@ -147,14 +147,14 @@ ZTEST(periodic_sync_transfer, test_periodic_sync_transfer_loc) struct pdu_data_llctrl_periodic_sync_ind local_periodic_sync_ind = { .id = 0x00, - .conn_event_count = 0x00, + .conn_event_count = 0xFFFFU, .last_pa_event_counter = 0x00, .sid = 0x00, .addr_type = 0x00, .sca = 0x00, .phy = 0x00, .adv_addr = { 0, 0, 0, 0, 0, 0}, - .sync_conn_event_count = 0 + .sync_conn_event_count = 0xFFFFU, }; /* Reset and setup mayfly_enqueue_custom_fake */ @@ -346,26 +346,26 @@ ZTEST(periodic_sync_transfer, test_periodic_sync_transfer_rem_2) struct pdu_data_llctrl_periodic_sync_ind local_periodic_sync_ind = { .id = 0x00, - .conn_event_count = 0x01, + .conn_event_count = 0x0000U, .last_pa_event_counter = 0x00, .sid = 0x00, .addr_type = 0x00, .sca = 0x00, .phy = 0x00, .adv_addr = { 0, 0, 0, 0, 0, 0}, - .sync_conn_event_count = 0x01 + .sync_conn_event_count = 0x0000U, }; struct pdu_data_llctrl_periodic_sync_ind remote_periodic_sync_ind = { .id = 0x01, - .conn_event_count = 0x00, + .conn_event_count = 0x0000U, .last_pa_event_counter = 0x00, .sid = 0x00, .addr_type = 0x01, .sca = 0x00, .phy = 0x01, .adv_addr = { 0, 0, 0, 0, 0, 0}, - .sync_conn_event_count = 0 + .sync_conn_event_count = 0x0000U, }; /* Reset and setup fake functions */ @@ -481,14 +481,14 @@ ZTEST(periodic_sync_transfer, test_periodic_sync_transfer_loc_twice) struct pdu_data_llctrl_periodic_sync_ind local_periodic_sync_ind = { .id = 0x00, - .conn_event_count = 0x00, + .conn_event_count = 0xFFFFU, .last_pa_event_counter = 0x00, .sid = 0x00, .addr_type = 0x00, .sca = 0x00, .phy = 0x00, .adv_addr = { 0, 0, 0, 0, 0, 0}, - .sync_conn_event_count = 0 + .sync_conn_event_count = 0xFFFFU, }; /* Reset and setup mayfly_enqueue_custom_fake */ diff --git a/tests/bsim/bluetooth/audio/test_scripts/bap_bass_client_sync.sh b/tests/bsim/bluetooth/audio/test_scripts/bap_bass_client_sync.sh index 1e2df5a74af3..c296a02302ea 100755 --- a/tests/bsim/bluetooth/audio/test_scripts/bap_bass_client_sync.sh +++ b/tests/bsim/bluetooth/audio/test_scripts/bap_bass_client_sync.sh @@ -25,7 +25,7 @@ Execute ./bs_${BOARD_TS}_tests_bsim_bluetooth_audio_prj_conf \ Execute ./bs_${BOARD_TS}_tests_bsim_bluetooth_audio_prj_conf \ -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} -d=2 -testid=bass_broadcaster \ - -RealEncryption=1 -rs=79 -D=3 -start_offset=6e3 + -RealEncryption=1 -rs=69 -D=3 # Simulation time should be larger than the WAIT_TIME in common.h Execute ./bs_2G4_phy_v1 -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} -D=3 \ From 5fe53aaa84b0dc44d29bd1be60df5c844bc7bafc Mon Sep 17 00:00:00 2001 From: Vinayak Kariappa Chettimada Date: Tue, 6 Jan 2026 22:17:48 +0100 Subject: [PATCH 0148/6328] Bluetooth: Controller: Use PPI/DPPI to start s/w switch timer Use PPI/DPPI to start s/w switch timer to reduce current consumption. Explicitly starting the s/w switch timer at prepare meant current being consumed in the prepare margin duration. Use of PPI/DPPI ensure s/w switch timer is start when event timer is started after the prepare margin. Signed-off-by: Vinayak Kariappa Chettimada --- .../controller/ll_sw/nordic/hal/nrf5/radio/radio.c | 4 ++-- .../ll_sw/nordic/hal/nrf5/radio/radio_nrf5_dppi.h | 7 +++++++ .../ll_sw/nordic/hal/nrf5/radio/radio_nrf5_ppi.h | 8 ++++++++ 3 files changed, 17 insertions(+), 2 deletions(-) diff --git a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio.c b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio.c index 00ed03050fdb..5a85883cb10f 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio.c +++ b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio.c @@ -1479,8 +1479,8 @@ uint32_t radio_tmr_start(uint8_t trx, uint32_t ticks_start, uint32_t remainder) SW_SWITCH_TIMER->MODE = 0; SW_SWITCH_TIMER->PRESCALER = HAL_EVENT_TIMER_PRESCALER_VALUE; SW_SWITCH_TIMER->BITMODE = 0; /* 16 bit */ - /* FIXME: start along with EVENT_TIMER, to save power */ - nrf_timer_task_trigger(SW_SWITCH_TIMER, NRF_TIMER_TASK_START); + + hal_sw_switch_timer_start_ppi_config(); #endif /* !CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER */ hal_sw_switch_timer_clear_ppi_config(); diff --git a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5_dppi.h b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5_dppi.h index 1085f72f0b98..68cd9716985e 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5_dppi.h +++ b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5_dppi.h @@ -264,6 +264,13 @@ static inline void hal_trigger_aar_ppi_config(void) #define HAL_RADIO_GROUP_TASK_ENABLE_PUBLISH_END HAL_RADIO_PUBLISH_PHYEND #endif /* !CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER || CONFIG_BT_CTLR_DF */ +/* Start SW-switch timer on event timer start. + */ +static inline void hal_sw_switch_timer_start_ppi_config(void) +{ + nrf_timer_subscribe_set(SW_SWITCH_TIMER, NRF_TIMER_TASK_START, HAL_EVENT_TIMER_START_PPI); +} + /* Clear SW-switch timer on packet end: * wire the RADIO EVENTS_END event to SW_SWITCH_TIMER TASKS_CLEAR task. * diff --git a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5_ppi.h b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5_ppi.h index 4b29bb4fe21d..4cc1440d7b7a 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5_ppi.h +++ b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5_ppi.h @@ -292,6 +292,14 @@ static inline void hal_trigger_aar_ppi_config(void) #if !defined(CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER) +/* Start SW-switch timer on event timer start. + */ +static inline void hal_sw_switch_timer_start_ppi_config(void) +{ + nrf_ppi_fork_endpoint_setup(NRF_PPI, HAL_EVENT_TIMER_START_PPI, + (uint32_t)&(SW_SWITCH_TIMER->TASKS_START)); +} + /* Clear SW-switch timer on packet end: * wire the RADIO EVENTS_END event to SW_SWITCH_TIMER TASKS_CLEAR task. * From 73c182509c1f8e01287bab593ec3c9e83471eca0 Mon Sep 17 00:00:00 2001 From: Vinayak Kariappa Chettimada Date: Tue, 6 Jan 2026 23:02:37 +0100 Subject: [PATCH 0149/6328] Bluetooth: Controller: LLL prepare at margin Kconfig Introduce Kconfig option to enfore LLL prepare at margin irrespective of whether there is an overlapping state/role. Signed-off-by: Vinayak Kariappa Chettimada --- .../bluetooth/controller/Kconfig.ll_sw_split | 20 ++++++++++ .../controller/ll_sw/nordic/lll/lll.c | 39 +++++++++++++++++-- 2 files changed, 56 insertions(+), 3 deletions(-) diff --git a/subsys/bluetooth/controller/Kconfig.ll_sw_split b/subsys/bluetooth/controller/Kconfig.ll_sw_split index 98a74224f624..6b2c9f2575e8 100644 --- a/subsys/bluetooth/controller/Kconfig.ll_sw_split +++ b/subsys/bluetooth/controller/Kconfig.ll_sw_split @@ -914,6 +914,26 @@ config BT_CTLR_ULL_LOW_PRIO The interrupt priority for Ticker's Job IRQ and Upper Link Layer lower priority functions. +config BT_CTLR_LLL_PREPARE_AT_MARGIN + bool "LLL prepare at margin" + depends on !BT_CTLR_LOW_LAT + default y if SOC_COMPATIBLE_NRF54LX + help + Execute LLL prepare callback at the prepare margin, even when no + overlapping state/role is currently active. + + This will lead to an additional CPU wake up after initial one at the + prepare tick. LLL prepare callback is executed sufficient time before + the hard real time radio transmission or reception instant so that any + resource that may otherwise consume current if setup at prepare tick + can be delayed until the prepare margin elapses. + + Disable this option if resources that need to be ready at the hard + real time radio transmission or reception instant can be setup at + prepare tick without impacting current consumption until actual + requirement at the hard real time radio transmission or reception + instant. + config BT_CTLR_LOW_LAT bool "Low latency non-negotiating event preemption" depends on BT_CTLR_LOW_LAT_ULL && BT_CTLR_LOW_LAT_ULL_DONE diff --git a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll.c b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll.c index 9ff7e9007285..9a39b1fe3829 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll.c +++ b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll.c @@ -47,6 +47,7 @@ static struct { void *param; lll_is_abort_cb_t is_abort_cb; lll_abort_cb_t abort_cb; + uint8_t has_margin:1; } curr; #if defined(CONFIG_BT_CTLR_LOW_LAT_ULL_DONE) @@ -934,9 +935,13 @@ int lll_prepare_resolve(lll_is_abort_cb_t is_abort_cb, lll_abort_cb_t abort_cb, } /* Current event active or another prepare is ready in the pipeline */ - if ((!is_dequeue && !is_done_sync()) || - event.curr.abort_cb || ready_short || - (ready && is_resume)) { + if (((is_dequeue == 0U) && (is_done_sync() == 0U)) || + (event.curr.abort_cb != NULL) || + (ready_short != NULL) || + ((ready != NULL) && (is_resume != 0U)) || + (IS_ENABLED(CONFIG_BT_CTLR_LLL_PREPARE_AT_MARGIN) && + (prepare_param->defer == 0U) && + (event.curr.has_margin == 0U))) { #if defined(CONFIG_BT_CTLR_LOW_LAT) lll_prepare_cb_t resume_cb; #endif /* CONFIG_BT_CTLR_LOW_LAT */ @@ -1019,6 +1024,10 @@ int lll_prepare_resolve(lll_is_abort_cb_t is_abort_cb, lll_abort_cb_t abort_cb, event.curr.is_abort_cb = is_abort_cb; event.curr.abort_cb = abort_cb; + if (IS_ENABLED(CONFIG_BT_CTLR_LLL_PREPARE_AT_MARGIN)) { + event.curr.has_margin = 0U; + } + err = prepare_cb(prepare_param); if (!IS_ENABLED(CONFIG_BT_CTLR_ASSERT_OVERHEAD_START) && @@ -1277,6 +1286,23 @@ static void preempt(void *param) /* No event to abort */ if (!event.curr.abort_cb || !event.curr.param) { + /* When a radio event is placed back in the prepare pipeline as + * resume prepare and a done event is not to be generated; in + * these cases, event.curr.abort_cb is not NULL, but + * event.curr.param is NULL. Let us setup the preempt timeout to + * ensure the margin for certain. + */ + if (IS_ENABLED(CONFIG_BT_CTLR_LLL_PREPARE_AT_MARGIN) && + (event.curr.abort_cb == NULL)) { + /* Previous event is done before the prepare margin for + * the event ready in the pipeline when we are here now. + */ + event.curr.has_margin = 1U; + + /* Execute the enqueued ready LLL prepare callbacks */ + ull_prepare_dequeue(TICKER_USER_ID_LLL); + } + return; } @@ -1374,6 +1400,13 @@ static void preempt(void *param) LL_ASSERT_ERR(ready->prepare_param.param == param); } + if (IS_ENABLED(CONFIG_BT_CTLR_LLL_PREPARE_AT_MARGIN)) { + /* Here prepare margin has expired while a previous event is + * active, set the flag and proceed with abort. + */ + event.curr.has_margin = 1U; + } + /* Check if current event want to continue */ err = event.curr.is_abort_cb(ready->prepare_param.param, event.curr.param, &resume_cb); if (!err || (err == -EBUSY)) { From d845a2230e17fe3f31b12c4216f6d2cf55b1096a Mon Sep 17 00:00:00 2001 From: Lingao Meng Date: Tue, 20 Jan 2026 16:44:12 +0800 Subject: [PATCH 0150/6328] fs: nvs: prevent ATE writes at sector boundary In NVS, allocation table entries (ATEs) are written backwards within each sector. Under delete-only or delete-heavy workloads, a sector may contain only delete ATEs, causing the ATE write pointer to approach the sector boundary. Without an explicit boundary check, ATE writes may occur at offset 0 of the current sector, allowing the write pointer to underflow into the previous sector and corrupt unrelated data or metadata. Fix this by disallowing ATE writes when the write pointer is at the sector boundary. This ensures that ATE writes remain confined to the current sector and prevents pointer underflow across sectors. Signed-off-by: Lingao Meng --- subsys/fs/nvs/nvs.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/subsys/fs/nvs/nvs.c b/subsys/fs/nvs/nvs.c index 8a710d570fb1..833600f4ab17 100644 --- a/subsys/fs/nvs/nvs.c +++ b/subsys/fs/nvs/nvs.c @@ -1176,7 +1176,13 @@ ssize_t nvs_write(struct nvs_fs *fs, uint16_t id, const void *data, size_t len) goto end; } - if (fs->ate_wra >= (fs->data_wra + required_space)) { + /* ATEs grow backwards within a sector. In delete-only scenarios, + * a sector may contain only delete ATEs and no data entries. + * Prevent ATE writes at current start of sector to avoid crossing + * into the previous sector. + */ + if (fs->ate_wra >= (fs->data_wra + required_space) && + (fs->ate_wra & ADDR_OFFS_MASK) != 0) { rc = nvs_flash_wrt_entry(fs, id, data, len); if (rc) { From 155d22a11782293823fcac7233eea15f3cfb5efd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A5kon=20Amundsen?= Date: Tue, 20 Jan 2026 11:07:41 +0100 Subject: [PATCH 0151/6328] soc: kconfig: gen_uicr: elaborate on setting ERASEPROTECT MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Provide some information on how to find the command that is used for generating the UICR hex file so that its easier for users to know what command to use. Signed-off-by: Håkon Amundsen --- soc/nordic/common/uicr/Kconfig.gen_uicr | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/soc/nordic/common/uicr/Kconfig.gen_uicr b/soc/nordic/common/uicr/Kconfig.gen_uicr index 4ee6af87eaef..e287773c6055 100644 --- a/soc/nordic/common/uicr/Kconfig.gen_uicr +++ b/soc/nordic/common/uicr/Kconfig.gen_uicr @@ -56,6 +56,17 @@ config GEN_UICR_ERASEPROTECT Note that gen_uicr.py can be used directly to create a configuration with both enabled if needed. + The command used when invoking gen_uicr.py can be found in the build directory. + For ninja based builds the command is found in + build/uicr/build.ninja + For make based builds the command is found in + build/CMakefiles/gen_uicr.dir/build.make + + Add the '--eraseprotect' argument to this command to enable the configuration + that would be added by setting this option. Note that programming the + resulting UICR hex file would completely lock the UICR from any modification + for the lifetime of the device. + menu "UICR.APPROTECT - Access Port Protection" config GEN_UICR_APPROTECT_APPLICATION_PROTECTED From c9c23bef54ba328b257a844180694bcc784cfbd5 Mon Sep 17 00:00:00 2001 From: Mathieu Choplain Date: Tue, 20 Jan 2026 12:58:17 +0100 Subject: [PATCH 0152/6328] drivers: sensor: stm32_temp: use CAL_RES everywhere The raw "12" constant was used in a place where the "CAL_RES" define should have been used instead. Signed-off-by: Mathieu Choplain --- drivers/sensor/st/stm32_temp/stm32_temp.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/sensor/st/stm32_temp/stm32_temp.c b/drivers/sensor/st/stm32_temp/stm32_temp.c index d306caafb9e5..5cbf4f13cb85 100644 --- a/drivers/sensor/st/stm32_temp/stm32_temp.c +++ b/drivers/sensor/st/stm32_temp/stm32_temp.c @@ -18,7 +18,7 @@ LOG_MODULE_REGISTER(stm32_temp, CONFIG_SENSOR_LOG_LEVEL); -#define CAL_RES 12 +#define CAL_RES 12U #define MAX_CALIB_POINTS 2 #if DT_HAS_COMPAT_STATUS_OKAY(st_stm32_temp) @@ -275,7 +275,7 @@ static int stm32_temp_init(const struct device *dev) .channels = BIT(data->adc_cfg.channel_id), .buffer = &data->sample_buffer, .buffer_size = sizeof(data->sample_buffer), - .resolution = 12U, + .resolution = CAL_RES, }; return 0; From 32260932f61678bb9a08c3e15da79eed780fc793 Mon Sep 17 00:00:00 2001 From: Mathieu Choplain Date: Tue, 20 Jan 2026 13:02:02 +0100 Subject: [PATCH 0153/6328] drivers: sensor: stm32_temp: move constants to instance configuration Various fields were stored in the instance data despite being initialized at compile-time to a constant value. Move these fields to the instance configuration instead. Signed-off-by: Mathieu Choplain --- drivers/sensor/st/stm32_temp/stm32_temp.c | 37 ++++++++++++----------- 1 file changed, 20 insertions(+), 17 deletions(-) diff --git a/drivers/sensor/st/stm32_temp/stm32_temp.c b/drivers/sensor/st/stm32_temp/stm32_temp.c index 5cbf4f13cb85..b260b49d7436 100644 --- a/drivers/sensor/st/stm32_temp/stm32_temp.c +++ b/drivers/sensor/st/stm32_temp/stm32_temp.c @@ -38,9 +38,6 @@ LOG_MODULE_REGISTER(stm32_temp, CONFIG_SENSOR_LOG_LEVEL); #endif struct stm32_temp_data { - const struct device *adc; - const struct adc_channel_cfg adc_cfg; - ADC_TypeDef *adc_base; struct adc_sequence adc_seq; struct k_mutex mutex; int16_t sample_buffer; @@ -48,6 +45,10 @@ struct stm32_temp_data { }; struct stm32_temp_config { + const struct device *adc; + struct adc_channel_cfg adc_cfg; + ADC_TypeDef *adc_base; + #if !defined(HAS_CALIBRATION) float average_slope; /** Unit: mV/°C */ int v25; /** Unit: mV */ @@ -125,7 +126,7 @@ static float convert_adc_sample_to_temperature(const struct device *dev) { struct stm32_temp_data *data = dev->data; const struct stm32_temp_config *cfg = dev->config; - const uint16_t vdda_mv = adc_ref_internal(data->adc); + const uint16_t vdda_mv = adc_ref_internal(cfg->adc); float temperature; #if !defined(HAS_CALIBRATION) @@ -209,6 +210,7 @@ static float convert_adc_sample_to_temperature(const struct device *dev) static int stm32_temp_sample_fetch(const struct device *dev, enum sensor_channel chan) { + const struct stm32_temp_config *cfg = dev->config; struct stm32_temp_data *data = dev->data; struct adc_sequence *sp = &data->adc_seq; int rc; @@ -218,25 +220,25 @@ static int stm32_temp_sample_fetch(const struct device *dev, enum sensor_channel } k_mutex_lock(&data->mutex, K_FOREVER); - pm_device_runtime_get(data->adc); + pm_device_runtime_get(cfg->adc); - rc = adc_channel_setup(data->adc, &data->adc_cfg); + rc = adc_channel_setup(cfg->adc, &cfg->adc_cfg); if (rc) { - LOG_DBG("Setup AIN%u got %d", data->adc_cfg.channel_id, rc); + LOG_DBG("Setup AIN%u got %d", cfg->adc_cfg.channel_id, rc); goto unlock; } - adc_enable_tempsensor_channel(data->adc_base); + adc_enable_tempsensor_channel(cfg->adc_base); - rc = adc_read(data->adc, sp); + rc = adc_read(cfg->adc, sp); if (rc == 0) { data->raw = data->sample_buffer; } - adc_disable_tempsensor_channel(data->adc_base); + adc_disable_tempsensor_channel(cfg->adc_base); unlock: - pm_device_runtime_put(data->adc); + pm_device_runtime_put(cfg->adc); k_mutex_unlock(&data->mutex); return rc; @@ -261,18 +263,19 @@ static DEVICE_API(sensor, stm32_temp_driver_api) = { static int stm32_temp_init(const struct device *dev) { + const struct stm32_temp_config *cfg = dev->config; struct stm32_temp_data *data = dev->data; struct adc_sequence *asp = &data->adc_seq; k_mutex_init(&data->mutex); - if (!device_is_ready(data->adc)) { - LOG_ERR("Device %s is not ready", data->adc->name); + if (!device_is_ready(cfg->adc)) { + LOG_ERR("Device %s is not ready", cfg->adc->name); return -ENODEV; } *asp = (struct adc_sequence){ - .channels = BIT(data->adc_cfg.channel_id), + .channels = BIT(cfg->adc_cfg.channel_id), .buffer = &data->sample_buffer, .buffer_size = sizeof(data->sample_buffer), .resolution = CAL_RES, @@ -298,7 +301,9 @@ BUILD_ASSERT(0, "ADC '" DT_NODE_FULL_NAME(DT_INST_IO_CHANNELS_CTLR(0)) "' needed */ #else -static struct stm32_temp_data stm32_temp_dev_data = { +static struct stm32_temp_data stm32_temp_dev_data; + +static const struct stm32_temp_config stm32_temp_dev_config = { .adc = DEVICE_DT_GET(DT_INST_IO_CHANNELS_CTLR(0)), .adc_base = (ADC_TypeDef *)DT_REG_ADDR(DT_INST_IO_CHANNELS_CTLR(0)), .adc_cfg = { @@ -308,9 +313,7 @@ static struct stm32_temp_data stm32_temp_dev_data = { .channel_id = DT_INST_IO_CHANNELS_INPUT(0), .differential = 0 }, -}; -static const struct stm32_temp_config stm32_temp_dev_config = { #if defined(HAS_CALIBRATION) .ts_cal1_addr = (const void *)DT_INST_PROP(0, ts_cal1_addr), .ts_cal1_temp = DT_INST_PROP(0, ts_cal1_temp), From bc9efec89675666ef9125722049db3c13f35db90 Mon Sep 17 00:00:00 2001 From: Mathieu Choplain Date: Tue, 20 Jan 2026 13:59:37 +0100 Subject: [PATCH 0154/6328] drivers: sensor: stm32_temp: use union as calibration info type MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Using a union enables accessing the calibration data using member names instead of an array index, which makes the code more readable. As long as the layout of struct { T m1; ... T mN; } and array A[N] is the same (implementation-specific?), usage of the union type as done should be Standard-compliant: accessing through either member of the union will use an lvalue with compatible type to the same underlying object, which is one of the allowed aliasing situations listed in §6.5.7 of N1548. Signed-off-by: Mathieu Choplain --- drivers/sensor/st/stm32_temp/stm32_temp.c | 33 ++++++++++++++--------- 1 file changed, 20 insertions(+), 13 deletions(-) diff --git a/drivers/sensor/st/stm32_temp/stm32_temp.c b/drivers/sensor/st/stm32_temp/stm32_temp.c index b260b49d7436..22a45e1346b9 100644 --- a/drivers/sensor/st/stm32_temp/stm32_temp.c +++ b/drivers/sensor/st/stm32_temp/stm32_temp.c @@ -37,6 +37,17 @@ LOG_MODULE_REGISTER(stm32_temp, CONFIG_SENSOR_LOG_LEVEL); #define HAS_CALIBRATION 1 #endif +union stm32_dietemp_calib_data { + uint16_t raw[MAX_CALIB_POINTS]; + + struct { + uint16_t ts_cal1; +#if defined(HAS_DUAL_CALIBRATION) + uint16_t ts_cal2; +#endif /* HAS_DUAL_CALIBRATION */ + }; +}; + struct stm32_temp_data { struct adc_sequence adc_seq; struct k_mutex mutex; @@ -94,12 +105,8 @@ static uint32_t fetch_mfg_data(const void *addr) return sys_read16((mem_addr_t)addr); } -/** - * @returns TS_CAL1 in calib_data[0] - * TS_CAL2 in calib_data[1] if applicable - */ static void read_calibration_data(const struct stm32_temp_config *cfg, - uint32_t calib_data[MAX_CALIB_POINTS]) + union stm32_dietemp_calib_data *cd) { #if defined(CONFIG_SOC_SERIES_STM32H5X) /* Disable the ICACHE to ensure all memory accesses are non-cacheable. @@ -109,9 +116,9 @@ static void read_calibration_data(const struct stm32_temp_config *cfg, sys_cache_instr_disable(); #endif /* CONFIG_SOC_SERIES_STM32H5X */ - calib_data[0] = fetch_mfg_data(cfg->ts_cal1_addr); + cd->raw[0] = fetch_mfg_data(cfg->ts_cal1_addr); #if defined(HAS_DUAL_CALIBRATION) - calib_data[1] = fetch_mfg_data(cfg->ts_cal2_addr); + cd->raw[1] = fetch_mfg_data(cfg->ts_cal2_addr); #endif @@ -156,9 +163,9 @@ static float convert_adc_sample_to_temperature(const struct device *dev) temperature /= cfg->average_slope; temperature += 25.0f; #else /* HAS_CALIBRATION */ - uint32_t calib[MAX_CALIB_POINTS]; + union stm32_dietemp_calib_data cd; - read_calibration_data(cfg, calib); + read_calibration_data(cfg, &cd); const float sense_data = ((float)vdda_mv / cfg->calib_vrefanalog) * data->raw; @@ -182,9 +189,9 @@ static float convert_adc_sample_to_temperature(const struct device *dev) float dividend; if (cfg->is_ntc) { - dividend = ((float)(calib[0] >> cfg->calib_data_shift) - sense_data); + dividend = ((float)(cd.ts_cal1 >> cfg->calib_data_shift) - sense_data); } else { - dividend = (sense_data - (calib[0] >> cfg->calib_data_shift)); + dividend = (sense_data - (cd.ts_cal1 >> cfg->calib_data_shift)); } temperature = (dividend / avg_slope_code) + cfg->ts_cal1_temp; @@ -198,9 +205,9 @@ static float convert_adc_sample_to_temperature(const struct device *dev) * (TS_CAL2 - TS_CAL1) */ const float slope = ((float)(cfg->ts_cal2_temp - cfg->ts_cal1_temp)) - / ((calib[1] - calib[0]) >> cfg->calib_data_shift); + / ((cd.ts_cal2 - cd.ts_cal1) >> cfg->calib_data_shift); - temperature = (slope * (sense_data - (calib[0] >> cfg->calib_data_shift))) + temperature = (slope * (sense_data - (cd.ts_cal1 >> cfg->calib_data_shift))) + cfg->ts_cal1_temp; #endif /* HAS_SINGLE_CALIBRATION */ #endif /* HAS_CALIBRATION */ From 4228409128450bb08ed8efc1973516df63d1b2a9 Mon Sep 17 00:00:00 2001 From: Mathieu Choplain Date: Tue, 20 Jan 2026 14:18:05 +0100 Subject: [PATCH 0155/6328] drivers: sensor: stm32_temp: read calibration data once during init Instead of reading calibration data (device-unique, but never changing!) as part of each conversion, perform the read once and cache the value. This notably avoids frequently an ICACHE disable/enable cycle on STM32H5, which is a somewhat slow operation. Signed-off-by: Mathieu Choplain --- drivers/sensor/st/stm32_temp/stm32_temp.c | 87 ++++++++++++----------- 1 file changed, 46 insertions(+), 41 deletions(-) diff --git a/drivers/sensor/st/stm32_temp/stm32_temp.c b/drivers/sensor/st/stm32_temp/stm32_temp.c index 22a45e1346b9..02ed4e906e56 100644 --- a/drivers/sensor/st/stm32_temp/stm32_temp.c +++ b/drivers/sensor/st/stm32_temp/stm32_temp.c @@ -51,6 +51,9 @@ union stm32_dietemp_calib_data { struct stm32_temp_data { struct adc_sequence adc_seq; struct k_mutex mutex; +#if defined(HAS_CALIBRATION) + union stm32_dietemp_calib_data calib_data; +#endif /* HAS_CALIBRATION */ int16_t sample_buffer; int16_t raw; /* raw adc Sensor value */ }; @@ -96,39 +99,6 @@ static inline void adc_disable_tempsensor_channel(ADC_TypeDef *adc) path & ~LL_ADC_PATH_INTERNAL_TEMPSENSOR); } -#if defined(HAS_CALIBRATION) -static uint32_t fetch_mfg_data(const void *addr) -{ - /* On all STM32 series, the calibration data is stored - * as 16-bit data in the manufacturing flash region - */ - return sys_read16((mem_addr_t)addr); -} - -static void read_calibration_data(const struct stm32_temp_config *cfg, - union stm32_dietemp_calib_data *cd) -{ -#if defined(CONFIG_SOC_SERIES_STM32H5X) - /* Disable the ICACHE to ensure all memory accesses are non-cacheable. - * This is required on STM32H5, where the manufacturing flash must be - * accessed in non-cacheable mode - otherwise, a bus error occurs. - */ - sys_cache_instr_disable(); -#endif /* CONFIG_SOC_SERIES_STM32H5X */ - - cd->raw[0] = fetch_mfg_data(cfg->ts_cal1_addr); -#if defined(HAS_DUAL_CALIBRATION) - cd->raw[1] = fetch_mfg_data(cfg->ts_cal2_addr); -#endif - - -#if defined(CONFIG_SOC_SERIES_STM32H5X) - /* Re-enable the ICACHE (unconditonally - it should always be turned on) */ - sys_cache_instr_enable(); -#endif /* CONFIG_SOC_SERIES_STM32H5X */ -} -#endif /* HAS_CALIBRATION */ - static float convert_adc_sample_to_temperature(const struct device *dev) { struct stm32_temp_data *data = dev->data; @@ -163,10 +133,7 @@ static float convert_adc_sample_to_temperature(const struct device *dev) temperature /= cfg->average_slope; temperature += 25.0f; #else /* HAS_CALIBRATION */ - union stm32_dietemp_calib_data cd; - - read_calibration_data(cfg, &cd); - + const union stm32_dietemp_calib_data *cd = &data->calib_data; const float sense_data = ((float)vdda_mv / cfg->calib_vrefanalog) * data->raw; #if defined(HAS_SINGLE_CALIBRATION) @@ -189,9 +156,9 @@ static float convert_adc_sample_to_temperature(const struct device *dev) float dividend; if (cfg->is_ntc) { - dividend = ((float)(cd.ts_cal1 >> cfg->calib_data_shift) - sense_data); + dividend = ((float)(cd->ts_cal1 >> cfg->calib_data_shift) - sense_data); } else { - dividend = (sense_data - (cd.ts_cal1 >> cfg->calib_data_shift)); + dividend = (sense_data - (cd->ts_cal1 >> cfg->calib_data_shift)); } temperature = (dividend / avg_slope_code) + cfg->ts_cal1_temp; @@ -205,9 +172,9 @@ static float convert_adc_sample_to_temperature(const struct device *dev) * (TS_CAL2 - TS_CAL1) */ const float slope = ((float)(cfg->ts_cal2_temp - cfg->ts_cal1_temp)) - / ((cd.ts_cal2 - cd.ts_cal1) >> cfg->calib_data_shift); + / ((cd->ts_cal2 - cd->ts_cal1) >> cfg->calib_data_shift); - temperature = (slope * (sense_data - (cd.ts_cal1 >> cfg->calib_data_shift))) + temperature = (slope * (sense_data - (cd->ts_cal1 >> cfg->calib_data_shift))) + cfg->ts_cal1_temp; #endif /* HAS_SINGLE_CALIBRATION */ #endif /* HAS_CALIBRATION */ @@ -268,6 +235,39 @@ static DEVICE_API(sensor, stm32_temp_driver_api) = { .channel_get = stm32_temp_channel_get, }; +#if defined(HAS_CALIBRATION) +static uint32_t fetch_mfg_data(const void *addr) +{ + /* On all STM32 series, the calibration data is stored + * as 16-bit data in the manufacturing flash region + */ + return sys_read16((mem_addr_t)addr); +} + +static void read_calibration_data(const struct stm32_temp_config *cfg, + union stm32_dietemp_calib_data *cd) +{ +#if defined(CONFIG_SOC_SERIES_STM32H5X) + /* Disable the ICACHE to ensure all memory accesses are non-cacheable. + * This is required on STM32H5, where the manufacturing flash must be + * accessed in non-cacheable mode - otherwise, a bus error occurs. + */ + sys_cache_instr_disable(); +#endif /* CONFIG_SOC_SERIES_STM32H5X */ + + cd->raw[0] = fetch_mfg_data(cfg->ts_cal1_addr); +#if defined(HAS_DUAL_CALIBRATION) + cd->raw[1] = fetch_mfg_data(cfg->ts_cal2_addr); +#endif + + +#if defined(CONFIG_SOC_SERIES_STM32H5X) + /* Re-enable the ICACHE (unconditonally - it should always be turned on) */ + sys_cache_instr_enable(); +#endif /* CONFIG_SOC_SERIES_STM32H5X */ +} +#endif /* HAS_CALIBRATION */ + static int stm32_temp_init(const struct device *dev) { const struct stm32_temp_config *cfg = dev->config; @@ -281,6 +281,11 @@ static int stm32_temp_init(const struct device *dev) return -ENODEV; } +#if defined(HAS_CALIBRATION) + /* Read calibration data once during init */ + read_calibration_data(cfg, &data->calib_data); +#endif + *asp = (struct adc_sequence){ .channels = BIT(cfg->adc_cfg.channel_id), .buffer = &data->sample_buffer, From 2d7b42ddc540fe8855ebef0e1e3bf8c653e95520 Mon Sep 17 00:00:00 2001 From: Grzegorz Chwierut Date: Wed, 21 Jan 2026 12:13:38 +0100 Subject: [PATCH 0156/6328] tests: boot: mcuboot_direct_xip: escape plus signs in regex patterns The plus signs in version strings need to be escaped with double backslashes when used in regex patterns for the test harness. This ensures proper pattern matching during test execution. Signed-off-by: Grzegorz Chwierut --- tests/boot/mcuboot_direct_xip/testcase.yaml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/boot/mcuboot_direct_xip/testcase.yaml b/tests/boot/mcuboot_direct_xip/testcase.yaml index d546688af16f..0707aa2ddb23 100644 --- a/tests/boot/mcuboot_direct_xip/testcase.yaml +++ b/tests/boot/mcuboot_direct_xip/testcase.yaml @@ -21,8 +21,8 @@ tests: type: multi_line regex: - "Starting Direct-XIP bootloader" - - "Primary slot: version=0.0.0+0" - - "Secondary slot: version=0.0.0+0" + - "Primary slot: version=0.0.0\\+0" + - "Secondary slot: version=0.0.0\\+0" - "Image 0 loaded from the primary slot" - "Bootloader chainload address offset" - "Image version: v0.0.0" @@ -36,7 +36,7 @@ tests: regex: - "Starting Direct-XIP bootloader" - "Image 0 Primary slot: Image not found" - - "Secondary slot: version=0.0.0+0" + - "Secondary slot: version=0.0.0\\+0" - "Image 0 loaded from the secondary slot" - "Bootloader chainload address offset" - "Image version: v0.0.0" From 0a8564a9b93d1ff139df716ce635a7532d57d733 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Thu, 22 Jan 2026 10:42:50 +0100 Subject: [PATCH 0157/6328] dts: auxdisplay: add auxdisplay_0 label to sparkfun,serlcd example MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is technically a workaround for a limitation in the Pygments DTS lexer causing the highlighting to break when rendering this example in the documentation, but this is also an excuse to plug the label that is used in the official auxdisplay sample. Signed-off-by: Benjamin Cabé --- dts/bindings/auxdisplay/sparkfun,serlcd.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dts/bindings/auxdisplay/sparkfun,serlcd.yaml b/dts/bindings/auxdisplay/sparkfun,serlcd.yaml index d718d5706877..d72421f53fba 100644 --- a/dts/bindings/auxdisplay/sparkfun,serlcd.yaml +++ b/dts/bindings/auxdisplay/sparkfun,serlcd.yaml @@ -46,7 +46,7 @@ properties: examples: - | &i2c1 { - serlcd@72 { + auxdisplay_0: serlcd@72 { compatible = "sparkfun,serlcd"; reg = <0x72>; columns = <16>; From 2d0139aa22c06387799497f6b64f7988dc5a4aa3 Mon Sep 17 00:00:00 2001 From: Adrian Bonislawski Date: Thu, 22 Jan 2026 10:42:24 +0100 Subject: [PATCH 0158/6328] MAINTAINERS: add myself as collaborator to Intel Xtensa platforms Intel Platforms (Xtensa) Drivers: DAI Signed-off-by: Adrian Bonislawski --- MAINTAINERS.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/MAINTAINERS.yml b/MAINTAINERS.yml index 1656a133f92d..022b29120e38 100644 --- a/MAINTAINERS.yml +++ b/MAINTAINERS.yml @@ -1520,6 +1520,7 @@ Documentation Infrastructure: - lgirdwood - iuliana-prodan - dbaluta + - abonislawski files: - drivers/dai/ - doc/hardware/peripherals/audio/dai.rst @@ -3061,6 +3062,7 @@ Intel Platforms (Xtensa): - jxstelter - marcinszkudlinski - nashif + - abonislawski files: - boards/intel/adsp/ - soc/intel/intel_adsp/ From 195a3ff63ae7d54e4644f6d69dd9c1fb6fc94059 Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Thu, 22 Jan 2026 08:26:15 +0000 Subject: [PATCH 0159/6328] tests: dfu: img_util: Disable variant image for slot 1 build Fixes an issue whereby a variant of the slot 1 image is built... which would occupy the same slot that the test is building for, therefore disable using the new experimental variant image Kconfig in this configuration Signed-off-by: Jamie McCrae --- tests/subsys/dfu/img_util/sysbuild_slot1.conf | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/subsys/dfu/img_util/sysbuild_slot1.conf b/tests/subsys/dfu/img_util/sysbuild_slot1.conf index 06c8ad027910..2c9a6189cdcf 100644 --- a/tests/subsys/dfu/img_util/sysbuild_slot1.conf +++ b/tests/subsys/dfu/img_util/sysbuild_slot1.conf @@ -1,2 +1,3 @@ SB_CONFIG_BOOTLOADER_MCUBOOT=y SB_CONFIG_MCUBOOT_MODE_DIRECT_XIP=y +SB_CONFIG_MCUBOOT_DIRECT_XIP_GENERATE_VARIANT=n From 53e6b7d54392069f5d06d0b5f0327f5f8b0bdf84 Mon Sep 17 00:00:00 2001 From: Johann Fischer Date: Wed, 21 Jan 2026 18:54:22 +0100 Subject: [PATCH 0160/6328] MAINTAINERS: remove jfischer-no from display collaborators I do not have any plans in the near future to collaborate in this area. Signed-off-by: Johann Fischer --- MAINTAINERS.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/MAINTAINERS.yml b/MAINTAINERS.yml index 022b29120e38..03479399096c 100644 --- a/MAINTAINERS.yml +++ b/MAINTAINERS.yml @@ -1181,7 +1181,6 @@ Display drivers: maintainers: - JarmouniA collaborators: - - jfischer-no - danieldegrasse - VynDragon - KATE-WANG-NXP From 59a57722aee0273079177e604a74f9a05f22f58a Mon Sep 17 00:00:00 2001 From: Flavio Ceolin Date: Tue, 20 Jan 2026 09:21:02 -0800 Subject: [PATCH 0161/6328] pm: Fix wrong type promotion In pm_system_suspend there is a possible invalid type promotion in sys_clock_set_timeout(MAX(0, ticks - exit_latency_ticks), true); ticks is int32_t and exit_latency_ticks is uint32_t consequently ticks is promoted to uint32_t resulting in a possible underflow and setting a wrong value in sys_clock_set_timeout(). Fixes #100005 Coverity CID: 535628 Signed-off-by: Flavio Ceolin --- subsys/pm/pm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/subsys/pm/pm.c b/subsys/pm/pm.c index 062c7bd623a0..13ed1ee7f0e0 100644 --- a/subsys/pm/pm.c +++ b/subsys/pm/pm.c @@ -214,7 +214,7 @@ bool pm_system_suspend(int32_t kernel_ticks) * is not passed as the next timeout. * */ - sys_clock_set_timeout(MAX(0, ticks - exit_latency_ticks), true); + sys_clock_set_timeout(MAX(0, (int64_t)ticks - (int64_t)exit_latency_ticks), true); } /* From 1350164d67e316068b779752a931a7cabfc629a0 Mon Sep 17 00:00:00 2001 From: Muhammad Waleed Badar Date: Tue, 20 Jan 2026 21:22:11 +0500 Subject: [PATCH 0162/6328] drivers: uart: bcm2711: fix poll_in uart_bcm2711_poll_in() incorrectly returned the received byte instead of writing it to the provided buffer. Update the implementation to store the character in *c and return 0 on success, matching the UART poll_in API. Signed-off-by: Muhammad Waleed Badar --- drivers/serial/uart_bcm2711.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/serial/uart_bcm2711.c b/drivers/serial/uart_bcm2711.c index 415fe2de54ce..6f07ea32a1b7 100644 --- a/drivers/serial/uart_bcm2711.c +++ b/drivers/serial/uart_bcm2711.c @@ -154,7 +154,10 @@ static int uart_bcm2711_poll_in(const struct device *dev, unsigned char *c) ; } - return sys_read32(uart_data->uart_addr + BCM2711_MU_IO) & 0xFF; + /* got a character */ + *c = sys_read32(uart_data->uart_addr + BCM2711_MU_IO) & 0xFF; + + return 0; } #ifdef CONFIG_UART_INTERRUPT_DRIVEN From df13dcc560382e4fc04efc23a634da92f4cea2f7 Mon Sep 17 00:00:00 2001 From: Scott Worley Date: Tue, 20 Jan 2026 11:03:27 -0500 Subject: [PATCH 0163/6328] dts: arm: microchip: mec: Fix MEC1653B code sram base address Microchip MEC1653B has 416KB of SRAM. ARM ICCM SRAM is 356KB starting at 0xC0000. ARM DCCM SRAM is 64KB starting at 0x118000. Chip DTS file had incorrect ICCM starting address. Signed-off-by: Scott Worley --- dts/arm/microchip/mec/mec5_mec1653bnsz.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dts/arm/microchip/mec/mec5_mec1653bnsz.dtsi b/dts/arm/microchip/mec/mec5_mec1653bnsz.dtsi index aee3d83bd2b2..1f7ead33331e 100644 --- a/dts/arm/microchip/mec/mec5_mec1653bnsz.dtsi +++ b/dts/arm/microchip/mec/mec5_mec1653bnsz.dtsi @@ -10,7 +10,7 @@ / { flash0: flash@b0000 { - reg = <0x000b0000 0x58000>; + reg = <0x000c0000 0x58000>; }; sram0: memory@118000 { From 0455416c52643462603aaa5446c5f9f45cdcc4e2 Mon Sep 17 00:00:00 2001 From: Maciej Perkowski Date: Tue, 20 Jan 2026 17:03:10 +0100 Subject: [PATCH 0164/6328] maintainers: Add fundakol as twister collaborator Lukasz Fundakowski is a python expert with an interest in testing frameworks and coding standards. He is a valuable reviewer with attention to details. He had a major impact on design and implementation of the pytest plugin for twister. Signed-off-by: Maciej Perkowski --- MAINTAINERS.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/MAINTAINERS.yml b/MAINTAINERS.yml index 03479399096c..c0433ae44d7b 100644 --- a/MAINTAINERS.yml +++ b/MAINTAINERS.yml @@ -5277,6 +5277,7 @@ Twister: - gchwier - LukaszMrugala - KamilxPaszkiet + - fundakol files: - scripts/twister - scripts/schemas/twister/ From c7fb653046808c80cf1d4102ab90d20dea73c75a Mon Sep 17 00:00:00 2001 From: Miika Karanki Date: Tue, 20 Jan 2026 15:04:31 +0200 Subject: [PATCH 0165/6328] serial: uart_native_pty: send UART_RX_DISABLED event When uart_rx_disable is called, or rx gets otherwise disabled, UART_RX_DISABLED event should be emitted. Signed-off-by: Miika Karanki --- drivers/serial/uart_native_pty.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/serial/uart_native_pty.c b/drivers/serial/uart_native_pty.c index 029ea47f92bb..abfdc7181bbe 100644 --- a/drivers/serial/uart_native_pty.c +++ b/drivers/serial/uart_native_pty.c @@ -402,6 +402,11 @@ static void native_pty_uart_async_poll_function(void *arg1, void *arg2, void *ar k_sleep(K_MSEC(10)); } } + + if (data->async.user_callback) { + evt.type = UART_RX_DISABLED; + data->async.user_callback(data->async.dev, &evt, data->async.user_data); + } } static int np_uart_rx_buf_rsp(const struct device *dev, uint8_t *buf, size_t len) From 5a0f33b31fa0fcfe7d2e862ad8d5f9cfed89869e Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Tue, 20 Jan 2026 12:33:12 +0100 Subject: [PATCH 0166/6328] net: sockets: tls: Enforce minimum TLS version Enforce the minimum TLS version on mbed TLS, based on the protocol version provided by the application when creating socket. This ensures that when application creates a TLS 1.3 socket, mbed TLS won't downgrade the session to TLS 1.2 for instance. Signed-off-by: Robert Lubos --- subsys/net/lib/sockets/sockets_tls.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/subsys/net/lib/sockets/sockets_tls.c b/subsys/net/lib/sockets/sockets_tls.c index cd81204d1837..04a599e5af72 100644 --- a/subsys/net/lib/sockets/sockets_tls.c +++ b/subsys/net/lib/sockets/sockets_tls.c @@ -1321,6 +1321,24 @@ static int tls_mbedtls_init(struct tls_context *context, bool is_server) } tls_set_max_frag_len(&context->config, context->type); + switch (context->tls_version) { + case NET_IPPROTO_TLS_1_3: + mbedtls_ssl_conf_min_tls_version(&context->config, MBEDTLS_SSL_VERSION_TLS1_3); + break; + case NET_IPPROTO_TLS_1_2: + case NET_IPPROTO_DTLS_1_2: + mbedtls_ssl_conf_min_tls_version(&context->config, MBEDTLS_SSL_VERSION_TLS1_2); + break; + case NET_IPPROTO_TLS_1_0: + case NET_IPPROTO_TLS_1_1: + case NET_IPPROTO_DTLS_1_0: + /* Nothing to do */ + break; + default: + NET_ASSERT(false, "Unknown (D)TLS version, cannot specify minimum requirement"); + break; + } + #if defined(MBEDTLS_SSL_RENEGOTIATION) mbedtls_ssl_conf_legacy_renegotiation(&context->config, MBEDTLS_SSL_LEGACY_BREAK_HANDSHAKE); From 8a5c82ae1d307037315cf33eee19e6d816a248b1 Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Tue, 20 Jan 2026 12:40:38 +0100 Subject: [PATCH 0167/6328] doc: net: sockets: tls: Document the meaning of the protocol version Document explicitly that the TLS version passed in the protocol parameter matters and specifies the minimum TLS version to use for the socket. Signed-off-by: Robert Lubos --- doc/connectivity/networking/api/sockets.rst | 3 +++ 1 file changed, 3 insertions(+) diff --git a/doc/connectivity/networking/api/sockets.rst b/doc/connectivity/networking/api/sockets.rst index ea33ec1a6c21..24dcfa0c622a 100644 --- a/doc/connectivity/networking/api/sockets.rst +++ b/doc/connectivity/networking/api/sockets.rst @@ -153,6 +153,9 @@ A secure socket can be created by specifying secure protocol type, for instance: sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TLS_1_2); +The protocol version specified when creating the secure socket indicates the +minimum TLS version used for the TLS session. + Once created, it can be configured with socket options. For instance, the CA certificate and hostname can be set: From a34409f0065a13e6be6fd8f897d2388f634cba57 Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Tue, 20 Jan 2026 13:17:41 +0100 Subject: [PATCH 0168/6328] doc: migration-guide-4.4: Document secure socket version enforcement Document that TLS version passed to a zsock_socket() function is no longer ignored and is now enforced as the minimum TLS version for the TLS session. Signed-off-by: Robert Lubos --- doc/releases/migration-guide-4.4.rst | 3 +++ 1 file changed, 3 insertions(+) diff --git a/doc/releases/migration-guide-4.4.rst b/doc/releases/migration-guide-4.4.rst index 50ff539a76e6..8240315e057e 100644 --- a/doc/releases/migration-guide-4.4.rst +++ b/doc/releases/migration-guide-4.4.rst @@ -704,6 +704,9 @@ Networking handle this status in the handler callback to properly reset resource state after successful response transmission. +* The protocol version passed to :c:func:`zsock_socket` when creating a secure socket is now + enforced as the minimum TLS version to use for the TLS session. + Modem ***** From 8f5f337419b502d511518f03a1b641aaf39378b2 Mon Sep 17 00:00:00 2001 From: Yangbo Lu Date: Tue, 20 Jan 2026 14:40:38 +0800 Subject: [PATCH 0169/6328] dts: arm: nxp_imx93_m33: add lpi2c dts nodes Added lpi2c dts nodes. Signed-off-by: Yangbo Lu --- dts/arm/nxp/nxp_imx93_m33.dtsi | 92 +++++++++++++++++++++++++++++++++- 1 file changed, 90 insertions(+), 2 deletions(-) diff --git a/dts/arm/nxp/nxp_imx93_m33.dtsi b/dts/arm/nxp/nxp_imx93_m33.dtsi index 4c61033a2c27..061dc2bbb556 100644 --- a/dts/arm/nxp/nxp_imx93_m33.dtsi +++ b/dts/arm/nxp/nxp_imx93_m33.dtsi @@ -1,12 +1,12 @@ /* - * Copyright 2024-2025 NXP - * + * SPDX-FileCopyrightText: Copyright 2024-2026 NXP * SPDX-License-Identifier: Apache-2.0 */ #include #include #include +#include #include #include @@ -42,6 +42,72 @@ reg = <0x20000000 DT_SIZE_K(124)>; }; + lpi2c3: i2c@42530000 { + compatible = "nxp,lpi2c"; + clock-frequency = ; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x42530000 0x4000>; + interrupts = <62 0>; + clocks = <&ccm IMX_CCM_LPI2C3_CLK 0x70 10>; + status = "disabled"; + }; + + lpi2c4: i2c@42540000 { + compatible = "nxp,lpi2c"; + clock-frequency = ; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x42540000 0x4000>; + interrupts = <63 0>; + clocks = <&ccm IMX_CCM_LPI2C4_CLK 0x80 24>; + status = "disabled"; + }; + + lpi2c5: i2c@426b0000 { + compatible = "nxp,lpi2c"; + clock-frequency = ; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x426b0000 0x4000>; + interrupts = <195 0>; + clocks = <&ccm IMX_CCM_LPI2C5_CLK 0x80 24>; + status = "disabled"; + }; + + lpi2c6: i2c@426c0000 { + compatible = "nxp,lpi2c"; + clock-frequency = ; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x426c0000 0x4000>; + interrupts = <196 0>; + clocks = <&ccm IMX_CCM_LPI2C6_CLK 0x80 24>; + status = "disabled"; + }; + + lpi2c7: i2c@426d0000 { + compatible = "nxp,lpi2c"; + clock-frequency = ; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x426d0000 0x4000>; + interrupts = <197 0>; + clocks = <&ccm IMX_CCM_LPI2C7_CLK 0x80 24>; + status = "disabled"; + }; + + lpi2c8: i2c@426e0000 { + compatible = "nxp,lpi2c"; + clock-frequency = ; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x426e0000 0x4000>; + interrupts = <198 0>; + clocks = <&ccm IMX_CCM_LPI2C8_CLK 0x80 24>; + status = "disabled"; + }; + mu1: mailbox@44220000 { compatible = "nxp,mbox-imx-mu"; reg = <0x44220000 DT_SIZE_K(4)>; @@ -50,6 +116,28 @@ status = "disabled"; }; + lpi2c1: i2c@44340000 { + compatible = "nxp,lpi2c"; + clock-frequency = ; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x44340000 0x4000>; + interrupts = <13 0>; + clocks = <&ccm IMX_CCM_LPI2C1_CLK 0x70 6>; + status = "disabled"; + }; + + lpi2c2: i2c@44350000 { + compatible = "nxp,lpi2c"; + clock-frequency = ; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x44350000 0x4000>; + interrupts = <14 0>; + clocks = <&ccm IMX_CCM_LPI2C2_CLK 0x70 8>; + status = "disabled"; + }; + iomuxc: iomuxc@443c0000 { compatible = "nxp,imx-iomuxc"; reg = <0x443c0000 DT_SIZE_K(64)>; From 41f296bc012f9128ab4dcbecb1225c235ebaf23e Mon Sep 17 00:00:00 2001 From: Yangbo Lu Date: Tue, 20 Jan 2026 16:44:29 +0800 Subject: [PATCH 0170/6328] boards: nxp: imx93_evk_mimx9352_m33: enable lpi2c2 Enabled lpi2c2, and verified with I2C shell commands. uart:~$ i2c scan i2c@44350000 0 1 2 3 4 5 6 7 8 9 a b c d e f 00: -- -- -- -- -- -- -- -- -- -- -- -- 10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 20: -- -- 22 -- -- 25 -- -- -- -- -- -- -- -- -- -- 30: -- -- -- -- 34 -- -- -- -- -- -- -- -- -- -- -- 40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 70: -- -- -- -- -- -- -- -- 3 devices found on i2c@44350000 uart:~$ uart:~$ i2c read i2c@44350000 0x22 0x4 1 00000000: ff uart:~$ i2c write i2c@44350000 0x22 0x4 0x0 1 uart:~$ i2c read i2c@44350000 0x22 0x4 1 00000000: 00 Signed-off-by: Yangbo Lu --- boards/nxp/imx93_evk/imx93_evk_mimx9352_m33.dts | 10 ++++++++-- boards/nxp/imx93_evk/imx93_evk_mimx9352_m33.yaml | 1 + 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/boards/nxp/imx93_evk/imx93_evk_mimx9352_m33.dts b/boards/nxp/imx93_evk/imx93_evk_mimx9352_m33.dts index fbab194989f8..87ca01471f92 100644 --- a/boards/nxp/imx93_evk/imx93_evk_mimx9352_m33.dts +++ b/boards/nxp/imx93_evk/imx93_evk_mimx9352_m33.dts @@ -1,6 +1,5 @@ /* - * Copyright 2024-2025 NXP - * + * SPDX-FileCopyrightText: Copyright 2024-2026 NXP * SPDX-License-Identifier: Apache-2.0 */ @@ -72,6 +71,13 @@ pinctrl-names = "default"; }; +&lpi2c2 { + status = "okay"; + clock-frequency = ; + pinctrl-0 = <&i2c2_default>; + pinctrl-names = "default"; +}; + &sar_adc1 { status = "okay"; }; diff --git a/boards/nxp/imx93_evk/imx93_evk_mimx9352_m33.yaml b/boards/nxp/imx93_evk/imx93_evk_mimx9352_m33.yaml index 62a2c3f06ec8..0f69285d14df 100644 --- a/boards/nxp/imx93_evk/imx93_evk_mimx9352_m33.yaml +++ b/boards/nxp/imx93_evk/imx93_evk_mimx9352_m33.yaml @@ -15,4 +15,5 @@ supported: - uart - pwm - adc + - i2c vendor: nxp From db5ec5f58fdea13cb0cd7e02b206241fd48635d7 Mon Sep 17 00:00:00 2001 From: Bill Waters Date: Fri, 16 Jan 2026 16:48:41 -0800 Subject: [PATCH 0171/6328] dts: arm: infineon: edge: pse84: ITCM/DTCM - There was a mistake with the CM33 core. It does not have ITCM/DTCM. Only the CM55 core does. - Also enabled ITCM/DTCM in the cm55 board file. Signed-off-by: Bill Waters --- .../kit_pse84_eval/kit_pse84_eval_m55.dts | 2 ++ dts/arm/infineon/edge/pse84/pse84.cm55.dtsi | 12 +++++++ dts/arm/infineon/edge/pse84/pse84.dtsi | 34 ------------------- 3 files changed, 14 insertions(+), 34 deletions(-) diff --git a/boards/infineon/kit_pse84_eval/kit_pse84_eval_m55.dts b/boards/infineon/kit_pse84_eval/kit_pse84_eval_m55.dts index bf62ee0fa668..7710376534c5 100644 --- a/boards/infineon/kit_pse84_eval/kit_pse84_eval_m55.dts +++ b/boards/infineon/kit_pse84_eval/kit_pse84_eval_m55.dts @@ -32,6 +32,8 @@ zephyr,sram = &m55_data; zephyr,console = &uart2; zephyr,shell-uart = &uart2; + zephyr,dtcm = &dtcm; + zephyr,itcm = &itcm; }; power-states { diff --git a/dts/arm/infineon/edge/pse84/pse84.cm55.dtsi b/dts/arm/infineon/edge/pse84/pse84.cm55.dtsi index 6d52796e6bda..455509b21118 100644 --- a/dts/arm/infineon/edge/pse84/pse84.cm55.dtsi +++ b/dts/arm/infineon/edge/pse84/pse84.cm55.dtsi @@ -19,6 +19,18 @@ clock-frequency = <400000000>; }; }; + + dtcm: dtcm@20000000 { + compatible = "zephyr,memory-region", "arm,dtcm"; + reg = <0x20000000 DT_SIZE_K(256)>; + zephyr,memory-region = "DTCM"; + }; + + itcm: itcm@0 { + compatible = "zephyr,memory-region", "arm,itcm"; + reg = <0x00000000 DT_SIZE_K(256)>; + zephyr,memory-region = "ITCM"; + }; }; &gpio_prt0 { diff --git a/dts/arm/infineon/edge/pse84/pse84.dtsi b/dts/arm/infineon/edge/pse84/pse84.dtsi index 3f41755e1841..e7352a1c79c0 100644 --- a/dts/arm/infineon/edge/pse84/pse84.dtsi +++ b/dts/arm/infineon/edge/pse84/pse84.dtsi @@ -13,40 +13,6 @@ reg = <0x24000000 0x100000>; }; - dtcm { - #address-cells = <1>; - #size-cells = <1>; - - dtcm_m33: dtcm_m33@48040000 { - compatible = "zephyr,memory-region", "arm,dtcm"; - reg = <0x48040000 DT_SIZE_K(256)>; - zephyr,memory-region = "DTCM_M33"; - }; - - dtcm_m55: dtcm_m55@20000000 { - compatible = "zephyr,memory-region", "arm,dtcm"; - reg = <0x20000000 DT_SIZE_K(256)>; - zephyr,memory-region = "DTCM_M55"; - }; - }; - - itcm { - #address-cells = <1>; - #size-cells = <1>; - - itcm_m33: itcm_m33@48000000 { - compatible = "zephyr,memory-region", "arm,itcm"; - reg = <0x48000000 DT_SIZE_K(256)>; - zephyr,memory-region = "ITCM_M33"; - }; - - itcm_m55: itcm_m55@0 { - compatible = "zephyr,memory-region", "arm,itcm"; - reg = <0x00000000 DT_SIZE_K(256)>; - zephyr,memory-region = "ITCM_M55"; - }; - }; - rram { #address-cells = <1>; #size-cells = <1>; From 77f933e7d3dfec9619bd5321d78ed0b974a3f41a Mon Sep 17 00:00:00 2001 From: Vincent Tardy Date: Thu, 20 Nov 2025 11:19:09 +0100 Subject: [PATCH 0172/6328] drivers: bluetooth: hci: fix RAM allocation in stm32wbax ble hci driver Remove useless allocated RAM in stm32wbax ble hci driver. Signed-off-by: Vincent Tardy --- drivers/bluetooth/hci/hci_stm32wba.c | 38 +--------------------------- 1 file changed, 1 insertion(+), 37 deletions(-) diff --git a/drivers/bluetooth/hci/hci_stm32wba.c b/drivers/bluetooth/hci/hci_stm32wba.c index a931c53e4936..faeac56d4886 100644 --- a/drivers/bluetooth/hci/hci_stm32wba.c +++ b/drivers/bluetooth/hci/hci_stm32wba.c @@ -40,24 +40,6 @@ static K_SEM_DEFINE(hci_sem, 1, 1); #define BLE_CTRLR_STACK_BUFFER_SIZE 300 -#define MBLOCK_COUNT (BLE_MBLOCKS_CALC(PREP_WRITE_LIST_SIZE, \ - CFG_BLE_ATT_MTU_MAX, \ - CFG_BLE_NUM_LINK) \ - + CFG_BLE_MBLOCK_COUNT_MARGIN) - -#define BLE_DYN_ALLOC_SIZE \ - (BLE_TOTAL_BUFFER_SIZE(CFG_BLE_NUM_LINK, \ - MBLOCK_COUNT, \ - (CFG_BLE_EATT_BEARER_PER_LINK * CFG_BLE_NUM_LINK))) - -/* GATT buffer size (in bytes)*/ -#define BLE_GATT_BUF_SIZE \ - BLE_TOTAL_BUFFER_SIZE_GATT(CFG_BLE_NUM_GATT_ATTRIBUTES, \ - CFG_BLE_NUM_GATT_SERVICES, \ - CFG_BLE_ATT_VALUE_ARRAY_SIZE) - -#define DIVC(x, y) (((x)+(y)-1)/(y)) - #if defined(CONFIG_BT_HCI_SETUP) /* Bluetooth LE public STM32WBA default device address (if udn not available) */ static bt_addr_t bd_addr_dflt = {{0x65, 0x43, 0x21, 0x1E, 0x08, 0x00}}; @@ -109,9 +91,6 @@ struct aci_reset { static uint8_t bt_hci_state = BT_HCI_STATE_DEINIT; -static uint32_t __noinit buffer[DIVC(BLE_DYN_ALLOC_SIZE, 4)]; -static uint32_t __noinit gatt_buffer[DIVC(BLE_GATT_BUF_SIZE, 4)]; - extern uint8_t ll_state_busy; #ifdef CONFIG_PM_DEVICE @@ -436,22 +415,7 @@ static int bt_ble_ctlr_init(void) { BleStack_init_t init_params_p = {0}; - init_params_p.numAttrRecord = CFG_BLE_NUM_GATT_ATTRIBUTES; - init_params_p.numAttrServ = CFG_BLE_NUM_GATT_SERVICES; - init_params_p.attrValueArrSize = CFG_BLE_ATT_VALUE_ARRAY_SIZE; - init_params_p.prWriteListSize = CFG_BLE_ATTR_PREPARE_WRITE_VALUE_SIZE; - init_params_p.attMtu = CFG_BLE_ATT_MTU_MAX; - init_params_p.max_coc_nbr = CFG_BLE_COC_NBR_MAX; - init_params_p.max_coc_mps = CFG_BLE_COC_MPS_MAX; - init_params_p.max_coc_initiator_nbr = CFG_BLE_COC_INITIATOR_NBR_MAX; - init_params_p.numOfLinks = CFG_BLE_NUM_LINK; - init_params_p.mblockCount = CFG_BLE_MBLOCK_COUNT; - init_params_p.bleStartRamAddress = (uint8_t *)buffer; - init_params_p.total_buffer_size = BLE_DYN_ALLOC_SIZE; - init_params_p.bleStartRamAddress_GATT = (uint8_t *)gatt_buffer; - init_params_p.total_buffer_size_GATT = BLE_GATT_BUF_SIZE; - init_params_p.options = CFG_BLE_OPTIONS; - init_params_p.debug = 0U; + init_params_p.options = BLE_OPTIONS_LL_ONLY | BLE_OPTIONS_EXTENDED_ADV; if (BleStack_Init(&init_params_p) != BLE_STATUS_SUCCESS) { return -EIO; From 86d55a8d81563f17a03a70a586c6eedaa5a7921e Mon Sep 17 00:00:00 2001 From: Vincent Tardy Date: Wed, 14 Jan 2026 11:32:34 +0100 Subject: [PATCH 0173/6328] drivers: bluetooth: hci: remove RAM allocation in send process Remove local Tx buffer allocated in the bt_hci_stm32wba_send() function. Get Event buffer resource to store data returned by lower layer and provide it to Host in case of Tx packet is an HCI Command type. Signed-off-by: Vincent Tardy --- drivers/bluetooth/hci/hci_stm32wba.c | 44 +++++++++++++++++++++++----- 1 file changed, 37 insertions(+), 7 deletions(-) diff --git a/drivers/bluetooth/hci/hci_stm32wba.c b/drivers/bluetooth/hci/hci_stm32wba.c index faeac56d4886..0e33a0ed9d1d 100644 --- a/drivers/bluetooth/hci/hci_stm32wba.c +++ b/drivers/bluetooth/hci/hci_stm32wba.c @@ -38,8 +38,6 @@ struct hci_data { static K_SEM_DEFINE(hci_sem, 1, 1); -#define BLE_CTRLR_STACK_BUFFER_SIZE 300 - #if defined(CONFIG_BT_HCI_SETUP) /* Bluetooth LE public STM32WBA default device address (if udn not available) */ static bt_addr_t bd_addr_dflt = {{0x65, 0x43, 0x21, 0x1E, 0x08, 0x00}}; @@ -387,7 +385,9 @@ uint8_t BLECB_Indication(const uint8_t *data, uint16_t length, static int bt_hci_stm32wba_send(const struct device *dev, struct net_buf *buf) { uint16_t event_length; - uint8_t tx_buffer[BLE_CTRLR_STACK_BUFFER_SIZE]; + struct hci_data *hci = dev->data; + struct net_buf *evt_buf = NULL; + uint8_t *data; ARG_UNUSED(dev); @@ -395,13 +395,43 @@ static int bt_hci_stm32wba_send(const struct device *dev, struct net_buf *buf) LOG_DBG("buf %p type %u len %u", buf, buf->data[0], buf->len); - memcpy(&tx_buffer, buf->data, buf->len); + if (buf->data[0] == BT_HCI_H4_CMD) { + /* + * Get Event Buffer which will be used to store Tx buffer and store + * the response event which is a Command Complete Event or a + * Command Status Event. + */ + evt_buf = bt_buf_get_evt(BT_HCI_EVT_CMD_COMPLETE, false, K_FOREVER); + if (!evt_buf) { + LOG_ERR("No available event buffers!"); + __ASSERT_NO_MSG(evt_buf); + return -ENOMEM; + } + /* + * Reset the event buffer length and copy the data packet to transmit + * in the event buffer resource. + */ + evt_buf->len = 0; + net_buf_add_mem(evt_buf, buf->data, buf->len); + data = evt_buf->data; + } else { + data = buf->data; + } - event_length = BleStack_Request(tx_buffer); + event_length = BleStack_Request(data); LOG_DBG("event_length: %u", event_length); - if (event_length) { - receive_data(dev, (uint8_t *)&tx_buffer, (size_t)event_length, NULL, 0); + if (evt_buf) { + if (event_length) { + /* + * Update the length of the event packet returned by + * the BleStack_Request() function. + */ + evt_buf->len = event_length; + hci->recv(dev, evt_buf); + } else { + net_buf_unref(evt_buf); + } } k_sem_give(&hci_sem); From 6ebf1963e8d1608133305faa030cd1a0895fff3f Mon Sep 17 00:00:00 2001 From: Maochen Wang Date: Wed, 14 Jan 2026 19:14:06 +0800 Subject: [PATCH 0174/6328] manifest: fix DPP remain_on_channel wait timeout The remain_on_channel callback triggers cookie_event, which checks pending_remain_on_channel before giving drv_resp_sem. Previously, pending_remain_on_channel was set after calling dev_ops->remain_on_channel, causing drv_resp_sem to timeout. Move the pending_remain_on_channel assignment before invoking dev_ops->remain_on_channel to ensure proper synchronization. Signed-off-by: Maochen Wang --- west.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/west.yml b/west.yml index ff2f3230cbe4..cf1eafd0dc20 100644 --- a/west.yml +++ b/west.yml @@ -291,7 +291,7 @@ manifest: - hal - name: hostap path: modules/lib/hostap - revision: 1a2fbb7910f23822a785294eab9f4922c6119711 + revision: 7c5d886f4b1afd6d00192e346268f03f5f44354c - name: liblc3 revision: 48bbd3eacd36e99a57317a0a4867002e0b09e183 path: modules/lib/liblc3 From 9d817c799232fc870dc2aeec2bfd99db4c0f6741 Mon Sep 17 00:00:00 2001 From: Albort Xue Date: Tue, 20 Jan 2026 15:48:34 +0800 Subject: [PATCH 0175/6328] drivers: flash: flash_mcux_flexspi_nor: fix QER S2B1v5 status reg case The JESD216_DW15_QER_VAL_S2B1v5 case had incorrect status register read/write logic. It was reading only SR2 but writing both SR1 and SR2, which could corrupt SR1 if not read first. Merge the S2B1v5 case with S2B1v1/v4 cases since they all set bit 1 of SR2. Update the common path to properly handle both single-byte (SR2 only) and two-byte (SR1+SR2) read/write operations by: - Reading SR1 first when rd_size is 2, saving it temporarily - Reading SR2 using the scratch command - Combining both bytes with SR2 in the upper byte when needed - Writing the combined value with the QE bit set Remove the now-redundant S2B1v5-specific case and simplify the LUT sequence to read SR2 directly instead of reading SR1 first. Signed-off-by: Albort Xue --- drivers/flash/flash_mcux_flexspi_nor.c | 52 +++++++++++++------------- 1 file changed, 25 insertions(+), 27 deletions(-) diff --git a/drivers/flash/flash_mcux_flexspi_nor.c b/drivers/flash/flash_mcux_flexspi_nor.c index 32f182b63f8c..e0b10aa6b576 100644 --- a/drivers/flash/flash_mcux_flexspi_nor.c +++ b/drivers/flash/flash_mcux_flexspi_nor.c @@ -597,17 +597,12 @@ static int flash_flexspi_nor_quad_enable(struct flash_flexspi_nor_data *data, return 0; case JESD216_DW15_QER_VAL_S2B1v1: case JESD216_DW15_QER_VAL_S2B1v4: + case JESD216_DW15_QER_VAL_S2B1v5: /* Install read and write status command */ flexspi_lut[SCRATCH_CMD][0] = FLEXSPI_LUT_SEQ( - kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, SPI_NOR_CMD_RDSR, - kFLEXSPI_Command_READ_SDR, kFLEXSPI_1PAD, 0x1); - flexspi_lut[SCRATCH_CMD][1] = FLEXSPI_LUT_SEQ( - kFLEXSPI_Command_JUMP_ON_CS, kFLEXSPI_1PAD, 0x2, - kFLEXSPI_Command_JUMP_ON_CS, kFLEXSPI_1PAD, 0x2); - flexspi_lut[SCRATCH_CMD][2] = FLEXSPI_LUT_SEQ( kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, SPI_NOR_CMD_RDSR2, kFLEXSPI_Command_READ_SDR, kFLEXSPI_1PAD, 0x1); - flexspi_lut[SCRATCH_CMD][3] = FLEXSPI_LUT_SEQ( + flexspi_lut[SCRATCH_CMD][1] = FLEXSPI_LUT_SEQ( kFLEXSPI_Command_STOP, kFLEXSPI_1PAD, 0x0, kFLEXSPI_Command_STOP, kFLEXSPI_1PAD, 0x0); flexspi_lut[SCRATCH_CMD2][0] = FLEXSPI_LUT_SEQ( @@ -647,20 +642,6 @@ static int flash_flexspi_nor_quad_enable(struct flash_flexspi_nor_data *data, rd_size = 1; wr_size = 1; break; - case JESD216_DW15_QER_VAL_S2B1v5: - /* Install read and write status command */ - flexspi_lut[SCRATCH_CMD][0] = FLEXSPI_LUT_SEQ( - kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, SPI_NOR_CMD_RDSR2, - kFLEXSPI_Command_READ_SDR, kFLEXSPI_1PAD, 0x1); - flexspi_lut[SCRATCH_CMD2][0] = FLEXSPI_LUT_SEQ( - kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, SPI_NOR_CMD_WRSR, - kFLEXSPI_Command_WRITE_SDR, kFLEXSPI_1PAD, 0x1); - - /* Set bit 1 of status register 2 */ - bit = BIT(9); - rd_size = 1; - wr_size = 2; - break; case JESD216_DW15_QER_VAL_S2B1v6: /* Install read and write status command */ flexspi_lut[SCRATCH_CMD][0] = FLEXSPI_LUT_SEQ( @@ -686,23 +667,40 @@ static int flash_flexspi_nor_quad_enable(struct flash_flexspi_nor_data *data, if (ret < 0) { return ret; } - transfer.dataSize = rd_size; + + uint8_t tmp_save = 0; + + if (rd_size == 2) { + /* Read first status register byte */ + transfer.dataSize = 1; + transfer.seqIndex = READ_STATUS_REG; + transfer.cmdType = kFLEXSPI_Read; + ret = memc_flexspi_transfer(&data->controller, &transfer); + if (ret < 0) { + return ret; + } + tmp_save = (uint8_t)(buffer & 0xFF); + } + + /* Read second status register byte */ + transfer.dataSize = 1; transfer.seqIndex = SCRATCH_CMD; transfer.cmdType = kFLEXSPI_Read; - /* Read status register */ ret = memc_flexspi_transfer(&data->controller, &transfer); if (ret < 0) { return ret; } + + if (rd_size == 2) { + /* Combine both bytes: SR2 in upper byte, SR1 in lower byte */ + buffer = ((buffer & 0xFF) << 8) | tmp_save; + } /* Enable write */ ret = flash_flexspi_nor_write_enable(data); if (ret < 0) { return ret; } - if (qer == JESD216_DW15_QER_VAL_S2B1v5) { - /* Left shift buffer by a byte */ - buffer = buffer << 8; - } + buffer |= bit; transfer.dataSize = wr_size; transfer.seqIndex = SCRATCH_CMD2; From 5a06cbdf82737a9792b47fe53594fe1f51dad1e0 Mon Sep 17 00:00:00 2001 From: Albort Xue Date: Tue, 20 Jan 2026 18:05:01 +0800 Subject: [PATCH 0176/6328] boards: mcx_nx4x_evk: correct W25Q64JV JEDEC ID The JEDEC ID for the Winbond W25Q64JV flash on the MCX NX4X EVK board was incorrectly specified as [ef 40 17]. According to the W25Q64JV datasheet, the correct JEDEC ID is [ef 60 17], where: - ef: Winbond manufacturer ID - 60: Memory type (W25Q series) - 17: Capacity (64 Mbit) Update the jedec-id property to match the actual flash device. Signed-off-by: Albort Xue --- boards/nxp/mcx_nx4x_evk/mcx_nx4x_evk.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/boards/nxp/mcx_nx4x_evk/mcx_nx4x_evk.dtsi b/boards/nxp/mcx_nx4x_evk/mcx_nx4x_evk.dtsi index 8332a3eea471..bc8a92d8d1f6 100644 --- a/boards/nxp/mcx_nx4x_evk/mcx_nx4x_evk.dtsi +++ b/boards/nxp/mcx_nx4x_evk/mcx_nx4x_evk.dtsi @@ -172,7 +172,7 @@ nxp_8080_touch_panel_i2c: &flexcomm2_lpi2c2 { size = ; reg = <0>; spi-max-frequency = ; - jedec-id = [ef 40 17]; + jedec-id = [ef 60 17]; erase-block-size = ; write-block-size = <1>; cs-interval-unit = <1>; From 565bb115499d8fb48fde745c5b77aa5c5e77dd24 Mon Sep 17 00:00:00 2001 From: Anil Ozrenk Date: Fri, 19 Dec 2025 10:39:18 +0300 Subject: [PATCH 0177/6328] cmake: xcc: prioritize board-specific toolchain version Change the toolchain version resolution order to check for board-specific TOOLCHAIN_VER_${NORMALIZED_BOARD_TARGET} first, falling back to the generic TOOLCHAIN_VER if not defined. Now if we want to use various boards lots of them uses same version but fewer ones differ. We won't have to define TOOLCHAIN_VER for every board. Signed-off-by: Anil Ozrenk --- cmake/toolchain/xcc/common.cmake | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/cmake/toolchain/xcc/common.cmake b/cmake/toolchain/xcc/common.cmake index 973b3bad97fc..12324d65d2c6 100644 --- a/cmake/toolchain/xcc/common.cmake +++ b/cmake/toolchain/xcc/common.cmake @@ -7,16 +7,9 @@ if(NOT EXISTS ${XTENSA_TOOLCHAIN_PATH}) message(FATAL_ERROR "Nothing found at XTENSA_TOOLCHAIN_PATH: '${XTENSA_TOOLCHAIN_PATH}'") endif() -zephyr_get(TOOLCHAIN_VER) -if(DEFINED TOOLCHAIN_VER) - set(XTENSA_TOOLCHAIN_VER ${TOOLCHAIN_VER}) -else() - zephyr_get(TOOLCHAIN_VER_${NORMALIZED_BOARD_TARGET}) - if(DEFINED TOOLCHAIN_VER_${NORMALIZED_BOARD_TARGET}) - set(XTENSA_TOOLCHAIN_VER ${TOOLCHAIN_VER_${NORMALIZED_BOARD_TARGET}}) - else() - message(FATAL "Environment variable TOOLCHAIN_VER must be set or given as -DTOOLCHAIN_VER=") - endif() +zephyr_get(XTENSA_TOOLCHAIN_VER VAR TOOLCHAIN_VER_${NORMALIZED_BOARD_TARGET} TOOLCHAIN_VER) +if(NOT DEFINED XTENSA_TOOLCHAIN_VER) + message(FATAL "Environment variable TOOLCHAIN_VER must be set or given as -DTOOLCHAIN_VER=") endif() zephyr_get(XTENSA_CORE_${NORMALIZED_BOARD_TARGET}) From e97559b6f2d93f9f5e418399d37bab19a66e89db Mon Sep 17 00:00:00 2001 From: Antoine Pradoux Date: Tue, 16 Dec 2025 16:17:26 +0100 Subject: [PATCH 0178/6328] dts: arm: st: Add RTC node for STM32U3 series - Add the rtc node for the stm32u3 - This enables RTC support for STM32U3 platforms once enabled Signed-off-by: Antoine Pradoux --- dts/arm/st/u3/stm32u3.dtsi | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/dts/arm/st/u3/stm32u3.dtsi b/dts/arm/st/u3/stm32u3.dtsi index 662a7936e919..8ac7b32e8980 100644 --- a/dts/arm/st/u3/stm32u3.dtsi +++ b/dts/arm/st/u3/stm32u3.dtsi @@ -401,6 +401,16 @@ status = "disabled"; }; + rtc: rtc@40007800 { + compatible = "st,stm32-rtc"; + reg = <0x40007800 0x400>; + interrupts = <2 0>; + clocks = <&rcc STM32_CLOCK(APB1, 30)>; + prescaler = <32768>; + alarms-count = <2>; + status = "disabled"; + }; + sai1_a: sai1@40015404 { compatible = "st,stm32-sai"; #address-cells = <1>; From c10819f93a4d4f8f7aca44e701513783837542b0 Mon Sep 17 00:00:00 2001 From: Antoine Pradoux Date: Tue, 16 Dec 2025 16:26:42 +0100 Subject: [PATCH 0179/6328] drivers: rtc: stm32: Add STM32U3 support for RTC alarm, clock & counter Extend RTC driver to handle STM32U3 series specifics: - Include STM32U3X in condition where RTC Alarm event is not routed to EXTI - Use LL_RCC_RTC_ClockEnable call for STM32U3 instead of LL_RCC_EnableRTC - Adapt counter_stm32_rtc driver for STM32U3 clock and EXTI handling Signed-off-by: Antoine Pradoux --- drivers/counter/counter_stm32_rtc.c | 32 ++++++++++++++++++++++------- drivers/rtc/rtc_stm32.c | 26 +++++++++++++++-------- 2 files changed, 42 insertions(+), 16 deletions(-) diff --git a/drivers/counter/counter_stm32_rtc.c b/drivers/counter/counter_stm32_rtc.c index 358e17abedc9..4bac7c26aefe 100644 --- a/drivers/counter/counter_stm32_rtc.c +++ b/drivers/counter/counter_stm32_rtc.c @@ -372,10 +372,15 @@ static int rtc_stm32_start(const struct device *dev) z_stm32_hsem_lock(CFG_HW_RCC_SEMID, HSEM_LOCK_DEFAULT_RETRY); stm32_backup_domain_enable_access(); +#ifdef CONFIG_SOC_SERIES_STM32U3X + /* STM32U3 series uses LL_RCC_RTC_ClockEnable instead of LL_RCC_EnableRTC */ + LL_RCC_RTC_ClockEnable(); +#else LL_RCC_EnableRTC(); +#endif /* CONFIG_SOC_SERIES_STM32U3X */ stm32_backup_domain_disable_access(); z_stm32_hsem_unlock(CFG_HW_RCC_SEMID); -#endif +#endif /* CONFIG_SOC_SERIES_STM32WBAX || CONFIG_SOC_SERIES_STM32U5X */ return 0; } @@ -397,10 +402,15 @@ static int rtc_stm32_stop(const struct device *dev) z_stm32_hsem_lock(CFG_HW_RCC_SEMID, HSEM_LOCK_DEFAULT_RETRY); stm32_backup_domain_enable_access(); +#ifdef CONFIG_SOC_SERIES_STM32U3X + /* STM32U3 series uses LL_RCC_RTC_ClockDisable instead of LL_RCC_DisableRTC */ + LL_RCC_RTC_ClockDisable(); +#else LL_RCC_DisableRTC(); +#endif /* CONFIG_SOC_SERIES_STM32U3X */ stm32_backup_domain_disable_access(); z_stm32_hsem_unlock(CFG_HW_RCC_SEMID); -#endif +#endif /* CONFIG_SOC_SERIES_STM32WBAX || CONFIG_SOC_SERIES_STM32U5X */ return 0; } @@ -724,8 +734,10 @@ void rtc_stm32_isr(const struct device *dev) || defined(CONFIG_SOC_SERIES_STM32L5X) \ || defined(CONFIG_SOC_SERIES_STM32H5X) LL_EXTI_ClearRisingFlag_0_31(RTC_EXTI_LINE); -#elif defined(CONFIG_SOC_SERIES_STM32U5X) || defined(CONFIG_SOC_SERIES_STM32WBAX) - /* in STM32U5 family RTC is not connected to EXTI */ +#elif defined(CONFIG_SOC_SERIES_STM32U3X) \ + || defined(CONFIG_SOC_SERIES_STM32U5X) \ + || defined(CONFIG_SOC_SERIES_STM32WBAX) + /* RTC is not connected to EXTI for these SoC series */ #else LL_EXTI_ClearFlag_0_31(RTC_EXTI_LINE); #endif @@ -771,8 +783,13 @@ static int rtc_stm32_init(const struct device *dev) } #if !defined(CONFIG_SOC_SERIES_STM32WBAX) +#ifdef CONFIG_SOC_SERIES_STM32U3X + /* STM32U3 series uses LL_RCC_RTC_ClockEnable instead of LL_RCC_EnableRTC */ + LL_RCC_RTC_ClockEnable(); +#else LL_RCC_EnableRTC(); -#endif +#endif /* CONFIG_SOC_SERIES_STM32U3X */ +#endif /* !CONFIG_SOC_SERIES_STM32WBAX */ z_stm32_hsem_unlock(CFG_HW_RCC_SEMID); @@ -799,8 +816,9 @@ static int rtc_stm32_init(const struct device *dev) #if defined(CONFIG_SOC_SERIES_STM32H7X) && defined(CONFIG_CPU_CORTEX_M4) LL_C2_EXTI_EnableIT_0_31(RTC_EXTI_LINE); LL_EXTI_EnableRisingTrig_0_31(RTC_EXTI_LINE); -#elif defined(CONFIG_SOC_SERIES_STM32U5X) || defined(CONFIG_SOC_SERIES_STM32WBAX) - /* in STM32U5 family RTC is not connected to EXTI */ +#elif defined(CONFIG_SOC_SERIES_STM32U3X) || defined(CONFIG_SOC_SERIES_STM32U5X) || \ + defined(CONFIG_SOC_SERIES_STM32WBAX) + /* RTC is not connected to EXTI for these SoC series */ #else LL_EXTI_EnableIT_0_31(RTC_EXTI_LINE); LL_EXTI_EnableRisingTrig_0_31(RTC_EXTI_LINE); diff --git a/drivers/rtc/rtc_stm32.c b/drivers/rtc/rtc_stm32.c index 6e94cb0b516e..dad243361754 100644 --- a/drivers/rtc/rtc_stm32.c +++ b/drivers/rtc/rtc_stm32.c @@ -132,8 +132,9 @@ struct rtc_stm32_data { static inline void exti_enable_rtc_alarm_it(uint32_t line_num) { -#if defined(CONFIG_SOC_SERIES_STM32U5X) || defined(CONFIG_SOC_SERIES_STM32WBAX) - /* in STM32U5 & STM32WBAX series, RTC Alarm event is not routed to EXTI */ +#if defined(CONFIG_SOC_SERIES_STM32U3X) || defined(CONFIG_SOC_SERIES_STM32U5X) || \ + defined(CONFIG_SOC_SERIES_STM32WBAX) + /* in STM32U3, STM32U5 & STM32WBAX series, RTC Alarm event is not routed to EXTI */ #else int ret; @@ -146,8 +147,9 @@ static inline void exti_enable_rtc_alarm_it(uint32_t line_num) static inline void exti_clear_rtc_alarm_flag(uint32_t line_num) { -#if defined(CONFIG_SOC_SERIES_STM32U5X) || defined(CONFIG_SOC_SERIES_STM32WBAX) - /* in STM32U5 & STM32WBAX series, RTC Alarm (EXTI event) is not routed to EXTI */ +#if defined(CONFIG_SOC_SERIES_STM32U3X) || defined(CONFIG_SOC_SERIES_STM32U5X) || \ + defined(CONFIG_SOC_SERIES_STM32WBAX) + /* in STM32U3, STM32U5 & STM32WBAX series, RTC Alarm (EXTI event) is not routed to EXTI */ #else if (stm32_exti_is_pending(line_num)) { stm32_exti_clear_pending(line_num); @@ -502,18 +504,24 @@ static int rtc_stm32_init(const struct device *dev) } /* - * On STM32WBAX series, there is no bit in BCDR register to enable RTC. - * Enabling RTC is done directly via the RCC APB register bit. - * On STM32WB0 series, LL_RCC_EnableRTC is not provided by STM32CubeWB0, - * but RTC IP clock has already been turned on - skip the call as well. + * On certain series, there is no bit in BCDR register to enable RTC; + * a single bit in RCC controls both the RTC and bus interface. On + * such series, the LL_RCC_EnableRTC function is usually not provided + * by the STM32Cube package, but it's fine to skip calling it since + * the RTC is already accessible thanks to clock_control_on() above. */ #if !defined(CONFIG_SOC_SERIES_STM32WBAX) && !defined(CONFIG_SOC_SERIES_STM32WB0X) z_stm32_hsem_lock(CFG_HW_RCC_SEMID, HSEM_LOCK_DEFAULT_RETRY); +#ifdef CONFIG_SOC_SERIES_STM32U3X + /* STM32U3 series uses LL_RCC_RTC_ClockEnable instead of LL_RCC_EnableRTC */ + LL_RCC_RTC_ClockEnable(); +#else LL_RCC_EnableRTC(); +#endif /* CONFIG_SOC_SERIES_STM32U3X */ z_stm32_hsem_unlock(CFG_HW_RCC_SEMID); -#endif /* CONFIG_SOC_SERIES_STM32WBAX */ +#endif /* !STM32WBAX && !STM32WB0X */ err = rtc_stm32_configure(dev); From 254c6e837798821624b8a46229556df2ecd04d50 Mon Sep 17 00:00:00 2001 From: Antoine Pradoux Date: Tue, 16 Dec 2025 16:21:41 +0100 Subject: [PATCH 0180/6328] boards: st: Enable RTC support on nucleo_u385rg_q board - Activate the RTC node in the device tree by enabling its clocks and setting its status to okay - Add 'rtc' to the supported features in the board YAML configuration Signed-off-by: Antoine Pradoux --- boards/st/nucleo_u385rg_q/nucleo_u385rg_q.dts | 6 ++++++ boards/st/nucleo_u385rg_q/nucleo_u385rg_q.yaml | 1 + 2 files changed, 7 insertions(+) diff --git a/boards/st/nucleo_u385rg_q/nucleo_u385rg_q.dts b/boards/st/nucleo_u385rg_q/nucleo_u385rg_q.dts index 1902855d8383..29e49b34f127 100644 --- a/boards/st/nucleo_u385rg_q/nucleo_u385rg_q.dts +++ b/boards/st/nucleo_u385rg_q/nucleo_u385rg_q.dts @@ -208,6 +208,12 @@ status = "okay"; }; +&rtc { + clocks = <&rcc STM32_CLOCK(APB1, 30)>, + <&rcc STM32_SRC_LSE RTC_SEL(1)>; + status = "okay"; +}; + zephyr_udc0: &usb { pinctrl-0 = <&usb_dm_pa11 &usb_dp_pa12>; pinctrl-names = "default"; diff --git a/boards/st/nucleo_u385rg_q/nucleo_u385rg_q.yaml b/boards/st/nucleo_u385rg_q/nucleo_u385rg_q.yaml index 058d6c327312..f6c5bfaa5853 100644 --- a/boards/st/nucleo_u385rg_q/nucleo_u385rg_q.yaml +++ b/boards/st/nucleo_u385rg_q/nucleo_u385rg_q.yaml @@ -22,5 +22,6 @@ supported: - watchdog - pwm - counter + - rtc ram: 256 flash: 1024 From 2cc03f791d7d5bef4b02d05af321cd6ae92d76d0 Mon Sep 17 00:00:00 2001 From: Antoine Pradoux Date: Tue, 16 Dec 2025 16:30:17 +0100 Subject: [PATCH 0181/6328] tests: rtc_api: Add RTC test configuration for nucleo_u385rg_q board - Add a new test configuration file enabling RTC calibration and alarm features for the nucleo_u385rg_q board - Add the nucleo_u385rg_q device tree overlay defining the RTC alias Signed-off-by: Antoine Pradoux --- tests/drivers/rtc/rtc_api/boards/nucleo_u385rg_q.conf | 2 ++ .../rtc/rtc_api/boards/nucleo_u385rg_q.overlay | 11 +++++++++++ 2 files changed, 13 insertions(+) create mode 100644 tests/drivers/rtc/rtc_api/boards/nucleo_u385rg_q.conf create mode 100644 tests/drivers/rtc/rtc_api/boards/nucleo_u385rg_q.overlay diff --git a/tests/drivers/rtc/rtc_api/boards/nucleo_u385rg_q.conf b/tests/drivers/rtc/rtc_api/boards/nucleo_u385rg_q.conf new file mode 100644 index 000000000000..8c6c114ee41f --- /dev/null +++ b/tests/drivers/rtc/rtc_api/boards/nucleo_u385rg_q.conf @@ -0,0 +1,2 @@ +CONFIG_RTC_CALIBRATION=y +CONFIG_RTC_ALARM=y diff --git a/tests/drivers/rtc/rtc_api/boards/nucleo_u385rg_q.overlay b/tests/drivers/rtc/rtc_api/boards/nucleo_u385rg_q.overlay new file mode 100644 index 000000000000..087d88680a18 --- /dev/null +++ b/tests/drivers/rtc/rtc_api/boards/nucleo_u385rg_q.overlay @@ -0,0 +1,11 @@ +/* + * Copyright (c) 2026 STMicroelectronics + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + aliases { + rtc = &rtc; + }; +}; From 4a914bf28157a9a255b4060799736b08e486541a Mon Sep 17 00:00:00 2001 From: Vinayak Kariappa Chettimada Date: Thu, 11 Dec 2025 14:23:31 +0100 Subject: [PATCH 0182/6328] Bluetooth: Host: ATT: Do not use bt_addr_le_to_str when CONFIG_LOG=n Do not use bt_addr_le_to_str() when CONFIG_LOG=n. Signed-off-by: Vinayak Kariappa Chettimada --- subsys/bluetooth/host/att.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/subsys/bluetooth/host/att.c b/subsys/bluetooth/host/att.c index eed079b08fc7..4c9a255653cb 100644 --- a/subsys/bluetooth/host/att.c +++ b/subsys/bluetooth/host/att.c @@ -376,7 +376,6 @@ static struct net_buf *att_create_rsp_pdu(struct bt_att_chan *chan, uint8_t op); static void att_disconnect(struct bt_att_chan *chan) { - char addr[BT_ADDR_LE_STR_LEN]; int err; /* In rare circumstances we are "forced" to disconnect the ATT bearer and the ACL. @@ -385,8 +384,7 @@ static void att_disconnect(struct bt_att_chan *chan) * invalid */ - bt_addr_le_to_str(bt_conn_get_dst(chan->att->conn), addr, sizeof(addr)); - LOG_DBG("ATT disconnecting device %s", addr); + LOG_DBG("ATT disconnecting device %s", bt_addr_le_str(bt_conn_get_dst(chan->att->conn))); bt_att_disconnected(&chan->chan.chan); @@ -3195,12 +3193,11 @@ static void att_chan_detach(struct bt_att_chan *chan) static void att_timeout(struct k_work *work) { - char addr[BT_ADDR_LE_STR_LEN]; struct k_work_delayable *dwork = k_work_delayable_from_work(work); struct bt_att_chan *chan = CONTAINER_OF(dwork, struct bt_att_chan, timeout_work); - bt_addr_le_to_str(bt_conn_get_dst(chan->att->conn), addr, sizeof(addr)); - LOG_ERR("ATT Timeout for device %s. Disconnecting...", addr); + LOG_ERR("ATT Timeout for device %s. Disconnecting...", + bt_addr_le_str(bt_conn_get_dst(chan->att->conn))); /* BLUETOOTH SPECIFICATION Version 4.2 [Vol 3, Part F] page 480: * From 2db3f7978f53dda8937b1bc9e9d49f4023f86a70 Mon Sep 17 00:00:00 2001 From: Vinayak Kariappa Chettimada Date: Thu, 11 Dec 2025 12:51:14 +0100 Subject: [PATCH 0183/6328] Bluetooth: Host: settings without snprintk use Update settings implementation for not reusing the OS snprintk implementation with CONFIG_PRINTK=n. Signed-off-by: Vinayak Kariappa Chettimada --- subsys/bluetooth/host/settings.c | 112 +++++++++++++++++++++++-------- subsys/bluetooth/host/settings.h | 2 +- 2 files changed, 84 insertions(+), 30 deletions(-) diff --git a/subsys/bluetooth/host/settings.c b/subsys/bluetooth/host/settings.c index 84b4f1eb4b6a..c93df66c3f77 100644 --- a/subsys/bluetooth/host/settings.c +++ b/subsys/bluetooth/host/settings.c @@ -33,28 +33,45 @@ LOG_MODULE_REGISTER(bt_settings); #if defined(CONFIG_BT_SETTINGS_USE_PRINTK) -void bt_settings_encode_key(char *path, size_t path_size, const char *subsys, +int bt_settings_encode_key(char *path, size_t path_size, const char *subsys, const bt_addr_le_t *addr, const char *key) { + int err; + if (key) { - snprintk(path, path_size, - "bt/%s/%02x%02x%02x%02x%02x%02x%u/%s", subsys, - addr->a.val[5], addr->a.val[4], addr->a.val[3], - addr->a.val[2], addr->a.val[1], addr->a.val[0], - addr->type, key); + err = snprintk(path, path_size, "bt/%s/%02x%02x%02x%02x%02x%02x%u/%s", subsys, + addr->a.val[5], addr->a.val[4], addr->a.val[3], addr->a.val[2], + addr->a.val[1], addr->a.val[0], addr->type, key); } else { - snprintk(path, path_size, - "bt/%s/%02x%02x%02x%02x%02x%02x%u", subsys, - addr->a.val[5], addr->a.val[4], addr->a.val[3], - addr->a.val[2], addr->a.val[1], addr->a.val[0], - addr->type); + err = snprintk(path, path_size, "bt/%s/%02x%02x%02x%02x%02x%02x%u", subsys, + addr->a.val[5], addr->a.val[4], addr->a.val[3], addr->a.val[2], + addr->a.val[1], addr->a.val[0], addr->type); + } + + if (err < 0) { + return -EINVAL; } LOG_DBG("Encoded path %s", path); + + return 0; } -#else -void bt_settings_encode_key(char *path, size_t path_size, const char *subsys, - const bt_addr_le_t *addr, const char *key) + +static int bt_settings_encode_key_no_addr(char *path, size_t path_size, const char *key) +{ + int err; + + err = snprintk(path, path_size, "bt/%s", key); + if (err < 0) { + return -EINVAL; + } + + return 0; +} + +#else /* !CONFIG_BT_SETTINGS_USE_PRINTK */ +int bt_settings_encode_key(char *path, size_t path_size, const char *subsys, + const bt_addr_le_t *addr, const char *key) { size_t len = 3; @@ -100,8 +117,41 @@ void bt_settings_encode_key(char *path, size_t path_size, const char *subsys, } LOG_DBG("Encoded path %s", path); + + return 0; } -#endif + +static int bt_settings_encode_key_no_addr(char *path, size_t path_size, const char *key) +{ + size_t len = 3; + + /* Skip if path_size is less than 3; strlen("bt/") */ + if (len < path_size) { + /* Key format: + * "bt/", "/" is optional + */ + strcpy(path, "bt/"); + + /* Concatenate key as much the free space permits */ + strncpy(&path[len], key, path_size - len); + len = strlen(path); + + /* If path string is full, always null terminate at path_size */ + if (len >= path_size) { + /* Truncate string */ + path[path_size - 1] = '\0'; + } + + } else if (path_size > 0) { + /* path_size not sufficient for "bt/" */ + *path = '\0'; + } + + LOG_DBG("Encoded path %s", path); + + return 0; +} +#endif /* !CONFIG_BT_SETTINGS_USE_PRINTK */ int bt_settings_decode_key(const char *key, bt_addr_le_t *addr) { @@ -324,21 +374,23 @@ __weak void bt_testing_settings_delete_hook(const char *key) int bt_settings_store(const char *key, uint8_t id, const bt_addr_le_t *addr, const void *value, size_t val_len) { - int err; - char id_str[4]; char key_str[BT_SETTINGS_KEY_MAX]; + char id_str[4]; + int err; if (addr) { if (id) { u8_to_dec(id_str, sizeof(id_str), id); } - bt_settings_encode_key(key_str, sizeof(key_str), key, addr, (id ? id_str : NULL)); + err = bt_settings_encode_key(key_str, sizeof(key_str), key, addr, + (id ? id_str : NULL)); } else { - err = snprintk(key_str, sizeof(key_str), "bt/%s", key); - if (err < 0) { - return -EINVAL; - } + err = bt_settings_encode_key_no_addr(key_str, sizeof(key_str), key); + } + + if (err != 0) { + return err; } if (IS_ENABLED(CONFIG_BT_TESTING)) { @@ -350,21 +402,23 @@ int bt_settings_store(const char *key, uint8_t id, const bt_addr_le_t *addr, con int bt_settings_delete(const char *key, uint8_t id, const bt_addr_le_t *addr) { - int err; - char id_str[4]; char key_str[BT_SETTINGS_KEY_MAX]; + char id_str[4]; + int err; if (addr) { if (id) { u8_to_dec(id_str, sizeof(id_str), id); } - bt_settings_encode_key(key_str, sizeof(key_str), key, addr, (id ? id_str : NULL)); + err = bt_settings_encode_key(key_str, sizeof(key_str), key, addr, + (id ? id_str : NULL)); } else { - err = snprintk(key_str, sizeof(key_str), "bt/%s", key); - if (err < 0) { - return -EINVAL; - } + err = bt_settings_encode_key_no_addr(key_str, sizeof(key_str), key); + } + + if (err != 0) { + return err; } if (IS_ENABLED(CONFIG_BT_TESTING)) { diff --git a/subsys/bluetooth/host/settings.h b/subsys/bluetooth/host/settings.h index 526d850f70ab..c56ca69f9ed6 100644 --- a/subsys/bluetooth/host/settings.h +++ b/subsys/bluetooth/host/settings.h @@ -32,7 +32,7 @@ void bt_testing_settings_store_hook(const char *key, const void *value, size_t v void bt_testing_settings_delete_hook(const char *key); /* Helpers for keys containing a bdaddr */ -void bt_settings_encode_key(char *path, size_t path_size, const char *subsys, +int bt_settings_encode_key(char *path, size_t path_size, const char *subsys, const bt_addr_le_t *addr, const char *key); int bt_settings_decode_key(const char *key, bt_addr_le_t *addr); From d8f3e43b204b34fb74380be8f0c763cfad426c88 Mon Sep 17 00:00:00 2001 From: Vinayak Kariappa Chettimada Date: Thu, 11 Dec 2025 12:51:14 +0100 Subject: [PATCH 0184/6328] Bluetooth: Host: Rework settings without snprintk use Rework settings implementation for not reusing the OS snprintk implementation with CONFIG_PRINTK=n. Signed-off-by: Vinayak Kariappa Chettimada --- subsys/bluetooth/host/settings.c | 111 ++++++++++++++++--------------- 1 file changed, 58 insertions(+), 53 deletions(-) diff --git a/subsys/bluetooth/host/settings.c b/subsys/bluetooth/host/settings.c index c93df66c3f77..0c1f86a458c4 100644 --- a/subsys/bluetooth/host/settings.c +++ b/subsys/bluetooth/host/settings.c @@ -24,6 +24,7 @@ #include "common/bt_settings_commit.h" #include "common/bt_str.h" +#include "common/assert.h" #include "hci_core.h" #include "settings.h" #include "sys/types.h" @@ -75,45 +76,51 @@ int bt_settings_encode_key(char *path, size_t path_size, const char *subsys, { size_t len = 3; - /* Skip if path_size is less than 3; strlen("bt/") */ + /* path_size is less than 3; strlen("bt/") */ + BT_ASSERT(path_size >= len); + + /* Key format: + * "bt///", "/" is optional + */ + strcpy(path, "bt/"); + + /* Concatenate subsys as much the free space permits */ + strncpy(&path[len], subsys, (path_size - len)); + + /* Postfix '/' if there is free space */ + len = strlen(path); if (len < path_size) { - /* Key format: - * "bt///", "/" is optional - */ - strcpy(path, "bt/"); - strncpy(&path[len], subsys, path_size - len); - len = strlen(path); - if (len < path_size) { - path[len] = '/'; - len++; - } + path[len] = '/'; + len++; + } - for (int8_t i = 5; i >= 0 && len < path_size; i--) { - len += bin2hex(&addr->a.val[i], 1, &path[len], - path_size - len); - } + /* Concatenate addr as much the free space permits */ + for (int8_t i = 5; i >= 0 && len < path_size; i--) { + len += bin2hex(&addr->a.val[i], 1, &path[len], + path_size - len); + } - if (len < path_size) { - /* Type can be either BT_ADDR_LE_PUBLIC or - * BT_ADDR_LE_RANDOM (value 0 or 1) - */ - path[len] = '0' + addr->type; - len++; - } + /* Postfix addr type if there is free space */ + if (len < path_size) { + /* Type can be either BT_ADDR_LE_PUBLIC or + * BT_ADDR_LE_RANDOM (value 0 or 1) + */ + path[len] = '0' + addr->type; + len++; + } - if (key && len < path_size) { - path[len] = '/'; - len++; - strncpy(&path[len], key, path_size - len); - len += strlen(&path[len]); - } + /* Postfix '/' and concatenate key as much the free space permits */ + if ((key != NULL) && (len < path_size)) { + path[len] = '/'; + len++; + strncpy(&path[len], key, path_size - len); + len += strlen(&path[len]); + } - if (len >= path_size) { - /* Truncate string */ - path[path_size - 1] = '\0'; - } - } else if (path_size > 0) { - *path = '\0'; + /* If path string is full, always null terminate at path_size */ + if (len >= path_size) { + /* Truncate string */ + path[path_size - 1] = '\0'; } LOG_DBG("Encoded path %s", path); @@ -125,26 +132,22 @@ static int bt_settings_encode_key_no_addr(char *path, size_t path_size, const ch { size_t len = 3; - /* Skip if path_size is less than 3; strlen("bt/") */ - if (len < path_size) { - /* Key format: - * "bt/", "/" is optional - */ - strcpy(path, "bt/"); + /* path_size is less than 3; strlen("bt/") */ + BT_ASSERT(path_size >= len); - /* Concatenate key as much the free space permits */ - strncpy(&path[len], key, path_size - len); - len = strlen(path); + /* Key format: + * "bt/" + */ + strcpy(path, "bt/"); - /* If path string is full, always null terminate at path_size */ - if (len >= path_size) { - /* Truncate string */ - path[path_size - 1] = '\0'; - } + /* Concatenate key as much the free space permits */ + strncpy(&path[len], key, path_size - len); + len = strlen(path); - } else if (path_size > 0) { - /* path_size not sufficient for "bt/" */ - *path = '\0'; + /* If path string is full, always null terminate at path_size */ + if (len >= path_size) { + /* Truncate string */ + path[path_size - 1] = '\0'; } LOG_DBG("Encoded path %s", path); @@ -375,10 +378,11 @@ int bt_settings_store(const char *key, uint8_t id, const bt_addr_le_t *addr, con size_t val_len) { char key_str[BT_SETTINGS_KEY_MAX]; - char id_str[4]; int err; if (addr) { + char id_str[4]; + if (id) { u8_to_dec(id_str, sizeof(id_str), id); } @@ -403,10 +407,11 @@ int bt_settings_store(const char *key, uint8_t id, const bt_addr_le_t *addr, con int bt_settings_delete(const char *key, uint8_t id, const bt_addr_le_t *addr) { char key_str[BT_SETTINGS_KEY_MAX]; - char id_str[4]; int err; if (addr) { + char id_str[4]; + if (id) { u8_to_dec(id_str, sizeof(id_str), id); } From d98c2cf0d8e04683251b5c6d5c3341ee9262a249 Mon Sep 17 00:00:00 2001 From: Vinayak Kariappa Chettimada Date: Thu, 11 Dec 2025 12:51:14 +0100 Subject: [PATCH 0185/6328] Bluetooth: Host: Rework settings without snprintk to return error Rework settings implementation for not reusing the OS snprintk implementation with CONFIG_PRINTK=n and to return error if path buffer is insufficient. Signed-off-by: Vinayak Kariappa Chettimada --- subsys/bluetooth/host/settings.c | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/subsys/bluetooth/host/settings.c b/subsys/bluetooth/host/settings.c index 0c1f86a458c4..bd7d372c00a7 100644 --- a/subsys/bluetooth/host/settings.c +++ b/subsys/bluetooth/host/settings.c @@ -24,7 +24,6 @@ #include "common/bt_settings_commit.h" #include "common/bt_str.h" -#include "common/assert.h" #include "hci_core.h" #include "settings.h" #include "sys/types.h" @@ -76,8 +75,10 @@ int bt_settings_encode_key(char *path, size_t path_size, const char *subsys, { size_t len = 3; - /* path_size is less than 3; strlen("bt/") */ - BT_ASSERT(path_size >= len); + /* path_size is less than or equal 3; strlen("bt/") */ + if (path_size <= len) { + return -EINVAL; + } /* Key format: * "bt///", "/" is optional @@ -117,10 +118,9 @@ int bt_settings_encode_key(char *path, size_t path_size, const char *subsys, len += strlen(&path[len]); } - /* If path string is full, always null terminate at path_size */ + /* Insufficient path_size, include null termination */ if (len >= path_size) { - /* Truncate string */ - path[path_size - 1] = '\0'; + return -EINVAL; } LOG_DBG("Encoded path %s", path); @@ -132,8 +132,10 @@ static int bt_settings_encode_key_no_addr(char *path, size_t path_size, const ch { size_t len = 3; - /* path_size is less than 3; strlen("bt/") */ - BT_ASSERT(path_size >= len); + /* path_size is less than or equal 3; strlen("bt/") */ + if (path_size <= len) { + return -EINVAL; + } /* Key format: * "bt/" @@ -144,10 +146,9 @@ static int bt_settings_encode_key_no_addr(char *path, size_t path_size, const ch strncpy(&path[len], key, path_size - len); len = strlen(path); - /* If path string is full, always null terminate at path_size */ + /* Insufficient path_size, include null termination */ if (len >= path_size) { - /* Truncate string */ - path[path_size - 1] = '\0'; + return -EINVAL; } LOG_DBG("Encoded path %s", path); From 230453b6ea088d20c69fd378f2570c99c6ba5890 Mon Sep 17 00:00:00 2001 From: Vinayak Kariappa Chettimada Date: Fri, 19 Dec 2025 13:53:43 +0100 Subject: [PATCH 0186/6328] Bluetooth: Host: settings: Fix truncation detection after strncpy Fix truncation detection after strncpy, as strlen cannot be used if the src was truncated due to insufficient size of dst. Signed-off-by: Vinayak Kariappa Chettimada --- subsys/bluetooth/host/settings.c | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/subsys/bluetooth/host/settings.c b/subsys/bluetooth/host/settings.c index bd7d372c00a7..3b8c506e78b3 100644 --- a/subsys/bluetooth/host/settings.c +++ b/subsys/bluetooth/host/settings.c @@ -87,9 +87,9 @@ int bt_settings_encode_key(char *path, size_t path_size, const char *subsys, /* Concatenate subsys as much the free space permits */ strncpy(&path[len], subsys, (path_size - len)); + len += MIN(strlen(subsys), (path_size - len)); /* Postfix '/' if there is free space */ - len = strlen(path); if (len < path_size) { path[len] = '/'; len++; @@ -97,8 +97,7 @@ int bt_settings_encode_key(char *path, size_t path_size, const char *subsys, /* Concatenate addr as much the free space permits */ for (int8_t i = 5; i >= 0 && len < path_size; i--) { - len += bin2hex(&addr->a.val[i], 1, &path[len], - path_size - len); + len += bin2hex(&addr->a.val[i], 1, &path[len], (path_size - len)); } /* Postfix addr type if there is free space */ @@ -114,11 +113,11 @@ int bt_settings_encode_key(char *path, size_t path_size, const char *subsys, if ((key != NULL) && (len < path_size)) { path[len] = '/'; len++; - strncpy(&path[len], key, path_size - len); - len += strlen(&path[len]); + strncpy(&path[len], key, (path_size - len)); + len += MIN(strlen(key), (path_size - len)); } - /* Insufficient path_size, include null termination */ + /* Insufficient path_size, including null termination */ if (len >= path_size) { return -EINVAL; } @@ -143,10 +142,10 @@ static int bt_settings_encode_key_no_addr(char *path, size_t path_size, const ch strcpy(path, "bt/"); /* Concatenate key as much the free space permits */ - strncpy(&path[len], key, path_size - len); - len = strlen(path); + strncpy(&path[len], key, (path_size - len)); + len += MIN(strlen(key), (path_size - len)); - /* Insufficient path_size, include null termination */ + /* Insufficient path_size, including null termination */ if (len >= path_size) { return -EINVAL; } From 43dede5acc8a64625aa2a341ede59e418762e4fa Mon Sep 17 00:00:00 2001 From: Vinayak Kariappa Chettimada Date: Tue, 23 Dec 2025 05:41:14 +0100 Subject: [PATCH 0187/6328] Bluetooth: Host: settings: Add early len check without strncpy/cmp use Add early len check, remove use of strcpy, strncpy and strncmp. Co-authored-by: Emil Gydesen Signed-off-by: Vinayak Kariappa Chettimada --- subsys/bluetooth/host/settings.c | 127 +++++++++++++++++-------------- 1 file changed, 69 insertions(+), 58 deletions(-) diff --git a/subsys/bluetooth/host/settings.c b/subsys/bluetooth/host/settings.c index 3b8c506e78b3..48bf4fd6e538 100644 --- a/subsys/bluetooth/host/settings.c +++ b/subsys/bluetooth/host/settings.c @@ -48,7 +48,8 @@ int bt_settings_encode_key(char *path, size_t path_size, const char *subsys, addr->a.val[1], addr->a.val[0], addr->type); } - if (err < 0) { + if ((err < 0) || (err >= path_size)) { + /* Error or output was truncated */ return -EINVAL; } @@ -62,7 +63,8 @@ static int bt_settings_encode_key_no_addr(char *path, size_t path_size, const ch int err; err = snprintk(path, path_size, "bt/%s", key); - if (err < 0) { + if ((err < 0) || (err >= path_size)) { + /* Error or output was truncated */ return -EINVAL; } @@ -73,55 +75,61 @@ static int bt_settings_encode_key_no_addr(char *path, size_t path_size, const ch int bt_settings_encode_key(char *path, size_t path_size, const char *subsys, const bt_addr_le_t *addr, const char *key) { - size_t len = 3; - - /* path_size is less than or equal 3; strlen("bt/") */ - if (path_size <= len) { - return -EINVAL; - } - /* Key format: * "bt///", "/" is optional */ - strcpy(path, "bt/"); - - /* Concatenate subsys as much the free space permits */ - strncpy(&path[len], subsys, (path_size - len)); - len += MIN(strlen(subsys), (path_size - len)); + const char delimiter = '/'; + const char null_term = '\0'; + const size_t prefix_len = sizeof("bt") - 1U; + const size_t subsys_len = strlen(subsys); + const size_t addr_str_len = sizeof("554433221100t") - 1U; + const size_t key_len = (key == NULL) ? 0U : strlen(key); + const size_t total_len = prefix_len + + sizeof(delimiter) + subsys_len + + sizeof(delimiter) + addr_str_len + + ((key == NULL) ? 0U : (sizeof(delimiter) + key_len)) + + sizeof(null_term); + size_t offset = 0U; + int err; - /* Postfix '/' if there is free space */ - if (len < path_size) { - path[len] = '/'; - len++; + if (path_size < total_len) { + return -EINVAL; } - /* Concatenate addr as much the free space permits */ - for (int8_t i = 5; i >= 0 && len < path_size; i--) { - len += bin2hex(&addr->a.val[i], 1, &path[len], (path_size - len)); - } + memcpy(path, "bt", prefix_len); + offset += prefix_len; - /* Postfix addr type if there is free space */ - if (len < path_size) { - /* Type can be either BT_ADDR_LE_PUBLIC or - * BT_ADDR_LE_RANDOM (value 0 or 1) - */ - path[len] = '0' + addr->type; - len++; - } + path[offset] = delimiter; + offset++; + memcpy(&path[offset], subsys, subsys_len); + offset += subsys_len; - /* Postfix '/' and concatenate key as much the free space permits */ - if ((key != NULL) && (len < path_size)) { - path[len] = '/'; - len++; - strncpy(&path[len], key, (path_size - len)); - len += MIN(strlen(key), (path_size - len)); + path[offset] = delimiter; + offset++; + for (int8_t i = 5; i >= 0; i--) { + /* We supply valid 0-15 as input */ + err = hex2char(addr->a.val[i] >> 4, &path[offset]); + __ASSERT_NO_MSG(err == 0); + offset++; + /* We supply valid 0-15 as input */ + err = hex2char(addr->a.val[i] & 0xf, &path[offset]); + __ASSERT_NO_MSG(err == 0); + offset++; } + /* We are not checking hex2char return value as we supply valid 0-1 as input */ + err = hex2char(addr->type, &path[offset]); + __ASSERT_NO_MSG(err == 0); + offset++; - /* Insufficient path_size, including null termination */ - if (len >= path_size) { - return -EINVAL; + if (key != NULL) { + path[offset] = delimiter; + offset++; + memcpy(&path[offset], key, key_len); + offset += key_len; } + path[offset] = null_term; + LOG_DBG("Encoded path %s", path); return 0; @@ -129,27 +137,30 @@ int bt_settings_encode_key(char *path, size_t path_size, const char *subsys, static int bt_settings_encode_key_no_addr(char *path, size_t path_size, const char *key) { - size_t len = 3; - - /* path_size is less than or equal 3; strlen("bt/") */ - if (path_size <= len) { - return -EINVAL; - } - /* Key format: * "bt/" */ - strcpy(path, "bt/"); - - /* Concatenate key as much the free space permits */ - strncpy(&path[len], key, (path_size - len)); - len += MIN(strlen(key), (path_size - len)); - - /* Insufficient path_size, including null termination */ - if (len >= path_size) { + const char delimiter = '/'; + const char null_term = '\0'; + const size_t prefix_len = sizeof("bt") - 1U; + const size_t key_len = strlen(key); + const size_t total_len = prefix_len + sizeof(delimiter) + key_len + sizeof(null_term); + size_t offset = 0U; + + if (path_size < total_len) { return -EINVAL; } + memcpy(path, "bt", prefix_len); + offset += prefix_len; + + path[offset] = delimiter; + offset++; + memcpy(&path[offset], key, key_len); + offset += key_len; + + path[offset] = null_term; + LOG_DBG("Encoded path %s", path); return 0; @@ -202,7 +213,7 @@ static int set_setting(const char *name, size_t len_rd, settings_read_cb read_cb len = settings_name_next(name, &next); - if (!strncmp(name, "id", len)) { + if ((len == 2) && (memcmp(name, "id", len) == 0)) { /* Any previously provided identities supersede flash */ if (atomic_test_bit(bt_dev.flags, BT_DEV_PRESET_ID)) { LOG_WRN("Ignoring identities stored in flash"); @@ -234,7 +245,7 @@ static int set_setting(const char *name, size_t len_rd, settings_read_cb read_cb } #if defined(CONFIG_BT_DEVICE_NAME_DYNAMIC) - if (!strncmp(name, "name", len)) { + if ((len == 4) && (memcmp(name, "name", len) == 0)) { len = read_cb(cb_arg, &bt_dev.name, sizeof(bt_dev.name) - 1); if (len < 0) { LOG_ERR("Failed to read device name from storage" @@ -249,7 +260,7 @@ static int set_setting(const char *name, size_t len_rd, settings_read_cb read_cb #endif #if defined(CONFIG_BT_DEVICE_APPEARANCE_DYNAMIC) - if (!strncmp(name, "appearance", len)) { + if ((len == 10) && (memcmp(name, "appearance", len) == 0)) { if (len_rd != sizeof(bt_dev.appearance)) { LOG_ERR("Ignoring settings entry 'bt/appearance'. Wrong length."); return -EINVAL; @@ -265,7 +276,7 @@ static int set_setting(const char *name, size_t len_rd, settings_read_cb read_cb #endif #if defined(CONFIG_BT_PRIVACY) - if (!strncmp(name, "irk", len)) { + if ((len == 3) && (memcmp(name, "irk", len) == 0)) { len = read_cb(cb_arg, bt_dev.irk, sizeof(bt_dev.irk)); if (len < sizeof(bt_dev.irk[0])) { if (len < 0) { From 891d50c396920b55697d2f5637ef4beac661aa36 Mon Sep 17 00:00:00 2001 From: Vinayak Kariappa Chettimada Date: Mon, 5 Jan 2026 10:29:25 +0100 Subject: [PATCH 0188/6328] tests: bsim: Bluetooth: Cover settings without snprintk use Cover settings without snprintk use in bsim test. Signed-off-by: Vinayak Kariappa Chettimada --- .../host/privacy/peripheral/prj.conf | 3 ++ .../privacy/peripheral/prj_no_snprintk.conf | 25 +++++++++++ .../test_scripts/run_test_no_snprintk.sh | 41 +++++++++++++++++++ .../host/privacy/peripheral/testcase.yaml | 5 +++ 4 files changed, 74 insertions(+) create mode 100644 tests/bsim/bluetooth/host/privacy/peripheral/prj_no_snprintk.conf create mode 100755 tests/bsim/bluetooth/host/privacy/peripheral/test_scripts/run_test_no_snprintk.sh diff --git a/tests/bsim/bluetooth/host/privacy/peripheral/prj.conf b/tests/bsim/bluetooth/host/privacy/peripheral/prj.conf index d7295596ac37..e001a35e951f 100644 --- a/tests/bsim/bluetooth/host/privacy/peripheral/prj.conf +++ b/tests/bsim/bluetooth/host/privacy/peripheral/prj.conf @@ -18,5 +18,8 @@ CONFIG_NVS=y CONFIG_SETTINGS=y CONFIG_BT_SETTINGS=y +# Lets cover settings with use of snprintk +CONFIG_BT_SETTINGS_USE_PRINTK=y + # Increased stack due to settings API usage CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=2048 diff --git a/tests/bsim/bluetooth/host/privacy/peripheral/prj_no_snprintk.conf b/tests/bsim/bluetooth/host/privacy/peripheral/prj_no_snprintk.conf new file mode 100644 index 000000000000..de2d86e678e2 --- /dev/null +++ b/tests/bsim/bluetooth/host/privacy/peripheral/prj_no_snprintk.conf @@ -0,0 +1,25 @@ +CONFIG_BT=y +CONFIG_BT_PERIPHERAL=y +CONFIG_BT_CENTRAL=y +CONFIG_BT_SMP=y +CONFIG_ASSERT=y + +CONFIG_BT_EXT_ADV=y +CONFIG_BT_PRIVACY=y +CONFIG_BT_RPA_TIMEOUT=10 +CONFIG_BT_EXT_ADV_MAX_ADV_SET=3 +CONFIG_BT_CTLR_ADVANCED_FEATURES=y +CONFIG_BT_CTLR_ADV_DATA_BUF_MAX=3 +CONFIG_BT_ID_MAX=3 + +CONFIG_FLASH=y +CONFIG_FLASH_MAP=y +CONFIG_NVS=y +CONFIG_SETTINGS=y +CONFIG_BT_SETTINGS=y + +# Lets cover settings without use of snprintk +CONFIG_BT_SETTINGS_USE_PRINTK=n + +# Increased stack due to settings API usage +CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=2048 diff --git a/tests/bsim/bluetooth/host/privacy/peripheral/test_scripts/run_test_no_snprintk.sh b/tests/bsim/bluetooth/host/privacy/peripheral/test_scripts/run_test_no_snprintk.sh new file mode 100755 index 000000000000..3ae6b762c271 --- /dev/null +++ b/tests/bsim/bluetooth/host/privacy/peripheral/test_scripts/run_test_no_snprintk.sh @@ -0,0 +1,41 @@ +#!/usr/bin/env bash +# Copyright 2023 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +set -eu +source ${ZEPHYR_BASE}/tests/bsim/sh_common.source + +verbosity_level=2 +simulation_id="host_privacy_peripheral_no_snprintk" +EXECUTE_TIMEOUT=240 + +central_exe="${BSIM_OUT_PATH}/bin/bs_${BOARD_TS}_$(guess_test_long_name)_prj_no_snprintk_conf" +peripheral_exe="${central_exe}" + +cd ${BSIM_OUT_PATH}/bin + +Execute "$central_exe" \ + -v=${verbosity_level} -s=${simulation_id} -d=0 -testid=central -RealEncryption=1 \ + -flash="${simulation_id}.central.log.bin" -flash_erase + +Execute "$peripheral_exe" \ + -v=${verbosity_level} -s=${simulation_id} -d=1 -testid=peripheral -RealEncryption=1 \ + -flash="${simulation_id}.peripheral.log.bin" -flash_erase + +Execute ./bs_2G4_phy_v1 -v=${verbosity_level} -s=${simulation_id} \ + -D=2 -sim_length=70e6 $@ + +wait_for_background_jobs + +Execute "$central_exe" \ + -v=${verbosity_level} -s=${simulation_id}.2 -d=0 -testid=central -RealEncryption=1 \ + -flash="${simulation_id}.central.log.bin" -flash_rm + +Execute "$peripheral_exe" \ + -v=${verbosity_level} -s=${simulation_id}.2 -d=1 -testid=peripheral -RealEncryption=1 \ + -flash="${simulation_id}.peripheral.log.bin" -flash_rm + +Execute ./bs_2G4_phy_v1 -v=${verbosity_level} -s=${simulation_id}.2 \ + -D=2 -sim_length=70e6 $@ + +wait_for_background_jobs diff --git a/tests/bsim/bluetooth/host/privacy/peripheral/testcase.yaml b/tests/bsim/bluetooth/host/privacy/peripheral/testcase.yaml index 0942bb4fbb50..b0308fb16828 100644 --- a/tests/bsim/bluetooth/host/privacy/peripheral/testcase.yaml +++ b/tests/bsim/bluetooth/host/privacy/peripheral/testcase.yaml @@ -12,6 +12,11 @@ tests: bluetooth.host.privacy.peripheral: harness_config: bsim_exe_name: tests_bsim_bluetooth_host_privacy_peripheral_prj_conf + bluetooth.host.privacy.peripheral_no_snprintk: + harness_config: + bsim_exe_name: tests_bsim_bluetooth_host_privacy_peripheral_prj_no_snprintk_conf + extra_args: + EXTRA_CONF_FILE=prj_no_snprintk.conf bluetooth.host.privacy.peripheral_rpa_expired: harness_config: bsim_exe_name: tests_bsim_bluetooth_host_privacy_peripheral_prj_rpa_expired_conf From 14268793a9779982de331eab73a39678e89f22d4 Mon Sep 17 00:00:00 2001 From: Braeden Lane Date: Wed, 10 Dec 2025 13:57:54 -0800 Subject: [PATCH 0189/6328] soc: infineon: psoc4: Add PSOC 4100S Max series support Add initial support for the PSOC 4100S Max series, starting with the CY8C4149AZI-S598 (100-TQFP package) used on the CY8CKIT-041S-MAX development board. The infrastructure supports adding additional part numbers in the future as needed. Signed-off-by: Braeden Lane --- modules/hal_infineon/infineon_kconfig.h | 13 ++++++++++ .../psoc4/psoc4100smax/CMakeLists.txt | 10 ++++++++ soc/infineon/psoc4/psoc4100smax/Kconfig | 25 +++++++++++++++++++ .../psoc4/psoc4100smax/Kconfig.defconfig | 14 +++++++++++ soc/infineon/psoc4/psoc4100smax/Kconfig.soc | 21 ++++++++++++++++ soc/infineon/psoc4/psoc4100smax/soc.c | 21 ++++++++++++++++ soc/infineon/psoc4/psoc4100smax/soc.h | 15 +++++++++++ soc/infineon/psoc4/soc.yml | 3 +++ 8 files changed, 122 insertions(+) create mode 100644 soc/infineon/psoc4/psoc4100smax/CMakeLists.txt create mode 100644 soc/infineon/psoc4/psoc4100smax/Kconfig create mode 100644 soc/infineon/psoc4/psoc4100smax/Kconfig.defconfig create mode 100644 soc/infineon/psoc4/psoc4100smax/Kconfig.soc create mode 100644 soc/infineon/psoc4/psoc4100smax/soc.c create mode 100644 soc/infineon/psoc4/psoc4100smax/soc.h diff --git a/modules/hal_infineon/infineon_kconfig.h b/modules/hal_infineon/infineon_kconfig.h index 464059d6f883..137885ba97b9 100644 --- a/modules/hal_infineon/infineon_kconfig.h +++ b/modules/hal_infineon/infineon_kconfig.h @@ -375,4 +375,17 @@ #endif /* CONFIG_SOC_SERIES_PSOC4100TP */ +#if defined(CONFIG_SOC_SERIES_PSOC4100SMAX) + +#if defined(CONFIG_SOC_CY8C4149AZI_S598) +#ifndef CY8C4149AZI_S598 +#define CY8C4149AZI_S598 +#endif +#ifndef CY8C4149AZI_S598_ +#define CY8C4149AZI_S598_ +#endif +#endif + +#endif /* CONFIG_SOC_SERIES_PSOC4100SMAX */ + #endif /* INFINEON_KCONFIG_H__ */ diff --git a/soc/infineon/psoc4/psoc4100smax/CMakeLists.txt b/soc/infineon/psoc4/psoc4100smax/CMakeLists.txt new file mode 100644 index 000000000000..638c47e666a4 --- /dev/null +++ b/soc/infineon/psoc4/psoc4100smax/CMakeLists.txt @@ -0,0 +1,10 @@ +# Copyright (c) 2025 Infineon Technologies AG, +# or an affiliate of Infineon Technologies AG. +# +# SPDX-License-Identifier: Apache-2.0 + +zephyr_sources(soc.c) +zephyr_include_directories(.) + +#default Zephyr linker script +set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "") diff --git a/soc/infineon/psoc4/psoc4100smax/Kconfig b/soc/infineon/psoc4/psoc4100smax/Kconfig new file mode 100644 index 000000000000..bc8b09e4237a --- /dev/null +++ b/soc/infineon/psoc4/psoc4100smax/Kconfig @@ -0,0 +1,25 @@ +# Copyright (c) 2025 Infineon Technologies AG, +# or an affiliate of Infineon Technologies AG. +# +# SPDX-License-Identifier: Apache-2.0 + +# SOC Packages for Infineon PSOC4100Smax series MCUs +config SOC_PACKAGE_PSOC4100SMAX_100_TQFP + bool + help + 100-pin TQFP package + +# Hardware configuration for PSOC4100SMAX series +config SOC_SERIES_PSOC4100SMAX + select ARM + select CPU_CORTEX_M0PLUS + select CPU_CORTEX_M_HAS_VTOR + select CPU_HAS_ARM_MPU + select BUILD_OUTPUT_HEX + select BUILD_OUTPUT_BIN + select DYNAMIC_INTERRUPTS + select SOC_EARLY_INIT_HOOK + select CPU_CORTEX_M_HAS_SYSTICK + +config SOC_CY8C4149AZI_S598 + select SOC_PACKAGE_PSOC4100SMAX_100_TQFP diff --git a/soc/infineon/psoc4/psoc4100smax/Kconfig.defconfig b/soc/infineon/psoc4/psoc4100smax/Kconfig.defconfig new file mode 100644 index 000000000000..c37cb8bb50eb --- /dev/null +++ b/soc/infineon/psoc4/psoc4100smax/Kconfig.defconfig @@ -0,0 +1,14 @@ +# Copyright (c) 2025 Infineon Technologies AG, +# or an affiliate of Infineon Technologies AG. +# +# SPDX-License-Identifier: Apache-2.0 + +if SOC_SERIES_PSOC4100SMAX + +config NUM_IRQS + default 32 + +config SYS_CLOCK_HW_CYCLES_PER_SEC + default $(dt_node_int_prop_int,/cpus/cpu@0,clock-frequency) + +endif # SOC_SERIES_PSOC4100SMAX diff --git a/soc/infineon/psoc4/psoc4100smax/Kconfig.soc b/soc/infineon/psoc4/psoc4100smax/Kconfig.soc new file mode 100644 index 000000000000..f804183d7869 --- /dev/null +++ b/soc/infineon/psoc4/psoc4100smax/Kconfig.soc @@ -0,0 +1,21 @@ +# Copyright (c) 2025 Infineon Technologies AG, +# or an affiliate of Infineon Technologies AG. +# +# SPDX-License-Identifier: Apache-2.0 + +# MCU series +config SOC_SERIES_PSOC4100SMAX + bool + select SOC_FAMILY_INFINEON_PSOC4 + help + PSOC4100Smax Series MCU + +config SOC_SERIES + default "psoc4100smax" if SOC_SERIES_PSOC4100SMAX + +config SOC_CY8C4149AZI_S598 + bool + select SOC_SERIES_PSOC4100SMAX + +config SOC + default "cy8c4149azi_s598" if SOC_CY8C4149AZI_S598 diff --git a/soc/infineon/psoc4/psoc4100smax/soc.c b/soc/infineon/psoc4/psoc4100smax/soc.c new file mode 100644 index 000000000000..37131f0bac7c --- /dev/null +++ b/soc/infineon/psoc4/psoc4100smax/soc.c @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2025 Infineon Technologies AG, + * or an affiliate of Infineon Technologies AG. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include + +#include +#include /* PSoC4 system init header from PDL */ +#include "cy_pdl.h" + +/* Minimal early initialization for PSoC 4100S Max */ +void soc_early_init_hook(void) +{ + /* Initializes the system */ + SystemInit(); +} diff --git a/soc/infineon/psoc4/psoc4100smax/soc.h b/soc/infineon/psoc4/psoc4100smax/soc.h new file mode 100644 index 000000000000..90edbd5b6754 --- /dev/null +++ b/soc/infineon/psoc4/psoc4100smax/soc.h @@ -0,0 +1,15 @@ +/* + * Copyright (c) 2025 Infineon Technologies AG, + * or an affiliate of Infineon Technologies AG. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_SOC_INFINEON_PSOC4_PSOC4100SMAX_SOC_H_ +#define ZEPHYR_SOC_INFINEON_PSOC4_PSOC4100SMAX_SOC_H_ + +#ifndef _ASMLANGUAGE +#include +#endif /* !_ASMLANGUAGE */ + +#endif /* ZEPHYR_SOC_INFINEON_PSOC4_PSOC4100SMAX_SOC_H_ */ diff --git a/soc/infineon/psoc4/soc.yml b/soc/infineon/psoc4/soc.yml index 2938ebf605e7..0f947bbffc3f 100644 --- a/soc/infineon/psoc4/soc.yml +++ b/soc/infineon/psoc4/soc.yml @@ -48,3 +48,6 @@ family: - name: cy8c4146azq_t453 - name: cy8c4147azq_t415 - name: cy8c4147azq_t455 + - name: psoc4100smax + socs: + - name: cy8c4149azi_s598 From fd991b749137643059bac611baeee40e205f9557 Mon Sep 17 00:00:00 2001 From: Braeden Lane Date: Wed, 10 Dec 2025 14:00:19 -0800 Subject: [PATCH 0190/6328] dts: arm: infineon: psoc4: Add PSOC 4100S Max devicetree Add devicetree support for PSOC 4100S Max series including: - Base SoC dtsi with GPIO, UART, HSIOM peripherals - 100-TQFP package dtsi for pin multiplexing - CY8C4149AZI-S598 MPN-specific devicetree include - Updated compatible strings for PSOC 4 support - Clock structure with clk_hf and clk_pump nodes - Simplified peripheral clock naming (peri_clk_div) - PSOC4xx clock source definitions and bindings Signed-off-by: Braeden Lane --- .../infineon/psoc4/mpns/cy8c4149azi_s598.dtsi | 8 + .../psoc4100smax/psoc4100smax.100-tqfp.dtsi | 1463 +++++++++++++++++ .../psoc4/psoc4100smax/psoc4100smax.cm0p.dtsi | 40 + .../psoc4/psoc4100smax/psoc4100smax.dtsi | 351 ++++ .../psoc4/psoc4100smax/system_clocks.dtsi | 237 +++ 5 files changed, 2099 insertions(+) create mode 100644 dts/arm/infineon/psoc4/mpns/cy8c4149azi_s598.dtsi create mode 100644 dts/arm/infineon/psoc4/psoc4100smax/psoc4100smax.100-tqfp.dtsi create mode 100644 dts/arm/infineon/psoc4/psoc4100smax/psoc4100smax.cm0p.dtsi create mode 100644 dts/arm/infineon/psoc4/psoc4100smax/psoc4100smax.dtsi create mode 100644 dts/arm/infineon/psoc4/psoc4100smax/system_clocks.dtsi diff --git a/dts/arm/infineon/psoc4/mpns/cy8c4149azi_s598.dtsi b/dts/arm/infineon/psoc4/mpns/cy8c4149azi_s598.dtsi new file mode 100644 index 000000000000..87dd94d20447 --- /dev/null +++ b/dts/arm/infineon/psoc4/mpns/cy8c4149azi_s598.dtsi @@ -0,0 +1,8 @@ +/* + * Copyright (c) 2025 Infineon Technologies AG, + * or an affiliate of Infineon Technologies AG. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "../psoc4100smax/psoc4100smax.100-tqfp.dtsi" diff --git a/dts/arm/infineon/psoc4/psoc4100smax/psoc4100smax.100-tqfp.dtsi b/dts/arm/infineon/psoc4/psoc4100smax/psoc4100smax.100-tqfp.dtsi new file mode 100644 index 000000000000..908f914a8b87 --- /dev/null +++ b/dts/arm/infineon/psoc4/psoc4100smax/psoc4100smax.100-tqfp.dtsi @@ -0,0 +1,1463 @@ +/* + * Copyright (c) 2025 Infineon Technologies AG, + * or an affiliate of Infineon Technologies AG. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include "psoc4100smax.dtsi" + +/ { + soc { + pinctrl: pinctrl@40020000 { + /* scb_i2c_scl */ + /omit-if-no-ref/ p0_0_scb2_i2c_scl: p0_0_scb2_i2c_scl { + pinmux = ; + }; + + /omit-if-no-ref/ p0_4_scb1_i2c_scl: p0_4_scb1_i2c_scl { + pinmux = ; + }; + + /omit-if-no-ref/ p1_0_scb0_i2c_scl: p1_0_scb0_i2c_scl { + pinmux = ; + }; + + /omit-if-no-ref/ p1_2_scb2_i2c_scl: p1_2_scb2_i2c_scl { + pinmux = ; + }; + + /omit-if-no-ref/ p1_4_scb3_i2c_scl: p1_4_scb3_i2c_scl { + pinmux = ; + }; + + /omit-if-no-ref/ p2_0_scb1_i2c_scl: p2_0_scb1_i2c_scl { + pinmux = ; + }; + + /omit-if-no-ref/ p3_0_scb1_i2c_scl: p3_0_scb1_i2c_scl { + pinmux = ; + }; + + /omit-if-no-ref/ p4_0_scb0_i2c_scl: p4_0_scb0_i2c_scl { + pinmux = ; + }; + + /omit-if-no-ref/ p5_0_scb2_i2c_scl: p5_0_scb2_i2c_scl { + pinmux = ; + }; + + /omit-if-no-ref/ p6_0_scb3_i2c_scl: p6_0_scb3_i2c_scl { + pinmux = ; + }; + + /omit-if-no-ref/ p6_4_scb4_i2c_scl: p6_4_scb4_i2c_scl { + pinmux = ; + }; + + /omit-if-no-ref/ p7_0_scb3_i2c_scl: p7_0_scb3_i2c_scl { + pinmux = ; + }; + + /omit-if-no-ref/ p8_0_scb4_i2c_scl: p8_0_scb4_i2c_scl { + pinmux = ; + }; + + /omit-if-no-ref/ p9_0_scb0_i2c_scl: p9_0_scb0_i2c_scl { + pinmux = ; + }; + + /omit-if-no-ref/ p10_0_scb2_i2c_scl: p10_0_scb2_i2c_scl { + pinmux = ; + }; + + /omit-if-no-ref/ p12_0_scb1_i2c_scl: p12_0_scb1_i2c_scl { + pinmux = ; + }; + + /* scb_i2c_sda */ + /omit-if-no-ref/ p0_1_scb2_i2c_sda: p0_1_scb2_i2c_sda { + pinmux = ; + }; + + /omit-if-no-ref/ p0_5_scb1_i2c_sda: p0_5_scb1_i2c_sda { + pinmux = ; + }; + + /omit-if-no-ref/ p1_1_scb0_i2c_sda: p1_1_scb0_i2c_sda { + pinmux = ; + }; + + /omit-if-no-ref/ p1_3_scb2_i2c_sda: p1_3_scb2_i2c_sda { + pinmux = ; + }; + + /omit-if-no-ref/ p1_5_scb3_i2c_sda: p1_5_scb3_i2c_sda { + pinmux = ; + }; + + /omit-if-no-ref/ p2_1_scb1_i2c_sda: p2_1_scb1_i2c_sda { + pinmux = ; + }; + + /omit-if-no-ref/ p3_1_scb1_i2c_sda: p3_1_scb1_i2c_sda { + pinmux = ; + }; + + /omit-if-no-ref/ p4_1_scb0_i2c_sda: p4_1_scb0_i2c_sda { + pinmux = ; + }; + + /omit-if-no-ref/ p5_1_scb2_i2c_sda: p5_1_scb2_i2c_sda { + pinmux = ; + }; + + /omit-if-no-ref/ p6_1_scb3_i2c_sda: p6_1_scb3_i2c_sda { + pinmux = ; + }; + + /omit-if-no-ref/ p6_5_scb4_i2c_sda: p6_5_scb4_i2c_sda { + pinmux = ; + }; + + /omit-if-no-ref/ p7_1_scb3_i2c_sda: p7_1_scb3_i2c_sda { + pinmux = ; + }; + + /omit-if-no-ref/ p8_1_scb4_i2c_sda: p8_1_scb4_i2c_sda { + pinmux = ; + }; + + /omit-if-no-ref/ p9_1_scb0_i2c_sda: p9_1_scb0_i2c_sda { + pinmux = ; + }; + + /omit-if-no-ref/ p10_1_scb2_i2c_sda: p10_1_scb2_i2c_sda { + pinmux = ; + }; + + /omit-if-no-ref/ p12_1_scb1_i2c_sda: p12_1_scb1_i2c_sda { + pinmux = ; + }; + + /* scb_spi_m_clk */ + /omit-if-no-ref/ p0_6_scb1_spi_m_clk: p0_6_scb1_spi_m_clk { + pinmux = ; + }; + + /omit-if-no-ref/ p1_2_scb0_spi_m_clk: p1_2_scb0_spi_m_clk { + pinmux = ; + }; + + /omit-if-no-ref/ p1_7_scb2_spi_m_clk: p1_7_scb2_spi_m_clk { + pinmux = ; + }; + + /omit-if-no-ref/ p2_2_scb1_spi_m_clk: p2_2_scb1_spi_m_clk { + pinmux = ; + }; + + /omit-if-no-ref/ p3_2_scb1_spi_m_clk: p3_2_scb1_spi_m_clk { + pinmux = ; + }; + + /omit-if-no-ref/ p4_2_scb0_spi_m_clk: p4_2_scb0_spi_m_clk { + pinmux = ; + }; + + /omit-if-no-ref/ p4_6_scb4_spi_m_clk: p4_6_scb4_spi_m_clk { + pinmux = ; + }; + + /omit-if-no-ref/ p5_2_scb2_spi_m_clk: p5_2_scb2_spi_m_clk { + pinmux = ; + }; + + /omit-if-no-ref/ p6_2_scb3_spi_m_clk: p6_2_scb3_spi_m_clk { + pinmux = ; + }; + + /omit-if-no-ref/ p7_2_scb3_spi_m_clk: p7_2_scb3_spi_m_clk { + pinmux = ; + }; + + /omit-if-no-ref/ p8_2_scb3_spi_m_clk: p8_2_scb3_spi_m_clk { + pinmux = ; + }; + + /omit-if-no-ref/ p9_2_scb0_spi_m_clk: p9_2_scb0_spi_m_clk { + pinmux = ; + }; + + /omit-if-no-ref/ p10_2_scb2_spi_m_clk: p10_2_scb2_spi_m_clk { + pinmux = ; + }; + + /omit-if-no-ref/ p11_2_scb1_spi_m_clk: p11_2_scb1_spi_m_clk { + pinmux = ; + }; + + /omit-if-no-ref/ p11_2_scb4_spi_m_clk: p11_2_scb4_spi_m_clk { + pinmux = ; + }; + + /* scb_spi_m_miso */ + /omit-if-no-ref/ p0_5_scb1_spi_m_miso: p0_5_scb1_spi_m_miso { + pinmux = ; + }; + + /omit-if-no-ref/ p1_1_scb0_spi_m_miso: p1_1_scb0_spi_m_miso { + pinmux = ; + }; + + /omit-if-no-ref/ p2_1_scb1_spi_m_miso: p2_1_scb1_spi_m_miso { + pinmux = ; + }; + + /omit-if-no-ref/ p3_1_scb1_spi_m_miso: p3_1_scb1_spi_m_miso { + pinmux = ; + }; + + /omit-if-no-ref/ p3_7_scb2_spi_m_miso: p3_7_scb2_spi_m_miso { + pinmux = ; + }; + + /omit-if-no-ref/ p4_1_scb0_spi_m_miso: p4_1_scb0_spi_m_miso { + pinmux = ; + }; + + /omit-if-no-ref/ p4_5_scb4_spi_m_miso: p4_5_scb4_spi_m_miso { + pinmux = ; + }; + + /omit-if-no-ref/ p5_1_scb2_spi_m_miso: p5_1_scb2_spi_m_miso { + pinmux = ; + }; + + /omit-if-no-ref/ p6_1_scb3_spi_m_miso: p6_1_scb3_spi_m_miso { + pinmux = ; + }; + + /omit-if-no-ref/ p7_1_scb3_spi_m_miso: p7_1_scb3_spi_m_miso { + pinmux = ; + }; + + /omit-if-no-ref/ p8_1_scb3_spi_m_miso: p8_1_scb3_spi_m_miso { + pinmux = ; + }; + + /omit-if-no-ref/ p9_1_scb0_spi_m_miso: p9_1_scb0_spi_m_miso { + pinmux = ; + }; + + /omit-if-no-ref/ p10_1_scb2_spi_m_miso: p10_1_scb2_spi_m_miso { + pinmux = ; + }; + + /omit-if-no-ref/ p11_1_scb1_spi_m_miso: p11_1_scb1_spi_m_miso { + pinmux = ; + }; + + /omit-if-no-ref/ p11_1_scb4_spi_m_miso: p11_1_scb4_spi_m_miso { + pinmux = ; + }; + + /* scb_spi_m_mosi */ + /omit-if-no-ref/ p0_4_scb1_spi_m_mosi: p0_4_scb1_spi_m_mosi { + pinmux = ; + }; + + /omit-if-no-ref/ p1_0_scb0_spi_m_mosi: p1_0_scb0_spi_m_mosi { + pinmux = ; + }; + + /omit-if-no-ref/ p2_0_scb1_spi_m_mosi: p2_0_scb1_spi_m_mosi { + pinmux = ; + }; + + /omit-if-no-ref/ p2_7_scb2_spi_m_mosi: p2_7_scb2_spi_m_mosi { + pinmux = ; + }; + + /omit-if-no-ref/ p3_0_scb1_spi_m_mosi: p3_0_scb1_spi_m_mosi { + pinmux = ; + }; + + /omit-if-no-ref/ p4_0_scb0_spi_m_mosi: p4_0_scb0_spi_m_mosi { + pinmux = ; + }; + + /omit-if-no-ref/ p4_4_scb4_spi_m_mosi: p4_4_scb4_spi_m_mosi { + pinmux = ; + }; + + /omit-if-no-ref/ p5_0_scb2_spi_m_mosi: p5_0_scb2_spi_m_mosi { + pinmux = ; + }; + + /omit-if-no-ref/ p6_0_scb3_spi_m_mosi: p6_0_scb3_spi_m_mosi { + pinmux = ; + }; + + /omit-if-no-ref/ p7_0_scb3_spi_m_mosi: p7_0_scb3_spi_m_mosi { + pinmux = ; + }; + + /omit-if-no-ref/ p8_0_scb3_spi_m_mosi: p8_0_scb3_spi_m_mosi { + pinmux = ; + }; + + /omit-if-no-ref/ p9_0_scb0_spi_m_mosi: p9_0_scb0_spi_m_mosi { + pinmux = ; + }; + + /omit-if-no-ref/ p10_0_scb2_spi_m_mosi: p10_0_scb2_spi_m_mosi { + pinmux = ; + }; + + /omit-if-no-ref/ p11_0_scb1_spi_m_mosi: p11_0_scb1_spi_m_mosi { + pinmux = ; + }; + + /omit-if-no-ref/ p11_0_scb4_spi_m_mosi: p11_0_scb4_spi_m_mosi { + pinmux = ; + }; + + /* scb_spi_m_select0 */ + /omit-if-no-ref/ p0_3_scb2_spi_m_select0: p0_3_scb2_spi_m_select0 { + pinmux = ; + }; + + /omit-if-no-ref/ p0_7_scb1_spi_m_select0: p0_7_scb1_spi_m_select0 { + pinmux = ; + }; + + /omit-if-no-ref/ p1_3_scb0_spi_m_select0: p1_3_scb0_spi_m_select0 { + pinmux = ; + }; + + /omit-if-no-ref/ p2_3_scb1_spi_m_select0: p2_3_scb1_spi_m_select0 { + pinmux = ; + }; + + /omit-if-no-ref/ p3_3_scb1_spi_m_select0: p3_3_scb1_spi_m_select0 { + pinmux = ; + }; + + /omit-if-no-ref/ p4_3_scb0_spi_m_select0: p4_3_scb0_spi_m_select0 { + pinmux = ; + }; + + /omit-if-no-ref/ p4_7_scb4_spi_m_select0: p4_7_scb4_spi_m_select0 { + pinmux = ; + }; + + /omit-if-no-ref/ p5_3_scb2_spi_m_select0: p5_3_scb2_spi_m_select0 { + pinmux = ; + }; + + /omit-if-no-ref/ p6_3_scb3_spi_m_select0: p6_3_scb3_spi_m_select0 { + pinmux = ; + }; + + /omit-if-no-ref/ p7_4_scb3_spi_m_select0: p7_4_scb3_spi_m_select0 { + pinmux = ; + }; + + /omit-if-no-ref/ p8_3_scb3_spi_m_select0: p8_3_scb3_spi_m_select0 { + pinmux = ; + }; + + /omit-if-no-ref/ p9_3_scb0_spi_m_select0: p9_3_scb0_spi_m_select0 { + pinmux = ; + }; + + /omit-if-no-ref/ p10_3_scb2_spi_m_select0: p10_3_scb2_spi_m_select0 { + pinmux = ; + }; + + /omit-if-no-ref/ p11_3_scb1_spi_m_select0: p11_3_scb1_spi_m_select0 { + pinmux = ; + }; + + /omit-if-no-ref/ p11_3_scb4_spi_m_select0: p11_3_scb4_spi_m_select0 { + pinmux = ; + }; + + /* scb_spi_m_select1 */ + /omit-if-no-ref/ p0_0_scb0_spi_m_select1: p0_0_scb0_spi_m_select1 { + pinmux = ; + }; + + /omit-if-no-ref/ p1_4_scb0_spi_m_select1: p1_4_scb0_spi_m_select1 { + pinmux = ; + }; + + /omit-if-no-ref/ p2_4_scb1_spi_m_select1: p2_4_scb1_spi_m_select1 { + pinmux = ; + }; + + /omit-if-no-ref/ p3_4_scb1_spi_m_select1: p3_4_scb1_spi_m_select1 { + pinmux = ; + }; + + /omit-if-no-ref/ p4_4_scb0_spi_m_select1: p4_4_scb0_spi_m_select1 { + pinmux = ; + }; + + /omit-if-no-ref/ p5_4_scb2_spi_m_select1: p5_4_scb2_spi_m_select1 { + pinmux = ; + }; + + /omit-if-no-ref/ p5_6_scb4_spi_m_select1: p5_6_scb4_spi_m_select1 { + pinmux = ; + }; + + /omit-if-no-ref/ p5_7_scb3_spi_m_select1: p5_7_scb3_spi_m_select1 { + pinmux = ; + }; + + /omit-if-no-ref/ p6_4_scb3_spi_m_select1: p6_4_scb3_spi_m_select1 { + pinmux = ; + }; + + /omit-if-no-ref/ p7_5_scb3_spi_m_select1: p7_5_scb3_spi_m_select1 { + pinmux = ; + }; + + /omit-if-no-ref/ p10_4_scb2_spi_m_select1: p10_4_scb2_spi_m_select1 { + pinmux = ; + }; + + /omit-if-no-ref/ p11_4_scb1_spi_m_select1: p11_4_scb1_spi_m_select1 { + pinmux = ; + }; + + /omit-if-no-ref/ p11_4_scb4_spi_m_select1: p11_4_scb4_spi_m_select1 { + pinmux = ; + }; + + /* scb_spi_m_select2 */ + /omit-if-no-ref/ p0_1_scb0_spi_m_select2: p0_1_scb0_spi_m_select2 { + pinmux = ; + }; + + /omit-if-no-ref/ p1_5_scb0_spi_m_select2: p1_5_scb0_spi_m_select2 { + pinmux = ; + }; + + /omit-if-no-ref/ p2_5_scb1_spi_m_select2: p2_5_scb1_spi_m_select2 { + pinmux = ; + }; + + /omit-if-no-ref/ p3_5_scb1_spi_m_select2: p3_5_scb1_spi_m_select2 { + pinmux = ; + }; + + /omit-if-no-ref/ p4_5_scb0_spi_m_select2: p4_5_scb0_spi_m_select2 { + pinmux = ; + }; + + /omit-if-no-ref/ p4_7_scb3_spi_m_select2: p4_7_scb3_spi_m_select2 { + pinmux = ; + }; + + /omit-if-no-ref/ p5_5_scb2_spi_m_select2: p5_5_scb2_spi_m_select2 { + pinmux = ; + }; + + /omit-if-no-ref/ p5_7_scb4_spi_m_select2: p5_7_scb4_spi_m_select2 { + pinmux = ; + }; + + /omit-if-no-ref/ p6_5_scb3_spi_m_select2: p6_5_scb3_spi_m_select2 { + pinmux = ; + }; + + /omit-if-no-ref/ p7_3_scb3_spi_m_select2: p7_3_scb3_spi_m_select2 { + pinmux = ; + }; + + /omit-if-no-ref/ p10_5_scb2_spi_m_select2: p10_5_scb2_spi_m_select2 { + pinmux = ; + }; + + /omit-if-no-ref/ p11_5_scb1_spi_m_select2: p11_5_scb1_spi_m_select2 { + pinmux = ; + }; + + /omit-if-no-ref/ p11_5_scb4_spi_m_select2: p11_5_scb4_spi_m_select2 { + pinmux = ; + }; + + /* scb_spi_m_select3 */ + /omit-if-no-ref/ p0_2_scb0_spi_m_select3: p0_2_scb0_spi_m_select3 { + pinmux = ; + }; + + /omit-if-no-ref/ p1_6_scb0_spi_m_select3: p1_6_scb0_spi_m_select3 { + pinmux = ; + }; + + /omit-if-no-ref/ p2_6_scb1_spi_m_select3: p2_6_scb1_spi_m_select3 { + pinmux = ; + }; + + /omit-if-no-ref/ p3_6_scb1_spi_m_select3: p3_6_scb1_spi_m_select3 { + pinmux = ; + }; + + /omit-if-no-ref/ p3_6_scb4_spi_m_select3: p3_6_scb4_spi_m_select3 { + pinmux = ; + }; + + /omit-if-no-ref/ p4_6_scb0_spi_m_select3: p4_6_scb0_spi_m_select3 { + pinmux = ; + }; + + /omit-if-no-ref/ p5_6_scb2_spi_m_select3: p5_6_scb2_spi_m_select3 { + pinmux = ; + }; + + /omit-if-no-ref/ p7_6_scb3_spi_m_select3: p7_6_scb3_spi_m_select3 { + pinmux = ; + }; + + /omit-if-no-ref/ p12_0_scb3_spi_m_select3: p12_0_scb3_spi_m_select3 { + pinmux = ; + }; + + /* scb_spi_s_clk */ + /omit-if-no-ref/ p0_6_scb1_spi_s_clk: p0_6_scb1_spi_s_clk { + pinmux = ; + }; + + /omit-if-no-ref/ p1_2_scb0_spi_s_clk: p1_2_scb0_spi_s_clk { + pinmux = ; + }; + + /omit-if-no-ref/ p1_7_scb2_spi_s_clk: p1_7_scb2_spi_s_clk { + pinmux = ; + }; + + /omit-if-no-ref/ p2_2_scb1_spi_s_clk: p2_2_scb1_spi_s_clk { + pinmux = ; + }; + + /omit-if-no-ref/ p3_2_scb1_spi_s_clk: p3_2_scb1_spi_s_clk { + pinmux = ; + }; + + /omit-if-no-ref/ p4_2_scb0_spi_s_clk: p4_2_scb0_spi_s_clk { + pinmux = ; + }; + + /omit-if-no-ref/ p4_6_scb4_spi_s_clk: p4_6_scb4_spi_s_clk { + pinmux = ; + }; + + /omit-if-no-ref/ p5_2_scb2_spi_s_clk: p5_2_scb2_spi_s_clk { + pinmux = ; + }; + + /omit-if-no-ref/ p6_2_scb3_spi_s_clk: p6_2_scb3_spi_s_clk { + pinmux = ; + }; + + /omit-if-no-ref/ p7_2_scb3_spi_s_clk: p7_2_scb3_spi_s_clk { + pinmux = ; + }; + + /omit-if-no-ref/ p8_2_scb3_spi_s_clk: p8_2_scb3_spi_s_clk { + pinmux = ; + }; + + /omit-if-no-ref/ p9_2_scb0_spi_s_clk: p9_2_scb0_spi_s_clk { + pinmux = ; + }; + + /omit-if-no-ref/ p10_2_scb2_spi_s_clk: p10_2_scb2_spi_s_clk { + pinmux = ; + }; + + /omit-if-no-ref/ p11_2_scb1_spi_s_clk: p11_2_scb1_spi_s_clk { + pinmux = ; + }; + + /omit-if-no-ref/ p11_2_scb4_spi_s_clk: p11_2_scb4_spi_s_clk { + pinmux = ; + }; + + /* scb_spi_s_miso */ + /omit-if-no-ref/ p0_5_scb1_spi_s_miso: p0_5_scb1_spi_s_miso { + pinmux = ; + }; + + /omit-if-no-ref/ p1_1_scb0_spi_s_miso: p1_1_scb0_spi_s_miso { + pinmux = ; + }; + + /omit-if-no-ref/ p2_1_scb1_spi_s_miso: p2_1_scb1_spi_s_miso { + pinmux = ; + }; + + /omit-if-no-ref/ p3_1_scb1_spi_s_miso: p3_1_scb1_spi_s_miso { + pinmux = ; + }; + + /omit-if-no-ref/ p3_7_scb2_spi_s_miso: p3_7_scb2_spi_s_miso { + pinmux = ; + }; + + /omit-if-no-ref/ p4_1_scb0_spi_s_miso: p4_1_scb0_spi_s_miso { + pinmux = ; + }; + + /omit-if-no-ref/ p4_5_scb4_spi_s_miso: p4_5_scb4_spi_s_miso { + pinmux = ; + }; + + /omit-if-no-ref/ p5_1_scb2_spi_s_miso: p5_1_scb2_spi_s_miso { + pinmux = ; + }; + + /omit-if-no-ref/ p6_1_scb3_spi_s_miso: p6_1_scb3_spi_s_miso { + pinmux = ; + }; + + /omit-if-no-ref/ p7_1_scb3_spi_s_miso: p7_1_scb3_spi_s_miso { + pinmux = ; + }; + + /omit-if-no-ref/ p8_1_scb3_spi_s_miso: p8_1_scb3_spi_s_miso { + pinmux = ; + }; + + /omit-if-no-ref/ p9_1_scb0_spi_s_miso: p9_1_scb0_spi_s_miso { + pinmux = ; + }; + + /omit-if-no-ref/ p10_1_scb2_spi_s_miso: p10_1_scb2_spi_s_miso { + pinmux = ; + }; + + /omit-if-no-ref/ p11_1_scb1_spi_s_miso: p11_1_scb1_spi_s_miso { + pinmux = ; + }; + + /omit-if-no-ref/ p11_1_scb4_spi_s_miso: p11_1_scb4_spi_s_miso { + pinmux = ; + }; + + /* scb_spi_s_mosi */ + /omit-if-no-ref/ p0_4_scb1_spi_s_mosi: p0_4_scb1_spi_s_mosi { + pinmux = ; + }; + + /omit-if-no-ref/ p1_0_scb0_spi_s_mosi: p1_0_scb0_spi_s_mosi { + pinmux = ; + }; + + /omit-if-no-ref/ p2_0_scb1_spi_s_mosi: p2_0_scb1_spi_s_mosi { + pinmux = ; + }; + + /omit-if-no-ref/ p2_7_scb2_spi_s_mosi: p2_7_scb2_spi_s_mosi { + pinmux = ; + }; + + /omit-if-no-ref/ p3_0_scb1_spi_s_mosi: p3_0_scb1_spi_s_mosi { + pinmux = ; + }; + + /omit-if-no-ref/ p4_0_scb0_spi_s_mosi: p4_0_scb0_spi_s_mosi { + pinmux = ; + }; + + /omit-if-no-ref/ p4_4_scb4_spi_s_mosi: p4_4_scb4_spi_s_mosi { + pinmux = ; + }; + + /omit-if-no-ref/ p5_0_scb2_spi_s_mosi: p5_0_scb2_spi_s_mosi { + pinmux = ; + }; + + /omit-if-no-ref/ p6_0_scb3_spi_s_mosi: p6_0_scb3_spi_s_mosi { + pinmux = ; + }; + + /omit-if-no-ref/ p7_0_scb3_spi_s_mosi: p7_0_scb3_spi_s_mosi { + pinmux = ; + }; + + /omit-if-no-ref/ p8_0_scb3_spi_s_mosi: p8_0_scb3_spi_s_mosi { + pinmux = ; + }; + + /omit-if-no-ref/ p9_0_scb0_spi_s_mosi: p9_0_scb0_spi_s_mosi { + pinmux = ; + }; + + /omit-if-no-ref/ p10_0_scb2_spi_s_mosi: p10_0_scb2_spi_s_mosi { + pinmux = ; + }; + + /omit-if-no-ref/ p11_0_scb1_spi_s_mosi: p11_0_scb1_spi_s_mosi { + pinmux = ; + }; + + /omit-if-no-ref/ p11_0_scb4_spi_s_mosi: p11_0_scb4_spi_s_mosi { + pinmux = ; + }; + + /* scb_spi_s_select0 */ + /omit-if-no-ref/ p0_3_scb2_spi_s_select0: p0_3_scb2_spi_s_select0 { + pinmux = ; + }; + + /omit-if-no-ref/ p0_7_scb1_spi_s_select0: p0_7_scb1_spi_s_select0 { + pinmux = ; + }; + + /omit-if-no-ref/ p1_3_scb0_spi_s_select0: p1_3_scb0_spi_s_select0 { + pinmux = ; + }; + + /omit-if-no-ref/ p2_3_scb1_spi_s_select0: p2_3_scb1_spi_s_select0 { + pinmux = ; + }; + + /omit-if-no-ref/ p3_3_scb1_spi_s_select0: p3_3_scb1_spi_s_select0 { + pinmux = ; + }; + + /omit-if-no-ref/ p4_3_scb0_spi_s_select0: p4_3_scb0_spi_s_select0 { + pinmux = ; + }; + + /omit-if-no-ref/ p4_7_scb4_spi_s_select0: p4_7_scb4_spi_s_select0 { + pinmux = ; + }; + + /omit-if-no-ref/ p5_3_scb2_spi_s_select0: p5_3_scb2_spi_s_select0 { + pinmux = ; + }; + + /omit-if-no-ref/ p6_3_scb3_spi_s_select0: p6_3_scb3_spi_s_select0 { + pinmux = ; + }; + + /omit-if-no-ref/ p7_4_scb3_spi_s_select0: p7_4_scb3_spi_s_select0 { + pinmux = ; + }; + + /omit-if-no-ref/ p8_3_scb3_spi_s_select0: p8_3_scb3_spi_s_select0 { + pinmux = ; + }; + + /omit-if-no-ref/ p9_3_scb0_spi_s_select0: p9_3_scb0_spi_s_select0 { + pinmux = ; + }; + + /omit-if-no-ref/ p10_3_scb2_spi_s_select0: p10_3_scb2_spi_s_select0 { + pinmux = ; + }; + + /omit-if-no-ref/ p11_3_scb1_spi_s_select0: p11_3_scb1_spi_s_select0 { + pinmux = ; + }; + + /omit-if-no-ref/ p11_3_scb4_spi_s_select0: p11_3_scb4_spi_s_select0 { + pinmux = ; + }; + + /* scb_spi_s_select1 */ + /omit-if-no-ref/ p0_0_scb0_spi_s_select1: p0_0_scb0_spi_s_select1 { + pinmux = ; + }; + + /omit-if-no-ref/ p1_4_scb0_spi_s_select1: p1_4_scb0_spi_s_select1 { + pinmux = ; + }; + + /omit-if-no-ref/ p2_4_scb1_spi_s_select1: p2_4_scb1_spi_s_select1 { + pinmux = ; + }; + + /omit-if-no-ref/ p3_4_scb1_spi_s_select1: p3_4_scb1_spi_s_select1 { + pinmux = ; + }; + + /omit-if-no-ref/ p4_4_scb0_spi_s_select1: p4_4_scb0_spi_s_select1 { + pinmux = ; + }; + + /omit-if-no-ref/ p5_4_scb2_spi_s_select1: p5_4_scb2_spi_s_select1 { + pinmux = ; + }; + + /omit-if-no-ref/ p5_6_scb4_spi_s_select1: p5_6_scb4_spi_s_select1 { + pinmux = ; + }; + + /omit-if-no-ref/ p5_7_scb3_spi_s_select1: p5_7_scb3_spi_s_select1 { + pinmux = ; + }; + + /omit-if-no-ref/ p6_4_scb3_spi_s_select1: p6_4_scb3_spi_s_select1 { + pinmux = ; + }; + + /omit-if-no-ref/ p7_5_scb3_spi_s_select1: p7_5_scb3_spi_s_select1 { + pinmux = ; + }; + + /omit-if-no-ref/ p10_4_scb2_spi_s_select1: p10_4_scb2_spi_s_select1 { + pinmux = ; + }; + + /omit-if-no-ref/ p11_4_scb1_spi_s_select1: p11_4_scb1_spi_s_select1 { + pinmux = ; + }; + + /omit-if-no-ref/ p11_4_scb4_spi_s_select1: p11_4_scb4_spi_s_select1 { + pinmux = ; + }; + + /* scb_spi_s_select2 */ + /omit-if-no-ref/ p0_1_scb0_spi_s_select2: p0_1_scb0_spi_s_select2 { + pinmux = ; + }; + + /omit-if-no-ref/ p1_5_scb0_spi_s_select2: p1_5_scb0_spi_s_select2 { + pinmux = ; + }; + + /omit-if-no-ref/ p2_5_scb1_spi_s_select2: p2_5_scb1_spi_s_select2 { + pinmux = ; + }; + + /omit-if-no-ref/ p3_5_scb1_spi_s_select2: p3_5_scb1_spi_s_select2 { + pinmux = ; + }; + + /omit-if-no-ref/ p4_5_scb0_spi_s_select2: p4_5_scb0_spi_s_select2 { + pinmux = ; + }; + + /omit-if-no-ref/ p4_7_scb3_spi_s_select2: p4_7_scb3_spi_s_select2 { + pinmux = ; + }; + + /omit-if-no-ref/ p5_5_scb2_spi_s_select2: p5_5_scb2_spi_s_select2 { + pinmux = ; + }; + + /omit-if-no-ref/ p5_7_scb4_spi_s_select2: p5_7_scb4_spi_s_select2 { + pinmux = ; + }; + + /omit-if-no-ref/ p6_5_scb3_spi_s_select2: p6_5_scb3_spi_s_select2 { + pinmux = ; + }; + + /omit-if-no-ref/ p7_3_scb3_spi_s_select2: p7_3_scb3_spi_s_select2 { + pinmux = ; + }; + + /omit-if-no-ref/ p10_5_scb2_spi_s_select2: p10_5_scb2_spi_s_select2 { + pinmux = ; + }; + + /omit-if-no-ref/ p11_5_scb1_spi_s_select2: p11_5_scb1_spi_s_select2 { + pinmux = ; + }; + + /omit-if-no-ref/ p11_5_scb4_spi_s_select2: p11_5_scb4_spi_s_select2 { + pinmux = ; + }; + + /* scb_spi_s_select3 */ + /omit-if-no-ref/ p0_2_scb0_spi_s_select3: p0_2_scb0_spi_s_select3 { + pinmux = ; + }; + + /omit-if-no-ref/ p1_6_scb0_spi_s_select3: p1_6_scb0_spi_s_select3 { + pinmux = ; + }; + + /omit-if-no-ref/ p2_6_scb1_spi_s_select3: p2_6_scb1_spi_s_select3 { + pinmux = ; + }; + + /omit-if-no-ref/ p3_6_scb1_spi_s_select3: p3_6_scb1_spi_s_select3 { + pinmux = ; + }; + + /omit-if-no-ref/ p3_6_scb4_spi_s_select3: p3_6_scb4_spi_s_select3 { + pinmux = ; + }; + + /omit-if-no-ref/ p4_6_scb0_spi_s_select3: p4_6_scb0_spi_s_select3 { + pinmux = ; + }; + + /omit-if-no-ref/ p5_6_scb2_spi_s_select3: p5_6_scb2_spi_s_select3 { + pinmux = ; + }; + + /omit-if-no-ref/ p7_6_scb3_spi_s_select3: p7_6_scb3_spi_s_select3 { + pinmux = ; + }; + + /omit-if-no-ref/ p12_0_scb3_spi_s_select3: p12_0_scb3_spi_s_select3 { + pinmux = ; + }; + + /* scb_uart_cts */ + /omit-if-no-ref/ p0_0_scb2_uart_cts: p0_0_scb2_uart_cts { + pinmux = ; + }; + + /omit-if-no-ref/ p0_6_scb1_uart_cts: p0_6_scb1_uart_cts { + pinmux = ; + }; + + /omit-if-no-ref/ p1_2_scb0_uart_cts: p1_2_scb0_uart_cts { + pinmux = ; + }; + + /omit-if-no-ref/ p2_6_scb3_uart_cts: p2_6_scb3_uart_cts { + pinmux = ; + }; + + /omit-if-no-ref/ p3_2_scb1_uart_cts: p3_2_scb1_uart_cts { + pinmux = ; + }; + + /omit-if-no-ref/ p4_2_scb0_uart_cts: p4_2_scb0_uart_cts { + pinmux = ; + }; + + /omit-if-no-ref/ p4_6_scb4_uart_cts: p4_6_scb4_uart_cts { + pinmux = ; + }; + + /omit-if-no-ref/ p5_2_scb2_uart_cts: p5_2_scb2_uart_cts { + pinmux = ; + }; + + /omit-if-no-ref/ p6_2_scb3_uart_cts: p6_2_scb3_uart_cts { + pinmux = ; + }; + + /omit-if-no-ref/ p7_2_scb3_uart_cts: p7_2_scb3_uart_cts { + pinmux = ; + }; + + /omit-if-no-ref/ p8_2_scb4_uart_cts: p8_2_scb4_uart_cts { + pinmux = ; + }; + + /omit-if-no-ref/ p9_2_scb0_uart_cts: p9_2_scb0_uart_cts { + pinmux = ; + }; + + /omit-if-no-ref/ p10_2_scb2_uart_cts: p10_2_scb2_uart_cts { + pinmux = ; + }; + + /omit-if-no-ref/ p11_2_scb4_uart_cts: p11_2_scb4_uart_cts { + pinmux = ; + }; + + /* scb_uart_rts */ + /omit-if-no-ref/ p0_1_scb2_uart_rts: p0_1_scb2_uart_rts { + pinmux = ; + }; + + /omit-if-no-ref/ p0_7_scb1_uart_rts: p0_7_scb1_uart_rts { + pinmux = ; + }; + + /omit-if-no-ref/ p1_3_scb0_uart_rts: p1_3_scb0_uart_rts { + pinmux = ; + }; + + /omit-if-no-ref/ p2_7_scb3_uart_rts: p2_7_scb3_uart_rts { + pinmux = ; + }; + + /omit-if-no-ref/ p3_3_scb1_uart_rts: p3_3_scb1_uart_rts { + pinmux = ; + }; + + /omit-if-no-ref/ p4_3_scb0_uart_rts: p4_3_scb0_uart_rts { + pinmux = ; + }; + + /omit-if-no-ref/ p4_7_scb4_uart_rts: p4_7_scb4_uart_rts { + pinmux = ; + }; + + /omit-if-no-ref/ p5_3_scb2_uart_rts: p5_3_scb2_uart_rts { + pinmux = ; + }; + + /omit-if-no-ref/ p6_3_scb3_uart_rts: p6_3_scb3_uart_rts { + pinmux = ; + }; + + /omit-if-no-ref/ p7_3_scb3_uart_rts: p7_3_scb3_uart_rts { + pinmux = ; + }; + + /omit-if-no-ref/ p8_3_scb4_uart_rts: p8_3_scb4_uart_rts { + pinmux = ; + }; + + /omit-if-no-ref/ p9_3_scb0_uart_rts: p9_3_scb0_uart_rts { + pinmux = ; + }; + + /omit-if-no-ref/ p10_3_scb2_uart_rts: p10_3_scb2_uart_rts { + pinmux = ; + }; + + /omit-if-no-ref/ p11_3_scb4_uart_rts: p11_3_scb4_uart_rts { + pinmux = ; + }; + + /* scb_uart_rx */ + /omit-if-no-ref/ p0_4_scb1_uart_rx: p0_4_scb1_uart_rx { + pinmux = ; + }; + + /omit-if-no-ref/ p0_4_scb2_uart_rx: p0_4_scb2_uart_rx { + pinmux = ; + }; + + /omit-if-no-ref/ p1_0_scb0_uart_rx: p1_0_scb0_uart_rx { + pinmux = ; + }; + + /omit-if-no-ref/ p2_4_scb3_uart_rx: p2_4_scb3_uart_rx { + pinmux = ; + }; + + /omit-if-no-ref/ p3_0_scb1_uart_rx: p3_0_scb1_uart_rx { + pinmux = ; + }; + + /omit-if-no-ref/ p4_0_scb0_uart_rx: p4_0_scb0_uart_rx { + pinmux = ; + }; + + /omit-if-no-ref/ p4_4_scb4_uart_rx: p4_4_scb4_uart_rx { + pinmux = ; + }; + + /omit-if-no-ref/ p5_0_scb2_uart_rx: p5_0_scb2_uart_rx { + pinmux = ; + }; + + /omit-if-no-ref/ p6_0_scb3_uart_rx: p6_0_scb3_uart_rx { + pinmux = ; + }; + + /omit-if-no-ref/ p7_0_scb3_uart_rx: p7_0_scb3_uart_rx { + pinmux = ; + }; + + /omit-if-no-ref/ p8_0_scb4_uart_rx: p8_0_scb4_uart_rx { + pinmux = ; + }; + + /omit-if-no-ref/ p9_0_scb0_uart_rx: p9_0_scb0_uart_rx { + pinmux = ; + }; + + /omit-if-no-ref/ p10_0_scb2_uart_rx: p10_0_scb2_uart_rx { + pinmux = ; + }; + + /omit-if-no-ref/ p11_0_scb4_uart_rx: p11_0_scb4_uart_rx { + pinmux = ; + }; + + /* scb_uart_tx */ + /omit-if-no-ref/ p0_5_scb1_uart_tx: p0_5_scb1_uart_tx { + pinmux = ; + }; + + /omit-if-no-ref/ p0_5_scb2_uart_tx: p0_5_scb2_uart_tx { + pinmux = ; + }; + + /omit-if-no-ref/ p0_6_scb2_uart_tx: p0_6_scb2_uart_tx { + pinmux = ; + }; + + /omit-if-no-ref/ p1_1_scb0_uart_tx: p1_1_scb0_uart_tx { + pinmux = ; + }; + + /omit-if-no-ref/ p2_5_scb3_uart_tx: p2_5_scb3_uart_tx { + pinmux = ; + }; + + /omit-if-no-ref/ p3_1_scb1_uart_tx: p3_1_scb1_uart_tx { + pinmux = ; + }; + + /omit-if-no-ref/ p4_1_scb0_uart_tx: p4_1_scb0_uart_tx { + pinmux = ; + }; + + /omit-if-no-ref/ p4_5_scb4_uart_tx: p4_5_scb4_uart_tx { + pinmux = ; + }; + + /omit-if-no-ref/ p5_1_scb2_uart_tx: p5_1_scb2_uart_tx { + pinmux = ; + }; + + /omit-if-no-ref/ p6_1_scb3_uart_tx: p6_1_scb3_uart_tx { + pinmux = ; + }; + + /omit-if-no-ref/ p7_1_scb3_uart_tx: p7_1_scb3_uart_tx { + pinmux = ; + }; + + /omit-if-no-ref/ p8_1_scb4_uart_tx: p8_1_scb4_uart_tx { + pinmux = ; + }; + + /omit-if-no-ref/ p9_1_scb0_uart_tx: p9_1_scb0_uart_tx { + pinmux = ; + }; + + /omit-if-no-ref/ p10_1_scb2_uart_tx: p10_1_scb2_uart_tx { + pinmux = ; + }; + + /omit-if-no-ref/ p11_1_scb4_uart_tx: p11_1_scb4_uart_tx { + pinmux = ; + }; + + /* PWM tcpwm_line*/ + /omit-if-no-ref/ p0_7_pwm0_0: p0_7_pwm0_0 { + pinmux = ; + }; + + /omit-if-no-ref/ p1_0_pwm0_2: p1_0_pwm0_2 { + pinmux = ; + }; + + /omit-if-no-ref/ p1_2_pwm0_3: p1_2_pwm0_3 { + pinmux = ; + }; + + /omit-if-no-ref/ p1_4_pwm0_6: p1_4_pwm0_6 { + pinmux = ; + }; + + /omit-if-no-ref/ p1_6_pwm0_7: p1_6_pwm0_7 { + pinmux = ; + }; + + /omit-if-no-ref/ p2_0_pwm0_4: p2_0_pwm0_4 { + pinmux = ; + }; + + /omit-if-no-ref/ p2_2_pwm0_5: p2_2_pwm0_5 { + pinmux = ; + }; + + /omit-if-no-ref/ p2_4_pwm0_0: p2_4_pwm0_0 { + pinmux = ; + }; + + /omit-if-no-ref/ p2_6_pwm0_1: p2_6_pwm0_1 { + pinmux = ; + }; + + /omit-if-no-ref/ p3_0_pwm0_0: p3_0_pwm0_0 { + pinmux = ; + }; + + /omit-if-no-ref/ p3_2_pwm0_1: p3_2_pwm0_1 { + pinmux = ; + }; + + /omit-if-no-ref/ p3_4_pwm0_2: p3_4_pwm0_2 { + pinmux = ; + }; + + /omit-if-no-ref/ p3_6_pwm0_3: p3_6_pwm0_3 { + pinmux = ; + }; + + /omit-if-no-ref/ p4_6_pwm0_6: p4_6_pwm0_6 { + pinmux = ; + }; + + /omit-if-no-ref/ p5_0_pwm0_4: p5_0_pwm0_4 { + pinmux = ; + }; + + /omit-if-no-ref/ p5_2_pwm0_5: p5_2_pwm0_5 { + pinmux = ; + }; + + /omit-if-no-ref/ p5_4_pwm0_6: p5_4_pwm0_6 { + pinmux = ; + }; + + /omit-if-no-ref/ p5_6_pwm0_7: p5_6_pwm0_7 { + pinmux = ; + }; + + /omit-if-no-ref/ p6_0_pwm0_4: p6_0_pwm0_4 { + pinmux = ; + }; + + /omit-if-no-ref/ p6_2_pwm0_5: p6_2_pwm0_5 { + pinmux = ; + }; + + /omit-if-no-ref/ p6_4_pwm0_6: p6_4_pwm0_6 { + pinmux = ; + }; + + /omit-if-no-ref/ p7_0_pwm0_0: p7_0_pwm0_0 { + pinmux = ; + }; + + /omit-if-no-ref/ p7_2_pwm0_1: p7_2_pwm0_1 { + pinmux = ; + }; + + /omit-if-no-ref/ p7_4_pwm0_2: p7_4_pwm0_2 { + pinmux = ; + }; + + /omit-if-no-ref/ p7_6_pwm0_3: p7_6_pwm0_3 { + pinmux = ; + }; + + /omit-if-no-ref/ p8_0_pwm0_4: p8_0_pwm0_4 { + pinmux = ; + }; + + /omit-if-no-ref/ p8_2_pwm0_5: p8_2_pwm0_5 { + pinmux = ; + }; + + /omit-if-no-ref/ p9_0_pwm0_0: p9_0_pwm0_0 { + pinmux = ; + }; + + /omit-if-no-ref/ p9_2_pwm0_1: p9_2_pwm0_1 { + pinmux = ; + }; + + /omit-if-no-ref/ p10_0_pwm0_7: p10_0_pwm0_7 { + pinmux = ; + }; + + /omit-if-no-ref/ p10_2_pwm0_2: p10_2_pwm0_2 { + pinmux = ; + }; + + /omit-if-no-ref/ p10_4_pwm0_3: p10_4_pwm0_3 { + pinmux = ; + }; + + /omit-if-no-ref/ p11_0_pwm0_4: p11_0_pwm0_4 { + pinmux = ; + }; + + /omit-if-no-ref/ p11_2_pwm0_5: p11_2_pwm0_5 { + pinmux = ; + }; + + /omit-if-no-ref/ p11_4_pwm0_6: p11_4_pwm0_6 { + pinmux = ; + }; + + /omit-if-no-ref/ p12_0_pwm0_7: p12_0_pwm0_7 { + pinmux = ; + }; + + /* PWM tcpwm_line_compl*/ + /omit-if-no-ref/ p1_1_pwm0_2: p1_1_pwm0_2_compl { + pinmux = ; + }; + + /omit-if-no-ref/ p1_3_pwm0_3: p1_3_pwm0_3_compl { + pinmux = ; + }; + + /omit-if-no-ref/ p1_5_pwm0_6: p1_5_pwm0_6_compl { + pinmux = ; + }; + + /omit-if-no-ref/ p1_7_pwm0_7: p1_7_pwm0_7_compl { + pinmux = ; + }; + + /omit-if-no-ref/ p2_1_pwm0_4: p2_1_pwm0_4_compl { + pinmux = ; + }; + + /omit-if-no-ref/ p2_3_pwm0_5: p2_3_pwm0_5_compl { + pinmux = ; + }; + + /omit-if-no-ref/ p2_5_pwm0_0: p2_5_pwm0_0_compl { + pinmux = ; + }; + + /omit-if-no-ref/ p2_7_pwm0_1: p2_7_pwm0_1_compl { + pinmux = ; + }; + + /omit-if-no-ref/ p3_1_pwm0_0: p3_1_pwm0_0_compl { + pinmux = ; + }; + + /omit-if-no-ref/ p3_3_pwm0_1: p3_3_pwm0_1_compl { + pinmux = ; + }; + + /omit-if-no-ref/ p3_5_pwm0_2: p3_5_pwm0_2_compl { + pinmux = ; + }; + + /omit-if-no-ref/ p3_7_pwm0_3: p3_7_pwm0_3_compl { + pinmux = ; + }; + + /omit-if-no-ref/ p4_7_pwm0_6: p4_7_pwm0_6_compl { + pinmux = ; + }; + + /omit-if-no-ref/ p5_1_pwm0_4: p5_1_pwm0_4_compl { + pinmux = ; + }; + + /omit-if-no-ref/ p5_3_pwm0_5: p5_3_pwm0_5_compl { + pinmux = ; + }; + + /omit-if-no-ref/ p5_5_pwm0_6: p5_5_pwm0_6_compl { + pinmux = ; + }; + + /omit-if-no-ref/ p5_7_pwm0_7: p5_7_pwm0_7_compl { + pinmux = ; + }; + + /omit-if-no-ref/ p6_1_pwm0_4: p6_1_pwm0_4_compl { + pinmux = ; + }; + + /omit-if-no-ref/ p6_3_pwm0_5: p6_3_pwm0_5_compl { + pinmux = ; + }; + + /omit-if-no-ref/ p6_5_pwm0_6: p6_5_pwm0_6_compl { + pinmux = ; + }; + + /omit-if-no-ref/ p7_1_pwm0_0: p7_1_pwm0_0_compl { + pinmux = ; + }; + + /omit-if-no-ref/ p7_3_pwm0_1: p7_3_pwm0_1_compl { + pinmux = ; + }; + + /omit-if-no-ref/ p7_5_pwm0_2: p7_5_pwm0_2_compl { + pinmux = ; + }; + + /omit-if-no-ref/ p7_7_pwm0_3: p7_7_pwm0_3_compl { + pinmux = ; + }; + + /omit-if-no-ref/ p8_1_pwm0_4: p8_1_pwm0_4_compl { + pinmux = ; + }; + + /omit-if-no-ref/ p8_3_pwm0_5: p8_3_pwm0_5_compl { + pinmux = ; + }; + + /omit-if-no-ref/ p9_1_pwm0_0: p9_1_pwm0_0_compl { + pinmux = ; + }; + + /omit-if-no-ref/ p9_3_pwm0_1: p9_3_pwm0_1_compl { + pinmux = ; + }; + + /omit-if-no-ref/ p10_1_pwm0_7: p10_1_pwm0_7_compl { + pinmux = ; + }; + + /omit-if-no-ref/ p10_3_pwm0_2: p10_3_pwm0_2_compl { + pinmux = ; + }; + + /omit-if-no-ref/ p10_5_pwm0_3: p10_5_pwm0_3_compl { + pinmux = ; + }; + + /omit-if-no-ref/ p11_1_pwm0_4: p11_1_pwm0_4_compl { + pinmux = ; + }; + + /omit-if-no-ref/ p11_3_pwm0_5: p11_3_pwm0_5_compl { + pinmux = ; + }; + + /omit-if-no-ref/ p11_5_pwm0_6: p11_5_pwm0_6_compl { + pinmux = ; + }; + + /omit-if-no-ref/ p12_1_pwm0_7: p12_1_pwm0_7_compl { + pinmux = ; + }; + + /* PWM tcpwm_tr_in*/ + /omit-if-no-ref/ p0_0_pwm0_0: p0_0_pwm0_0 { + pinmux = ; + }; + + /omit-if-no-ref/ p0_1_pwm0_1: p0_1_pwm0_1 { + pinmux = ; + }; + + /omit-if-no-ref/ p1_2_pwm0_2: p1_2_pwm0_2 { + pinmux = ; + }; + + /omit-if-no-ref/ p1_3_pwm0_3: p1_3_pwm0_3 { + pinmux = ; + }; + + /omit-if-no-ref/ p2_1_pwm0_5: p2_1_pwm0_5 { + pinmux = ; + }; + + /omit-if-no-ref/ p3_4_pwm0_6: p3_4_pwm0_6 { + pinmux = ; + }; + }; + }; +}; diff --git a/dts/arm/infineon/psoc4/psoc4100smax/psoc4100smax.cm0p.dtsi b/dts/arm/infineon/psoc4/psoc4100smax/psoc4100smax.cm0p.dtsi new file mode 100644 index 000000000000..89e6ac1a87e2 --- /dev/null +++ b/dts/arm/infineon/psoc4/psoc4100smax/psoc4100smax.cm0p.dtsi @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2025 Infineon Technologies AG, + * or an affiliate of Infineon Technologies AG. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +/ { + cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpu0: cpu@0 { + device_type = "cpu"; + compatible = "arm,cortex-m0+"; + reg = <0>; + clock-frequency = <48000000>; + }; + }; + + soc { + compatible = "simple-bus"; + #address-cells = <1>; + #size-cells = <1>; + ranges; + + /* Pinctrl node for Infineon PSOC4 SoC */ + pinctrl0: pinctrl@40310000 { + compatible = "infineon,cat1-pinctrl"; + reg = <0x40310000 0x1000>; + status = "okay"; + }; + }; +}; + +&nvic { + arm,num-irq-priority-bits = <2>; +}; diff --git a/dts/arm/infineon/psoc4/psoc4100smax/psoc4100smax.dtsi b/dts/arm/infineon/psoc4/psoc4100smax/psoc4100smax.dtsi new file mode 100644 index 000000000000..0835dae8df8c --- /dev/null +++ b/dts/arm/infineon/psoc4/psoc4100smax/psoc4100smax.dtsi @@ -0,0 +1,351 @@ +/* + * Copyright (c) 2025 Infineon Technologies AG, + * or an affiliate of Infineon Technologies AG + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include "psoc4100smax.cm0p.dtsi" +#include + +/ { + flash0: flash@0 { + compatible = "soc-nv-flash"; + reg = <0x00000000 DT_SIZE_K(384)>; /* 384 KB Flash */ + }; + + sram0: memory@20000000 { + compatible = "mmio-sram"; + reg = <0x20000000 DT_SIZE_K(32)>; /* 32 KB SRAM */ + }; + + soc { + pinctrl: pinctrl@40020000 { + compatible = "infineon,pinctrl"; + reg = <0x40020000 0x24000>; + }; + + hsiom: hsiom@40020000 { + compatible = "infineon,hsiom"; + reg = <0x40020000 0x4000>; + status = "disabled"; + }; + + gpio_prt0: gpio@40040000 { + compatible = "infineon,gpio"; + reg = <0x40040000 0x100>; + interrupts = <0 3>; + gpio-controller; + ngpios = <8>; + status = "disabled"; + #gpio-cells = <2>; + }; + + gpio_prt1: gpio@40040100 { + compatible = "infineon,gpio"; + reg = <0x40040100 0x100>; + interrupts = <1 3>; + gpio-controller; + ngpios = <8>; + status = "disabled"; + #gpio-cells = <2>; + }; + + gpio_prt2: gpio@40040200 { + compatible = "infineon,gpio"; + reg = <0x40040200 0x100>; + interrupts = <2 3>; + gpio-controller; + ngpios = <8>; + status = "disabled"; + #gpio-cells = <2>; + }; + + gpio_prt3: gpio@40040300 { + compatible = "infineon,gpio"; + reg = <0x40040300 0x100>; + interrupts = <3 3>; + gpio-controller; + ngpios = <8>; + status = "disabled"; + #gpio-cells = <2>; + }; + + /* Ports 4-12 share interrupt 4 (ioss_interrupt_gpio_IRQn) */ + gpio_prt4: gpio@40040400 { + compatible = "infineon,gpio"; + reg = <0x40040400 0x100>; + interrupts = <4 3>; + gpio-controller; + ngpios = <8>; + status = "disabled"; + #gpio-cells = <2>; + }; + + gpio_prt5: gpio@40040500 { + compatible = "infineon,gpio"; + reg = <0x40040500 0x100>; + interrupts = <4 3>; + gpio-controller; + ngpios = <8>; + status = "disabled"; + #gpio-cells = <2>; + }; + + gpio_prt6: gpio@40040600 { + compatible = "infineon,gpio"; + reg = <0x40040600 0x100>; + interrupts = <4 3>; + gpio-controller; + ngpios = <8>; + status = "disabled"; + #gpio-cells = <2>; + }; + + gpio_prt7: gpio@40040700 { + compatible = "infineon,gpio"; + reg = <0x40040700 0x100>; + interrupts = <4 3>; + gpio-controller; + ngpios = <8>; + status = "disabled"; + #gpio-cells = <2>; + }; + + gpio_prt8: gpio@40040800 { + compatible = "infineon,gpio"; + reg = <0x40040800 0x100>; + interrupts = <4 3>; + gpio-controller; + ngpios = <8>; + status = "disabled"; + #gpio-cells = <2>; + }; + + gpio_prt9: gpio@40040900 { + compatible = "infineon,gpio"; + reg = <0x40040900 0x100>; + interrupts = <4 3>; + gpio-controller; + ngpios = <8>; + status = "disabled"; + #gpio-cells = <2>; + }; + + gpio_prt10: gpio@40040a00 { + compatible = "infineon,gpio"; + reg = <0x40040a00 0x100>; + interrupts = <4 3>; + gpio-controller; + ngpios = <8>; + status = "disabled"; + #gpio-cells = <2>; + }; + + gpio_prt11: gpio@40040b00 { + compatible = "infineon,gpio"; + reg = <0x40040b00 0x100>; + interrupts = <4 3>; + gpio-controller; + ngpios = <6>; + status = "disabled"; + #gpio-cells = <2>; + }; + + gpio_prt12: gpio@40040c00 { + compatible = "infineon,gpio"; + reg = <0x40040c00 0x100>; + interrupts = <4 3>; + gpio-controller; + ngpios = <2>; + status = "disabled"; + #gpio-cells = <2>; + }; + + scb0: scb@40240000 { + compatible = "infineon,scb"; + reg = <0x40240000 0xfd0>; + interrupts = <7 3>; + status = "disabled"; + }; + + scb1: scb@40250000 { + compatible = "infineon,scb"; + reg = <0x40250000 0xfd0>; + interrupts = <8 3>; + status = "disabled"; + }; + + scb2: scb@40260000 { + compatible = "infineon,scb"; + reg = <0x40260000 0xfd0>; + interrupts = <9 3>; + status = "disabled"; + }; + + scb3: scb@40270000 { + compatible = "infineon,scb"; + reg = <0x40270000 0xfd0>; + interrupts = <10 3>; + status = "disabled"; + }; + + scb4: scb@40280000 { + compatible = "infineon,scb"; + reg = <0x40280000 0xfd0>; + interrupts = <11 3>; + status = "disabled"; + }; + + tcpwm0: tcpwm0@40200100 { + reg = <0x40200100 0x240>; + #address-cells = <1>; + #size-cells = <1>; + + tcpwm0_0: tcpwm0_0@40200100 { + compatible = "infineon,tcpwm"; + reg = <0x40200100 0x40>; + resolution = <16>; + status = "disabled"; + + pwm0_0: pwm0_0 { + compatible = "infineon,tcpwm-pwm"; + #pwm-cells = <3>; + status = "disabled"; + }; + + counter0_0: counter0_0 { + compatible = "infineon,tcpwm-counter"; + status = "disabled"; + }; + }; + + tcpwm0_1: tcpwm0_1@40200140 { + compatible = "infineon,tcpwm"; + reg = <0x40200140 0x40>; + resolution = <16>; + status = "disabled"; + + pwm0_1: pwm0_1 { + compatible = "infineon,tcpwm-pwm"; + #pwm-cells = <3>; + status = "disabled"; + }; + + counter0_1: counter0_1 { + compatible = "infineon,tcpwm-counter"; + status = "disabled"; + }; + }; + + tcpwm0_2: tcpwm0_2@40200180 { + compatible = "infineon,tcpwm"; + reg = <0x40200180 0x40>; + resolution = <16>; + status = "disabled"; + + pwm0_2: pwm0_2 { + compatible = "infineon,tcpwm-pwm"; + #pwm-cells = <3>; + status = "disabled"; + }; + + counter0_2: counter0_2 { + compatible = "infineon,tcpwm-counter"; + status = "disabled"; + }; + }; + + tcpwm0_3: tcpwm0_3@402001c0 { + compatible = "infineon,tcpwm"; + reg = <0x402001c0 0x40>; + resolution = <16>; + status = "disabled"; + + pwm0_3: pwm0_3 { + compatible = "infineon,tcpwm-pwm"; + #pwm-cells = <3>; + status = "disabled"; + }; + + counter0_3: counter0_3 { + compatible = "infineon,tcpwm-counter"; + status = "disabled"; + }; + }; + + tcpwm0_4: tcpwm0_4@40200200 { + compatible = "infineon,tcpwm"; + reg = <0x40200200 0x40>; + resolution = <16>; + status = "disabled"; + + pwm0_4: pwm0_4 { + compatible = "infineon,tcpwm-pwm"; + #pwm-cells = <3>; + status = "disabled"; + }; + + counter0_4: counter0_4 { + compatible = "infineon,tcpwm-counter"; + status = "disabled"; + }; + }; + + tcpwm0_5: tcpwm0_5@40200240 { + compatible = "infineon,tcpwm"; + reg = <0x40200240 0x40>; + resolution = <16>; + status = "disabled"; + + pwm0_5: pwm0_5 { + compatible = "infineon,tcpwm-pwm"; + #pwm-cells = <3>; + status = "disabled"; + }; + + counter0_5: counter0_5 { + compatible = "infineon,tcpwm-counter"; + status = "disabled"; + }; + }; + + tcpwm0_6: tcpwm0_6@40200280 { + compatible = "infineon,tcpwm"; + reg = <0x40200280 0x40>; + resolution = <16>; + status = "disabled"; + + pwm0_6: pwm0_6 { + compatible = "infineon,tcpwm-pwm"; + #pwm-cells = <3>; + status = "disabled"; + }; + + counter0_6: counter0_6 { + compatible = "infineon,tcpwm-counter"; + status = "disabled"; + }; + }; + + tcpwm0_7: tcpwm0_7@402002c0 { + compatible = "infineon,tcpwm"; + reg = <0x402002c0 0x40>; + resolution = <16>; + status = "disabled"; + + pwm0_7: pwm0_7 { + compatible = "infineon,tcpwm-pwm"; + #pwm-cells = <3>; + status = "disabled"; + }; + + counter0_7: counter0_7 { + compatible = "infineon,tcpwm-counter"; + status = "disabled"; + }; + }; + }; + }; +}; diff --git a/dts/arm/infineon/psoc4/psoc4100smax/system_clocks.dtsi b/dts/arm/infineon/psoc4/psoc4100smax/system_clocks.dtsi new file mode 100644 index 000000000000..322814d231fd --- /dev/null +++ b/dts/arm/infineon/psoc4/psoc4100smax/system_clocks.dtsi @@ -0,0 +1,237 @@ +/* + * Copyright (c) 2025 Infineon Technologies AG, + * or an affiliate of Infineon Technologies AG. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DIV_16_BIT 1 +#define DIV_16_5_BIT 2 +#define DIV_24_5_BIT 3 + +#include +#include +#include "freq.h" + +/ { + clocks { + /* Internal main oscillator (IMO) */ + clk_imo: clk-imo { + #clock-cells = <0>; + compatible = "infineon,fixed-clock"; + clock-frequency = ; + system-clock = ; + status = "okay"; + }; + + /* Internal low-speed oscillator (ILO) */ + clk_ilo: clk-ilo { + #clock-cells = <0>; + compatible = "infineon,fixed-clock"; + clock-frequency = ; + system-clock = ; + status = "okay"; + }; + + /* External clock (EXTCLK) */ + clk_ext: clk-extclk { + #clock-cells = <0>; + compatible = "infineon,fixed-clock"; + clock-frequency = ; + system-clock = ; + status = "okay"; + }; + + /* Watch crystal oscillator (WCO) */ + clk_wco: clk-wco { + #clock-cells = <0>; + compatible = "infineon,fixed-clock"; + clock-frequency = <0>; + system-clock = ; + status = "okay"; + }; + + clk_hf: clk-hf { + #clock-cells = <0>; + compatible = "infineon,fixed-factor-clock"; + clock-div = ; + source-path = ; + system-clock = ; + instance = <0>; + status = "disabled"; + }; + + clk_pump: clk-pump { + #clock-cells = <0>; + compatible = "infineon,fixed-factor-clock"; + system-clock = ; + source-path = ; + instance = <0>; + status = "disabled"; + }; + }; + + peri_div: peri-div { + peri_clk_div0: peri-clk-div0 { + #clock-cells = <0>; + compatible = "infineon,peri-div"; + div-type = ; + channel = <0>; + clock-div = <1>; + status = "disabled"; + }; + + peri_clk_div1: peri-clk-div1 { + #clock-cells = <0>; + compatible = "infineon,peri-div"; + div-type = ; + channel = <1>; + clock-div = <1>; + status = "disabled"; + }; + + peri_clk_div2: peri-clk-div2 { + #clock-cells = <0>; + compatible = "infineon,peri-div"; + div-type = ; + channel = <2>; + clock-div = <1>; + status = "disabled"; + }; + + peri_clk_div3: peri-clk-div3 { + #clock-cells = <0>; + compatible = "infineon,peri-div"; + div-type = ; + channel = <3>; + clock-div = <1>; + status = "disabled"; + }; + + peri_clk_div4: peri-clk-div4 { + #clock-cells = <0>; + compatible = "infineon,peri-div"; + div-type = ; + channel = <4>; + clock-div = <1>; + status = "disabled"; + }; + + peri_clk_div5: peri-clk-div5 { + #clock-cells = <0>; + compatible = "infineon,peri-div"; + div-type = ; + channel = <5>; + clock-div = <1>; + status = "disabled"; + }; + + peri_clk_div6: peri-clk-div6 { + #clock-cells = <0>; + compatible = "infineon,peri-div"; + div-type = ; + channel = <6>; + clock-div = <1>; + status = "disabled"; + }; + + peri_clk_div7: peri-clk-div7 { + #clock-cells = <0>; + compatible = "infineon,peri-div"; + div-type = ; + channel = <7>; + clock-div = <1>; + status = "disabled"; + }; + + peri_clk_div8: peri-clk-div8 { + #clock-cells = <0>; + compatible = "infineon,peri-div"; + div-type = ; + channel = <8>; + clock-div = <1>; + status = "disabled"; + }; + + peri_clk_div9: peri-clk-div9 { + #clock-cells = <0>; + compatible = "infineon,peri-div"; + div-type = ; + channel = <9>; + clock-div = <1>; + status = "disabled"; + }; + + peri_clk_div10: peri-clk-div10 { + #clock-cells = <0>; + compatible = "infineon,peri-div"; + div-type = ; + channel = <10>; + clock-div = <1>; + status = "disabled"; + }; + + peri_clk_div11: peri-clk-div11 { + #clock-cells = <0>; + compatible = "infineon,peri-div"; + div-type = ; + channel = <11>; + clock-div = <1>; + status = "disabled"; + }; + + peri_clk_fract_div0: peri-clk-fract-div0 { + #clock-cells = <0>; + compatible = "infineon,peri-div"; + div-type = ; + channel = <0>; + clock-div = <1>; + status = "disabled"; + }; + + peri_clk_fract_div1: peri-clk-fract-div1 { + #clock-cells = <0>; + compatible = "infineon,peri-div"; + div-type = ; + channel = <1>; + clock-div = <1>; + status = "disabled"; + }; + + peri_clk_fract_div2: peri-clk-fract-div2 { + #clock-cells = <0>; + compatible = "infineon,peri-div"; + div-type = ; + channel = <2>; + clock-div = <1>; + status = "disabled"; + }; + + peri_clk_fract_div3: peri-clk-fract-div3 { + #clock-cells = <0>; + compatible = "infineon,peri-div"; + div-type = ; + channel = <3>; + clock-div = <1>; + status = "disabled"; + }; + + peri_clk_fract_div4: peri-clk-fract-div4 { + #clock-cells = <0>; + compatible = "infineon,peri-div"; + div-type = ; + channel = <4>; + clock-div = <1>; + status = "disabled"; + }; + + peri_clk_fract_div5: peri-clk-fract-div5 { + #clock-cells = <0>; + compatible = "infineon,peri-div"; + div-type = ; + channel = <0>; + clock-div = <1>; + status = "disabled"; + }; + }; +}; From fe9ecee97e21297a07da450b27cbd5142ff2e663 Mon Sep 17 00:00:00 2001 From: Braeden Lane Date: Wed, 10 Dec 2025 14:02:48 -0800 Subject: [PATCH 0191/6328] drivers: gpio: Add Infineon PSOC 4 GPIO driver support Add GPIO driver for Infineon PSOC 4 series MCUs using the Infineon PDL. Signed-off-by: Braeden Lane --- drivers/gpio/CMakeLists.txt | 2 +- drivers/gpio/Kconfig.infineon | 11 ++++++----- drivers/gpio/gpio_infineon.c | 19 +------------------ 3 files changed, 8 insertions(+), 24 deletions(-) diff --git a/drivers/gpio/CMakeLists.txt b/drivers/gpio/CMakeLists.txt index 3811b378f4ec..24581982d465 100644 --- a/drivers/gpio/CMakeLists.txt +++ b/drivers/gpio/CMakeLists.txt @@ -38,7 +38,7 @@ zephyr_library_sources_ifdef(CONFIG_GPIO_GD32 gpio_gd32.c) zephyr_library_sources_ifdef(CONFIG_GPIO_GECKO gpio_gecko.c) zephyr_library_sources_ifdef(CONFIG_GPIO_GRGPIO2 gpio_grgpio2.c) zephyr_library_sources_ifdef(CONFIG_GPIO_IMX gpio_imx.c) -zephyr_library_sources_ifdef(CONFIG_GPIO_INFINEON_CAT1 gpio_infineon.c) +zephyr_library_sources_ifdef(CONFIG_GPIO_INFINEON gpio_infineon.c) zephyr_library_sources_ifdef(CONFIG_GPIO_INTEL gpio_intel.c) zephyr_library_sources_ifdef(CONFIG_GPIO_IPROC gpio_iproc.c) zephyr_library_sources_ifdef(CONFIG_GPIO_ITE_IT51XXX gpio_ite_it51xxx.c) diff --git a/drivers/gpio/Kconfig.infineon b/drivers/gpio/Kconfig.infineon index d80c7cfc6234..35e7fd4a7351 100644 --- a/drivers/gpio/Kconfig.infineon +++ b/drivers/gpio/Kconfig.infineon @@ -1,12 +1,13 @@ -# Infineon CAT1 GPIO configuration options +# Infineon GPIO configuration options -# Copyright (c) 2022 Cypress Semiconductor Corporation (an Infineon company) or +# Copyright (c) 2022-2025 Cypress Semiconductor Corporation (an Infineon company) or # an affiliate of Cypress Semiconductor Corporation # SPDX-License-Identifier: Apache-2.0 -config GPIO_INFINEON_CAT1 - bool "Infineon CAT1 GPIO driver" +config GPIO_INFINEON + bool "Infineon GPIO driver" default y depends on DT_HAS_INFINEON_GPIO_ENABLED help - Enable support for Infineon CAT1 GPIO controllers. + Enable GPIO driver for Infineon MCUs using the "infineon,gpio" + compatible. diff --git a/drivers/gpio/gpio_infineon.c b/drivers/gpio/gpio_infineon.c index 767fd4f62eb2..fcb47893ea32 100644 --- a/drivers/gpio/gpio_infineon.c +++ b/drivers/gpio/gpio_infineon.c @@ -206,24 +206,7 @@ static uint32_t gpio_cat1_get_pending_int(const struct device *dev) static uint32_t __maybe_unused gpio_get_pending_pins(const struct gpio_cat1_config *const cfg, GPIO_PRT_Type * const base) { - uint32_t pending; - -#if defined(CONFIG_SOC_FAMILY_INFINEON_PSOC4) - uint32_t intr_status = base->INTR; - uint32_t intr_mask = 0U; - - for (uint8_t i = 0; i < cfg->ngpios; i++) { - uint32_t intr_cfg = (base->INTR_CFG >> (i * 2U)) & 0x3U; - - if (intr_cfg != CY_GPIO_INTR_DISABLE) { - intr_mask |= BIT(i); - } - } - - pending = intr_status & intr_mask; -#else - pending = GPIO_PRT_INTR_MASKED(base); -#endif + uint32_t pending = GPIO_PRT_INTR(base) & gpio_cat1_valid_mask(cfg->ngpios); return pending; } From f68885f1c6e76cbf4cbe701e8bd84adcc3509e41 Mon Sep 17 00:00:00 2001 From: Braeden Lane Date: Wed, 10 Dec 2025 14:04:01 -0800 Subject: [PATCH 0192/6328] drivers: Add PSOC 4 clock control and serial support Add clock control and UART support for PSOC 4 family: - Clock control drivers with PSOC 4 compatibility - PSOC4xx clock source bindings and definitions - HF clock divider configuration support - UART FIFO trigger level configuration for PSOC 4100S Max series with 8-deep FIFO (RX trigger=7, TX trigger=0) Signed-off-by: Braeden Lane --- drivers/serial/uart_infineon_pdl.c | 6 +++--- include/zephyr/dt-bindings/clock/ifx_clock_source_boards.h | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/serial/uart_infineon_pdl.c b/drivers/serial/uart_infineon_pdl.c index f9d0647951a6..89a831f8f41e 100644 --- a/drivers/serial/uart_infineon_pdl.c +++ b/drivers/serial/uart_infineon_pdl.c @@ -46,13 +46,13 @@ LOG_MODULE_REGISTER(uart_ifx, CONFIG_UART_LOG_LEVEL); #define _IFX_CAT1_SCB_ARRAY_SIZE (CY_IP_MXS22SCB_INSTANCES) #endif /* CY_IP_MXSCB_INSTANCES */ -#if defined(CONFIG_SOC_SERIES_PSOC4100TP) +#if defined(CONFIG_SOC_FAMILY_INFINEON_PSOC4) #define IFX_UART_RX_FIFO_TRIGGER_LEVEL 7 #define IFX_UART_TX_FIFO_TRIGGER_LEVEL 0 #else #define IFX_UART_RX_FIFO_TRIGGER_LEVEL 63UL #define IFX_UART_TX_FIFO_TRIGGER_LEVEL 63UL -#endif /* CONFIG_SOC_SERIES_PSOC4100TP */ +#endif /* CONFIG_SOC_FAMILY_INFINEON_PSOC4 */ #define IFX_UART_RX_INT_MASK_NONE 0UL #define IFX_UART_TX_INT_MASK_NONE 0UL @@ -698,7 +698,7 @@ static const cy_stc_scb_uart_config_t _uart_default_config = { .breakWidth = 11UL, .dropOnFrameError = false, .dropOnParityError = false, -#if !defined(CONFIG_SOC_SERIES_PSOC4100TP) +#if !defined(CONFIG_SOC_FAMILY_INFINEON_PSOC4) .breaklevel = false, #else .breakLevel = false, diff --git a/include/zephyr/dt-bindings/clock/ifx_clock_source_boards.h b/include/zephyr/dt-bindings/clock/ifx_clock_source_boards.h index 42b8efc285eb..e94a3eb33481 100644 --- a/include/zephyr/dt-bindings/clock/ifx_clock_source_boards.h +++ b/include/zephyr/dt-bindings/clock/ifx_clock_source_boards.h @@ -9,6 +9,6 @@ #include "ifx_clock_source_pse8xx.h" #elif defined(CONFIG_SOC_SERIES_PSC3) #include "ifx_clock_source_psc3xx.h" -#elif defined(CONFIG_SOC_SERIES_PSOC4100TP) +#elif defined(CONFIG_SOC_FAMILY_INFINEON_PSOC4) #include "ifx_clock_source_psoc4xx.h" #endif From 060fe41df02024288056613dc1655cff920d1b48 Mon Sep 17 00:00:00 2001 From: Braeden Lane Date: Wed, 10 Dec 2025 14:05:21 -0800 Subject: [PATCH 0193/6328] boards: infineon: Add CY8CKIT-041S-MAX board Add support for Infineon CY8CKIT-041S-MAX development kit based on CY8C4149AZI-S598 (PSoC 4100S Max). Board features: - 100-pin TQFP PSOC 4100S Max MCU (384KB Flash, 32KB SRAM) - User LED and button - KitProg3 for programming/debugging - Common dtsi structure for peripheral configuration Signed-off-by: Braeden Lane --- .../cy8ckit_041s_max/Kconfig.cy8ckit_041s_max | 7 ++ boards/infineon/cy8ckit_041s_max/board.cmake | 7 ++ boards/infineon/cy8ckit_041s_max/board.yml | 11 +++ .../cy8ckit_041s_max-pinctrl.dtsi | 15 +++ .../cy8ckit_041s_max/cy8ckit_041s_max.dts | 38 ++++++++ .../cy8ckit_041s_max/cy8ckit_041s_max.yaml | 20 ++++ .../cy8ckit_041s_max_common.dtsi | 68 +++++++++++++ .../cy8ckit_041s_max_defconfig | 14 +++ .../infineon/cy8ckit_041s_max/docs/index.rst | 97 +++++++++++++++++++ .../cy8ckit_041s_max/support/openocd.cfg | 18 ++++ 10 files changed, 295 insertions(+) create mode 100644 boards/infineon/cy8ckit_041s_max/Kconfig.cy8ckit_041s_max create mode 100644 boards/infineon/cy8ckit_041s_max/board.cmake create mode 100644 boards/infineon/cy8ckit_041s_max/board.yml create mode 100644 boards/infineon/cy8ckit_041s_max/cy8ckit_041s_max-pinctrl.dtsi create mode 100644 boards/infineon/cy8ckit_041s_max/cy8ckit_041s_max.dts create mode 100644 boards/infineon/cy8ckit_041s_max/cy8ckit_041s_max.yaml create mode 100644 boards/infineon/cy8ckit_041s_max/cy8ckit_041s_max_common.dtsi create mode 100644 boards/infineon/cy8ckit_041s_max/cy8ckit_041s_max_defconfig create mode 100644 boards/infineon/cy8ckit_041s_max/docs/index.rst create mode 100644 boards/infineon/cy8ckit_041s_max/support/openocd.cfg diff --git a/boards/infineon/cy8ckit_041s_max/Kconfig.cy8ckit_041s_max b/boards/infineon/cy8ckit_041s_max/Kconfig.cy8ckit_041s_max new file mode 100644 index 000000000000..3051ffa83c44 --- /dev/null +++ b/boards/infineon/cy8ckit_041s_max/Kconfig.cy8ckit_041s_max @@ -0,0 +1,7 @@ +# Copyright (c) 2025 Infineon Technologies AG, +# or an affiliate of Infineon Technologies AG. +# +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_CY8CKIT_041S_MAX + select SOC_CY8C4149AZI_S598 diff --git a/boards/infineon/cy8ckit_041s_max/board.cmake b/boards/infineon/cy8ckit_041s_max/board.cmake new file mode 100644 index 000000000000..85b1fb6ebeae --- /dev/null +++ b/boards/infineon/cy8ckit_041s_max/board.cmake @@ -0,0 +1,7 @@ +# Copyright (c) 2025 Infineon Technologies AG, +# or an affiliate of Infineon Technologies AG. +# +# SPDX-License-Identifier: Apache-2.0 + +# Include standard OpenOCD runner helpers +include(${ZEPHYR_BASE}/boards/common/openocd.board.cmake) diff --git a/boards/infineon/cy8ckit_041s_max/board.yml b/boards/infineon/cy8ckit_041s_max/board.yml new file mode 100644 index 000000000000..ac5f159fdeb4 --- /dev/null +++ b/boards/infineon/cy8ckit_041s_max/board.yml @@ -0,0 +1,11 @@ +# Copyright (c) 2025 Infineon Technologies AG, +# or an affiliate of Infineon Technologies AG. +# +# SPDX-License-Identifier: Apache-2.0 + +board: + name: cy8ckit_041s_max + full_name: PSOC™ 4100S Max pioneer kit + vendor: infineon + socs: + - name: cy8c4149azi_s598 diff --git a/boards/infineon/cy8ckit_041s_max/cy8ckit_041s_max-pinctrl.dtsi b/boards/infineon/cy8ckit_041s_max/cy8ckit_041s_max-pinctrl.dtsi new file mode 100644 index 000000000000..f192b77eaad8 --- /dev/null +++ b/boards/infineon/cy8ckit_041s_max/cy8ckit_041s_max-pinctrl.dtsi @@ -0,0 +1,15 @@ +/* + * Copyright (c) 2025 Infineon Technologies AG, + * or an affiliate of Infineon Technologies AG. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/* Configure pin drive mode for uart pins */ +&p0_5_scb2_uart_tx { + drive-push-pull; +}; + +&p0_4_scb2_uart_rx { + input-enable; +}; diff --git a/boards/infineon/cy8ckit_041s_max/cy8ckit_041s_max.dts b/boards/infineon/cy8ckit_041s_max/cy8ckit_041s_max.dts new file mode 100644 index 000000000000..4e0256e44eaf --- /dev/null +++ b/boards/infineon/cy8ckit_041s_max/cy8ckit_041s_max.dts @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2025 Infineon Technologies AG, + * or an affiliate of Infineon Technologies AG. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; +#include +#include + +#include "cy8ckit_041s_max_common.dtsi" + +/ { + model = "CY8CKIT-041S-MAX Development Board"; + compatible = "infineon,cy8ckit-041s-max", "infineon,psoc4100smax"; + + chosen { + zephyr,sram = &sram0; + zephyr,flash = &flash0; + zephyr,console = &uart2; + zephyr,shell-uart = &uart2; + }; + + aliases { + led0 = &user_led1; + }; + + leds { + compatible = "gpio-leds"; + status = "okay"; + + user_led1: led_1 { + label = "LED_1"; + gpios = <&gpio_prt7 3 GPIO_ACTIVE_LOW>; + }; + }; +}; diff --git a/boards/infineon/cy8ckit_041s_max/cy8ckit_041s_max.yaml b/boards/infineon/cy8ckit_041s_max/cy8ckit_041s_max.yaml new file mode 100644 index 000000000000..cbae5def6d3d --- /dev/null +++ b/boards/infineon/cy8ckit_041s_max/cy8ckit_041s_max.yaml @@ -0,0 +1,20 @@ +# Copyright (c) 2025 Infineon Technologies AG, +# or an affiliate of Infineon Technologies AG. +# +# SPDX-License-Identifier: Apache-2.0 + +identifier: cy8ckit_041s_max +name: CY8CKIT-041S-MAX Development Board +type: mcu +arch: arm +ram: 32 +flash: 384 +toolchain: + - zephyr + - gnuarmemb +supported: + - uart + - gpio + - clock_control + - pinctrl +vendor: infineon diff --git a/boards/infineon/cy8ckit_041s_max/cy8ckit_041s_max_common.dtsi b/boards/infineon/cy8ckit_041s_max/cy8ckit_041s_max_common.dtsi new file mode 100644 index 000000000000..89220cc928b7 --- /dev/null +++ b/boards/infineon/cy8ckit_041s_max/cy8ckit_041s_max_common.dtsi @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2025 Infineon Technologies AG, + * or an affiliate of Infineon Technologies AG. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include "cy8ckit_041s_max-pinctrl.dtsi" + +uart2: &scb2 { + compatible = "infineon,uart"; + status = "okay"; + current-speed = <115200>; + clocks = <&peri_clk_div1>; + pinctrl-0 = <&p0_5_scb2_uart_tx &p0_4_scb2_uart_rx>; + pinctrl-names = "default"; +}; + +&peri_clk_div0 { + status = "okay"; + resource-type = ; + resource-instance = <0>; +}; + +&peri_clk_div1 { + status = "okay"; + resource-type = ; + resource-instance = <2>; +}; + +&peri_clk_div2 { + status = "okay"; + resource-type = ; + resource-instance = <1>; +}; + +&peri_clk_div3 { + status = "okay"; + resource-type = ; + resource-instance = <0>; + clock-div = <11500>; +}; + +/* + * Note : use IFX_PATH_PSOC4_IMO for internal main oscillator as src + * use IFX_PATH_PSOC4_EXT for External clock as src + */ +&clk_hf { + status = "okay"; + source-path = ; +}; + +/* + * Note : use IFX_PATH_PSOC4_PUMP_GND for No clock, connect to gnd + * use IFX_PATH_PSOC4_PUMP_IMO for main IMO pump output + * use IFX_PATH_PSOC4_PUMP_HFCLK for clk_hf pump + * + * usage : The pump clock can be used for the analog pump + */ +&clk_pump { + status = "okay"; + source-path = ; +}; + +&gpio_prt7 { + status = "okay"; +}; diff --git a/boards/infineon/cy8ckit_041s_max/cy8ckit_041s_max_defconfig b/boards/infineon/cy8ckit_041s_max/cy8ckit_041s_max_defconfig new file mode 100644 index 000000000000..ab312bcd2d16 --- /dev/null +++ b/boards/infineon/cy8ckit_041s_max/cy8ckit_041s_max_defconfig @@ -0,0 +1,14 @@ +# Copyright (c) 2025 Infineon Technologies AG, +# or an affiliate of Infineon Technologies AG. +# +# SPDX-License-Identifier: Apache-2.0 + +# Console +CONFIG_CONSOLE=y +CONFIG_UART_CONSOLE=y + +# UART driver +CONFIG_SERIAL=y + +# Clock controller +CONFIG_CLOCK_CONTROL=y diff --git a/boards/infineon/cy8ckit_041s_max/docs/index.rst b/boards/infineon/cy8ckit_041s_max/docs/index.rst new file mode 100644 index 000000000000..2a8540f78547 --- /dev/null +++ b/boards/infineon/cy8ckit_041s_max/docs/index.rst @@ -0,0 +1,97 @@ +.. zephyr:board:: cy8ckit_041s_max + +Overview +******** + +The PSOC™ 4100S Max Pioneer Kit (CY8CKIT-041S-MAX) enables you to evaluate and develop applications using the PSOC™ 4100S Max microcontroller, part of Infineon's PSOC™ 4 family. +The device integrates an Arm Cortex-M0+ CPU running up to 48 MHz, combining programmable analog and digital subsystems to support flexible mixed-signal designs. It features up to 384 KB Flash and up to 32 KB SRAM, and includes a wide range of configurable peripherals such as SAR ADC, comparators, opamps (CTBm), CapSense™ capacitive touch sensing, and TCPWM for timer/counter/PWM functionality. + +32-bit MCU subsystem +- 48-MHz Arm® Cortex®-M0+ CPU with single-cycle multiply +- Up to 384 KB of flash with read accelerator +- Up to 32 KB of SRAM +- Direct memory access (DMA) +- Low-power 1.71 V to 5.5 V operation +- Deep sleep mode with low-power touch sensing +- Active touch detection and tracking with low power consumption +- Real Time clock support +- Power supply: 3.3 V or 5 V operation + +Programming and Debugging +************************* + +.. zephyr:board-supported-runners:: + +Building +======== + +Here is an example for building the :zephyr:code-sample:`hello_world` sample application. + +.. zephyr-app-commands:: + :zephyr-app: samples/hello_world + :board: cy8ckit_041s_max + :goals: build + +Flashing +======== + +The CY8CKIT-041S-MAX includes an onboard programmer/debugger (`KitProg3`_) to provide debugging, flash programming, and serial communication over USB. Flash and debug commands use OpenOCD and require a custom Infineon OpenOCD version, that supports KitProg3, to be installed. + +Infineon OpenOCD Installation +============================= + +Both the full `ModusToolbox`_ and the `ModusToolbox Programming Tools`_ packages include Infineon OpenOCD. +Installing either of these packages will also install Infineon OpenOCD. + +If neither package is installed, a minimal installation can be done by downloading the `Infineon OpenOCD`_ release for your system and manually extract the files to a location of your choice. + +.. note:: Linux requires device access rights to be set up for KitProg3. This is handled automatically by the ModusToolbox and ModusToolbox Programming Tools installations. When doing a minimal installation, this can be done manually by executing the script ``openocd/udev_rules/install_rules.sh``. + +West Commands +============= + +The path to the installed Infineon OpenOCD executable must be available to the ``west`` tool commands. There are multiple ways of doing this. The example below uses a permanent CMake argument to set the CMake variable ``OPENOCD``. + +Run ``west config`` once to set permanent CMake argument: + + .. tabs:: + .. group-tab:: Windows + + .. code-block:: shell + + west config build.cmake-args -- -DOPENOCD=path/to/infineon/openocd/bin/openocd.exe + + .. group-tab:: Linux + + .. code-block:: shell + + west config build.cmake-args -- -DOPENOCD=path/to/infineon/openocd/bin/openocd + +Once configured, you can build and flash applications: + +.. zephyr-app-commands:: + :zephyr-app: samples/hello_world + :board: cy8ckit_041s_max + :goals: build flash debug + +Once the gdb console starts after executing the west debug command, you may now set breakpoints and perform other standard GDB debugging. + +References +********** + +.. target-notes:: + +.. _cy8ckit_041s_max Board Website: + https://www.infineon.com/evaluation-board/CY8CKIT-041S-MAX + +.. _ModusToolbox: + https://www.infineon.com/design-resources/development-tools/sdk/modustoolbox-software + +.. _ModusToolbox Programming Tools: + https://www.infineon.com/design-resources/development-tools/sdk/modustoolbox-software/modustoolbox-programming-tools + +.. _Infineon OpenOCD: + https://github.com/Infineon/openocd/releases/latest + +.. _KitProg3: + https://github.com/Infineon/KitProg3 diff --git a/boards/infineon/cy8ckit_041s_max/support/openocd.cfg b/boards/infineon/cy8ckit_041s_max/support/openocd.cfg new file mode 100644 index 000000000000..f7f165c28c07 --- /dev/null +++ b/boards/infineon/cy8ckit_041s_max/support/openocd.cfg @@ -0,0 +1,18 @@ +# SPDX-License-Identifier: Apache-2.0 +# +# OpenOCD configuration for CY8CKIT-041S-MAX +# PSoC 4100S Max with KitProg3 programmer + +source [find interface/kitprog3.cfg] + +# Set transport to SWD +transport select swd + +# Set adapter speed (KitProg3 supports up to 1000 kHz for PSoC 4) +adapter speed 1000 + +# PSoC 4 family configuration +source [find target/psoc4.cfg] + +# Reset configuration +reset_config srst_only From 56014df8d9adef9eb62d2f02310539be072cb8ac Mon Sep 17 00:00:00 2001 From: Braeden Lane Date: Wed, 10 Dec 2025 14:06:37 -0800 Subject: [PATCH 0194/6328] tests: Add cy8ckit_041s_max test overlays Add test and sample overlays for CY8CKIT-041S-MAX board: - GPIO basic API test using P1.2 and P1.3 pins - Button sample using P11.5 with pull-up configuration Signed-off-by: Braeden Lane --- .../button/boards/cy8ckit_041s_max.overlay | 26 +++++++++++++++++++ .../boards/cy8ckit_041s_max.overlay | 17 ++++++++++++ 2 files changed, 43 insertions(+) create mode 100644 samples/basic/button/boards/cy8ckit_041s_max.overlay create mode 100644 tests/drivers/gpio/gpio_basic_api/boards/cy8ckit_041s_max.overlay diff --git a/samples/basic/button/boards/cy8ckit_041s_max.overlay b/samples/basic/button/boards/cy8ckit_041s_max.overlay new file mode 100644 index 000000000000..6a5b7691bc07 --- /dev/null +++ b/samples/basic/button/boards/cy8ckit_041s_max.overlay @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2025 Infineon Technologies AG, + * or an affiliate of Infineon Technologies AG. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + aliases { + sw0 = &user_btn; + }; + + gpio_keys { + compatible = "gpio-keys"; + + user_btn: button_0 { + label = "SW_0"; + gpios = <&gpio_prt11 5 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>; + zephyr,code = ; + }; + }; +}; + +&gpio_prt11 { + status = "okay"; +}; diff --git a/tests/drivers/gpio/gpio_basic_api/boards/cy8ckit_041s_max.overlay b/tests/drivers/gpio/gpio_basic_api/boards/cy8ckit_041s_max.overlay new file mode 100644 index 000000000000..5abf04d5fd3a --- /dev/null +++ b/tests/drivers/gpio/gpio_basic_api/boards/cy8ckit_041s_max.overlay @@ -0,0 +1,17 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * + * Copyright (c) 2025 Infineon Technologies AG + */ + +/ { + resources { + compatible = "test-gpio-basic-api"; + out-gpios = <&gpio_prt1 2 0>; + in-gpios = <&gpio_prt1 3 0>; + }; +}; + +&gpio_prt1 { + status = "okay"; +}; From 6b3117827293750861d7651c9ebae2080a122c76 Mon Sep 17 00:00:00 2001 From: Victor Brzeski Date: Wed, 3 Dec 2025 15:34:49 -0800 Subject: [PATCH 0195/6328] uac2: disable active terminals when class is disabled When the USB Bus is reset, the USBD stack will disable and re-enable all Classes. If this occurs while streaming audio with UAC2, the terminals remain active when re-enabled, yet the endpoints have yet to be enabled (resulting in -ENODEV logspam). This change disables all active terminals when the class is disabled. Signed-off-by: Victor Brzeski --- subsys/usb/device_next/class/usbd_uac2.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/subsys/usb/device_next/class/usbd_uac2.c b/subsys/usb/device_next/class/usbd_uac2.c index ee95e643294e..047b340ce2ce 100644 --- a/subsys/usb/device_next/class/usbd_uac2.c +++ b/subsys/usb/device_next/class/usbd_uac2.c @@ -926,6 +926,26 @@ static void *uac2_get_desc(struct usbd_class_data *const c_data, return cfg->fs_descriptors; } +static void uac2_disable(struct usbd_class_data *const c_data) +{ + const struct device *dev = usbd_class_get_private(c_data); + struct uac2_ctx *ctx = dev->data; + const struct uac2_cfg *cfg = dev->config; + const bool microframes = + USBD_SUPPORTS_HIGH_SPEED && usbd_bus_speed(c_data->uds_ctx) == USBD_SPEED_HS; + atomic_val_t as_active; + + as_active = atomic_clear(&ctx->as_active); + + while (as_active) { + unsigned int as_idx = find_lsb_set(as_active) - 1; + + ctx->ops->terminal_update_cb(dev, cfg->as_terminals[as_idx], 0, microframes, + ctx->user_data); + as_active &= ~BIT(as_idx); + } +} + static int uac2_init(struct usbd_class_data *const c_data) { const struct device *dev = usbd_class_get_private(c_data); @@ -946,6 +966,7 @@ struct usbd_class_api uac2_api = { .request = uac2_request, .sof = uac2_sof, .get_desc = uac2_get_desc, + .disable = uac2_disable, .init = uac2_init, }; From 5ca1fe739944eff0e7436fa84fd78e40ae07bae8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 22 Jan 2026 17:04:24 +0000 Subject: [PATCH 0196/6328] ci: github: bump the actions-deps group across 1 directory with 15 updates Bumps the actions-deps group with 15 updates in the / directory: | Package | From | To | | --- | --- | --- | | [actions/checkout](https://github.com/actions/checkout) | `5.0.0` | `6.0.2` | | [dawidd6/action-download-artifact](https://github.com/dawidd6/action-download-artifact) | `11` | `12` | | [EnricoMi/publish-unit-test-result-action](https://github.com/enricomi/publish-unit-test-result-action) | `2.21.0` | `2.22.0` | | [tj-actions/changed-files](https://github.com/tj-actions/changed-files) | `47.0.0` | `47.0.1` | | [actions/upload-artifact](https://github.com/actions/upload-artifact) | `5.0.0` | `6.0.0` | | [aws-actions/configure-aws-credentials](https://github.com/aws-actions/configure-aws-credentials) | `5.1.0` | `5.1.1` | | [actions/download-artifact](https://github.com/actions/download-artifact) | `6.0.0` | `7.0.0` | | [codecov/codecov-action](https://github.com/codecov/codecov-action) | `5.5.1` | `5.5.2` | | [github/codeql-action](https://github.com/github/codeql-action) | `4.31.2` | `4.31.10` | | [actions/setup-node](https://github.com/actions/setup-node) | `6.0.0` | `6.2.0` | | [zephyrproject-rtos/action-zephyr-setup](https://github.com/zephyrproject-rtos/action-zephyr-setup) | `1.0.11` | `1.0.12` | | [carpentries/actions](https://github.com/carpentries/actions) | `0.15.0` | `0.17.0` | | [zgosalvez/github-actions-ensure-sha-pinned-actions](https://github.com/zgosalvez/github-actions-ensure-sha-pinned-actions) | `4.0.0` | `4.0.1` | | [actions/stale](https://github.com/actions/stale) | `10.1.0` | `10.1.1` | | [codecov/test-results-action](https://github.com/codecov/test-results-action) | `1.1.1` | `1.2.1` | Updates `actions/checkout` from 5.0.0 to 6.0.2 - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/08c6903cd8c0fde910a37f88322edcfb5dd907a8...de0fac2e4500dabe0009e67214ff5f5447ce83dd) Updates `dawidd6/action-download-artifact` from 11 to 12 - [Release notes](https://github.com/dawidd6/action-download-artifact/releases) - [Commits](https://github.com/dawidd6/action-download-artifact/compare/ac66b43f0e6a346234dd65d4d0c8fbb31cb316e5...0bd50d53a6d7fb5cb921e607957e9cc12b4ce392) Updates `EnricoMi/publish-unit-test-result-action` from 2.21.0 to 2.22.0 - [Release notes](https://github.com/enricomi/publish-unit-test-result-action/releases) - [Commits](https://github.com/enricomi/publish-unit-test-result-action/compare/34d7c956a59aed1bfebf31df77b8de55db9bbaaf...27d65e188ec43221b20d26de30f4892fad91df2f) Updates `tj-actions/changed-files` from 47.0.0 to 47.0.1 - [Release notes](https://github.com/tj-actions/changed-files/releases) - [Changelog](https://github.com/tj-actions/changed-files/blob/main/HISTORY.md) - [Commits](https://github.com/tj-actions/changed-files/compare/24d32ffd492484c1d75e0c0b894501ddb9d30d62...e0021407031f5be11a464abee9a0776171c79891) Updates `actions/upload-artifact` from 5.0.0 to 6.0.0 - [Release notes](https://github.com/actions/upload-artifact/releases) - [Commits](https://github.com/actions/upload-artifact/compare/330a01c490aca151604b8cf639adc76d48f6c5d4...b7c566a772e6b6bfb58ed0dc250532a479d7789f) Updates `aws-actions/configure-aws-credentials` from 5.1.0 to 5.1.1 - [Release notes](https://github.com/aws-actions/configure-aws-credentials/releases) - [Changelog](https://github.com/aws-actions/configure-aws-credentials/blob/main/CHANGELOG.md) - [Commits](https://github.com/aws-actions/configure-aws-credentials/compare/00943011d9042930efac3dcd3a170e4273319bc8...61815dcd50bd041e203e49132bacad1fd04d2708) Updates `actions/download-artifact` from 6.0.0 to 7.0.0 - [Release notes](https://github.com/actions/download-artifact/releases) - [Commits](https://github.com/actions/download-artifact/compare/018cc2cf5baa6db3ef3c5f8a56943fffe632ef53...37930b1c2abaa49bbe596cd826c3c89aef350131) Updates `codecov/codecov-action` from 5.5.1 to 5.5.2 - [Release notes](https://github.com/codecov/codecov-action/releases) - [Changelog](https://github.com/codecov/codecov-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/codecov/codecov-action/compare/5a1091511ad55cbe89839c7260b706298ca349f7...671740ac38dd9b0130fbe1cec585b89eea48d3de) Updates `github/codeql-action` from 4.31.2 to 4.31.10 - [Release notes](https://github.com/github/codeql-action/releases) - [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/github/codeql-action/compare/0499de31b99561a6d14a36a5f662c2a54f91beee...cdefb33c0f6224e58673d9004f47f7cb3e328b89) Updates `actions/setup-node` from 6.0.0 to 6.2.0 - [Release notes](https://github.com/actions/setup-node/releases) - [Commits](https://github.com/actions/setup-node/compare/2028fbc5c25fe9cf00d9f06a71cc4710d4507903...6044e13b5dc448c55e2357c09f80417699197238) Updates `zephyrproject-rtos/action-zephyr-setup` from 1.0.11 to 1.0.12 - [Commits](https://github.com/zephyrproject-rtos/action-zephyr-setup/compare/cefbf9086ce2da7d70e7ad9589af8aa1e4bda265...360ff9b36e58499d9eb28015cdcde7ca03a5b04d) Updates `carpentries/actions` from 0.15.0 to 0.17.0 - [Release notes](https://github.com/carpentries/actions/releases) - [Commits](https://github.com/carpentries/actions/compare/2e20fd5ee53b691e27455ce7ca3b16ea885140e8...083bb9952b1414bd2b9e10ecec1717c938aba4c5) Updates `zgosalvez/github-actions-ensure-sha-pinned-actions` from 4.0.0 to 4.0.1 - [Release notes](https://github.com/zgosalvez/github-actions-ensure-sha-pinned-actions/releases) - [Commits](https://github.com/zgosalvez/github-actions-ensure-sha-pinned-actions/compare/9e9574ef04ea69da568d6249bd69539ccc704e74...6124774845927d14c601359ab8138699fa5b70c3) Updates `actions/stale` from 10.1.0 to 10.1.1 - [Release notes](https://github.com/actions/stale/releases) - [Changelog](https://github.com/actions/stale/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/stale/compare/5f858e3efba33a5ca4407a664cc011ad407f2008...997185467fa4f803885201cee163a9f38240193d) Updates `codecov/test-results-action` from 1.1.1 to 1.2.1 - [Release notes](https://github.com/codecov/test-results-action/releases) - [Commits](https://github.com/codecov/test-results-action/compare/47f89e9acb64b76debcd5ea40642d25a4adced9f...0fa95f0e1eeaafde2c782583b36b28ad0d8c77d3) --- updated-dependencies: - dependency-name: actions/checkout dependency-version: 6.0.2 dependency-type: direct:production update-type: version-update:semver-major dependency-group: actions-deps - dependency-name: dawidd6/action-download-artifact dependency-version: '12' dependency-type: direct:production update-type: version-update:semver-major dependency-group: actions-deps - dependency-name: EnricoMi/publish-unit-test-result-action dependency-version: 2.22.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: actions-deps - dependency-name: tj-actions/changed-files dependency-version: 47.0.1 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: actions-deps - dependency-name: actions/upload-artifact dependency-version: 6.0.0 dependency-type: direct:production update-type: version-update:semver-major dependency-group: actions-deps - dependency-name: aws-actions/configure-aws-credentials dependency-version: 5.1.1 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: actions-deps - dependency-name: actions/download-artifact dependency-version: 7.0.0 dependency-type: direct:production update-type: version-update:semver-major dependency-group: actions-deps - dependency-name: codecov/codecov-action dependency-version: 5.5.2 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: actions-deps - dependency-name: github/codeql-action dependency-version: 4.31.10 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: actions-deps - dependency-name: actions/setup-node dependency-version: 6.2.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: actions-deps - dependency-name: zephyrproject-rtos/action-zephyr-setup dependency-version: 1.0.12 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: actions-deps - dependency-name: carpentries/actions dependency-version: 0.17.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: actions-deps - dependency-name: zgosalvez/github-actions-ensure-sha-pinned-actions dependency-version: 4.0.1 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: actions-deps - dependency-name: actions/stale dependency-version: 10.1.1 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: actions-deps - dependency-name: codecov/test-results-action dependency-version: 1.2.1 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: actions-deps ... Signed-off-by: dependabot[bot] --- .github/workflows/assigner.yml | 2 +- .github/workflows/backport_issue_check.yml | 2 +- .github/workflows/bsim-tests-publish.yaml | 4 ++-- .github/workflows/bsim-tests.yaml | 16 +++++++------- .github/workflows/bug_snapshot.yaml | 4 ++-- .github/workflows/clang.yaml | 12 +++++----- .github/workflows/codecov.yaml | 16 +++++++------- .github/workflows/codeql.yml | 6 ++--- .github/workflows/coding_guidelines.yml | 2 +- .github/workflows/compliance.yml | 8 +++---- .github/workflows/daily_test_version.yml | 4 ++-- .github/workflows/devicetree_checks.yml | 2 +- .github/workflows/doc-build.yml | 18 +++++++-------- .github/workflows/doc-publish-pr.yml | 6 ++--- .github/workflows/doc-publish.yml | 4 ++-- .github/workflows/errno.yml | 4 ++-- .github/workflows/footprint-tracking.yml | 4 ++-- .../greet_first_time_contributor.yml | 2 +- .../workflows/hello_world_multiplatform.yaml | 6 ++--- .github/workflows/issue_count.yml | 4 ++-- .github/workflows/license_check.yml | 4 ++-- .github/workflows/manifest.yml | 2 +- .github/workflows/pinned-gh-actions.yml | 4 ++-- .github/workflows/pr_metadata_check.yml | 2 +- .github/workflows/pylib_tests.yml | 2 +- .github/workflows/release.yml | 4 ++-- .github/workflows/scorecards.yml | 6 ++--- .github/workflows/scripts_tests.yml | 2 +- .github/workflows/stale_issue.yml | 2 +- .github/workflows/stats_merged_prs.yml | 2 +- .github/workflows/twister-publish.yaml | 4 ++-- .github/workflows/twister.yaml | 22 +++++++++---------- .github/workflows/twister_tests.yml | 2 +- .github/workflows/twister_tests_blackbox.yml | 4 ++-- .github/workflows/west_cmds.yml | 2 +- 35 files changed, 95 insertions(+), 95 deletions(-) diff --git a/.github/workflows/assigner.yml b/.github/workflows/assigner.yml index 5ee44a84ce9c..a4670d05b800 100644 --- a/.github/workflows/assigner.yml +++ b/.github/workflows/assigner.yml @@ -28,7 +28,7 @@ jobs: steps: - name: Check out source code - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: fetch-depth: 0 persist-credentials: false diff --git a/.github/workflows/backport_issue_check.yml b/.github/workflows/backport_issue_check.yml index 7811f30d050a..44320bbd0e95 100644 --- a/.github/workflows/backport_issue_check.yml +++ b/.github/workflows/backport_issue_check.yml @@ -26,7 +26,7 @@ jobs: steps: - name: Check out source code - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Set up Python uses: actions/setup-python@e797f83bcb11b83ae66e0230d6156d7c80228e7c # v6.0.0 diff --git a/.github/workflows/bsim-tests-publish.yaml b/.github/workflows/bsim-tests-publish.yaml index 17d424f18493..28d69b7bcc44 100644 --- a/.github/workflows/bsim-tests-publish.yaml +++ b/.github/workflows/bsim-tests-publish.yaml @@ -19,12 +19,12 @@ jobs: steps: - name: Download artifacts - uses: dawidd6/action-download-artifact@ac66b43f0e6a346234dd65d4d0c8fbb31cb316e5 # v11 + uses: dawidd6/action-download-artifact@0bd50d53a6d7fb5cb921e607957e9cc12b4ce392 # v12 with: run_id: ${{ github.event.workflow_run.id }} - name: Publish BabbleSim Test Results - uses: EnricoMi/publish-unit-test-result-action@34d7c956a59aed1bfebf31df77b8de55db9bbaaf # v2.21.0 + uses: EnricoMi/publish-unit-test-result-action@27d65e188ec43221b20d26de30f4892fad91df2f # v2.22.0 with: check_name: BabbleSim Test Results comment_mode: off diff --git a/.github/workflows/bsim-tests.yaml b/.github/workflows/bsim-tests.yaml index 37e2ca050164..7c8082fcd7c1 100644 --- a/.github/workflows/bsim-tests.yaml +++ b/.github/workflows/bsim-tests.yaml @@ -74,7 +74,7 @@ jobs: git remote set-url origin ${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY} - name: Checkout - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: fetch-depth: 0 @@ -102,7 +102,7 @@ jobs: pip install -r scripts/requirements-actions.txt --require-hashes - name: Check common triggering files - uses: tj-actions/changed-files@24d32ffd492484c1d75e0c0b894501ddb9d30d62 # v47.0.0 + uses: tj-actions/changed-files@e0021407031f5be11a464abee9a0776171c79891 # v47.0.1 id: check-common-files with: files: | @@ -121,7 +121,7 @@ jobs: modules/hal_nordic/** - name: Check if Bluethooth files changed - uses: tj-actions/changed-files@24d32ffd492484c1d75e0c0b894501ddb9d30d62 # v47.0.0 + uses: tj-actions/changed-files@e0021407031f5be11a464abee9a0776171c79891 # v47.0.1 id: check-bluetooth-files with: files: | @@ -131,7 +131,7 @@ jobs: tests/bsim/bluetooth/ - name: Check if Networking files changed - uses: tj-actions/changed-files@24d32ffd492484c1d75e0c0b894501ddb9d30d62 # v47.0.0 + uses: tj-actions/changed-files@e0021407031f5be11a464abee9a0776171c79891 # v47.0.1 id: check-networking-files with: files: | @@ -144,7 +144,7 @@ jobs: include/zephyr/net/ieee802154* - name: Check if UART files changed - uses: tj-actions/changed-files@24d32ffd492484c1d75e0c0b894501ddb9d30d62 # v47.0.0 + uses: tj-actions/changed-files@e0021407031f5be11a464abee9a0776171c79891 # v47.0.1 id: check-uart-files with: files: | @@ -189,7 +189,7 @@ jobs: - name: Upload Unit Test Results in HTML if: always() - uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0 + uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 with: name: HTML Unit Test Results if-no-files-found: ignore @@ -197,7 +197,7 @@ jobs: junit.html - name: Publish Unit Test Results - uses: EnricoMi/publish-unit-test-result-action@34d7c956a59aed1bfebf31df77b8de55db9bbaaf # v2.21.0 + uses: EnricoMi/publish-unit-test-result-action@27d65e188ec43221b20d26de30f4892fad91df2f # v2.22.0 with: check_name: Bsim Test Results files: "junit.xml" @@ -205,7 +205,7 @@ jobs: - name: Upload Event Details if: always() - uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0 + uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 with: name: event path: | diff --git a/.github/workflows/bug_snapshot.yaml b/.github/workflows/bug_snapshot.yaml index 8ab3035bf036..d785ceaea9db 100644 --- a/.github/workflows/bug_snapshot.yaml +++ b/.github/workflows/bug_snapshot.yaml @@ -23,7 +23,7 @@ jobs: steps: - name: Checkout - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Set up Python uses: actions/setup-python@e797f83bcb11b83ae66e0230d6156d7c80228e7c # v6.0.0 @@ -51,7 +51,7 @@ jobs: echo "BUGS_PICKLE_PATH=${BUGS_PICKLE_PATH}" >> ${GITHUB_ENV} - name: Configure AWS Credentials - uses: aws-actions/configure-aws-credentials@00943011d9042930efac3dcd3a170e4273319bc8 # v5.1.0 + uses: aws-actions/configure-aws-credentials@61815dcd50bd041e203e49132bacad1fd04d2708 # v5.1.1 with: aws-access-key-id: ${{ vars.AWS_BUILDS_ZEPHYR_BUG_SNAPSHOT_ACCESS_KEY_ID }} aws-secret-access-key: ${{ secrets.AWS_BUILDS_ZEPHYR_BUG_SNAPSHOT_SECRET_ACCESS_KEY }} diff --git a/.github/workflows/clang.yaml b/.github/workflows/clang.yaml index 91e9c6e27e91..b7085375d06c 100644 --- a/.github/workflows/clang.yaml +++ b/.github/workflows/clang.yaml @@ -53,7 +53,7 @@ jobs: git remote set-url origin ${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY} - name: Checkout - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: fetch-depth: 0 persist-credentials: false @@ -123,7 +123,7 @@ jobs: - name: Upload Unit Test Results if: always() - uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0 + uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 with: name: Unit Test Results (Subset ${{ matrix.subset }}) path: | @@ -140,13 +140,13 @@ jobs: if: (success() || failure()) steps: - name: Checkout - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: fetch-depth: 0 persist-credentials: false - name: Download Artifacts - uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53 # v6.0.0 + uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7.0.0 with: path: artifacts @@ -168,7 +168,7 @@ jobs: - name: Upload Unit Test Results in HTML if: always() - uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0 + uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 with: name: HTML Unit Test Results if-no-files-found: ignore @@ -176,7 +176,7 @@ jobs: junit-clang.html - name: Publish Unit Test Results - uses: EnricoMi/publish-unit-test-result-action@34d7c956a59aed1bfebf31df77b8de55db9bbaaf # v2.21.0 + uses: EnricoMi/publish-unit-test-result-action@27d65e188ec43221b20d26de30f4892fad91df2f # v2.22.0 if: always() with: check_name: Unit Test Results diff --git a/.github/workflows/codecov.yaml b/.github/workflows/codecov.yaml index af14276612e0..d5647048794e 100644 --- a/.github/workflows/codecov.yaml +++ b/.github/workflows/codecov.yaml @@ -67,7 +67,7 @@ jobs: git remote set-url origin ${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY} - name: checkout - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: fetch-depth: 0 @@ -126,7 +126,7 @@ jobs: - name: Upload Doxygen Coverage Results if: matrix.platform == 'unit_testing' - uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0 + uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 with: name: doxygen-coverage-results path: | @@ -145,7 +145,7 @@ jobs: - name: Upload Coverage Results if: always() - uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0 + uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 with: name: Coverage Data (Subset ${{ matrix.normalized }}) path: | @@ -161,7 +161,7 @@ jobs: steps: - name: checkout - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: fetch-depth: 0 @@ -177,7 +177,7 @@ jobs: pip install -r scripts/requirements-actions.txt --require-hashes - name: Download Artifacts - uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53 # v6.0.0 + uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7.0.0 with: path: coverage/reports @@ -242,7 +242,7 @@ jobs: - name: Upload Merged Coverage Results and Report if: always() - uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0 + uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 with: name: Coverage Data and report path: | @@ -253,7 +253,7 @@ jobs: - name: Upload test coverage to Codecov if: always() - uses: codecov/codecov-action@5a1091511ad55cbe89839c7260b706298ca349f7 # v5.5.1 + uses: codecov/codecov-action@671740ac38dd9b0130fbe1cec585b89eea48d3de # v5.5.2 with: env_vars: OS,PYTHON fail_ci_if_error: false @@ -264,7 +264,7 @@ jobs: - name: Upload Doxygen coverage to Codecov if: always() - uses: codecov/codecov-action@5a1091511ad55cbe89839c7260b706298ca349f7 # v5.5.1 + uses: codecov/codecov-action@671740ac38dd9b0130fbe1cec585b89eea48d3de # v5.5.2 with: env_vars: OS,PYTHON fail_ci_if_error: false diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index dd3aa9b9f7d2..cefe4222440a 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -36,10 +36,10 @@ jobs: config: ./.github/codeql/codeql-js-config.yml steps: - name: Checkout - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Initialize CodeQL - uses: github/codeql-action/init@0499de31b99561a6d14a36a5f662c2a54f91beee # v4.31.2 + uses: github/codeql-action/init@cdefb33c0f6224e58673d9004f47f7cb3e328b89 # v4.31.10 with: languages: ${{ matrix.language }} build-mode: ${{ matrix.build-mode }} @@ -53,6 +53,6 @@ jobs: exit 0 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@0499de31b99561a6d14a36a5f662c2a54f91beee # v4.31.2 + uses: github/codeql-action/analyze@cdefb33c0f6224e58673d9004f47f7cb3e328b89 # v4.31.10 with: category: "/language:${{matrix.language}}" diff --git a/.github/workflows/coding_guidelines.yml b/.github/workflows/coding_guidelines.yml index 258e80d1d5e4..471659bd4c43 100644 --- a/.github/workflows/coding_guidelines.yml +++ b/.github/workflows/coding_guidelines.yml @@ -11,7 +11,7 @@ jobs: name: Run coding guidelines checks on patch series (PR) steps: - name: Checkout the code - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: ref: ${{ github.event.pull_request.head.sha }} fetch-depth: 0 diff --git a/.github/workflows/compliance.yml b/.github/workflows/compliance.yml index 26e41485ef67..c1922b5b37dd 100644 --- a/.github/workflows/compliance.yml +++ b/.github/workflows/compliance.yml @@ -21,7 +21,7 @@ jobs: echo "$HOME/.local/bin" >> $GITHUB_PATH - name: Checkout the code - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: ref: ${{ github.event.pull_request.head.sha }} fetch-depth: 0 @@ -61,7 +61,7 @@ jobs: west update -o=--depth=1 -n 2>&1 1> west.update.log || west update -o=--depth=1 -n 2>&1 1> west.update2.log - name: Setup Node.js - uses: actions/setup-node@2028fbc5c25fe9cf00d9f06a71cc4710d4507903 # v6.0.0 + uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0 with: node-version: "lts/*" cache: npm @@ -91,14 +91,14 @@ jobs: ./scripts/ci/check_compliance.py --annotate $excludes -c origin/${BASE_REF}.. - name: upload-results - uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0 + uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 continue-on-error: true with: name: compliance.xml path: compliance.xml - name: Upload dts linter patch - uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0 + uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 continue-on-error: true if: hashFiles('dts_linter.patch') != '' with: diff --git a/.github/workflows/daily_test_version.yml b/.github/workflows/daily_test_version.yml index d604c7fe9d3c..8af9c450b19f 100644 --- a/.github/workflows/daily_test_version.yml +++ b/.github/workflows/daily_test_version.yml @@ -20,14 +20,14 @@ jobs: steps: - name: Configure AWS Credentials - uses: aws-actions/configure-aws-credentials@00943011d9042930efac3dcd3a170e4273319bc8 # v5.1.0 + uses: aws-actions/configure-aws-credentials@61815dcd50bd041e203e49132bacad1fd04d2708 # v5.1.1 with: aws-access-key-id: ${{ vars.AWS_TESTING_ACCESS_KEY_ID }} aws-secret-access-key: ${{ secrets.AWS_TESTING_SECRET_ACCESS_KEY }} aws-region: us-east-1 - name: checkout - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: fetch-depth: 0 diff --git a/.github/workflows/devicetree_checks.yml b/.github/workflows/devicetree_checks.yml index c0efa60951f0..22fe4cb33709 100644 --- a/.github/workflows/devicetree_checks.yml +++ b/.github/workflows/devicetree_checks.yml @@ -33,7 +33,7 @@ jobs: os: [ubuntu-22.04, macos-14, windows-2022] steps: - name: checkout - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Set up Python ${{ matrix.python-version }} uses: actions/setup-python@e797f83bcb11b83ae66e0230d6156d7c80228e7c # v6.0.0 diff --git a/.github/workflows/doc-build.yml b/.github/workflows/doc-build.yml index 054fee42472e..a9bd5677b604 100644 --- a/.github/workflows/doc-build.yml +++ b/.github/workflows/doc-build.yml @@ -27,12 +27,12 @@ jobs: file_check: ${{ steps.check-doc-files.outputs.any_modified }} steps: - name: checkout - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: ref: ${{ github.event.pull_request.head.sha }} fetch-depth: 0 - name: Check if Documentation related files changed - uses: tj-actions/changed-files@24d32ffd492484c1d75e0c0b894501ddb9d30d62 # v47.0.0 + uses: tj-actions/changed-files@e0021407031f5be11a464abee9a0776171c79891 # v47.0.1 id: check-doc-files with: files: | @@ -92,7 +92,7 @@ jobs: git remote set-url origin ${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY} - name: Checkout - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: ref: ${{ github.event.pull_request.head.sha }} fetch-depth: 0 @@ -156,13 +156,13 @@ jobs: tar --use-compress-program="xz -T0" -cf api-coverage.tar.xz coverage-report - name: Upload HTML output - uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0 + uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 with: name: html-output path: html-output.tar.xz - name: Upload Doxygen coverage artifacts - uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0 + uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 with: name: api-coverage path: api-coverage.tar.xz @@ -183,7 +183,7 @@ jobs: echo "API Coverage Report will be available shortly at: ${API_COVERAGE_URL}" >> $GITHUB_STEP_SUMMARY - name: Upload PR number - uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0 + uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 if: github.event_name == 'pull_request' with: name: pr_num @@ -202,7 +202,7 @@ jobs: steps: - name: checkout - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: path: zephyr @@ -230,7 +230,7 @@ jobs: echo "/opt/doxygen-${DOXYGEN_VERSION}/bin" >> $GITHUB_PATH - name: Setup Zephyr project - uses: zephyrproject-rtos/action-zephyr-setup@cefbf9086ce2da7d70e7ad9589af8aa1e4bda265 # v1.0.11 + uses: zephyrproject-rtos/action-zephyr-setup@360ff9b36e58499d9eb28015cdcde7ca03a5b04d # v1.0.12 with: app-path: zephyr toolchains: 'arm-zephyr-eabi' @@ -259,7 +259,7 @@ jobs: - name: upload-build if: always() - uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0 + uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 with: name: pdf-output if-no-files-found: ignore diff --git a/.github/workflows/doc-publish-pr.yml b/.github/workflows/doc-publish-pr.yml index 054046815b2a..28ee3e6a81f5 100644 --- a/.github/workflows/doc-publish-pr.yml +++ b/.github/workflows/doc-publish-pr.yml @@ -25,7 +25,7 @@ jobs: steps: - name: Download artifacts id: download-artifacts - uses: dawidd6/action-download-artifact@ac66b43f0e6a346234dd65d4d0c8fbb31cb316e5 # v11 + uses: dawidd6/action-download-artifact@0bd50d53a6d7fb5cb921e607957e9cc12b4ce392 # v12 with: workflow: doc-build.yml run_id: ${{ github.event.workflow_run.id }} @@ -43,7 +43,7 @@ jobs: - name: Check PR number if: steps.download-artifacts.outputs.found_artifact == 'true' id: check-pr - uses: carpentries/actions/check-valid-pr@2e20fd5ee53b691e27455ce7ca3b16ea885140e8 # v0.15.0 + uses: carpentries/actions/check-valid-pr@083bb9952b1414bd2b9e10ecec1717c938aba4c5 # v0.17.0 with: pr: ${{ env.PR_NUM }} sha: ${{ github.event.workflow_run.head_sha }} @@ -66,7 +66,7 @@ jobs: - name: Configure AWS Credentials if: steps.download-artifacts.outputs.found_artifact == 'true' - uses: aws-actions/configure-aws-credentials@00943011d9042930efac3dcd3a170e4273319bc8 # v5.1.0 + uses: aws-actions/configure-aws-credentials@61815dcd50bd041e203e49132bacad1fd04d2708 # v5.1.1 with: aws-access-key-id: ${{ vars.AWS_BUILDS_ZEPHYR_PR_ACCESS_KEY_ID }} aws-secret-access-key: ${{ secrets.AWS_BUILDS_ZEPHYR_PR_SECRET_ACCESS_KEY }} diff --git a/.github/workflows/doc-publish.yml b/.github/workflows/doc-publish.yml index 14c620846e12..2df0b240675d 100644 --- a/.github/workflows/doc-publish.yml +++ b/.github/workflows/doc-publish.yml @@ -27,7 +27,7 @@ jobs: steps: - name: Download artifacts - uses: dawidd6/action-download-artifact@ac66b43f0e6a346234dd65d4d0c8fbb31cb316e5 # v11 + uses: dawidd6/action-download-artifact@0bd50d53a6d7fb5cb921e607957e9cc12b4ce392 # v12 with: workflow: doc-build.yml run_id: ${{ github.event.workflow_run.id }} @@ -40,7 +40,7 @@ jobs: fi - name: Configure AWS Credentials - uses: aws-actions/configure-aws-credentials@00943011d9042930efac3dcd3a170e4273319bc8 # v5.1.0 + uses: aws-actions/configure-aws-credentials@61815dcd50bd041e203e49132bacad1fd04d2708 # v5.1.1 with: aws-access-key-id: ${{ vars.AWS_DOCS_ACCESS_KEY_ID }} aws-secret-access-key: ${{ secrets.AWS_DOCS_SECRET_ACCESS_KEY }} diff --git a/.github/workflows/errno.yml b/.github/workflows/errno.yml index 906435200c02..1e71580341d3 100644 --- a/.github/workflows/errno.yml +++ b/.github/workflows/errno.yml @@ -15,12 +15,12 @@ jobs: runs-on: ubuntu-24.04 steps: - name: checkout - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: path: zephyr - name: Setup Zephyr project - uses: zephyrproject-rtos/action-zephyr-setup@cefbf9086ce2da7d70e7ad9589af8aa1e4bda265 # v1.0.11 + uses: zephyrproject-rtos/action-zephyr-setup@360ff9b36e58499d9eb28015cdcde7ca03a5b04d # v1.0.12 with: app-path: zephyr toolchains: 'arm-zephyr-eabi' diff --git a/.github/workflows/footprint-tracking.yml b/.github/workflows/footprint-tracking.yml index 010ed9ec1b30..6f68ef19a016 100644 --- a/.github/workflows/footprint-tracking.yml +++ b/.github/workflows/footprint-tracking.yml @@ -62,7 +62,7 @@ jobs: sudo apt-get install -y python3-venv - name: checkout - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: ref: ${{ github.event.pull_request.head.sha }} fetch-depth: 0 @@ -89,7 +89,7 @@ jobs: west update 2>&1 1> west.update.log || west update 2>&1 1> west.update2.log - name: Configure AWS Credentials - uses: aws-actions/configure-aws-credentials@00943011d9042930efac3dcd3a170e4273319bc8 # v5.1.0 + uses: aws-actions/configure-aws-credentials@61815dcd50bd041e203e49132bacad1fd04d2708 # v5.1.1 with: aws-access-key-id: ${{ vars.AWS_TESTING_ACCESS_KEY_ID }} aws-secret-access-key: ${{ secrets.AWS_TESTING_SECRET_ACCESS_KEY }} diff --git a/.github/workflows/greet_first_time_contributor.yml b/.github/workflows/greet_first_time_contributor.yml index 6a499275461e..be0616d4194d 100644 --- a/.github/workflows/greet_first_time_contributor.yml +++ b/.github/workflows/greet_first_time_contributor.yml @@ -18,7 +18,7 @@ jobs: issues: write # to comment on issues steps: - - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - uses: zephyrproject-rtos/action-first-interaction@58853996b1ac504b8e0f6964301f369d2bb22e5c # v1.1.1+zephyr.6 with: repo-token: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/hello_world_multiplatform.yaml b/.github/workflows/hello_world_multiplatform.yaml index 81f1ed60bd0d..d20f057742a8 100644 --- a/.github/workflows/hello_world_multiplatform.yaml +++ b/.github/workflows/hello_world_multiplatform.yaml @@ -32,7 +32,7 @@ jobs: runs-on: ${{ matrix.os }} steps: - name: Checkout - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: path: zephyr fetch-depth: 0 @@ -59,7 +59,7 @@ jobs: python-version: 3.12 - name: Setup Zephyr project - uses: zephyrproject-rtos/action-zephyr-setup@cefbf9086ce2da7d70e7ad9589af8aa1e4bda265 # v1.0.11 + uses: zephyrproject-rtos/action-zephyr-setup@360ff9b36e58499d9eb28015cdcde7ca03a5b04d # v1.0.12 with: app-path: zephyr toolchains: arm-zephyr-eabi:riscv64-zephyr-elf @@ -88,7 +88,7 @@ jobs: - name: Upload artifacts if: failure() - uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0 + uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 with: if-no-files-found: ignore path: diff --git a/.github/workflows/issue_count.yml b/.github/workflows/issue_count.yml index a7bfe9e2507c..830e41d34c1e 100644 --- a/.github/workflows/issue_count.yml +++ b/.github/workflows/issue_count.yml @@ -38,14 +38,14 @@ jobs: token: ${{ secrets.GITHUB_TOKEN }} - name: upload-stats - uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0 + uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 continue-on-error: true with: name: ${{ env.OUTPUT_FILE_NAME }} path: ${{ env.OUTPUT_FILE_NAME }} - name: Configure AWS Credentials - uses: aws-actions/configure-aws-credentials@00943011d9042930efac3dcd3a170e4273319bc8 # v5.1.0 + uses: aws-actions/configure-aws-credentials@61815dcd50bd041e203e49132bacad1fd04d2708 # v5.1.1 with: aws-access-key-id: ${{ vars.AWS_TESTING_ACCESS_KEY_ID }} aws-secret-access-key: ${{ secrets.AWS_TESTING_SECRET_ACCESS_KEY }} diff --git a/.github/workflows/license_check.yml b/.github/workflows/license_check.yml index b7547d95e65c..67751a067a9a 100644 --- a/.github/workflows/license_check.yml +++ b/.github/workflows/license_check.yml @@ -11,7 +11,7 @@ jobs: name: Scan code for licenses steps: - name: Checkout the code - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: fetch-depth: 0 - name: Scan the code @@ -20,7 +20,7 @@ jobs: with: directory-to-scan: 'scan/' - name: Artifact Upload - uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0 + uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 with: name: scancode path: ./artifacts diff --git a/.github/workflows/manifest.yml b/.github/workflows/manifest.yml index 3cbf007f187e..5412cf7f0994 100644 --- a/.github/workflows/manifest.yml +++ b/.github/workflows/manifest.yml @@ -13,7 +13,7 @@ jobs: name: Manifest steps: - name: Checkout the code - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: path: zephyrproject/zephyr fetch-depth: 0 diff --git a/.github/workflows/pinned-gh-actions.yml b/.github/workflows/pinned-gh-actions.yml index f1d1bad4a43e..8cdc84780c69 100644 --- a/.github/workflows/pinned-gh-actions.yml +++ b/.github/workflows/pinned-gh-actions.yml @@ -14,6 +14,6 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout code - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Ensure SHA pinned actions - uses: zgosalvez/github-actions-ensure-sha-pinned-actions@9e9574ef04ea69da568d6249bd69539ccc704e74 # v4.0.0 + uses: zgosalvez/github-actions-ensure-sha-pinned-actions@6124774845927d14c601359ab8138699fa5b70c3 # v4.0.1 diff --git a/.github/workflows/pr_metadata_check.yml b/.github/workflows/pr_metadata_check.yml index 6d48d29129b1..52450b9510e9 100644 --- a/.github/workflows/pr_metadata_check.yml +++ b/.github/workflows/pr_metadata_check.yml @@ -23,7 +23,7 @@ jobs: timeout-minutes: 30 steps: - name: Checkout - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Set up Python uses: actions/setup-python@e797f83bcb11b83ae66e0230d6156d7c80228e7c # v6.0.0 diff --git a/.github/workflows/pylib_tests.yml b/.github/workflows/pylib_tests.yml index dfd6d5d44eb5..1a1e0428d443 100644 --- a/.github/workflows/pylib_tests.yml +++ b/.github/workflows/pylib_tests.yml @@ -32,7 +32,7 @@ jobs: os: [ubuntu-24.04] steps: - name: checkout - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Set up Python ${{ matrix.python-version }} uses: actions/setup-python@e797f83bcb11b83ae66e0230d6156d7c80228e7c # v6.0.0 diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index dcaca963a016..a832d1e7b931 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -15,7 +15,7 @@ jobs: permissions: contents: write # to create GitHub release entry steps: - - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: fetch-depth: 0 @@ -31,7 +31,7 @@ jobs: args: spdx -o zephyr-${{ steps.get_version.outputs.VERSION }}.spdx - name: upload-results - uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0 + uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 continue-on-error: true with: name: zephyr-${{ steps.get_version.outputs.VERSION }}.spdx diff --git a/.github/workflows/scorecards.yml b/.github/workflows/scorecards.yml index 8c35bee033e5..c9d3abc1b409 100644 --- a/.github/workflows/scorecards.yml +++ b/.github/workflows/scorecards.yml @@ -29,7 +29,7 @@ jobs: steps: - name: "Checkout code" - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: persist-credentials: false @@ -47,7 +47,7 @@ jobs: # uploads of run results in SARIF format to the repository Actions tab. # https://docs.github.com/en/actions/advanced-guides/storing-workflow-data-as-artifacts - name: "Upload artifact" - uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0 + uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 with: name: SARIF file path: results.sarif @@ -56,6 +56,6 @@ jobs: # Upload the results to GitHub's code scanning dashboard (optional). # Commenting out will disable upload of results to your repo's Code Scanning dashboard - name: "Upload to code-scanning" - uses: github/codeql-action/upload-sarif@0499de31b99561a6d14a36a5f662c2a54f91beee # v4.31.2 + uses: github/codeql-action/upload-sarif@cdefb33c0f6224e58673d9004f47f7cb3e328b89 # v4.31.10 with: sarif_file: results.sarif diff --git a/.github/workflows/scripts_tests.yml b/.github/workflows/scripts_tests.yml index f3acc3da4fcc..7073bfaae01d 100644 --- a/.github/workflows/scripts_tests.yml +++ b/.github/workflows/scripts_tests.yml @@ -32,7 +32,7 @@ jobs: os: [ubuntu-24.04] steps: - name: checkout - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: ref: ${{ github.event.pull_request.head.sha }} fetch-depth: 0 diff --git a/.github/workflows/stale_issue.yml b/.github/workflows/stale_issue.yml index 96d38de631f0..fd3474c910ed 100644 --- a/.github/workflows/stale_issue.yml +++ b/.github/workflows/stale_issue.yml @@ -16,7 +16,7 @@ jobs: issues: write # to comment on stale issues steps: - - uses: actions/stale@5f858e3efba33a5ca4407a664cc011ad407f2008 # v10.1.0 + - uses: actions/stale@997185467fa4f803885201cee163a9f38240193d # v10.1.1 with: stale-pr-message: 'This pull request has been marked as stale because it has been open (more than) 60 days with no activity. Remove the stale label or add a comment saying that you diff --git a/.github/workflows/stats_merged_prs.yml b/.github/workflows/stats_merged_prs.yml index e18fc30f5c7d..1bf58e16c63a 100644 --- a/.github/workflows/stats_merged_prs.yml +++ b/.github/workflows/stats_merged_prs.yml @@ -16,7 +16,7 @@ jobs: runs-on: ubuntu-24.04 steps: - name: checkout - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Set up Python uses: actions/setup-python@e797f83bcb11b83ae66e0230d6156d7c80228e7c # v6.0.0 diff --git a/.github/workflows/twister-publish.yaml b/.github/workflows/twister-publish.yaml index a6ff339df57e..c9deaad450b4 100644 --- a/.github/workflows/twister-publish.yaml +++ b/.github/workflows/twister-publish.yaml @@ -23,7 +23,7 @@ jobs: steps: # Needed for elasticearch and upload script - name: Checkout - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: fetch-depth: 0 persist-credentials: false @@ -39,7 +39,7 @@ jobs: - name: Download Artifacts id: download-artifacts - uses: dawidd6/action-download-artifact@ac66b43f0e6a346234dd65d4d0c8fbb31cb316e5 # v11 + uses: dawidd6/action-download-artifact@0bd50d53a6d7fb5cb921e607957e9cc12b4ce392 # v12 with: path: artifacts workflow: twister.yml diff --git a/.github/workflows/twister.yaml b/.github/workflows/twister.yaml index 480003ffe56d..ba40dbb83596 100644 --- a/.github/workflows/twister.yaml +++ b/.github/workflows/twister.yaml @@ -42,7 +42,7 @@ jobs: steps: - name: Checkout if: github.event_name == 'pull_request' - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: ref: ${{ github.event.pull_request.head.sha }} fetch-depth: 0 @@ -65,7 +65,7 @@ jobs: - name: Setup Zephyr project if: github.event_name == 'pull_request' - uses: zephyrproject-rtos/action-zephyr-setup@cefbf9086ce2da7d70e7ad9589af8aa1e4bda265 # v1.0.11 + uses: zephyrproject-rtos/action-zephyr-setup@360ff9b36e58499d9eb28015cdcde7ca03a5b04d # v1.0.12 with: app-path: zephyr enable-ccache: false @@ -171,7 +171,7 @@ jobs: git remote set-url origin ${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY} - name: Checkout - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: ref: ${{ github.event.pull_request.head.sha }} fetch-depth: 0 @@ -283,7 +283,7 @@ jobs: - name: Upload Unit Test Results if: always() - uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0 + uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 with: name: Unit Test Results (Subset ${{ matrix.subset }}) if-no-files-found: ignore @@ -305,7 +305,7 @@ jobs: - if: matrix.subset == 1 && github.event_name == 'push' name: Upload the list of Python packages - uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0 + uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 with: name: Frozen PIP package set path: | @@ -323,7 +323,7 @@ jobs: steps: - name: Check out source code - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: ref: ${{ github.event.pull_request.head.sha }} fetch-depth: 0 @@ -341,7 +341,7 @@ jobs: pip install -r scripts/requirements-actions.txt --require-hashes - name: Download Artifacts - uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53 # v6.0.0 + uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7.0.0 with: path: artifacts @@ -352,7 +352,7 @@ jobs: - name: Upload Unit Test Results if: always() - uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0 + uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 with: name: Unit Test Results if-no-files-found: ignore @@ -362,12 +362,12 @@ jobs: - name: Upload test results to Codecov if: ${{ !cancelled() && (github.event_name == 'push') }} - uses: codecov/test-results-action@47f89e9acb64b76debcd5ea40642d25a4adced9f # v1.1.1 + uses: codecov/test-results-action@0fa95f0e1eeaafde2c782583b36b28ad0d8c77d3 # v1.2.1 with: token: ${{ secrets.CODECOV_TOKEN }} - name: Publish Unit Test Results - uses: EnricoMi/publish-unit-test-result-action@34d7c956a59aed1bfebf31df77b8de55db9bbaaf # v2.21.0 + uses: EnricoMi/publish-unit-test-result-action@27d65e188ec43221b20d26de30f4892fad91df2f # v2.22.0 with: check_name: Unit Test Results files: "**/twister.xml" @@ -384,7 +384,7 @@ jobs: - name: Upload Twister Analysis Results if: needs.twister-build.result == 'failure' - uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0 + uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 with: name: Twister Analysis Results if-no-files-found: ignore diff --git a/.github/workflows/twister_tests.yml b/.github/workflows/twister_tests.yml index 7efdab39f03e..09ef984447b6 100644 --- a/.github/workflows/twister_tests.yml +++ b/.github/workflows/twister_tests.yml @@ -39,7 +39,7 @@ jobs: os: [ubuntu-24.04] steps: - name: checkout - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Set up Python ${{ matrix.python-version }} uses: actions/setup-python@e797f83bcb11b83ae66e0230d6156d7c80228e7c # v6.0.0 diff --git a/.github/workflows/twister_tests_blackbox.yml b/.github/workflows/twister_tests_blackbox.yml index 8fc09d7c040c..9748af7f20a4 100644 --- a/.github/workflows/twister_tests_blackbox.yml +++ b/.github/workflows/twister_tests_blackbox.yml @@ -31,7 +31,7 @@ jobs: runs-on: ubuntu-24.04 steps: - name: Checkout - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: path: zephyr fetch-depth: 0 @@ -44,7 +44,7 @@ jobs: cache-dependency-path: scripts/requirements-actions.txt - name: Setup Zephyr project - uses: zephyrproject-rtos/action-zephyr-setup@cefbf9086ce2da7d70e7ad9589af8aa1e4bda265 # v1.0.11 + uses: zephyrproject-rtos/action-zephyr-setup@360ff9b36e58499d9eb28015cdcde7ca03a5b04d # v1.0.12 with: app-path: zephyr toolchains: 'arm-zephyr-eabi:riscv64-zephyr-elf:x86_64-zephyr-elf' diff --git a/.github/workflows/west_cmds.yml b/.github/workflows/west_cmds.yml index e94b3138fe94..a85c88b89372 100644 --- a/.github/workflows/west_cmds.yml +++ b/.github/workflows/west_cmds.yml @@ -36,7 +36,7 @@ jobs: os: [ubuntu-22.04, macos-14, windows-2022] steps: - name: checkout - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Set up Python ${{ matrix.python-version }} uses: actions/setup-python@e797f83bcb11b83ae66e0230d6156d7c80228e7c # v6.0.0 From 151a9a33e6a861924cb9ee1b5e10b2a20459523e Mon Sep 17 00:00:00 2001 From: Hanan Arshad Date: Mon, 28 Apr 2025 14:43:46 +0500 Subject: [PATCH 0197/6328] drivers: sensor: pms7003: add support for additional PM parameters MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The current PMS7003 sensor driver in Zephyr only supports reading the basic PM1.0, PM2.5, and PM10 concentration values. This update extends the driver to support additional data provided by the PMS7003 sensor, including: - Standard particle concentration values (CF=1) for PM1.0, PM2.5, and PM10 - Particle counts for particles greater than or equal to 0.3 µm, 0.5 µm, 1.0 µm, 2.5 µm, 5.0 µm, and 10.0 µm per 0.1 liter of air Adding support for these readings allows applications to access more detailed particulate data, improving the sensor’s usability in air quality monitoring and analysis scenarios. Signed-off-by: Hanan Arshad --- drivers/sensor/pms7003/pms7003.c | 61 ++++++++++++++++++++++++++------ drivers/sensor/sensor_shell.c | 9 +++++ include/zephyr/drivers/sensor.h | 19 ++++++++++ 3 files changed, 79 insertions(+), 10 deletions(-) diff --git a/drivers/sensor/pms7003/pms7003.c b/drivers/sensor/pms7003/pms7003.c index e47805171547..239f9b985dab 100644 --- a/drivers/sensor/pms7003/pms7003.c +++ b/drivers/sensor/pms7003/pms7003.c @@ -32,9 +32,18 @@ struct pms7003_config { }; struct pms7003_data { + uint16_t pm_1_0_cf; + uint16_t pm_2_5_cf; + uint16_t pm_10_cf; uint16_t pm_1_0; uint16_t pm_2_5; uint16_t pm_10; + uint16_t pm_0_3_count; + uint16_t pm_0_5_count; + uint16_t pm_1_0_count; + uint16_t pm_2_5_count; + uint16_t pm_5_0_count; + uint16_t pm_10_0_count; }; /** @@ -133,16 +142,32 @@ static int pms7003_sample_fetch(const struct device *dev, return -ETIME; } - drv_data->pm_1_0 = - (pms7003_receive_buffer[8] << 8) + pms7003_receive_buffer[9]; - drv_data->pm_2_5 = - (pms7003_receive_buffer[10] << 8) + pms7003_receive_buffer[11]; - drv_data->pm_10 = - (pms7003_receive_buffer[12] << 8) + pms7003_receive_buffer[13]; - + drv_data->pm_1_0_cf = (pms7003_receive_buffer[2] << 8) + pms7003_receive_buffer[3]; + drv_data->pm_2_5_cf = (pms7003_receive_buffer[4] << 8) + pms7003_receive_buffer[5]; + drv_data->pm_10_cf = (pms7003_receive_buffer[6] << 8) + pms7003_receive_buffer[7]; + drv_data->pm_1_0 = (pms7003_receive_buffer[8] << 8) + pms7003_receive_buffer[9]; + drv_data->pm_2_5 = (pms7003_receive_buffer[10] << 8) + pms7003_receive_buffer[11]; + drv_data->pm_10 = (pms7003_receive_buffer[12] << 8) + pms7003_receive_buffer[13]; + drv_data->pm_0_3_count = (pms7003_receive_buffer[14] << 8) + pms7003_receive_buffer[15]; + drv_data->pm_0_5_count = (pms7003_receive_buffer[16] << 8) + pms7003_receive_buffer[17]; + drv_data->pm_1_0_count = (pms7003_receive_buffer[18] << 8) + pms7003_receive_buffer[19]; + drv_data->pm_2_5_count = (pms7003_receive_buffer[20] << 8) + pms7003_receive_buffer[21]; + drv_data->pm_5_0_count = (pms7003_receive_buffer[22] << 8) + pms7003_receive_buffer[23]; + drv_data->pm_10_0_count = (pms7003_receive_buffer[24] << 8) + pms7003_receive_buffer[25]; + + LOG_DBG("pm1.0_cf = %d", drv_data->pm_1_0_cf); + LOG_DBG("pm2.5_cf = %d", drv_data->pm_2_5_cf); + LOG_DBG("pm10_cf = %d", drv_data->pm_10_cf); LOG_DBG("pm1.0 = %d", drv_data->pm_1_0); LOG_DBG("pm2.5 = %d", drv_data->pm_2_5); LOG_DBG("pm10 = %d", drv_data->pm_10); + LOG_DBG("pm0.3_count = %d", drv_data->pm_0_3_count); + LOG_DBG("pm0.5_count = %d", drv_data->pm_0_5_count); + LOG_DBG("pm1.0_count = %d", drv_data->pm_1_0_count); + LOG_DBG("pm2.5_count = %d", drv_data->pm_2_5_count); + LOG_DBG("pm5.0_count = %d", drv_data->pm_5_0_count); + LOG_DBG("pm10_count = %d", drv_data->pm_10_0_count); + return 0; } @@ -154,16 +179,32 @@ static int pms7003_channel_get(const struct device *dev, if (chan == SENSOR_CHAN_PM_1_0) { val->val1 = drv_data->pm_1_0; - val->val2 = 0; } else if (chan == SENSOR_CHAN_PM_2_5) { val->val1 = drv_data->pm_2_5; - val->val2 = 0; } else if (chan == SENSOR_CHAN_PM_10) { val->val1 = drv_data->pm_10; - val->val2 = 0; + } else if (chan == SENSOR_CHAN_PM_1_0_CF) { + val->val1 = drv_data->pm_1_0_cf; + } else if (chan == SENSOR_CHAN_PM_2_5_CF) { + val->val1 = drv_data->pm_2_5_cf; + } else if (chan == SENSOR_CHAN_PM_10_CF) { + val->val1 = drv_data->pm_10_cf; + } else if (chan == SENSOR_CHAN_PM_0_3_COUNT) { + val->val1 = drv_data->pm_0_3_count; + } else if (chan == SENSOR_CHAN_PM_0_5_COUNT) { + val->val1 = drv_data->pm_0_5_count; + } else if (chan == SENSOR_CHAN_PM_1_0_COUNT) { + val->val1 = drv_data->pm_1_0_count; + } else if (chan == SENSOR_CHAN_PM_2_5_COUNT) { + val->val1 = drv_data->pm_2_5_count; + } else if (chan == SENSOR_CHAN_PM_5_COUNT) { + val->val1 = drv_data->pm_5_0_count; + } else if (chan == SENSOR_CHAN_PM_10_COUNT) { + val->val1 = drv_data->pm_10_0_count; } else { return -ENOTSUP; } + val->val2 = 0; return 0; } diff --git a/drivers/sensor/sensor_shell.c b/drivers/sensor/sensor_shell.c index 5c816fa41901..e308dd79dd03 100644 --- a/drivers/sensor/sensor_shell.c +++ b/drivers/sensor/sensor_shell.c @@ -74,9 +74,18 @@ static const char *const sensor_channel_name[SENSOR_CHAN_COMMON_COUNT] = { [SENSOR_CHAN_GREEN] = "green", [SENSOR_CHAN_BLUE] = "blue", [SENSOR_CHAN_ALTITUDE] = "altitude", + [SENSOR_CHAN_PM_1_0_CF] = "pm_1_0_cf", + [SENSOR_CHAN_PM_2_5_CF] = "pm_2_5_cf", + [SENSOR_CHAN_PM_10_CF] = "pm_10_cf", [SENSOR_CHAN_PM_1_0] = "pm_1_0", [SENSOR_CHAN_PM_2_5] = "pm_2_5", [SENSOR_CHAN_PM_10] = "pm_10", + [SENSOR_CHAN_PM_0_3_COUNT] = "pm_0_3_count", + [SENSOR_CHAN_PM_0_5_COUNT] = "pm_0_5_count", + [SENSOR_CHAN_PM_1_0_COUNT] = "pm_1_0_count", + [SENSOR_CHAN_PM_2_5_COUNT] = "pm_2_5_count", + [SENSOR_CHAN_PM_5_COUNT] = "pm_5_0_count", + [SENSOR_CHAN_PM_10_COUNT] = "pm_10_count", [SENSOR_CHAN_DISTANCE] = "distance", [SENSOR_CHAN_CO2] = "co2", [SENSOR_CHAN_O2] = "o2", diff --git a/include/zephyr/drivers/sensor.h b/include/zephyr/drivers/sensor.h index c67fea68e2a8..4ece0abbd2a8 100644 --- a/include/zephyr/drivers/sensor.h +++ b/include/zephyr/drivers/sensor.h @@ -115,12 +115,31 @@ enum sensor_channel { /** Altitude, in meters */ SENSOR_CHAN_ALTITUDE, + /** PM1.0 concentration (standard particle, CF=1), in µg/m³ */ + SENSOR_CHAN_PM_1_0_CF, + /** PM2.5 concentration (standard particle, CF=1), in µg/m³ */ + SENSOR_CHAN_PM_2_5_CF, + /** PM10 concentration (standard particle, CF=1), in µg/m³ */ + SENSOR_CHAN_PM_10_CF, /** 1.0 micro-meters Particulate Matter, in ug/m^3 */ SENSOR_CHAN_PM_1_0, /** 2.5 micro-meters Particulate Matter, in ug/m^3 */ SENSOR_CHAN_PM_2_5, /** 10 micro-meters Particulate Matter, in ug/m^3 */ SENSOR_CHAN_PM_10, + /** Number of particles ≥ 0.3 µm per 0.1 liter of air */ + SENSOR_CHAN_PM_0_3_COUNT, + /** Number of particles ≥ 0.5 µm per 0.1 liter of air */ + SENSOR_CHAN_PM_0_5_COUNT, + /** Number of particles ≥ 1.0 µm per 0.1 liter of air */ + SENSOR_CHAN_PM_1_0_COUNT, + /** Number of particles ≥ 2.5 µm per 0.1 liter of air */ + SENSOR_CHAN_PM_2_5_COUNT, + /** Number of particles ≥ 5.0 µm per 0.1 liter of air */ + SENSOR_CHAN_PM_5_COUNT, + /** Number of particles ≥ 10.0 µm per 0.1 liter of air */ + SENSOR_CHAN_PM_10_COUNT, + /** Distance. From sensor to target, in meters */ SENSOR_CHAN_DISTANCE, From 75640be632575db66a84743f061d20844fa32e24 Mon Sep 17 00:00:00 2001 From: Thomas Lang Date: Sat, 6 Dec 2025 12:01:28 -0600 Subject: [PATCH 0198/6328] drivers: sensor: apds9960: Allow multiple sensor instances Allow for multiple apds9960s to be present Signed-off-by: Thomas Lang --- drivers/sensor/apds9960/Kconfig | 77 ---------------------- drivers/sensor/apds9960/apds9960.c | 73 +++++++------------- drivers/sensor/apds9960/apds9960_trigger.c | 2 +- dts/bindings/sensor/avago,apds9960.yaml | 45 +++++++++++++ 4 files changed, 68 insertions(+), 129 deletions(-) diff --git a/drivers/sensor/apds9960/Kconfig b/drivers/sensor/apds9960/Kconfig index 7f6b4bb00a5b..91e74b268c1b 100644 --- a/drivers/sensor/apds9960/Kconfig +++ b/drivers/sensor/apds9960/Kconfig @@ -58,81 +58,4 @@ config APDS9960_ENABLE_ALS help Enable Ambient Light Sense (ALS). -choice - prompt "Proximity Gain" - default APDS9960_PGAIN_4X - -config APDS9960_PGAIN_1X - bool "1x" - -config APDS9960_PGAIN_2X - bool "2x" - -config APDS9960_PGAIN_4X - bool "4x" - -config APDS9960_PGAIN_8X - bool "8x" - -endchoice - -choice - prompt "ALS and Color Gain" - default APDS9960_AGAIN_4X - -config APDS9960_AGAIN_1X - bool "1x" - -config APDS9960_AGAIN_4X - bool "4x" - -config APDS9960_AGAIN_16X - bool "16x" - -config APDS9960_AGAIN_64X - bool "64x" - -endchoice - -choice - prompt "Proximity Pulse Length" - default APDS9960_PPULSE_LENGTH_8US - -config APDS9960_PPULSE_LENGTH_4US - bool "4us" - -config APDS9960_PPULSE_LENGTH_8US - bool "8us" - -config APDS9960_PPULSE_LENGTH_16US - bool "16us" - -config APDS9960_PPULSE_LENGTH_32US - bool "32us" - -endchoice - -choice - prompt "Proximity LED boost current" - default APDS9960_PLED_BOOST_100PCT - -config APDS9960_PLED_BOOST_300PCT - bool "300%" - -config APDS9960_PLED_BOOST_200PCT - bool "200%" - -config APDS9960_PLED_BOOST_150PCT - bool "150%" - -config APDS9960_PLED_BOOST_100PCT - bool "100%" - -endchoice - -config APDS9960_PPULSE_COUNT - int "Proximity Pulse Count" - range 1 64 - default 8 - endif # APDS9960 diff --git a/drivers/sensor/apds9960/apds9960.c b/drivers/sensor/apds9960/apds9960.c index 32bb14caa22d..98d019aedc43 100644 --- a/drivers/sensor/apds9960/apds9960.c +++ b/drivers/sensor/apds9960/apds9960.c @@ -520,57 +520,28 @@ static DEVICE_API(sensor, apds9960_driver_api) = { #endif }; -static const struct apds9960_config apds9960_config = { - .i2c = I2C_DT_SPEC_INST_GET(0), -#ifdef CONFIG_APDS9960_FETCH_MODE_INTERRUPT - .int_gpio = GPIO_DT_SPEC_INST_GET(0, int_gpios), -#endif -#if CONFIG_APDS9960_PGAIN_8X - .pgain = APDS9960_PGAIN_8X, -#elif CONFIG_APDS9960_PGAIN_4X - .pgain = APDS9960_PGAIN_4X, -#elif CONFIG_APDS9960_PGAIN_2X - .pgain = APDS9960_PGAIN_2X, -#else - .pgain = APDS9960_PGAIN_1X, -#endif -#if CONFIG_APDS9960_AGAIN_64X - .again = APDS9960_AGAIN_64X, -#elif CONFIG_APDS9960_AGAIN_16X - .again = APDS9960_AGAIN_16X, -#elif CONFIG_APDS9960_AGAIN_4X - .again = APDS9960_AGAIN_4X, -#else - .again = APDS9960_AGAIN_1X, -#endif -#if CONFIG_APDS9960_PPULSE_LENGTH_32US - .ppcount = APDS9960_PPULSE_LENGTH_32US | - (CONFIG_APDS9960_PPULSE_COUNT - 1), -#elif CONFIG_APDS9960_PPULSE_LENGTH_16US - .ppcount = APDS9960_PPULSE_LENGTH_16US | - (CONFIG_APDS9960_PPULSE_COUNT - 1), -#elif CONFIG_APDS9960_PPULSE_LENGTH_8US - .ppcount = APDS9960_PPULSE_LENGTH_8US | - (CONFIG_APDS9960_PPULSE_COUNT - 1), +#if CONFIG_APDS9960_FETCH_MODE_INTERRUPT +#define APDS9960_CONFIG_INTERRUPT(inst) \ + .int_gpio = GPIO_DT_SPEC_INST_GET_OR(inst, int_gpios, {0}), #else - .ppcount = APDS9960_PPULSE_LENGTH_4US | - (CONFIG_APDS9960_PPULSE_COUNT - 1), +#define APDS9960_CONFIG_INTERRUPT(inst) #endif -#if CONFIG_APDS9960_PLED_BOOST_300PCT - .pled_boost = APDS9960_PLED_BOOST_300, -#elif CONFIG_APDS9960_PLED_BOOST_200PCT - .pled_boost = APDS9960_PLED_BOOST_200, -#elif CONFIG_APDS9960_PLED_BOOST_150PCT - .pled_boost = APDS9960_PLED_BOOST_150, -#else - .pled_boost = APDS9960_PLED_BOOST_100, -#endif -}; - -static struct apds9960_data apds9960_data; - -PM_DEVICE_DT_INST_DEFINE(0, apds9960_pm_action); -SENSOR_DEVICE_DT_INST_DEFINE(0, apds9960_init, - PM_DEVICE_DT_INST_GET(0), &apds9960_data, &apds9960_config, - POST_KERNEL, CONFIG_SENSOR_INIT_PRIORITY, &apds9960_driver_api); +#define APDS9960_INIT(i) \ + static struct apds9960_data apds9960_data_##i; \ + static const struct apds9960_config apds9960_config_##i = { \ + .i2c = I2C_DT_SPEC_INST_GET(i), \ + APDS9960_CONFIG_INTERRUPT(i) \ + .pgain = DT_INST_PROP(i, pgain) << 1, \ + .again = DT_INST_PROP(i, again), \ + .ppcount = DT_INST_PROP(i, ppulse_length) | (DT_INST_PROP(i, ppulse_count) - 1), \ + .pled_boost = DT_INST_PROP(i, pled_boost) << 4, \ + }; \ + \ + PM_DEVICE_DT_INST_DEFINE(i, apds9960_pm_action); \ + \ + SENSOR_DEVICE_DT_INST_DEFINE(i, apds9960_init, \ + PM_DEVICE_DT_INST_GET(i), &apds9960_data_##i, &apds9960_config_##i, \ + POST_KERNEL, CONFIG_SENSOR_INIT_PRIORITY, &apds9960_driver_api); + +DT_INST_FOREACH_STATUS_OKAY(APDS9960_INIT) diff --git a/drivers/sensor/apds9960/apds9960_trigger.c b/drivers/sensor/apds9960/apds9960_trigger.c index 245fdab68fba..d8a7a3d2a292 100644 --- a/drivers/sensor/apds9960/apds9960_trigger.c +++ b/drivers/sensor/apds9960/apds9960_trigger.c @@ -10,7 +10,7 @@ #include #include #include -#include "apds9960.h" +#include extern struct apds9960_data apds9960_driver; diff --git a/dts/bindings/sensor/avago,apds9960.yaml b/dts/bindings/sensor/avago,apds9960.yaml index 67e0043ff6e0..22df1431d4b2 100644 --- a/dts/bindings/sensor/avago,apds9960.yaml +++ b/dts/bindings/sensor/avago,apds9960.yaml @@ -15,3 +15,48 @@ properties: The interrupt pin of APDS9960 is open-drain, active low. If connected directly the MCU pin should be configured as pull-up, active low. + + pled-boost: + type: int + default: 0x01 + description: Proximity LED Boost Current + enum: + - 0x00 # 100 + - 0x01 # 150 + - 0x10 # 200 + - 0x11 # 300 + + pgain: + type: int + default: 0x01 + description: ALS and Color Gain + enum: + - 0x00 # 1x + - 0x01 # 4x + - 0x10 # 4x + - 0x11 # 8x + + again: + type: int + default: 0x01 + description: ALS and Color Gain + enum: + - 0x00 # 1x + - 0x01 # 4x + - 0x10 # 16x + - 0x11 # 64x + + ppulse-length: + type: int + default: 0x01 + description: Proximity Pulse Length + enum: + - 0x00 # 4us + - 0x01 # 8us + - 0x10 # 16us + - 0x11 # 32us + + ppulse-count: + type: int + default: 0x8 + description: Proximity Pulse Count From f505d31be62bfed6a1591872198c8fc8c4d83b01 Mon Sep 17 00:00:00 2001 From: Thomas Lang Date: Sat, 6 Dec 2025 18:00:15 -0600 Subject: [PATCH 0199/6328] drivers: sensor: apds9960: Setup gesture sensing configuration Created sensor specific channels and Kconfig for gesture sensing. Signed-off-by: Thomas Lang --- drivers/sensor/apds9960/Kconfig | 6 +++++ drivers/sensor/apds9960/apds9960.c | 13 ++++++++++- dts/bindings/sensor/avago,apds9960.yaml | 10 ++++++++ .../zephyr/drivers/sensor}/apds9960.h | 23 +++++++++++++++++++ 4 files changed, 51 insertions(+), 1 deletion(-) rename {drivers/sensor/apds9960 => include/zephyr/drivers/sensor}/apds9960.h (94%) diff --git a/drivers/sensor/apds9960/Kconfig b/drivers/sensor/apds9960/Kconfig index 91e74b268c1b..c1f65ca69b13 100644 --- a/drivers/sensor/apds9960/Kconfig +++ b/drivers/sensor/apds9960/Kconfig @@ -58,4 +58,10 @@ config APDS9960_ENABLE_ALS help Enable Ambient Light Sense (ALS). +config APDS9960_ENABLE_GESTURE + bool "Gesture Sense" + default n + help + Enable Gesture Sense. + endif # APDS9960 diff --git a/drivers/sensor/apds9960/apds9960.c b/drivers/sensor/apds9960/apds9960.c index 98d019aedc43..95d46f8f9e98 100644 --- a/drivers/sensor/apds9960/apds9960.c +++ b/drivers/sensor/apds9960/apds9960.c @@ -22,7 +22,7 @@ #include #include -#include "apds9960.h" +#include LOG_MODULE_REGISTER(APDS9960, CONFIG_SENSOR_LOG_LEVEL); @@ -527,6 +527,16 @@ static DEVICE_API(sensor, apds9960_driver_api) = { #define APDS9960_CONFIG_INTERRUPT(inst) #endif +#if CONFIG_APDS9960_ENABLE_GESTURE +#define APDS9960_CONFIG_GESTURE(inst) \ + .gesture_config = { \ + .proximity = DT_INST_PROP(inst, proximity), \ + .ir_difference = DT_INST_PROP(inst, ir_difference), \ + }, +#else +#define APDS9960_CONFIG_GESTURE(inst) +#endif + #define APDS9960_INIT(i) \ static struct apds9960_data apds9960_data_##i; \ static const struct apds9960_config apds9960_config_##i = { \ @@ -536,6 +546,7 @@ static DEVICE_API(sensor, apds9960_driver_api) = { .again = DT_INST_PROP(i, again), \ .ppcount = DT_INST_PROP(i, ppulse_length) | (DT_INST_PROP(i, ppulse_count) - 1), \ .pled_boost = DT_INST_PROP(i, pled_boost) << 4, \ + APDS9960_CONFIG_GESTURE(i) \ }; \ \ PM_DEVICE_DT_INST_DEFINE(i, apds9960_pm_action); \ diff --git a/dts/bindings/sensor/avago,apds9960.yaml b/dts/bindings/sensor/avago,apds9960.yaml index 22df1431d4b2..7cfb8dbda246 100644 --- a/dts/bindings/sensor/avago,apds9960.yaml +++ b/dts/bindings/sensor/avago,apds9960.yaml @@ -60,3 +60,13 @@ properties: type: int default: 0x8 description: Proximity Pulse Count + + proximity: + type: int + description: Gesture Proximity Enter Threshold + default: 40 + + ir-difference: + type: int + description: Minimum IR diode difference for gesture + default: 5 diff --git a/drivers/sensor/apds9960/apds9960.h b/include/zephyr/drivers/sensor/apds9960.h similarity index 94% rename from drivers/sensor/apds9960/apds9960.h rename to include/zephyr/drivers/sensor/apds9960.h index d40d12ac3fd4..79f994a87c59 100644 --- a/drivers/sensor/apds9960/apds9960.h +++ b/include/zephyr/drivers/sensor/apds9960.h @@ -9,6 +9,7 @@ #define ZEPHYR_DRIVERS_SENSOR_APDS9960_APDS9960_H_ #include +#include #define APDS9960_ENABLE_REG 0x80 #define APDS9960_ENABLE_GEN BIT(6) @@ -216,6 +217,11 @@ #define APDS9960_DEFAULT_WAIT_TIME 2.78 #define APDS9960_MAX_WAIT_TIME 10000 +struct apds9960_gesture_setup { + int proximity; + int ir_difference; +}; + struct apds9960_config { struct i2c_dt_spec i2c; #ifdef CONFIG_APDS9960_FETCH_MODE_INTERRUPT @@ -225,6 +231,22 @@ struct apds9960_config { uint8_t again; uint8_t ppcount; uint8_t pled_boost; +#ifdef CONFIG_APDS9960_ENABLE_GESTURE + struct apds9960_gesture_setup gesture_config; +#endif +}; + +/* apds9960 specific channels */ +enum sensor_channel_apds9960 { + SENSOR_CHAN_APDS9960_GESTURE = SENSOR_CHAN_PRIV_START, +}; + +enum apds9960_gesture { + APDS9960_GESTURE_NONE, + APDS9960_GESTURE_UP, + APDS9960_GESTURE_DOWN, + APDS9960_GESTURE_LEFT, + APDS9960_GESTURE_RIGHT, }; struct apds9960_data { @@ -233,6 +255,7 @@ struct apds9960_data { const struct device *dev; uint16_t sample_crgb[4]; uint8_t pdata; + enum apds9960_gesture gesture; #ifdef CONFIG_APDS9960_TRIGGER sensor_trigger_handler_t p_th_handler; From 109f0e15c49c8e144f3c32953e76ec9861ed9665 Mon Sep 17 00:00:00 2001 From: Thomas Lang Date: Thu, 9 Oct 2025 20:49:29 -0400 Subject: [PATCH 0200/6328] drivers: sensor: apds9960: Added gesture detection Created logic to calculate gestures from the APDS9960 sensor Signed-off-by: Thomas Lang --- drivers/sensor/apds9960/apds9960.c | 186 +++++++++++++++++++++++++++-- 1 file changed, 177 insertions(+), 9 deletions(-) diff --git a/drivers/sensor/apds9960/apds9960.c b/drivers/sensor/apds9960/apds9960.c index 95d46f8f9e98..eb78ea455d54 100644 --- a/drivers/sensor/apds9960/apds9960.c +++ b/drivers/sensor/apds9960/apds9960.c @@ -48,6 +48,124 @@ static void apds9960_gpio_callback(const struct device *dev, } #endif +#if CONFIG_APDS9960_ENABLE_GESTURE +static void apds9960_gesture_determine(struct apds9960_data *data, + uint8_t *gesture_fifo, int ir_difference) +{ + int tmp_up; + int tmp_left; + int net_up = 0; + int net_left = 0; + + static bool up_trig; + static bool down_trig; + static bool left_trig; + static bool right_trig; + + tmp_up = (int) gesture_fifo[0] - (int) gesture_fifo[1]; + tmp_left = (int) gesture_fifo[2] - (int) gesture_fifo[3]; + + if (abs(tmp_up) > ir_difference && abs(tmp_up) > abs(tmp_left)) { + net_up = tmp_up; + } + if (abs(tmp_left) > ir_difference && abs(tmp_left) > abs(tmp_up)) { + net_left = tmp_left; + } + + if (net_up > 0) { + if (down_trig) { + data->gesture = APDS9960_GESTURE_DOWN; + up_trig = false; + down_trig = false; + left_trig = false; + right_trig = false; + } else { + up_trig = true; + } + } else if (net_up < 0) { + if (up_trig) { + data->gesture = APDS9960_GESTURE_UP; + up_trig = false; + down_trig = false; + left_trig = false; + right_trig = false; + } else { + down_trig = true; + } + } else { + /* No movement in up down direction */ + } + if (net_left > 0) { + if (right_trig) { + data->gesture = APDS9960_GESTURE_RIGHT; + up_trig = false; + down_trig = false; + left_trig = false; + right_trig = false; + } else { + left_trig = true; + } + } else if (net_left < 0) { + if (left_trig) { + data->gesture = APDS9960_GESTURE_LEFT; + up_trig = false; + down_trig = false; + left_trig = false; + right_trig = false; + } else { + right_trig = true; + } + } else { + /* No movement in left right direction*/ + } + LOG_DBG("Net up: 0x%x, Net left: 0x%x", net_up, net_left); + +} +static int apds9960_gesture_fetch(const struct device *dev) +{ + const struct apds9960_config *config = dev->config; + struct apds9960_data *data = dev->data; + + uint8_t gesture_fifo_cnt; + uint8_t gstatus; + uint8_t gesture_fifo[4]; + + data->gesture = APDS9960_GESTURE_NONE; + + if (i2c_reg_read_byte_dt(&config->i2c, + APDS9960_GSTATUS_REG, &gstatus)) { + return -EIO; + } + + while (gstatus & APDS9960_GSTATUS_GVALID) { + if (i2c_reg_read_byte_dt(&config->i2c, + APDS9960_GFLVL_REG, &gesture_fifo_cnt)) { + return -EIO; + } + + for (int i = 0; i < gesture_fifo_cnt; ++i) { + /* Read up fifo and adjacent registers */ + if (i2c_burst_read_dt(&config->i2c, + APDS9960_GFIFO_U_REG, + (uint8_t *) gesture_fifo, + 4)) { + return -EIO; + } + + apds9960_gesture_determine(data, gesture_fifo, + config->gesture_config.ir_difference); + } + + if (i2c_reg_read_byte_dt(&config->i2c, + APDS9960_GSTATUS_REG, &gstatus)) { + return -EIO; + } + } + + return 0; +} +#endif + static int apds9960_sample_fetch(const struct device *dev, enum sensor_channel chan) { @@ -63,6 +181,12 @@ static int apds9960_sample_fetch(const struct device *dev, return -ENOTSUP; } +#ifdef CONFIG_APDS9960_ENABLE_GESTURE + if (apds9960_gesture_fetch(dev)) { + return -EIO; + } +#endif + #ifndef CONFIG_APDS9960_TRIGGER #ifdef CONFIG_APDS9960_FETCH_MODE_INTERRUPT apds9960_setup_int(config, true); @@ -90,16 +214,9 @@ static int apds9960_sample_fetch(const struct device *dev, start_time = k_uptime_get(); #ifdef CONFIG_APDS9960_ENABLE_ALS while (!(tmp & APDS9960_STATUS_AINT)) { - k_sleep(K_MSEC(APDS9960_DEFAULT_WAIT_TIME)); - if (i2c_reg_read_byte_dt(&config->i2c, APDS9960_STATUS_REG, &tmp)) { - return -EIO; - } - if ((k_uptime_get() - start_time) > APDS9960_MAX_WAIT_TIME) { - return -ETIMEDOUT; - } - } #else while (!(tmp & APDS9960_STATUS_PINT)) { +#endif k_sleep(K_MSEC(APDS9960_DEFAULT_WAIT_TIME)); if (i2c_reg_read_byte_dt(&config->i2c, APDS9960_STATUS_REG, &tmp)) { return -EIO; @@ -108,7 +225,6 @@ static int apds9960_sample_fetch(const struct device *dev, return -ETIMEDOUT; } } -#endif #endif LOG_DBG("status: 0x%x", tmp); @@ -172,6 +288,12 @@ static int apds9960_channel_get(const struct device *dev, val->val1 = sys_le16_to_cpu(data->sample_crgb[3]); val->val2 = 0; break; +#endif +#ifdef CONFIG_APDS9960_ENABLE_GESTURE + case SENSOR_CHAN_APDS9960_GESTURE: + val->val1 = data->gesture; + val->val2 = 0; + break; #endif case SENSOR_CHAN_PROX: val->val1 = data->pdata; @@ -304,6 +426,45 @@ static int apds9960_ambient_setup(const struct device *dev) } #endif +#ifdef CONFIG_APDS9960_ENABLE_GESTURE +static int apds9960_gesture_setup(const struct device *dev) +{ + const struct apds9960_config *config = dev->config; + + if (i2c_reg_write_byte_dt(&config->i2c, + APDS9960_GPENTH_REG, config->gesture_config.proximity)) { + LOG_ERR("Gesture proximity enter not set."); + return -EIO; + } + if (i2c_reg_write_byte_dt(&config->i2c, + APDS9960_GEXTH_REG, config->gesture_config.proximity)) { + LOG_ERR("Gesture proximity exit not set."); + return -EIO; + } + if (i2c_reg_write_byte_dt(&config->i2c, + APDS9960_GCONFIG1_REG, 0)) { + LOG_ERR("Gesture config 1 not set."); + return -EIO; + } + if (i2c_reg_write_byte_dt(&config->i2c, + APDS9960_GCONFIG2_REG, APDS9960_GGAIN_4X)) { + LOG_ERR("Gesture config 2 not set."); + return -EIO; + } + if (i2c_reg_write_byte_dt(&config->i2c, + APDS9960_GCONFIG4_REG, 0)) { + LOG_ERR("Gesture config 4 not set."); + return -EIO; + } + if (i2c_reg_update_byte_dt(&config->i2c, APDS9960_ENABLE_REG, APDS9960_ENABLE_GEN, + APDS9960_ENABLE_GEN)) { + LOG_ERR("Gesture on bit not set."); + return -EIO; + } + return 0; +} +#endif + static int apds9960_sensor_setup(const struct device *dev) { const struct apds9960_config *config = dev->config; @@ -385,6 +546,13 @@ static int apds9960_sensor_setup(const struct device *dev) } #endif +#ifdef CONFIG_APDS9960_ENABLE_GESTURE + if (apds9960_gesture_setup(dev)) { + LOG_ERR("Failed to setup gesture functionality"); + return -EIO; + } +#endif + #ifdef CONFIG_APDS9960_FETCH_MODE_POLL if (i2c_reg_update_byte_dt(&config->i2c, APDS9960_ENABLE_REG, APDS9960_ENABLE_PON, APDS9960_ENABLE_PON)) { From b5f71d3028ee358f311f6101c540e36e98430a5d Mon Sep 17 00:00:00 2001 From: Thomas Lang Date: Sun, 12 Oct 2025 21:09:01 -0400 Subject: [PATCH 0201/6328] samples: sensor: apds9960: Added gesture support Added a new channel fetch to demonstrate reading gestures Signed-off-by: Thomas Lang --- samples/sensor/apds9960/prj.conf | 2 ++ samples/sensor/apds9960/src/main.c | 16 +++++++++++++--- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/samples/sensor/apds9960/prj.conf b/samples/sensor/apds9960/prj.conf index 9f4b4aa1c8c8..8147a7762c95 100644 --- a/samples/sensor/apds9960/prj.conf +++ b/samples/sensor/apds9960/prj.conf @@ -9,3 +9,5 @@ CONFIG_I2C_LOG_LEVEL_INF=y CONFIG_APDS9960_TRIGGER_GLOBAL_THREAD=n CONFIG_PM_DEVICE=n + +CONFIG_APDS9960_ENABLE_GESTURE=n diff --git a/samples/sensor/apds9960/src/main.c b/samples/sensor/apds9960/src/main.c index ab96ae7990f1..220992631b6e 100644 --- a/samples/sensor/apds9960/src/main.c +++ b/samples/sensor/apds9960/src/main.c @@ -7,6 +7,7 @@ #include #include +#include #include #include #include @@ -24,10 +25,18 @@ static void trigger_handler(const struct device *dev, } #endif +char states[5][6] = { + "NONE", + "UP", + "DOWN", + "LEFT", + "RIGHT", +}; + int main(void) { const struct device *dev; - struct sensor_value intensity, pdata; + struct sensor_value intensity, pdata, gesture; printk("APDS9960 sample application\n"); dev = DEVICE_DT_GET_ONE(avago_apds9960); @@ -72,9 +81,10 @@ int main(void) sensor_channel_get(dev, SENSOR_CHAN_LIGHT, &intensity); sensor_channel_get(dev, SENSOR_CHAN_PROX, &pdata); + sensor_channel_get(dev, SENSOR_CHAN_APDS9960_GESTURE, &gesture); - printk("ambient light intensity %d, proximity %d\n", - intensity.val1, pdata.val1); + printk("ambient light intensity %d, proximity %d, gesture %s\n", + intensity.val1, pdata.val1, states[gesture.val1]); #ifdef CONFIG_PM_DEVICE pm_device_action_run(dev, PM_DEVICE_ACTION_SUSPEND); From 7744d2084033fb489b882772f7702d50f634082f Mon Sep 17 00:00:00 2001 From: Marcelo Roberto Jimenez Date: Sun, 7 Dec 2025 17:20:14 -0300 Subject: [PATCH 0202/6328] drivers: serial: uart_xmc4xxx: Run clang-format before applying a patch This patch just formats the uart_xmc4xxx.c file before the real patch, otherwise the changes would be hard to read. Signed-off-by: Marcelo Roberto Jimenez --- drivers/serial/uart_xmc4xxx.c | 102 +++++++++++++++++----------------- 1 file changed, 50 insertions(+), 52 deletions(-) diff --git a/drivers/serial/uart_xmc4xxx.c b/drivers/serial/uart_xmc4xxx.c index 770b86aee8dd..074cee62ad13 100644 --- a/drivers/serial/uart_xmc4xxx.c +++ b/drivers/serial/uart_xmc4xxx.c @@ -5,7 +5,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -#define DT_DRV_COMPAT infineon_xmc4xxx_uart +#define DT_DRV_COMPAT infineon_xmc4xxx_uart #include #include @@ -20,7 +20,7 @@ #define IRQS_PER_USIC 6 #define CURRENT_BUFFER 0 -#define NEXT_BUFFER 1 +#define NEXT_BUFFER 1 struct uart_xmc4xxx_config { XMC_USIC_CH_t *uart; @@ -114,7 +114,7 @@ static void disable_tx_events(const struct uart_xmc4xxx_config *config) { if (config->fifo_tx_size > 0) { XMC_USIC_CH_TXFIFO_DisableEvent(config->uart, - XMC_USIC_CH_TXFIFO_EVENT_CONF_STANDARD); + XMC_USIC_CH_TXFIFO_EVENT_CONF_STANDARD); } else { XMC_USIC_CH_DisableEvent(config->uart, XMC_USIC_CH_EVENT_TRANSMIT_SHIFT); } @@ -222,7 +222,7 @@ static int uart_xmc4xxx_irq_tx_ready(const struct device *dev) return !XMC_USIC_CH_TXFIFO_IsFull(config->uart); } else { return XMC_USIC_CH_GetTransmitBufferStatus(config->uart) == - XMC_USIC_CH_TBUF_STATUS_IDLE; + XMC_USIC_CH_TBUF_STATUS_IDLE; } } @@ -233,10 +233,11 @@ static void uart_xmc4xxx_irq_rx_disable(const struct device *dev) if (config->fifo_rx_size > 0) { XMC_USIC_CH_RXFIFO_DisableEvent(config->uart, XMC_USIC_CH_RXFIFO_EVENT_CONF_STANDARD | - XMC_USIC_CH_RXFIFO_EVENT_CONF_ALTERNATE); + XMC_USIC_CH_RXFIFO_EVENT_CONF_ALTERNATE); } else { - XMC_USIC_CH_DisableEvent(config->uart, XMC_USIC_CH_EVENT_STANDARD_RECEIVE | - XMC_USIC_CH_EVENT_ALTERNATIVE_RECEIVE); + XMC_USIC_CH_DisableEvent(config->uart, + XMC_USIC_CH_EVENT_STANDARD_RECEIVE | + XMC_USIC_CH_EVENT_ALTERNATIVE_RECEIVE); } } static void uart_xmc4xxx_irq_rx_enable(const struct device *dev) @@ -256,7 +257,7 @@ static void uart_xmc4xxx_irq_rx_enable(const struct device *dev) #endif XMC_USIC_CH_RXFIFO_EnableEvent(config->uart, XMC_USIC_CH_RXFIFO_EVENT_CONF_STANDARD | - XMC_USIC_CH_RXFIFO_EVENT_CONF_ALTERNATE); + XMC_USIC_CH_RXFIFO_EVENT_CONF_ALTERNATE); } else { /* flush out any received bytes while the uart rx irq was disabled */ recv_status = XMC_USIC_CH_GetReceiveBufferStatus(config->uart); @@ -267,8 +268,9 @@ static void uart_xmc4xxx_irq_rx_enable(const struct device *dev) XMC_UART_CH_GetReceivedData(config->uart); } - XMC_USIC_CH_EnableEvent(config->uart, XMC_USIC_CH_EVENT_STANDARD_RECEIVE | - XMC_USIC_CH_EVENT_ALTERNATIVE_RECEIVE); + XMC_USIC_CH_EnableEvent(config->uart, + XMC_USIC_CH_EVENT_STANDARD_RECEIVE | + XMC_USIC_CH_EVENT_ALTERNATIVE_RECEIVE); } } #endif @@ -925,8 +927,7 @@ static int uart_xmc4xxx_init(const struct device *dev) return ret; } /* Connect UART RX to the target pin */ - XMC_UART_CH_SetInputSource(config->uart, XMC_UART_CH_INPUT_RXD, - config->input_src); + XMC_UART_CH_SetInputSource(config->uart, XMC_UART_CH_INPUT_RXD, config->input_src); #if defined(CONFIG_UART_INTERRUPT_DRIVEN) || defined(CONFIG_UART_ASYNC_API) config->irq_config_func(dev); @@ -990,22 +991,22 @@ static DEVICE_API(uart, uart_xmc4xxx_driver_api) = { #endif #if defined(CONFIG_UART_INTERRUPT_DRIVEN) || defined(CONFIG_UART_ASYNC_API) -#define XMC4XXX_IRQ_HANDLER(index) \ -static void uart_xmc4xxx_irq_setup_##index(const struct device *dev) \ -{ \ - IRQ_CONNECT(DT_INST_IRQ_BY_NAME(index, tx, irq), \ - DT_INST_IRQ_BY_NAME(index, tx, priority), uart_xmc4xxx_isr, \ - DEVICE_DT_INST_GET(index), 0); \ - IRQ_CONNECT(DT_INST_IRQ_BY_NAME(index, rx, irq), \ - DT_INST_IRQ_BY_NAME(index, rx, priority), uart_xmc4xxx_isr, \ - DEVICE_DT_INST_GET(index), 0); \ - irq_enable(DT_INST_IRQ_BY_NAME(index, tx, irq)); \ - irq_enable(DT_INST_IRQ_BY_NAME(index, rx, irq)); \ -} +#define XMC4XXX_IRQ_HANDLER(index) \ + static void uart_xmc4xxx_irq_setup_##index(const struct device *dev) \ + { \ + IRQ_CONNECT(DT_INST_IRQ_BY_NAME(index, tx, irq), \ + DT_INST_IRQ_BY_NAME(index, tx, priority), uart_xmc4xxx_isr, \ + DEVICE_DT_INST_GET(index), 0); \ + IRQ_CONNECT(DT_INST_IRQ_BY_NAME(index, rx, irq), \ + DT_INST_IRQ_BY_NAME(index, rx, priority), uart_xmc4xxx_isr, \ + DEVICE_DT_INST_GET(index), 0); \ + irq_enable(DT_INST_IRQ_BY_NAME(index, tx, irq)); \ + irq_enable(DT_INST_IRQ_BY_NAME(index, rx, irq)); \ + } -#define XMC4XXX_IRQ_STRUCT_INIT(index) \ - .irq_config_func = uart_xmc4xxx_irq_setup_##index, \ - .irq_num_tx = DT_INST_IRQ_BY_NAME(index, tx, irq), \ +#define XMC4XXX_IRQ_STRUCT_INIT(index) \ + .irq_config_func = uart_xmc4xxx_irq_setup_##index, \ + .irq_num_tx = DT_INST_IRQ_BY_NAME(index, tx, irq), \ .irq_num_rx = DT_INST_IRQ_BY_NAME(index, rx, irq), #else @@ -1013,30 +1014,27 @@ static void uart_xmc4xxx_irq_setup_##index(const struct device *dev) #define XMC4XXX_IRQ_STRUCT_INIT(index) #endif -#define XMC4XXX_INIT(index) \ -PINCTRL_DT_INST_DEFINE(index); \ -XMC4XXX_IRQ_HANDLER(index) \ -static struct uart_xmc4xxx_data xmc4xxx_data_##index = { \ - .config.baudrate = DT_INST_PROP(index, current_speed), \ - UART_DMA_CHANNEL(index, tx, MEMORY_TO_PERIPHERAL, 8, 1) \ - UART_DMA_CHANNEL(index, rx, PERIPHERAL_TO_MEMORY, 1, 8) \ -}; \ - \ -static const struct uart_xmc4xxx_config xmc4xxx_config_##index = { \ - .uart = (XMC_USIC_CH_t *)DT_INST_REG_ADDR(index), \ - .pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(index), \ - .input_src = DT_INST_ENUM_IDX(index, input_src), \ -XMC4XXX_IRQ_STRUCT_INIT(index) \ - .fifo_start_offset = DT_INST_PROP(index, fifo_start_offset), \ - .fifo_tx_size = DT_INST_ENUM_IDX(index, fifo_tx_size), \ - .fifo_rx_size = DT_INST_ENUM_IDX(index, fifo_rx_size), \ -}; \ - \ - DEVICE_DT_INST_DEFINE(index, uart_xmc4xxx_init, \ - NULL, \ - &xmc4xxx_data_##index, \ - &xmc4xxx_config_##index, PRE_KERNEL_1, \ - CONFIG_SERIAL_INIT_PRIORITY, \ - &uart_xmc4xxx_driver_api); +#define XMC4XXX_INIT(index) \ + PINCTRL_DT_INST_DEFINE(index); \ + XMC4XXX_IRQ_HANDLER(index) \ + \ + static struct uart_xmc4xxx_data xmc4xxx_data_##index = { \ + .config.baudrate = DT_INST_PROP(index, current_speed), \ + UART_DMA_CHANNEL(index, tx, MEMORY_TO_PERIPHERAL, 8, 1) \ + UART_DMA_CHANNEL(index, rx, PERIPHERAL_TO_MEMORY, 1, 8)}; \ + \ + static const struct uart_xmc4xxx_config xmc4xxx_config_##index = { \ + .uart = (XMC_USIC_CH_t *)DT_INST_REG_ADDR(index), \ + .pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(index), \ + .input_src = DT_INST_ENUM_IDX(index, input_src), \ + XMC4XXX_IRQ_STRUCT_INIT(index).fifo_start_offset = \ + DT_INST_PROP(index, fifo_start_offset), \ + .fifo_tx_size = DT_INST_ENUM_IDX(index, fifo_tx_size), \ + .fifo_rx_size = DT_INST_ENUM_IDX(index, fifo_rx_size), \ + }; \ + \ + DEVICE_DT_INST_DEFINE(index, uart_xmc4xxx_init, NULL, &xmc4xxx_data_##index, \ + &xmc4xxx_config_##index, PRE_KERNEL_1, CONFIG_SERIAL_INIT_PRIORITY, \ + &uart_xmc4xxx_driver_api); DT_INST_FOREACH_STATUS_OKAY(XMC4XXX_INIT) From 62a49211b158066cad133f8a08df75d3ad03a577 Mon Sep 17 00:00:00 2001 From: Marcelo Roberto Jimenez Date: Mon, 8 Dec 2025 23:16:41 -0300 Subject: [PATCH 0203/6328] drivers: serial: uart_xmc4xxx: Enable run time configuration This patch enables run time configuration for the XMC4xxx serial ports. Signed-off-by: Marcelo Roberto Jimenez --- .../xmc45_relax_kit/xmc45_relax_kit.dts | 2 + .../xmc47_relax_kit/xmc47_relax_kit.dts | 4 + drivers/serial/uart_xmc4xxx.c | 206 +++++++++++++++++- .../boards/xmc45_relax_kit.overlay | 2 + .../boards/xmc47_relax_kit.overlay | 2 + 5 files changed, 213 insertions(+), 3 deletions(-) diff --git a/boards/infineon/xmc45_relax_kit/xmc45_relax_kit.dts b/boards/infineon/xmc45_relax_kit/xmc45_relax_kit.dts index b578d244bea4..f5f1dc32b53c 100644 --- a/boards/infineon/xmc45_relax_kit/xmc45_relax_kit.dts +++ b/boards/infineon/xmc45_relax_kit/xmc45_relax_kit.dts @@ -111,6 +111,8 @@ fifo-start-offset = <0>; fifo-tx-size = <16>; fifo-rx-size = <16>; + data-bits = <8>; + stop-bits = "1"; status = "okay"; }; diff --git a/boards/infineon/xmc47_relax_kit/xmc47_relax_kit.dts b/boards/infineon/xmc47_relax_kit/xmc47_relax_kit.dts index 11bd2f42e3c4..528142633a2d 100644 --- a/boards/infineon/xmc47_relax_kit/xmc47_relax_kit.dts +++ b/boards/infineon/xmc47_relax_kit/xmc47_relax_kit.dts @@ -102,6 +102,8 @@ fifo-start-offset = <0>; fifo-tx-size = <16>; fifo-rx-size = <16>; + data-bits = <8>; + stop-bits = "1"; status = "okay"; }; @@ -116,6 +118,8 @@ fifo-start-offset = <0>; fifo-tx-size = <0>; fifo-rx-size = <0>; + data-bits = <8>; + stop-bits = "1"; status = "okay"; }; diff --git a/drivers/serial/uart_xmc4xxx.c b/drivers/serial/uart_xmc4xxx.c index 074cee62ad13..d132589d206b 100644 --- a/drivers/serial/uart_xmc4xxx.c +++ b/drivers/serial/uart_xmc4xxx.c @@ -53,6 +53,7 @@ struct uart_dma_stream { struct uart_xmc4xxx_data { XMC_UART_CH_CONFIG_t config; + struct uart_config *uart_cfg; #if defined(CONFIG_UART_INTERRUPT_DRIVEN) uart_irq_callback_user_data_t user_cb; void *user_data; @@ -102,6 +103,162 @@ static void uart_xmc4xxx_poll_out(const struct device *dev, unsigned char c) XMC_UART_CH_Transmit(config->uart, c); } +static int convert_config_xmc4xxx_to_zephyr(struct uart_config *zephyr, + const XMC_UART_CH_CONFIG_t *x) +{ + struct uart_config z; + + z.baudrate = x->baudrate; + + switch (x->parity_mode) { + case XMC_USIC_CH_PARITY_MODE_NONE: + z.parity = UART_CFG_PARITY_NONE; + break; + case XMC_USIC_CH_PARITY_MODE_ODD: + z.parity = UART_CFG_PARITY_ODD; + break; + case XMC_USIC_CH_PARITY_MODE_EVEN: + z.parity = UART_CFG_PARITY_EVEN; + break; + /* XMC4xxx has no support for MARK and SPACE parity */ + /* + * case XMC_USIC_CH_PARITY_MODE_MARK: + * z.parity = UART_CFG_PARITY_MARK; + * break; + * case XMC_USIC_CH_PARITY_MODE_SPACE: + * z.parity = UART_CFG_PARITY_SPACE; + * break; + */ + default: + return -EINVAL; + } + + switch (x->stop_bits) { + case 1: + z.stop_bits = UART_CFG_STOP_BITS_1; + break; + case 2: + z.stop_bits = UART_CFG_STOP_BITS_2; + break; + default: + return -EINVAL; + } + + switch (x->data_bits) { + case 5: + z.data_bits = UART_CFG_DATA_BITS_5; + break; + case 6: + z.data_bits = UART_CFG_DATA_BITS_6; + break; + case 7: + z.data_bits = UART_CFG_DATA_BITS_7; + break; + case 8: + z.data_bits = UART_CFG_DATA_BITS_8; + break; + case 9: + z.data_bits = UART_CFG_DATA_BITS_9; + break; + default: + return -EINVAL; + } + + z.flow_ctrl = UART_CFG_FLOW_CTRL_NONE; + + *zephyr = z; + + return 0; +} + +static int convert_config_zephyr_to_xmc4xxx(XMC_UART_CH_CONFIG_t *xmc, const struct uart_config *z) +{ + XMC_UART_CH_CONFIG_t x; + + x.baudrate = z->baudrate; + + /* When zero -> will always use "fractional divider mode". */ + x.normal_divider_mode = 0; + + switch (z->data_bits) { + case UART_CFG_DATA_BITS_5: + x.data_bits = 5; + break; + case UART_CFG_DATA_BITS_6: + x.data_bits = 6; + break; + case UART_CFG_DATA_BITS_7: + x.data_bits = 7; + break; + case UART_CFG_DATA_BITS_8: + x.data_bits = 8; + break; + case UART_CFG_DATA_BITS_9: + x.data_bits = 9; + break; + default: + return -EINVAL; + } + + /* When zero -> driver takes care. */ + x.frame_length = 0; + + switch (z->stop_bits) { + case UART_CFG_STOP_BITS_0_5: + x.stop_bits = 1; + return -EINVAL; + case UART_CFG_STOP_BITS_1: + x.stop_bits = 1; + break; + case UART_CFG_STOP_BITS_1_5: + x.stop_bits = 1; + return -EINVAL; + case UART_CFG_STOP_BITS_2: + x.stop_bits = 2; + break; + default: + x.stop_bits = 1; + return -EINVAL; + } + + /* When zero -> driver actual oversampling == 16 */ + x.oversampling = 0; + + switch (z->parity) { + case UART_CFG_PARITY_NONE: + x.parity_mode = XMC_USIC_CH_PARITY_MODE_NONE; + break; + case UART_CFG_PARITY_ODD: + x.parity_mode = XMC_USIC_CH_PARITY_MODE_ODD; + break; + case UART_CFG_PARITY_EVEN: + x.parity_mode = XMC_USIC_CH_PARITY_MODE_EVEN; + break; + case UART_CFG_PARITY_MARK: + x.parity_mode = UART_CFG_PARITY_NONE; + return -ENOTSUP; + case UART_CFG_PARITY_SPACE: + x.parity_mode = UART_CFG_PARITY_NONE; + return -ENOTSUP; + default: + return -EINVAL; + } + + switch (z->flow_ctrl) { + case UART_CFG_FLOW_CTRL_NONE: + break; + case UART_CFG_FLOW_CTRL_RTS_CTS: + case UART_CFG_FLOW_CTRL_DTR_DSR: + case UART_CFG_FLOW_CTRL_RS485: + return -ENOTSUP; + default: + return -EINVAL; + } + *xmc = x; + + return 0; +} + #if defined(CONFIG_UART_ASYNC_API) static inline void async_timer_start(struct k_work_delayable *work, int32_t timeout) { @@ -892,8 +1049,10 @@ static int uart_xmc4xxx_init(const struct device *dev) struct uart_xmc4xxx_data *data = dev->data; uint8_t fifo_offset = config->fifo_start_offset; - data->config.data_bits = 8U; - data->config.stop_bits = 1U; + ret = convert_config_zephyr_to_xmc4xxx(&data->config, data->uart_cfg); + if (ret) { + return ret; + } XMC_UART_CH_Init(config->uart, &(data->config)); @@ -941,9 +1100,41 @@ static int uart_xmc4xxx_init(const struct device *dev) return ret; } +#ifdef CONFIG_UART_USE_RUNTIME_CONFIGURE +static int uart_xmc4xxx_configure(const struct device *dev, const struct uart_config *cfg) +{ + int ret; + struct uart_xmc4xxx_data *data = dev->data; + struct uart_config uart_cfg_bak = *data->uart_cfg; + + *data->uart_cfg = *cfg; + ret = uart_xmc4xxx_init(dev); + if (ret) { + *data->uart_cfg = uart_cfg_bak; + } + + return ret; +} + +static int uart_xmc4xxx_config_get(const struct device *dev, struct uart_config *cfg) +{ + int ret; + struct uart_xmc4xxx_data *data = dev->data; + + ret = convert_config_xmc4xxx_to_zephyr(data->uart_cfg, &data->config); + *cfg = *data->uart_cfg; + + return ret; +} +#endif /* CONFIG_UART_USE_RUNTIME_CONFIGURE */ + static DEVICE_API(uart, uart_xmc4xxx_driver_api) = { .poll_in = uart_xmc4xxx_poll_in, .poll_out = uart_xmc4xxx_poll_out, +#ifdef CONFIG_UART_USE_RUNTIME_CONFIGURE + .configure = uart_xmc4xxx_configure, + .config_get = uart_xmc4xxx_config_get, +#endif /* CONFIG_UART_USE_RUNTIME_CONFIGURE */ #if defined(CONFIG_UART_INTERRUPT_DRIVEN) .fifo_fill = uart_xmc4xxx_fifo_fill, .fifo_read = uart_xmc4xxx_fifo_read, @@ -1018,8 +1209,17 @@ static DEVICE_API(uart, uart_xmc4xxx_driver_api) = { PINCTRL_DT_INST_DEFINE(index); \ XMC4XXX_IRQ_HANDLER(index) \ \ + static struct uart_config uart_cfg_##index = { \ + .baudrate = DT_INST_PROP(index, current_speed), \ + .parity = DT_INST_ENUM_IDX(index, parity), \ + .stop_bits = DT_INST_ENUM_IDX(index, stop_bits), \ + .data_bits = DT_INST_ENUM_IDX(index, data_bits), \ + .flow_ctrl = DT_INST_PROP(index, hw_flow_control) ? UART_CFG_FLOW_CTRL_RTS_CTS \ + : UART_CFG_FLOW_CTRL_NONE, \ + }; \ + \ static struct uart_xmc4xxx_data xmc4xxx_data_##index = { \ - .config.baudrate = DT_INST_PROP(index, current_speed), \ + .uart_cfg = &uart_cfg_##index, \ UART_DMA_CHANNEL(index, tx, MEMORY_TO_PERIPHERAL, 8, 1) \ UART_DMA_CHANNEL(index, rx, PERIPHERAL_TO_MEMORY, 1, 8)}; \ \ diff --git a/tests/drivers/uart/uart_async_api/boards/xmc45_relax_kit.overlay b/tests/drivers/uart/uart_async_api/boards/xmc45_relax_kit.overlay index 69ed39b02208..447c7e4cd409 100644 --- a/tests/drivers/uart/uart_async_api/boards/xmc45_relax_kit.overlay +++ b/tests/drivers/uart/uart_async_api/boards/xmc45_relax_kit.overlay @@ -15,6 +15,8 @@ dut: &usic2ch0 { fifo-start-offset = <0>; fifo-tx-size = <0>; fifo-rx-size = <0>; + data-bits = <8>; + stop-bits = "1"; status = "okay"; }; diff --git a/tests/drivers/uart/uart_async_api/boards/xmc47_relax_kit.overlay b/tests/drivers/uart/uart_async_api/boards/xmc47_relax_kit.overlay index a6db8e6f8d8a..8697af51d430 100644 --- a/tests/drivers/uart/uart_async_api/boards/xmc47_relax_kit.overlay +++ b/tests/drivers/uart/uart_async_api/boards/xmc47_relax_kit.overlay @@ -20,6 +20,8 @@ dut: &usic1ch1 { fifo-start-offset = <0>; fifo-tx-size = <0>; fifo-rx-size = <0>; + data-bits = <8>; + stop-bits = "1"; }; &uart_tx_p3_15_u1c1 { From abaf2518001da31713606851da2ae9fb16bee5f0 Mon Sep 17 00:00:00 2001 From: Liam Ogletree Date: Tue, 6 Jan 2026 10:30:52 -0600 Subject: [PATCH 0204/6328] drivers: haptics: Add error callback mechanism to haptics API Haptics devices provide protection features to prevent damage during operation. Adds an error callback mechanism to the haptics API to enable haptics device drivers to raise these conditions to the application layer. Enumerates a subset of errors that are common to modern haptics devices across major vendors. Signed-off-by: Liam Ogletree --- include/zephyr/drivers/haptics.h | 58 +++++++++++++++++++++++++++++++- 1 file changed, 57 insertions(+), 1 deletion(-) diff --git a/include/zephyr/drivers/haptics.h b/include/zephyr/drivers/haptics.h index b00d821ccba3..1e074b86083d 100644 --- a/include/zephyr/drivers/haptics.h +++ b/include/zephyr/drivers/haptics.h @@ -31,10 +31,23 @@ extern "C" { #endif +/** + * @brief Haptics error types + */ +enum haptics_error_type { + HAPTICS_ERROR_OVERCURRENT = BIT(0), /**< Output overcurrent error */ + HAPTICS_ERROR_OVERTEMPERATURE = BIT(1), /**< Device overtemperature error */ + HAPTICS_ERROR_UNDERVOLTAGE = BIT(2), /**< Power source undervoltage error */ + HAPTICS_ERROR_OVERVOLTAGE = BIT(3), /**< Power source overvoltage error */ + HAPTICS_ERROR_DC = BIT(4), /**< Output direct-current error */ + + /* Device-specific error codes can follow, refer to the device’s header file */ + HAPTICS_ERROR_PRIV_START = BIT(5), +}; + /** * @typedef haptics_stop_output_t * @brief Set the haptic device to stop output - * @param dev Pointer to the device structure for haptic device instance */ typedef int (*haptics_stop_output_t)(const struct device *dev); @@ -44,12 +57,32 @@ typedef int (*haptics_stop_output_t)(const struct device *dev); */ typedef int (*haptics_start_output_t)(const struct device *dev); +/** + * @typedef haptics_error_callback_t + * @brief Callback function for error interrupt + * + * @param dev Pointer to the haptic device + * @param errors Device errors (bitmask of @ref haptics_error_type values) + * @param user_data User data provided when the error callback was registered + */ +typedef void (*haptics_error_callback_t)(const struct device *dev, const uint32_t errors, + void *const user_data); + +/** + * @typedef haptics_register_error_callback_t + * @brief Register a callback function for haptics errors + */ +typedef int (*haptics_register_error_callback_t)(const struct device *dev, + haptics_error_callback_t cb, + void *const user_data); + /** * @brief Haptic device API */ __subsystem struct haptics_driver_api { haptics_start_output_t start_output; haptics_stop_output_t stop_output; + haptics_register_error_callback_t register_error_callback; }; /** @@ -86,6 +119,29 @@ static inline int z_impl_haptics_stop_output(const struct device *dev) return api->stop_output(dev); } +/** + * @brief Register a callback function for haptics errors + * + * @param dev Pointer to the haptic device + * @param cb Callback function (of type @ref haptics_error_callback_t) + * @param user_data User data to be provided back to the application via the callback + * + * @retval 0 if successful + * @retval <0 if failed + */ +static inline int haptics_register_error_callback(const struct device *dev, + haptics_error_callback_t cb, + void *const user_data) +{ + const struct haptics_driver_api *api = (const struct haptics_driver_api *)dev->api; + + if (api->register_error_callback == NULL) { + return -ENOSYS; + } + + return api->register_error_callback(dev, cb, user_data); +} + /** * @} */ From 339d2df232495209f0287186aa58017630e3da13 Mon Sep 17 00:00:00 2001 From: Liam Ogletree Date: Tue, 6 Jan 2026 10:40:07 -0600 Subject: [PATCH 0205/6328] drivers: haptics: Update CS40L5x driver to use new haptics API Modifies the CS40L5x driver to use the error callback mechanism added to the haptics API instead of a device-specific API extension. Signed-off-by: Liam Ogletree --- drivers/haptics/cs40l5x.c | 27 ++++++++++++---------- include/zephyr/drivers/haptics/cs40l5x.h | 29 +++--------------------- 2 files changed, 18 insertions(+), 38 deletions(-) diff --git a/drivers/haptics/cs40l5x.c b/drivers/haptics/cs40l5x.c index 76111e902a5d..020bf0ad5c80 100644 --- a/drivers/haptics/cs40l5x.c +++ b/drivers/haptics/cs40l5x.c @@ -770,7 +770,7 @@ static void cs40l5x_error_callback(const struct device *const dev, const uint32_ struct cs40l5x_data *const data = dev->data; if (data->error_callback != NULL) { - (void)data->error_callback(dev, error_bitmask); + (void)data->error_callback(dev, error_bitmask, data->user_data); } } @@ -854,7 +854,7 @@ static int cs40l5x_process_mailbox(const struct device *const dev) case CS40L5X_MBOX_PERMANENT_SHORT_DETECTED: __fallthrough; case CS40L5X_MBOX_RUNTIME_SHORT_DETECTED: - (void)cs40l5x_error_callback(dev, CS40L5X_ERROR_AMPLIFIER_SHORT); + (void)cs40l5x_error_callback(dev, HAPTICS_ERROR_OVERCURRENT); return 0; default: @@ -881,37 +881,37 @@ static int cs40l5x_process_interrupts(const struct device *const dev, if (FIELD_GET(CS40L5X_MASK_IRQ1_AMP, irq_ints[CS40L5X_INT1]) != 0) { LOG_INST_WRN(config->log, "amplifier short detected"); - error_bitmask |= CS40L5X_ERROR_AMPLIFIER_SHORT; + error_bitmask |= HAPTICS_ERROR_OVERCURRENT; } if (FIELD_GET(CS40L5X_MASK_IRQ8_TEMP, irq_ints[CS40L5X_INT8]) != 0) { LOG_INST_WRN(config->log, "overtemperature detected"); - error_bitmask |= CS40L5X_ERROR_OVERTEMPERATURE; + error_bitmask |= HAPTICS_ERROR_OVERTEMPERATURE; } if (FIELD_GET(CS40L5X_MASK_IRQ9_UVP, irq_ints[CS40L5X_INT9]) != 0) { LOG_INST_WRN(config->log, "undervoltage detected"); - error_bitmask |= CS40L5X_ERROR_UNDERVOLTAGE; + error_bitmask |= HAPTICS_ERROR_UNDERVOLTAGE; } if (FIELD_GET(CS40L5X_MASK_IRQ9_IND_SHORT, irq_ints[CS40L5X_INT9]) != 0) { LOG_INST_WRN(config->log, "inductor short detected"); - error_bitmask |= CS40L5X_ERROR_INDUCTOR_SHORT; + error_bitmask |= HAPTICS_ERROR_OVERCURRENT; } if (FIELD_GET(CS40L5X_MASK_IRQ9_CUR_LIMIT, irq_ints[CS40L5X_INT9]) != 0) { LOG_INST_WRN(config->log, "overcurrent condition detected"); - error_bitmask |= CS40L5X_ERROR_OVERCURRENT; + error_bitmask |= HAPTICS_ERROR_OVERCURRENT; } if (FIELD_GET(CS40L5X_MASK_IRQ1_VDDB, irq_ints[CS40L5X_INT10]) != 0) { LOG_INST_WRN(config->log, "battery undervoltage detected"); - error_bitmask |= CS40L5X_ERROR_BATTERY_UNDERVOLTAGE; + error_bitmask |= HAPTICS_ERROR_UNDERVOLTAGE; } if (error_bitmask != 0) { @@ -1870,13 +1870,15 @@ int cs40l5x_logger_get(const struct device *const dev, enum cs40l5x_logger_sourc return ret; } -void cs40l5x_register_error_callback(const struct device *dev, - void (*error_callback)(const struct device *const haptic_dev, - const uint32_t errors)) +static int cs40l5x_register_error_callback(const struct device *dev, haptics_error_callback_t cb, + void *const user_data) { struct cs40l5x_data *const data = dev->data; - data->error_callback = error_callback; + data->error_callback = cb; + data->user_data = user_data; + + return 0; } int cs40l5x_select_output(const struct device *const dev, const enum cs40l5x_bank bank, @@ -2293,6 +2295,7 @@ int cs40l5x_upload_pwle(const struct device *const dev, const enum cs40l5x_custo static DEVICE_API(haptics, cs40l5x_driver_api) = { .start_output = &cs40l5x_start_output, .stop_output = &cs40l5x_stop_output, + .register_error_callback = &cs40l5x_register_error_callback, }; static int cs40l5x_pm_resume(const struct device *const dev) diff --git a/include/zephyr/drivers/haptics/cs40l5x.h b/include/zephyr/drivers/haptics/cs40l5x.h index 1770470ec79e..8f2d6f8d67ba 100644 --- a/include/zephyr/drivers/haptics/cs40l5x.h +++ b/include/zephyr/drivers/haptics/cs40l5x.h @@ -77,20 +77,6 @@ enum cs40l5x_custom_index { CS40L5X_NUM_CUSTOM_EFFECTS, /**< Maximum number of custom haptics effects */ }; -/** - * @brief Types of fatal CS40L5x hardware errors - * - * @details Provided to application callback function. See @ref cs40l5x_register_error_callback(). - */ -enum cs40l5x_error_type { - CS40L5X_ERROR_AMPLIFIER_SHORT = BIT(0), /**< Amplifier short detected */ - CS40L5X_ERROR_OVERTEMPERATURE = BIT(1), /**< Overtemperature detected */ - CS40L5X_ERROR_UNDERVOLTAGE = BIT(2), /**< Undervoltage detected */ - CS40L5X_ERROR_INDUCTOR_SHORT = BIT(3), /**< Inductor short detected */ - CS40L5X_ERROR_OVERCURRENT = BIT(4), /**< Overcurrent condition detected */ - CS40L5X_ERROR_BATTERY_UNDERVOLTAGE = BIT(4), /**< Vdd_batt undervoltage detected */ -}; - /** * @brief Options for runtime haptics logging * @@ -318,7 +304,9 @@ struct cs40l5x_data { /**< Callback handler for trigger logging */ struct gpio_callback trigger_callback; /**< Application-provided callback to recover from fatal hardware errors */ - void (*error_callback)(const struct device *const haptic_dev, const uint32_t errors); + haptics_error_callback_t error_callback; + /**< Application-provided user data for callback context */ + void *user_data; /**< Semaphore used to sequence the calibration routine */ struct k_sem calibration_semaphore; /**< F0 and ReDC data derived from calibration */ @@ -418,17 +406,6 @@ int cs40l5x_logger(const struct device *const dev, enum cs40l5x_logger logger_st int cs40l5x_logger_get(const struct device *const dev, enum cs40l5x_logger_source source, enum cs40l5x_logger_source_type type, uint32_t *const value); -/** - * @brief Register an application callback to handle fatal hardware errors - * - * @param dev Pointer to the device structure for haptic device instance - * @param error_callback Application function that takes a pointer to the device structure for a - * haptic device instance and a bitmask of @ref cs40l5x_error_type - */ -void cs40l5x_register_error_callback(const struct device *dev, - void (*error_callback)(const struct device *const haptic_dev, - const uint32_t errors)); - /** * @brief Select haptic effect triggered via @ref haptics_start_output() * From 4bf67fca7a55c13a5c16a318f26b451ba9ba3105 Mon Sep 17 00:00:00 2001 From: Liam Ogletree Date: Tue, 6 Jan 2026 10:54:41 -0600 Subject: [PATCH 0206/6328] samples: cs40l5x: Update sample application based on driver changes Modifies sample application to use error callback mechanism added to haptics API instead of device-specific API extension. Signed-off-by: Liam Ogletree --- samples/drivers/haptics/cs40l5x/src/main.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/samples/drivers/haptics/cs40l5x/src/main.c b/samples/drivers/haptics/cs40l5x/src/main.c index c23c2636b140..0ab46460c82b 100644 --- a/samples/drivers/haptics/cs40l5x/src/main.c +++ b/samples/drivers/haptics/cs40l5x/src/main.c @@ -288,7 +288,8 @@ static const struct cs40l5x_pwle_section pwle_sections[] = { }, }; -static void cs40l5x_dummy_callback(const struct device *const dev, const uint32_t errors) +static void cs40l5x_dummy_callback(const struct device *const dev, const uint32_t errors, + void *const user_data) { LOG_INF("fatal errors detected (0x%08X)", errors); } @@ -310,7 +311,7 @@ int main(void) } } - (void)cs40l5x_register_error_callback(cs40l5x, cs40l5x_dummy_callback); + (void)haptics_register_error_callback(cs40l5x, cs40l5x_dummy_callback, NULL); /* Demonstration of PCM upload (CUSTOM0) */ error = cs40l5x_upload_pcm(cs40l5x, CS40L5X_CUSTOM_0, CS40L5X_DEMO_REDC, CS40L5X_DEMO_F0, From 61dea0bcc8a74458728e5670e5bfa076a0139559 Mon Sep 17 00:00:00 2001 From: Mohamed Azhar Date: Mon, 5 Jan 2026 16:47:40 +0530 Subject: [PATCH 0207/6328] dts: arm: microchip: sam: add SPI node and binding file Add device tree binding file for Microchip g1 SPI driver Signed-off-by: Mohamed Azhar --- .../sam/sam_d5x_e5x/common/samd5xe5x_n.dtsi | 2 +- .../sam/sam_d5x_e5x/common/samd5xe5x_p.dtsi | 2 +- dts/bindings/spi/microchip,sercom-g1-spi.yaml | 53 +++++++++++++++++++ 3 files changed, 55 insertions(+), 2 deletions(-) create mode 100644 dts/bindings/spi/microchip,sercom-g1-spi.yaml diff --git a/dts/arm/microchip/sam/sam_d5x_e5x/common/samd5xe5x_n.dtsi b/dts/arm/microchip/sam/sam_d5x_e5x/common/samd5xe5x_n.dtsi index a2c252691599..4e1eedac1358 100644 --- a/dts/arm/microchip/sam/sam_d5x_e5x/common/samd5xe5x_n.dtsi +++ b/dts/arm/microchip/sam/sam_d5x_e5x/common/samd5xe5x_n.dtsi @@ -45,12 +45,12 @@ sercom6: sercom@43000800 { compatible = "microchip,sercom-g1"; - status = "disabled"; reg = <0x43000800 0x31>; interrupts = <70 0>, <71 0>, <72 0>, <73 0>; clocks = <&mclkperiph CLOCK_MCHP_MCLKPERIPH_ID_APBD_SERCOM6>, <&gclkperiph CLOCK_MCHP_GCLKPERIPH_ID_SERCOM6_CORE>; clock-names = "mclk", "gclk"; + status = "disabled"; }; sercom7: sercom@43000c00 { diff --git a/dts/arm/microchip/sam/sam_d5x_e5x/common/samd5xe5x_p.dtsi b/dts/arm/microchip/sam/sam_d5x_e5x/common/samd5xe5x_p.dtsi index ac71565163d8..13e662e9c828 100644 --- a/dts/arm/microchip/sam/sam_d5x_e5x/common/samd5xe5x_p.dtsi +++ b/dts/arm/microchip/sam/sam_d5x_e5x/common/samd5xe5x_p.dtsi @@ -45,12 +45,12 @@ sercom6: sercom@43000800 { compatible = "microchip,sercom-g1"; - status = "disabled"; reg = <0x43000800 0x31>; interrupts = <70 0>, <71 0>, <72 0>, <73 0>; clocks = <&mclkperiph CLOCK_MCHP_MCLKPERIPH_ID_APBD_SERCOM6>, <&gclkperiph CLOCK_MCHP_GCLKPERIPH_ID_SERCOM6_CORE>; clock-names = "mclk", "gclk"; + status = "disabled"; }; sercom7: sercom@43000c00 { diff --git a/dts/bindings/spi/microchip,sercom-g1-spi.yaml b/dts/bindings/spi/microchip,sercom-g1-spi.yaml new file mode 100644 index 000000000000..9d1189b37dd4 --- /dev/null +++ b/dts/bindings/spi/microchip,sercom-g1-spi.yaml @@ -0,0 +1,53 @@ +# Copyright (c) 2026 Microchip Technology Inc. +# SPDX-License-Identifier: Apache-2.0 + +description: | + Microchip SERCOM SPI + + Group G1 SERCOM SPI includes the following hardware peripherals: + - module name="SERCOM" id="U2201" version="5.0.0" + +compatible: "microchip,sercom-g1-spi" + +include: + - name: spi-controller.yaml + - name: pinctrl-device.yaml + +properties: + reg: + required: true + + clocks: + required: true + + clock-names: + required: true + + dipo: + type: int + required: true + description: | + Data In Pinout + + dopo: + type: int + required: true + description: | + Data Out Pinout + + dmas: + description: | + Optional TX & RX dma specifiers. Each specifier will have a phandle + reference to the dmac controller, the channel number, and peripheral + trigger source. + + For example dmas for TX, RX on SERCOM3 + dmas = <&dmac 0 0xb>, <&dmac 1 0xa>; + + dma-names: + description: | + Required if the dmas property exists. This should be "tx" and "rx" + to match the dmas property. + + For example + dma-names = "tx", "rx"; From 139f2e7b833383bf07b752330abbf2bc264a0738 Mon Sep 17 00:00:00 2001 From: Mohamed Azhar Date: Mon, 5 Jan 2026 19:30:41 +0530 Subject: [PATCH 0208/6328] drivers: spi: microchip: Add SPI g1 driver - Add SPI driver for Microchip SERCOM g1 - Add and update Kconfig files to support the driver - Update CMakeLists.txt to include the new driver Signed-off-by: Mohamed Azhar --- drivers/spi/CMakeLists.txt | 1 + drivers/spi/Kconfig | 1 + drivers/spi/Kconfig.mchp | 55 + drivers/spi/spi_mchp_sercom_g1.c | 1765 ++++++++++++++++++++++++++++++ 4 files changed, 1822 insertions(+) create mode 100644 drivers/spi/Kconfig.mchp create mode 100644 drivers/spi/spi_mchp_sercom_g1.c diff --git a/drivers/spi/CMakeLists.txt b/drivers/spi/CMakeLists.txt index afafbc749ebf..ca5652b60acd 100644 --- a/drivers/spi/CMakeLists.txt +++ b/drivers/spi/CMakeLists.txt @@ -37,6 +37,7 @@ zephyr_library_sources_ifdef(CONFIG_SPI_LITEX_LITESPI spi_litex_litespi.c) zephyr_library_sources_ifdef(CONFIG_SPI_MAX32 spi_max32.c) zephyr_library_sources_ifdef(CONFIG_SPI_MCHP_MSS spi_mchp_mss.c) zephyr_library_sources_ifdef(CONFIG_SPI_MCHP_QSPI spi_mchp_mss_qspi.c) +zephyr_library_sources_ifdef(CONFIG_SPI_MCHP_SERCOM_G1 spi_mchp_sercom_g1.c) zephyr_library_sources_ifdef(CONFIG_SPI_MCUX_DSPI spi_mcux_dspi.c) zephyr_library_sources_ifdef(CONFIG_SPI_MCUX_ECSPI spi_mcux_ecspi.c) zephyr_library_sources_ifdef(CONFIG_SPI_MCUX_FLEXCOMM spi_mcux_flexcomm.c) diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig index 53d1ffc415d5..5e87cabd1271 100644 --- a/drivers/spi/Kconfig +++ b/drivers/spi/Kconfig @@ -122,6 +122,7 @@ source "drivers/spi/Kconfig.it51xxx" source "drivers/spi/Kconfig.it8xxx2" source "drivers/spi/Kconfig.litex" source "drivers/spi/Kconfig.max32" +source "drivers/spi/Kconfig.mchp" source "drivers/spi/Kconfig.mchp_mss" source "drivers/spi/Kconfig.mchp_mss_qspi" source "drivers/spi/Kconfig.mcux_dspi" diff --git a/drivers/spi/Kconfig.mchp b/drivers/spi/Kconfig.mchp new file mode 100644 index 000000000000..acb0a314c1e5 --- /dev/null +++ b/drivers/spi/Kconfig.mchp @@ -0,0 +1,55 @@ +# Copyright (c) 2026 Microchip Technology Inc. +# SPDX-License-Identifier: Apache-2.0 + +config SPI_MCHP_SERCOM_G1 + bool "Microchip SERCOM SPI driver" + default y + depends on DT_HAS_MICROCHIP_SERCOM_G1_SPI_ENABLED + select PINCTRL + select GPIO + help + Enable support for the Microchip SERCOM SPI driver. + +menu "Microchip SERCOM SPI driver options" + +config SPI_MCHP_INTER_CHARACTER_SPACE + int "Microchip SERCOM SPI Inter-Character Spacing (in clock cycles)" + default 63 if SPI_SLAVE + default 0 + range 0 63 + depends on SPI_MCHP_SERCOM_G1 + help + Number of clock cycles to delay between characters on SPI bus. + +endmenu + + +config SPI_MCHP_INTERRUPT_DRIVEN + bool "Microchip SERCOM SPI driver (Interrupt Driven)" + depends on SPI_MCHP_SERCOM_G1 && !SPI_ASYNC + help + Enable interrupt-driven support for Microchip Devices + SERCOM SPI driver. + +menu "SPI ASYNC SELECTION" + depends on SPI_MCHP_SERCOM_G1 && SPI_ASYNC + +choice + prompt "Select Async Mode: Interrupt or DMA" + default SPI_MCHP_INTERRUPT_DRIVEN_ASYNC + help + Choose between interrupt or DMA async mode for the MCHP SPI driver. + +config SPI_MCHP_INTERRUPT_DRIVEN_ASYNC + bool "MCHP Interrupt Async" + help + Enables interrupt support for the MCHP SPI driver in async mode. + +config SPI_MCHP_DMA_DRIVEN_ASYNC + bool "MCHP DMA" + select DMA + help + Enables DMA in async mode for the MCHP SPI driver. + +endchoice +endmenu diff --git a/drivers/spi/spi_mchp_sercom_g1.c b/drivers/spi/spi_mchp_sercom_g1.c new file mode 100644 index 000000000000..24d5cee987ca --- /dev/null +++ b/drivers/spi/spi_mchp_sercom_g1.c @@ -0,0 +1,1765 @@ +/* + * Copyright (c) 2026 Microchip Technology Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#define DT_DRV_COMPAT microchip_sercom_g1_spi + +#define LOG_LEVEL CONFIG_SPI_LOG_LEVEL +LOG_MODULE_REGISTER(spi_mchp_sercom_g1); + +#include "spi_context.h" + +#define SPI_MCHP_MAX_XFER_SIZE 65535 +#define SUPPORTED_SPI_WORD_SIZE 8 +#define SPI_PIN_CNT 4 +#define TIMEOUT_VALUE_US 1000 +#define DELAY_US 2 + +struct mchp_spi_reg_config { + sercom_registers_t *regs; + uint32_t pads; +}; + +struct mchp_spi_clock { + const struct device *clock_dev; + clock_control_subsys_t mclk_sys; + clock_control_subsys_t gclk_sys; +}; + +struct mchp_spi_dma { + const struct device *dma_dev; + uint8_t tx_dma_request; + uint8_t tx_dma_channel; + uint8_t rx_dma_request; + uint8_t rx_dma_channel; +}; + +struct spi_mchp_dev_config { + struct mchp_spi_reg_config reg_cfg; + const struct pinctrl_dev_config *pcfg; + +#if CONFIG_SPI_MCHP_DMA_DRIVEN_ASYNC + struct mchp_spi_dma spi_dma; +#endif /* CONFIG_SPI_MCHP_DMA_DRIVEN_ASYNC */ + +#if defined(CONFIG_SPI_ASYNC) || defined(CONFIG_SPI_MCHP_INTERRUPT_DRIVEN) + void (*irq_config_func)(const struct device *dev); +#endif /* CONFIG_SPI_ASYNC) || CONFIG_SPI_MCHP_INTERRUPT_DRIVEN */ + + struct mchp_spi_clock spi_clock; +}; + +struct spi_mchp_dev_data { + struct spi_context ctx; + +#if defined(CONFIG_SPI_ASYNC) || defined(CONFIG_SPI_MCHP_INTERRUPT_DRIVEN) + uint8_t dummysize; +#endif /* CONFIG_SPI_ASYNC) || CONFIG_SPI_MCHP_INTERRUPT_DRIVEN */ + +#if CONFIG_SPI_MCHP_DMA_DRIVEN_ASYNC + const struct device *dev; + uint32_t dma_segment_len; +#endif /* CONFIG_SPI_MCHP_DMA_DRIVEN_ASYNC */ +}; + +/*Wait for synchronization*/ +static inline void spi_wait_sync(const struct mchp_spi_reg_config *spi_reg_cfg, uint32_t sync_flag) +{ + if (WAIT_FOR(((spi_reg_cfg->regs->SPIM.SERCOM_SYNCBUSY & sync_flag) == 0), TIMEOUT_VALUE_US, + k_busy_wait(DELAY_US)) == false) { + LOG_ERR("Timeout waiting for SPI SYNCBUSY ENABLE clear"); + } +} + +/*Enable the SPI peripheral*/ +static void spi_enable(const struct mchp_spi_reg_config *spi_reg_cfg, spi_operation_t op) +{ + spi_wait_sync(spi_reg_cfg, SERCOM_SPIM_SYNCBUSY_ENABLE_Msk); + if (SPI_OP_MODE_GET(op) == SPI_OP_MODE_MASTER) { + spi_reg_cfg->regs->SPIM.SERCOM_CTRLA |= SERCOM_SPIM_CTRLA_ENABLE_Msk; + } else { + spi_reg_cfg->regs->SPIS.SERCOM_CTRLA |= SERCOM_SPIS_CTRLA_ENABLE_Msk; + } + spi_wait_sync(spi_reg_cfg, SERCOM_SPIM_SYNCBUSY_ENABLE_Msk); +} + +/*Disable the SPI peripheral*/ +static void spi_disable(const struct mchp_spi_reg_config *spi_reg_cfg) +{ + spi_wait_sync(spi_reg_cfg, SERCOM_SPIM_SYNCBUSY_ENABLE_Msk); + spi_reg_cfg->regs->SPIM.SERCOM_CTRLA &= ~SERCOM_SPIM_CTRLA_ENABLE_Msk; + spi_wait_sync(spi_reg_cfg, SERCOM_SPIM_SYNCBUSY_ENABLE_Msk); +} + +/*Set the SPI Master Mode*/ +static inline void spi_master_mode(const struct mchp_spi_reg_config *spi_reg_cfg) +{ + /* Clear the MODE bit field and set it to SPI Master mode */ + spi_reg_cfg->regs->SPIM.SERCOM_CTRLA = + (spi_reg_cfg->regs->SPIM.SERCOM_CTRLA & ~SERCOM_SPIM_CTRLA_MODE_Msk) | + SERCOM_SPIM_CTRLA_MODE_SPI_MASTER; +} + +/*Set the SPI Slave Mode*/ +static inline void spi_slave_mode(const struct mchp_spi_reg_config *spi_reg_cfg) +{ + /* Clear the MODE bit field and set it to SPI Slave mode */ + spi_reg_cfg->regs->SPIS.SERCOM_CTRLA = + (spi_reg_cfg->regs->SPIS.SERCOM_CTRLA & ~SERCOM_SPIS_CTRLA_MODE_Msk) | + SERCOM_SPIS_CTRLA_MODE_SPI_SLAVE; +} + +/*Set the SPI Data Order, MSB first*/ +static void spi_msb_first(const struct mchp_spi_reg_config *spi_reg_cfg, spi_operation_t op) +{ + /* Clear the DORD bit field and set it to MSB first */ + if (SPI_OP_MODE_GET(op) == SPI_OP_MODE_MASTER) { + spi_reg_cfg->regs->SPIM.SERCOM_CTRLA = + (spi_reg_cfg->regs->SPIM.SERCOM_CTRLA & ~SERCOM_SPIM_CTRLA_DORD_Msk) | + SERCOM_SPIM_CTRLA_DORD_MSB; + } else { + spi_reg_cfg->regs->SPIS.SERCOM_CTRLA = + (spi_reg_cfg->regs->SPIS.SERCOM_CTRLA & ~SERCOM_SPIS_CTRLA_DORD_Msk) | + SERCOM_SPIS_CTRLA_DORD_MSB; + } +} + +/*Set the SPI Data Order,LSB first*/ +static void spi_lsb_first(const struct mchp_spi_reg_config *spi_reg_cfg, spi_operation_t op) +{ + /* Clear the DORD bit field and set it to LSB first */ + if (SPI_OP_MODE_GET(op) == SPI_OP_MODE_MASTER) { + spi_reg_cfg->regs->SPIM.SERCOM_CTRLA = + (spi_reg_cfg->regs->SPIM.SERCOM_CTRLA & ~SERCOM_SPIM_CTRLA_DORD_Msk) | + SERCOM_SPIM_CTRLA_DORD_LSB; + } else { + spi_reg_cfg->regs->SPIS.SERCOM_CTRLA = + (spi_reg_cfg->regs->SPIS.SERCOM_CTRLA & ~SERCOM_SPIS_CTRLA_DORD_Msk) | + SERCOM_SPIS_CTRLA_DORD_LSB; + } +} + +/*Set the SPI Clock Polarity Idle Low*/ +static void spi_cpol_idle_low(const struct mchp_spi_reg_config *spi_reg_cfg, spi_operation_t op) +{ + /* Clear the CPOL bit field and set clock polarity to Idle Low */ + if (SPI_OP_MODE_GET(op) == SPI_OP_MODE_MASTER) { + spi_reg_cfg->regs->SPIM.SERCOM_CTRLA = + (spi_reg_cfg->regs->SPIM.SERCOM_CTRLA & ~SERCOM_SPIM_CTRLA_CPOL_Msk) | + SERCOM_SPIM_CTRLA_CPOL_IDLE_LOW; + } else { + spi_reg_cfg->regs->SPIS.SERCOM_CTRLA = + (spi_reg_cfg->regs->SPIS.SERCOM_CTRLA & ~SERCOM_SPIS_CTRLA_CPOL_Msk) | + SERCOM_SPIS_CTRLA_CPOL_IDLE_LOW; + } +} + +/*Set the SPI Clock Polarity Idle High*/ +static void spi_cpol_idle_high(const struct mchp_spi_reg_config *spi_reg_cfg, spi_operation_t op) +{ + /* Clear the CPOL bit field and set clock polarity to Idle High */ + if (SPI_OP_MODE_GET(op) == SPI_OP_MODE_MASTER) { + spi_reg_cfg->regs->SPIM.SERCOM_CTRLA = + (spi_reg_cfg->regs->SPIM.SERCOM_CTRLA & ~SERCOM_SPIM_CTRLA_CPOL_Msk) | + SERCOM_SPIM_CTRLA_CPOL_IDLE_HIGH; + } else { + spi_reg_cfg->regs->SPIS.SERCOM_CTRLA = + (spi_reg_cfg->regs->SPIS.SERCOM_CTRLA & ~SERCOM_SPIS_CTRLA_CPOL_Msk) | + SERCOM_SPIS_CTRLA_CPOL_IDLE_HIGH; + } +} + +/*Set the SPI Clock Phase leading Edge*/ +static void spi_cpha_lead_edge(const struct mchp_spi_reg_config *spi_reg_cfg, spi_operation_t op) +{ + /* Clear the CPHA bit field and set clock phase to Leading Edge */ + if (SPI_OP_MODE_GET(op) == SPI_OP_MODE_MASTER) { + spi_reg_cfg->regs->SPIM.SERCOM_CTRLA = + (spi_reg_cfg->regs->SPIM.SERCOM_CTRLA & ~SERCOM_SPIM_CTRLA_CPHA_Msk) | + SERCOM_SPIM_CTRLA_CPHA_LEADING_EDGE; + } else { + spi_reg_cfg->regs->SPIS.SERCOM_CTRLA = + (spi_reg_cfg->regs->SPIS.SERCOM_CTRLA & ~SERCOM_SPIS_CTRLA_CPHA_Msk) | + SERCOM_SPIS_CTRLA_CPHA_LEADING_EDGE; + } +} + +/*Set the SPI Clock Phase Trailing Edge*/ +static void spi_cpha_trail_edge(const struct mchp_spi_reg_config *spi_reg_cfg, spi_operation_t op) +{ + /* Clear the CPHA bit field and set clock phase to Trailing Edge */ + if (SPI_OP_MODE_GET(op) == SPI_OP_MODE_MASTER) { + spi_reg_cfg->regs->SPIM.SERCOM_CTRLA = + (spi_reg_cfg->regs->SPIM.SERCOM_CTRLA & ~SERCOM_SPIM_CTRLA_CPHA_Msk) | + SERCOM_SPIM_CTRLA_CPHA_TRAILING_EDGE; + } else { + spi_reg_cfg->regs->SPIS.SERCOM_CTRLA = + (spi_reg_cfg->regs->SPIS.SERCOM_CTRLA & ~SERCOM_SPIS_CTRLA_CPHA_Msk) | + SERCOM_SPIS_CTRLA_CPHA_TRAILING_EDGE; + } +} + +/*Set the SPI Half Duplex Mode*/ +static inline int spi_half_duplex_mode(const struct mchp_spi_reg_config *spi_reg_cfg) +{ + LOG_ERR("SPI half-duplex mode is not supported"); + + return -ENOTSUP; +} + +/*Set the SPI Full Duplex Mode. Since the device is full duplex mode by default this API returns + *success + */ +static inline int spi_full_duplex_mode(const struct mchp_spi_reg_config *spi_reg_cfg) +{ + return 0; +} + +/*Set the pads for the SPI Transmission*/ +static inline void spi_slave_config_pinout(const struct mchp_spi_reg_config *spi_reg_cfg) +{ + /* Clear the DIPO and DOPO bit fields and apply the new pad configuration */ + spi_reg_cfg->regs->SPIS.SERCOM_CTRLA = + (spi_reg_cfg->regs->SPIS.SERCOM_CTRLA & + ~(SERCOM_SPIS_CTRLA_DIPO_Msk | SERCOM_SPIS_CTRLA_DOPO_Msk)) | + spi_reg_cfg->pads; +} + +/*Set the pads for the SPI Transmission*/ +static inline void spi_master_config_pinout(const struct mchp_spi_reg_config *spi_reg_cfg) +{ + /* Clear the DIPO and DOPO bit fields and apply the new pad configuration */ + spi_reg_cfg->regs->SPIM.SERCOM_CTRLA = + (spi_reg_cfg->regs->SPIM.SERCOM_CTRLA & + ~(SERCOM_SPIM_CTRLA_DIPO_Msk | SERCOM_SPIM_CTRLA_DOPO_Msk)) | + spi_reg_cfg->pads; +} + +/*Set the pads for the SPI Transmission for loopback mode*/ +static inline void spi_mode_loopback(const struct mchp_spi_reg_config *spi_reg_cfg) +{ + /* Clear the DIPO and DOPO bit fields and set them to PAD0 */ + spi_reg_cfg->regs->SPIM.SERCOM_CTRLA = + (spi_reg_cfg->regs->SPIM.SERCOM_CTRLA & + ~(SERCOM_SPIM_CTRLA_DIPO_Msk | SERCOM_SPIM_CTRLA_DOPO_Msk)) | + (SERCOM_SPIM_CTRLA_DIPO_PAD0 | SERCOM_SPIM_CTRLA_DOPO_PAD0); +} + +/*Enable the Receiver in SPI peripheral*/ +static void spi_rx_enable(const struct mchp_spi_reg_config *spi_reg_cfg, spi_operation_t op) +{ + if (SPI_OP_MODE_GET(op) == SPI_OP_MODE_MASTER) { + spi_wait_sync(spi_reg_cfg, SERCOM_SPIM_SYNCBUSY_CTRLB_Msk); + /* Clear the RXEN bit field and enable Receiver */ + spi_reg_cfg->regs->SPIM.SERCOM_CTRLB = + (spi_reg_cfg->regs->SPIM.SERCOM_CTRLB & ~SERCOM_SPIM_CTRLB_RXEN_Msk) | + SERCOM_SPIM_CTRLB_RXEN_Msk; + spi_wait_sync(spi_reg_cfg, SERCOM_SPIM_SYNCBUSY_CTRLB_Msk); + } else { + spi_wait_sync(spi_reg_cfg, SERCOM_SPIS_SYNCBUSY_CTRLB_Msk); + /* Clear the RXEN bit field and enable Receiver */ + spi_reg_cfg->regs->SPIS.SERCOM_CTRLB = + (spi_reg_cfg->regs->SPIS.SERCOM_CTRLB & ~SERCOM_SPIS_CTRLB_RXEN_Msk) | + SERCOM_SPIS_CTRLB_RXEN_Msk; + spi_wait_sync(spi_reg_cfg, SERCOM_SPIS_SYNCBUSY_CTRLB_Msk); + } +} + +/*Set the 8 BIT Character Size in SPI peripheral*/ +static void spi_8bit_ch_size(const struct mchp_spi_reg_config *spi_reg_cfg, spi_operation_t op) +{ + if (SPI_OP_MODE_GET(op) == SPI_OP_MODE_MASTER) { + /* Clear the CHSIZE bit field and set character size to 8-bit */ + spi_reg_cfg->regs->SPIM.SERCOM_CTRLB = + (spi_reg_cfg->regs->SPIM.SERCOM_CTRLB & ~SERCOM_SPIM_CTRLB_CHSIZE_Msk) | + SERCOM_SPIM_CTRLB_CHSIZE_8_BIT; + } else { + /* Clear the CHSIZE bit field and set character size to 8-bit */ + spi_reg_cfg->regs->SPIS.SERCOM_CTRLB = + (spi_reg_cfg->regs->SPIS.SERCOM_CTRLB & ~SERCOM_SPIS_CTRLB_CHSIZE_Msk) | + SERCOM_SPIS_CTRLB_CHSIZE_8_BIT; + } +} + +/*Set the BAUD Rate value for SPI peripheral*/ +static void spi_set_baudrate(const struct mchp_spi_reg_config *spi_reg_cfg, + const struct spi_config *config, uint32_t clk_freq_hz) +{ + uint32_t divisor = 2U * config->frequency; + + /* Use the requested or next highest possible frequency */ + uint32_t baud_value = (clk_freq_hz / divisor) - 1; + + if ((clk_freq_hz % divisor) >= (divisor / 2U)) { + /* Round up the baud_value to ensures SPI clock is as close as possible to + * the requested frequency + */ + baud_value += 1U; + } + + baud_value = CLAMP(baud_value, 0, UINT8_MAX); + + if (SPI_OP_MODE_GET(config->operation) == SPI_OP_MODE_MASTER) { + spi_reg_cfg->regs->SPIM.SERCOM_BAUD = baud_value; + } else { + spi_reg_cfg->regs->SPIS.SERCOM_BAUD = baud_value; + } +} + +/*Set the Inter character dpacing*/ +static inline void spi_set_icspace(const struct mchp_spi_reg_config *spi_reg_cfg) +{ + spi_reg_cfg->regs->SPIM.SERCOM_CTRLC |= + SERCOM_SPIM_CTRLC_ICSPACE(CONFIG_SPI_MCHP_INTER_CHARACTER_SPACE); +} + +/*Write Data into DATA register*/ +static inline void spi_write_data(const struct mchp_spi_reg_config *spi_reg_cfg, uint8_t data) +{ + spi_reg_cfg->regs->SPIM.SERCOM_DATA = data; +} + +/*Read Data from the SPI MASTER DATA register*/ +static inline uint8_t spi_read_data(const struct mchp_spi_reg_config *spi_reg_cfg) +{ + return (uint8_t)spi_reg_cfg->regs->SPIM.SERCOM_DATA; +} + +/*Read Data from the SPI SLAVE DATA register*/ +static inline uint8_t spi_slave_read_data(const struct mchp_spi_reg_config *spi_reg_cfg) +{ + return (uint8_t)spi_reg_cfg->regs->SPIS.SERCOM_DATA; +} + +/*Return true if receive complete flag is set*/ +static inline bool spi_is_rx_comp(const struct mchp_spi_reg_config *spi_reg_cfg) +{ + return (spi_reg_cfg->regs->SPIM.SERCOM_INTFLAG & SERCOM_SPIM_INTFLAG_RXC_Msk) == + SERCOM_SPIM_INTFLAG_RXC_Msk; +} + +/*Return true if transmit complete flag is set*/ +static inline bool spi_is_tx_comp(const struct mchp_spi_reg_config *spi_reg_cfg) +{ + return ((spi_reg_cfg->regs->SPIM.SERCOM_INTFLAG & SERCOM_SPIM_INTFLAG_TXC_Msk) == + SERCOM_SPIM_INTFLAG_TXC_Msk); +} + +/*Clear the DATA register*/ +static inline void spi_clr_data(const struct mchp_spi_reg_config *spi_reg_cfg) +{ + /*Clear the DATA register until the RXC flag is cleared*/ + if (WAIT_FOR(((spi_reg_cfg->regs->SPIM.SERCOM_INTFLAG & SERCOM_SPIM_INTFLAG_RXC_Msk) == 0), + TIMEOUT_VALUE_US, + ((void)spi_reg_cfg->regs->SPIM.SERCOM_DATA, k_busy_wait(DELAY_US))) == false) { + LOG_ERR("Timeout while clearing RXC"); + } +} + +/*Return true if data register empty flag is set*/ +static inline bool spi_is_data_empty(const struct mchp_spi_reg_config *spi_reg_cfg) +{ + return (spi_reg_cfg->regs->SPIM.SERCOM_INTFLAG & SERCOM_SPIM_INTFLAG_DRE_Msk) == + SERCOM_SPIM_INTFLAG_DRE_Msk; +} + +#if defined(CONFIG_SPI_MCHP_INTERRUPT_DRIVEN) || (CONFIG_SPI_MCHP_INTERRUPT_DRIVEN_ASYNC) +/*Enable the Receive Complete Interrupt*/ +static void spi_enable_rxc_interrupt(const struct mchp_spi_reg_config *spi_reg_cfg, + spi_operation_t op) +{ + if (SPI_OP_MODE_GET(op) == SPI_OP_MODE_MASTER) { + spi_reg_cfg->regs->SPIM.SERCOM_INTENSET = SERCOM_SPIM_INTENSET_RXC_Msk; + } else { + spi_reg_cfg->regs->SPIS.SERCOM_INTENSET = SERCOM_SPIS_INTENSET_RXC_Msk; + } +} +#endif /* CONFIG_SPI_MCHP_INTERRUPT_DRIVEN || CONFIG_SPI_MCHP_INTERRUPT_DRIVEN_ASYNC */ + +/*Enable the Transmit Complete Interrupt*/ +static inline void spi_enable_txc_interrupt(const struct mchp_spi_reg_config *spi_reg_cfg) +{ + spi_reg_cfg->regs->SPIM.SERCOM_INTENSET = SERCOM_SPIM_INTENSET_TXC_Msk; +} + +/*Enable the Data Register Empty Interrupt*/ +static inline void spi_enable_data_empty_interrupt(const struct mchp_spi_reg_config *spi_reg_cfg) +{ + spi_reg_cfg->regs->SPIM.SERCOM_INTENSET = SERCOM_SPIM_INTENSET_DRE_Msk; +} + +/*Disable the Receive Complete Interrupt*/ +static inline void spi_disable_rxc_interrupt(const struct mchp_spi_reg_config *spi_reg_cfg) +{ + spi_reg_cfg->regs->SPIM.SERCOM_INTENCLR = SERCOM_SPIM_INTENCLR_RXC_Msk; +} + +/*Disable the Transmit Complete Interrupt*/ +static inline void spi_disable_txc_interrupt(const struct mchp_spi_reg_config *spi_reg_cfg) +{ + spi_reg_cfg->regs->SPIM.SERCOM_INTENCLR = SERCOM_SPIM_INTENCLR_TXC_Msk; +} + +/*Disable the Data Register Empty Interrupt*/ +static inline void spi_disable_data_empty_interrupt(const struct mchp_spi_reg_config *spi_reg_cfg) +{ + spi_reg_cfg->regs->SPIM.SERCOM_INTENCLR = SERCOM_SPIM_INTENCLR_DRE_Msk; +} + +/* Enable the preload slave data*/ +static inline void spi_slave_preload_enable(const struct mchp_spi_reg_config *spi_reg_cfg) +{ + spi_reg_cfg->regs->SPIS.SERCOM_CTRLB = + (spi_reg_cfg->regs->SPIS.SERCOM_CTRLB & ~SERCOM_SPIS_CTRLB_PLOADEN_Msk) | + SERCOM_SPIS_CTRLB_PLOADEN_Msk; +} + +/* Enable the slave select detection*/ +static inline void spi_slave_select_low_enable(const struct mchp_spi_reg_config *spi_reg_cfg) +{ + spi_reg_cfg->regs->SPIS.SERCOM_CTRLB = + (spi_reg_cfg->regs->SPIS.SERCOM_CTRLB & ~SERCOM_SPIS_CTRLB_SSDE_Msk) | + SERCOM_SPIS_CTRLB_SSDE_Msk; +} + +/* Enable the Immediate buffer overflow*/ +static inline void spi_immediate_buf_overflow(const struct mchp_spi_reg_config *spi_reg_cfg) +{ + spi_reg_cfg->regs->SPIS.SERCOM_CTRLA = + (spi_reg_cfg->regs->SPIS.SERCOM_CTRLA & ~SERCOM_SPIS_CTRLA_IBON_Msk) | + SERCOM_SPIS_CTRLA_IBON_Msk; +} + +/* Enable slave select line interrupt */ +static inline void spi_slave_select_line_enable(const struct mchp_spi_reg_config *spi_reg_cfg) +{ + spi_reg_cfg->regs->SPIS.SERCOM_INTENSET = + (spi_reg_cfg->regs->SPIS.SERCOM_INTENSET & ~SERCOM_SPIS_INTENSET_SSL_Msk) | + SERCOM_SPIS_INTENSET_SSL_Msk; +} + +/* Return the slave select line status*/ +static inline bool spi_slave_select_line(const struct mchp_spi_reg_config *spi_reg_cfg) +{ + return ((spi_reg_cfg->regs->SPIS.SERCOM_INTFLAG & SERCOM_SPIS_INTFLAG_SSL_Msk) == + SERCOM_SPIS_INTFLAG_SSL_Msk); +} + +/* Clear the slave select line interrupt */ +static inline void spi_slave_clr_slave_select_line(const struct mchp_spi_reg_config *spi_reg_cfg) +{ + spi_reg_cfg->regs->SPIS.SERCOM_INTFLAG = SERCOM_SPIS_INTFLAG_SSL_Msk; +} + +/* Clear buffer overflow flag */ +static inline void spi_slave_clr_buf_overflow(const struct mchp_spi_reg_config *spi_reg_cfg) +{ + spi_reg_cfg->regs->SPIS.SERCOM_STATUS = SERCOM_SPIS_STATUS_BUFOVF_Msk; +} + +/* Set the Hardware slave select*/ +static void spi_slave_select_enable(const struct mchp_spi_reg_config *spi_reg_cfg) +{ + spi_wait_sync(spi_reg_cfg, SERCOM_SPIM_SYNCBUSY_CTRLB_Msk); + + /* Clear the MSSEN bit field and enable Master Slave Select */ + spi_reg_cfg->regs->SPIM.SERCOM_CTRLB = + (spi_reg_cfg->regs->SPIM.SERCOM_CTRLB & ~SERCOM_SPIM_CTRLB_MSSEN_Msk) | + SERCOM_SPIM_CTRLB_MSSEN_Msk; + spi_wait_sync(spi_reg_cfg, SERCOM_SPIM_SYNCBUSY_CTRLB_Msk); +} + +/* Enable the Transmit Complete Interrupt */ +static inline void spi_slave_enable_txc_interrupt(const struct mchp_spi_reg_config *spi_reg_cfg) +{ + spi_reg_cfg->regs->SPIS.SERCOM_INTENSET = SERCOM_SPIS_INTENSET_TXC_Msk; +} + +/* Clear the DATA register */ +static inline void spi_slave_clr_data(const struct mchp_spi_reg_config *spi_reg_cfg) +{ + if (WAIT_FOR(((spi_reg_cfg->regs->SPIS.SERCOM_INTFLAG & SERCOM_SPIS_INTFLAG_RXC_Msk) == 0), + TIMEOUT_VALUE_US, + ((void)spi_reg_cfg->regs->SPIM.SERCOM_DATA, k_busy_wait(DELAY_US))) == false) { + LOG_ERR("Timeout while clearing RXC"); + } +} + +/*Clear the Error Interrupt Flag */ +static inline void spi_slave_clr_error_int_flag(const struct mchp_spi_reg_config *spi_reg_cfg) +{ + spi_reg_cfg->regs->SPIS.SERCOM_INTFLAG = (uint8_t)SERCOM_SPIS_INTFLAG_ERROR_Msk; +} + +/*Return true if receive complete flag is set*/ +static inline bool spi_slave_is_rx_comp(const struct mchp_spi_reg_config *spi_reg_cfg) +{ + return (spi_reg_cfg->regs->SPIS.SERCOM_INTFLAG & SERCOM_SPIS_INTFLAG_RXC_Msk) == + SERCOM_SPIS_INTFLAG_RXC_Msk; +} + +/*Return true if data register empty flag is set*/ +static inline bool spi_slave_is_data_empty(const struct mchp_spi_reg_config *spi_reg_cfg) +{ + return (spi_reg_cfg->regs->SPIS.SERCOM_INTFLAG & SERCOM_SPIS_INTFLAG_DRE_Msk) == + SERCOM_SPIS_INTFLAG_DRE_Msk; +} + +/*Return true if transmit complete flag is set*/ +static inline bool spi_slave_is_tx_comp(const struct mchp_spi_reg_config *spi_reg_cfg) +{ + return ((spi_reg_cfg->regs->SPIS.SERCOM_INTFLAG & SERCOM_SPIS_INTFLAG_TXC_Msk) == + SERCOM_SPIS_INTFLAG_TXC_Msk); +} + +/*Write Data into DATA register*/ +static inline void spi_slave_write_data(const struct mchp_spi_reg_config *spi_reg_cfg, uint8_t data) +{ + spi_reg_cfg->regs->SPIS.SERCOM_DATA = data; +} + +/*Disable DRE interrupt*/ +static inline void spi_slave_disable_dre_int(const struct mchp_spi_reg_config *spi_reg_cfg) +{ + spi_reg_cfg->regs->SPIS.SERCOM_INTENCLR = (uint8_t)SERCOM_SPIS_INTENCLR_DRE_Msk; +} + +/*Clear transmit complete flag is set*/ +static inline void spi_slave_clr_tx_comp_flag(const struct mchp_spi_reg_config *spi_reg_cfg) +{ + spi_reg_cfg->regs->SPIS.SERCOM_INTFLAG = SERCOM_SPIS_INTFLAG_TXC_Msk; +} + +/*Disable all SPI Interrupt*/ +static inline void spi_slave_disable_interrupts(const struct mchp_spi_reg_config *spi_reg_cfg) +{ + spi_reg_cfg->regs->SPIS.SERCOM_INTENCLR = SERCOM_SPIS_INTENCLR_Msk; +} + +/*Clear all SPI Interrupt*/ +static inline void spi_slave_clr_interrupts(const struct mchp_spi_reg_config *spi_reg_cfg) +{ + spi_reg_cfg->regs->SPIS.SERCOM_INTFLAG = SERCOM_SPIS_INTFLAG_Msk; +} + +/*Enable the Data Register Empty Interrupt*/ +static inline void +spi_slave_enable_data_empty_interrupt(const struct mchp_spi_reg_config *spi_reg_cfg) +{ + spi_reg_cfg->regs->SPIS.SERCOM_INTENSET = SERCOM_SPIS_INTENSET_DRE_Msk; +} + +static int spi_configure_pinout(const struct mchp_spi_reg_config *spi_reg_cfg, + const struct spi_config *config) +{ + if ((config->operation & SPI_MODE_LOOP) != 0U) { + if (SPI_OP_MODE_GET(config->operation) == SPI_OP_MODE_SLAVE) { + LOG_ERR("For slave Loopback mode is not supported"); + + return -ENOTSUP; + } + spi_mode_loopback(spi_reg_cfg); + } else { + if (SPI_OP_MODE_GET(config->operation) != SPI_OP_MODE_MASTER) { + spi_slave_config_pinout(spi_reg_cfg); + } else { + spi_master_config_pinout(spi_reg_cfg); + } + } + + return 0; +} + +static void spi_configure_cpol(const struct mchp_spi_reg_config *spi_reg_cfg, + const struct spi_config *config) +{ + if ((config->operation & SPI_MODE_CPOL) != 0U) { + spi_cpol_idle_high(spi_reg_cfg, config->operation); + } else { + spi_cpol_idle_low(spi_reg_cfg, config->operation); + } +} + +static void spi_configure_cpha(const struct mchp_spi_reg_config *spi_reg_cfg, + const struct spi_config *config) +{ + if ((config->operation & SPI_MODE_CPHA) != 0U) { + spi_cpha_trail_edge(spi_reg_cfg, config->operation); + } else { + spi_cpha_lead_edge(spi_reg_cfg, config->operation); + } +} + +static void spi_configure_bit_order(const struct mchp_spi_reg_config *spi_reg_cfg, + const struct spi_config *config) +{ + if ((config->operation & SPI_TRANSFER_LSB) != 0U) { + spi_lsb_first(spi_reg_cfg, config->operation); + } else { + spi_msb_first(spi_reg_cfg, config->operation); + } +} + +static int spi_mchp_configure(const struct device *dev, const struct spi_config *config) +{ + const struct spi_mchp_dev_config *cfg = dev->config; + const struct mchp_spi_reg_config *spi_reg_cfg = &cfg->reg_cfg; + struct spi_mchp_dev_data *const data = dev->data; + int retval; + uint32_t clock_rate; + bool has_cs = false; + + spi_disable(spi_reg_cfg); + + if (spi_context_configured(&data->ctx, config) == true) { + spi_enable(spi_reg_cfg, config->operation); + + return 0; + } + + /* Select the Character Size */ + if (SPI_WORD_SIZE_GET(config->operation) != SUPPORTED_SPI_WORD_SIZE) { + LOG_ERR("Unsupported SPI word size: %d bits. Only 8-bit transfers are supported.", + SPI_WORD_SIZE_GET(config->operation)); + + return -ENOTSUP; + } + spi_8bit_ch_size(spi_reg_cfg, config->operation); + + spi_rx_enable(spi_reg_cfg, config->operation); + +#if CONFIG_SPI_SLAVE + if (SPI_OP_MODE_GET(config->operation) == SPI_OP_MODE_SLAVE) { + + spi_slave_preload_enable(spi_reg_cfg); + + spi_slave_select_low_enable(spi_reg_cfg); + + spi_immediate_buf_overflow(spi_reg_cfg); + + spi_slave_mode(spi_reg_cfg); + } +#endif /* CONFIG_SPI_SLAVE */ + + if (SPI_OP_MODE_GET(config->operation) == SPI_OP_MODE_MASTER) { + + spi_set_icspace(spi_reg_cfg); + + clock_control_get_rate(cfg->spi_clock.clock_dev, cfg->spi_clock.gclk_sys, + &clock_rate); + + if ((config->frequency != 0) && (clock_rate >= (2 * config->frequency))) { + spi_set_baudrate(spi_reg_cfg, config, clock_rate); + } else { + return -ENOTSUP; + } + + spi_master_mode(spi_reg_cfg); + +#if !DT_SPI_CTX_HAS_NO_CS_GPIOS + has_cs = (data->ctx.num_cs_gpios != 0); +#endif + + if (has_cs) { + retval = spi_context_cs_configure_all(&data->ctx); + if (retval < 0) { + return retval; + } + } else if (cfg->pcfg->states->pin_cnt == SPI_PIN_CNT) { + spi_slave_select_enable(spi_reg_cfg); + } else { + /* Handled by user */ + } + } + + if ((config->operation & SPI_LINES_MASK) != SPI_LINES_SINGLE) { + LOG_ERR("Only single line mode is supported"); + + return -ENOTSUP; + } + + /*Set the Data out and Pin out Configuration*/ + retval = spi_configure_pinout(spi_reg_cfg, config); + if (retval < 0) { + return retval; + } + + spi_configure_cpol(spi_reg_cfg, config); + spi_configure_cpha(spi_reg_cfg, config); + spi_configure_bit_order(spi_reg_cfg, config); + + if ((config->operation & SPI_HALF_DUPLEX) != 0U) { + retval = spi_half_duplex_mode(spi_reg_cfg); + if (retval != 0) { + return retval; + } + } else { + retval = spi_full_duplex_mode(spi_reg_cfg); + if (retval != 0) { + return -ENOTSUP; + } + } + + spi_enable(spi_reg_cfg, config->operation); + +#if defined(CONFIG_SPI_ASYNC) || defined(CONFIG_SPI_MCHP_INTERRUPT_DRIVEN) + cfg->irq_config_func(dev); +#endif /* CONFIG_SPI_ASYNC || CONFIG_SPI_MCHP_INTERRUPT_DRIVEN */ + +#if CONFIG_SPI_MCHP_DMA_DRIVEN_ASYNC + if (device_is_ready(cfg->spi_dma.dma_dev) != true) { + return -ENODEV; + } + data->dev = dev; +#endif /* CONFIG_SPI_MCHP_DMA_DRIVEN_ASYNC */ + + data->ctx.config = config; + + return 0; +} + +static int spi_mchp_check_buf_len(const struct spi_buf_set *buf_set) +{ + if ((buf_set == NULL) || (buf_set->buffers == NULL)) { + return 0; + } + + for (size_t i = 0; i < buf_set->count; i++) { + if (buf_set->buffers[i].len > SPI_MCHP_MAX_XFER_SIZE) { + LOG_ERR("SPI buffer length (%u) exceeds max allowed (%u)", + buf_set->buffers[i].len, SPI_MCHP_MAX_XFER_SIZE); + + return -EINVAL; + } + } + + return 0; +} + +#ifndef CONFIG_SPI_MCHP_INTERRUPT_DRIVEN +static bool spi_mchp_transfer_in_progress(struct spi_mchp_dev_data *data) +{ + return spi_context_tx_on(&data->ctx) || spi_context_rx_on(&data->ctx); +} + +static int spi_mchp_finish(const struct mchp_spi_reg_config *spi_reg_cfg) +{ + /* Wait until transmit complete */ + if (WAIT_FOR((spi_is_tx_comp(spi_reg_cfg) == true), TIMEOUT_VALUE_US, + k_busy_wait(DELAY_US)) == false) { + + LOG_ERR("SPI TX complete timeout"); + + return -ETIMEDOUT; + } + spi_clr_data(spi_reg_cfg); + + return 0; +} + +static int spi_mchp_poll_in(const struct mchp_spi_reg_config *spi_reg_cfg, + struct spi_mchp_dev_data *data) +{ + uint8_t tx_data; + uint8_t rx_data; + + /* Check if there is data to transmit */ + if (spi_context_tx_buf_on(&data->ctx) == true) { + tx_data = *data->ctx.tx_buf; + } else { + tx_data = 0U; + } + + /* wait until the SPI data is empty */ + if (WAIT_FOR((spi_is_data_empty(spi_reg_cfg) == true), TIMEOUT_VALUE_US, + k_busy_wait(DELAY_US)) == false) { + LOG_ERR("SPI data empty timeout"); + + return -ETIMEDOUT; + } + + spi_write_data(spi_reg_cfg, tx_data); + + spi_context_update_tx(&data->ctx, 1, 1); + + /* Wait for the reception to complete */ + while (spi_is_rx_comp(spi_reg_cfg) != true) { + /* Wait for completion */ + }; + + rx_data = spi_read_data(spi_reg_cfg); + + /* Check if there is a buffer to store received data */ + if (spi_context_rx_buf_on(&data->ctx) == true) { + *data->ctx.rx_buf = rx_data; + } + + spi_context_update_rx(&data->ctx, 1, 1); + + return 0; +} + +static int spi_mchp_fast_tx(const struct mchp_spi_reg_config *spi_reg_cfg, + const struct spi_buf *tx_buf) +{ + const uint8_t *tx_data_ptr = tx_buf->buf; + uint8_t tx_data; + size_t len = tx_buf->len; + uint8_t dummy_data = 0U; + int retval; + + /* Transmit each byte in the buffer */ + while (len != 0) { + if (tx_buf->buf != NULL) { + tx_data = *tx_data_ptr++; + } else { + tx_data = dummy_data; + } + + /* Wait until the tramist is complete */ + if (WAIT_FOR((spi_is_data_empty(spi_reg_cfg) == true), TIMEOUT_VALUE_US, + k_busy_wait(DELAY_US)) == false) { + LOG_ERR("SPI data empty timeout"); + + return -ETIMEDOUT; + } + + spi_write_data(spi_reg_cfg, tx_data); + len--; + } + + retval = spi_mchp_finish(spi_reg_cfg); + + return retval; +} + +static int spi_mchp_fast_rx(const struct mchp_spi_reg_config *spi_reg_cfg, + const struct spi_buf *rx_buf) +{ + uint8_t *rx_data_ptr = rx_buf->buf; + size_t len = rx_buf->len; + uint8_t dummy_data = 0U; + int retval; + + if (len == 0) { + return -EINVAL; + } + + while (len != 0) { + + /* Write a dummy data to receive data */ + spi_write_data(spi_reg_cfg, dummy_data); + len--; + + /* Wait for completion, and read */ + while (spi_is_rx_comp(spi_reg_cfg) != true) { + /* Wait for completion */ + }; + + if (rx_buf->buf != NULL) { + *rx_data_ptr = spi_read_data(spi_reg_cfg); + rx_data_ptr++; + } else { + (void)spi_read_data(spi_reg_cfg); + } + } + + retval = spi_mchp_finish(spi_reg_cfg); + + return retval; +} + +static int spi_mchp_fast_txrx(const struct mchp_spi_reg_config *spi_reg_cfg, + const struct spi_buf *tx_buf, const struct spi_buf *rx_buf) +{ + const uint8_t *tx_data_ptr = tx_buf->buf; + uint8_t *rx_data_ptr = rx_buf->buf; + size_t len = rx_buf->len; + uint8_t dummy_data = 0U; + int retval; + + if (len == 0) { + return -EINVAL; + } + + while (len > 0) { + /* Send the next byte */ + if (tx_data_ptr != NULL) { + spi_write_data(spi_reg_cfg, *tx_data_ptr); + tx_data_ptr++; + } else { + spi_write_data(spi_reg_cfg, dummy_data); + } + + /* Wait for completion */ + while (spi_is_rx_comp(spi_reg_cfg) != true) { + /* Wait for completion */ + }; + + /* Read received data */ + if (rx_data_ptr != NULL) { + *rx_data_ptr = spi_read_data(spi_reg_cfg); + rx_data_ptr++; + } else { + (void)spi_read_data(spi_reg_cfg); + } + len--; + } + + retval = spi_mchp_finish(spi_reg_cfg); + + return retval; +} + +static int spi_mchp_fast_transceive(const struct device *dev, const struct spi_config *config, + const struct spi_buf_set *tx_bufs, + const struct spi_buf_set *rx_bufs) +{ + const struct spi_mchp_dev_config *cfg = dev->config; + const struct mchp_spi_reg_config *spi_reg_cfg = &cfg->reg_cfg; + size_t tx_count = 0; + size_t rx_count = 0; + const struct spi_buf *tx_data_ptr = NULL; + const struct spi_buf *rx_data_ptr = NULL; + int retval; + + if (tx_bufs != NULL) { + tx_data_ptr = tx_bufs->buffers; + tx_count = tx_bufs->count; + } + + if (rx_bufs != NULL) { + rx_data_ptr = rx_bufs->buffers; + rx_count = rx_bufs->count; + } else { + rx_data_ptr = NULL; + } + + while ((tx_count != 0) && (rx_count != 0)) { + /* This function is called only if the count is equal*/ + retval = spi_mchp_fast_txrx(spi_reg_cfg, tx_data_ptr, rx_data_ptr); + + tx_data_ptr++; + tx_count--; + rx_data_ptr++; + rx_count--; + } + + /* Handle remaining transmit buffers */ + while (tx_count > 0) { + retval = spi_mchp_fast_tx(spi_reg_cfg, tx_data_ptr); + tx_data_ptr++; + tx_count--; + } + + /* Handle remaining receive buffers */ + while (rx_count > 0) { + retval = spi_mchp_fast_rx(spi_reg_cfg, rx_data_ptr); + rx_data_ptr++; + rx_count--; + } + + return retval; +} + +static bool spi_mchp_is_same_len(const struct spi_buf_set *tx_bufs, + const struct spi_buf_set *rx_bufs) +{ + const struct spi_buf *tx_data_ptr = NULL; + const struct spi_buf *rx_data_ptr = NULL; + size_t tx_count = 0; + size_t rx_count = 0; + + if (tx_bufs != NULL) { + tx_data_ptr = tx_bufs->buffers; + tx_count = tx_bufs->count; + } + + if (rx_bufs != NULL) { + rx_data_ptr = rx_bufs->buffers; + rx_count = rx_bufs->count; + } + + while (tx_count != 0 && rx_count != 0) { + /* Compare the length of each corresponding TX and RX buffer */ + if (tx_data_ptr->len != rx_data_ptr->len) { + return false; + } + + tx_data_ptr++; + tx_count--; + rx_data_ptr++; + rx_count--; + } + + return true; +} +#endif /* CONFIG_SPI_MCHP_INTERRUPT_DRIVEN*/ + +#if defined(CONFIG_SPI_MCHP_INTERRUPT_DRIVEN) || (CONFIG_SPI_MCHP_INTERRUPT_DRIVEN_ASYNC) +static int spi_mchp_transceive_interrupt(const struct device *dev, const struct spi_config *config, + const struct spi_buf_set *tx_bufs, + const struct spi_buf_set *rx_bufs) +{ + const struct spi_mchp_dev_config *cfg = dev->config; + const struct mchp_spi_reg_config *spi_reg_cfg = &cfg->reg_cfg; + struct spi_mchp_dev_data *const data = dev->data; + uint8_t tx_data; + + /* Setup SPI buffers */ + spi_context_buffers_setup(&data->ctx, tx_bufs, rx_bufs, 1); + + /* Prepare first byte for transmission */ + if (spi_context_tx_buf_on(&data->ctx) == true) { + tx_data = *data->ctx.tx_buf; + } else { + tx_data = 0U; + } + + spi_clr_data(spi_reg_cfg); + + /* Get the dummysize */ + if ((data->ctx.rx_len) > (data->ctx.tx_len)) { + data->dummysize = (data->ctx.rx_len) - (data->ctx.tx_len); + } + + /* Write first data byte to the SPI data register */ + spi_context_update_tx(&data->ctx, 1, 1); + spi_write_data(spi_reg_cfg, tx_data); + + /* Enable SPI interrupts for RX, TX completion, and data empty events */ + if (data->ctx.rx_len > 0) { + spi_enable_rxc_interrupt(spi_reg_cfg, config->operation); + } else { + spi_enable_data_empty_interrupt(spi_reg_cfg); + } + +#if defined(CONFIG_SPI_MCHP_INTERRUPT_DRIVEN) + spi_context_wait_for_completion(&data->ctx); +#endif /* CONFIG_SPI_MCHP_INTERRUPT_DRIVEN */ + + return 0; +} + +#if CONFIG_SPI_SLAVE +static void spi_mchp_slave_write(const struct device *dev) +{ + const struct spi_mchp_dev_config *cfg = dev->config; + const struct mchp_spi_reg_config *spi_reg_cfg = &cfg->reg_cfg; + uint8_t tx_data; + uint8_t dummy_data = 0U; + struct spi_mchp_dev_data *const data = dev->data; + bool write_ready; + + /* Prepare initial bytes for transmission */ + if (spi_context_tx_buf_on(&data->ctx) == true) { + write_ready = spi_context_tx_buf_on(&data->ctx); + write_ready = write_ready && (spi_slave_is_data_empty(spi_reg_cfg) == true); + while (write_ready == true) { + tx_data = *data->ctx.tx_buf; + spi_slave_write_data(spi_reg_cfg, tx_data); + + /* Write data byte to the SPI data register */ + spi_context_update_tx(&data->ctx, 1, 1); + write_ready = spi_context_tx_buf_on(&data->ctx); + write_ready = write_ready && (spi_slave_is_data_empty(spi_reg_cfg) == true); + } + } else { + write_ready = (spi_slave_is_data_empty(spi_reg_cfg)); + while (write_ready == true) { + tx_data = dummy_data; + spi_slave_write_data(spi_reg_cfg, tx_data); + write_ready = (spi_slave_is_data_empty(spi_reg_cfg)); + } + } + spi_slave_enable_data_empty_interrupt(spi_reg_cfg); +} + +static int spi_mchp_slave_transceive_interrupt(const struct device *dev, + const struct spi_config *config, + const struct spi_buf_set *tx_bufs, + const struct spi_buf_set *rx_bufs) +{ + const struct spi_mchp_dev_config *cfg = dev->config; + const struct mchp_spi_reg_config *spi_reg_cfg = &cfg->reg_cfg; + struct spi_mchp_dev_data *const data = dev->data; + int ret = 0; + + spi_context_buffers_setup(&data->ctx, tx_bufs, rx_bufs, 1); + + if (spi_context_tx_on(&data->ctx) == true) { + /* Prepare for transmission */ + spi_mchp_slave_write(dev); + } + + spi_enable_rxc_interrupt(spi_reg_cfg, config->operation); + + spi_slave_select_line_enable(spi_reg_cfg); + +#if defined(CONFIG_SPI_MCHP_INTERRUPT_DRIVEN) + ret = spi_context_wait_for_completion(&data->ctx); +#endif /* CONFIG_SPI_MCHP_INTERRUPT_DRIVEN */ + + return ret; +} + +#endif /* CONFIG_SPI_SLAVE */ +#endif /* CONFIG_SPI_MCHP_INTERRUPT_DRIVEN || (CONFIG_SPI_MCHP_INTERRUPT_DRIVEN_ASYNC */ + +static int spi_mchp_transceive_sync(const struct device *dev, const struct spi_config *config, + const struct spi_buf_set *tx_bufs, + const struct spi_buf_set *rx_bufs) +{ + const struct spi_mchp_dev_config *cfg = dev->config; + const struct mchp_spi_reg_config *spi_reg_cfg = &cfg->reg_cfg; + struct spi_mchp_dev_data *data = dev->data; + int ret; + + ret = spi_mchp_check_buf_len(tx_bufs); + if (ret < 0) { + return ret; + } + + ret = spi_mchp_check_buf_len(rx_bufs); + if (ret < 0) { + return ret; + } + + ARG_UNUSED(spi_reg_cfg); + + spi_context_lock(&data->ctx, false, NULL, NULL, config); + + ret = spi_mchp_configure(dev, config); + if (ret != 0) { + spi_context_release(&data->ctx, ret); + + return ret; + } + + if (SPI_OP_MODE_GET(config->operation) == SPI_OP_MODE_MASTER) { + spi_context_cs_control(&data->ctx, true); + } + +#if CONFIG_SPI_MCHP_INTERRUPT_DRIVEN +#if CONFIG_SPI_SLAVE + if (SPI_OP_MODE_GET(config->operation) == SPI_OP_MODE_SLAVE) { + ret = spi_mchp_slave_transceive_interrupt(dev, config, tx_bufs, rx_bufs); + } +#endif /* CONFIG_SPI_SLAVE */ + if (SPI_OP_MODE_GET(config->operation) == SPI_OP_MODE_MASTER) { + ret = spi_mchp_transceive_interrupt(dev, config, tx_bufs, rx_bufs); + } +#else + /* Use optimized fast path if TX and RX buffer lengths match */ + if (SPI_OP_MODE_GET(config->operation) == SPI_OP_MODE_MASTER) { + if (spi_mchp_is_same_len(tx_bufs, rx_bufs) == true) { + spi_mchp_fast_transceive(dev, config, tx_bufs, rx_bufs); + } else { + /* Setup SPI buffers and process using polling */ + spi_context_buffers_setup(&data->ctx, tx_bufs, rx_bufs, 1); + + do { + ret = spi_mchp_poll_in(spi_reg_cfg, data); + } while (spi_mchp_transfer_in_progress(data) && ret == 0); + } + } + +#if CONFIG_SPI_SLAVE + if (SPI_OP_MODE_GET(config->operation) == SPI_OP_MODE_SLAVE) { + spi_context_release(&data->ctx, ret); + + return -ENOTSUP; + } +#endif /* CONFIG_SPI_SLAVE */ +#endif /* CONFIG_SPI_MCHP_INTERRUPT_DRIVEN */ + + if (SPI_OP_MODE_GET(config->operation) == SPI_OP_MODE_MASTER) { + spi_context_cs_control(&data->ctx, false); + } + + spi_context_release(&data->ctx, ret); + + return ret; +} + +#if CONFIG_SPI_ASYNC +#if CONFIG_SPI_MCHP_DMA_DRIVEN_ASYNC +static void spi_mchp_dma_rx_done(const struct device *dma_dev, void *arg, uint32_t id, + int error_code); + +static int spi_mchp_dma_tx_load(const struct device *dev, const uint8_t *buf, size_t len) +{ + const struct spi_mchp_dev_config *cfg = dev->config; + const struct mchp_spi_reg_config *spi_reg_cfg = &cfg->reg_cfg; + + struct dma_config dma_cfg = {0}; + struct dma_block_config dma_blk = {0}; + int retval; + + dma_cfg.channel_direction = PERIPHERAL_TO_MEMORY; + dma_cfg.source_data_size = 1; + dma_cfg.dest_data_size = 1; + dma_cfg.block_count = 1; + dma_cfg.head_block = &dma_blk; + dma_cfg.dma_slot = cfg->spi_dma.tx_dma_request; + + dma_blk.block_size = len; + + if (buf != NULL) { + dma_blk.source_address = (uint32_t)buf; + } else { + static const uint8_t dummy_data; + + dma_blk.source_address = (uint32_t)&dummy_data; + dma_blk.source_addr_adj = DMA_ADDR_ADJ_NO_CHANGE; + } + + dma_blk.dest_address = (uint32_t)&spi_reg_cfg->regs->SPIM.SERCOM_DATA; + dma_blk.dest_addr_adj = DMA_ADDR_ADJ_NO_CHANGE; + + retval = dma_config(cfg->spi_dma.dma_dev, cfg->spi_dma.tx_dma_channel, &dma_cfg); + + if (retval != 0) { + return retval; + } + + retval = dma_start(cfg->spi_dma.dma_dev, cfg->spi_dma.tx_dma_channel); + + return retval; +} + +static int spi_mchp_dma_rx_load(const struct device *dev, uint8_t *buf, size_t len) +{ + const struct spi_mchp_dev_config *cfg = dev->config; + const struct mchp_spi_reg_config *spi_reg_cfg = &cfg->reg_cfg; + struct spi_mchp_dev_data *data = dev->data; + + struct dma_config dma_cfg = {0}; + struct dma_block_config dma_blk = {0}; + int retval; + + dma_cfg.channel_direction = PERIPHERAL_TO_MEMORY; + dma_cfg.source_data_size = 1; + dma_cfg.dest_data_size = 1; + dma_cfg.user_data = data; + dma_cfg.dma_callback = spi_mchp_dma_rx_done; + dma_cfg.block_count = 1; + dma_cfg.head_block = &dma_blk; + dma_cfg.dma_slot = cfg->spi_dma.rx_dma_request; + + dma_blk.block_size = len; + + if (buf != NULL) { + dma_blk.dest_address = (uint32_t)buf; + } else { + /* Use a static dummy variable if no buffer is provided */ + static uint8_t dummy_data; + + dma_blk.dest_address = (uint32_t)&dummy_data; + dma_blk.dest_addr_adj = DMA_ADDR_ADJ_NO_CHANGE; + } + + dma_blk.source_address = (uint32_t)&spi_reg_cfg->regs->SPIM.SERCOM_DATA; + dma_blk.source_addr_adj = DMA_ADDR_ADJ_NO_CHANGE; + + retval = dma_config(cfg->spi_dma.dma_dev, cfg->spi_dma.rx_dma_channel, &dma_cfg); + if (retval != 0) { + return retval; + } + + retval = dma_start(cfg->spi_dma.dma_dev, cfg->spi_dma.rx_dma_channel); + + return retval; +} + +static bool spi_mchp_dma_select_segment(const struct device *dev) +{ + struct spi_mchp_dev_data *data = dev->data; + uint32_t segment_len; + + /* Pick the shorter buffer of ones that have an actual length */ + if (data->ctx.rx_len != 0) { + segment_len = data->ctx.rx_len; + if (data->ctx.tx_len != 0) { + segment_len = MIN(segment_len, data->ctx.tx_len); + } + } else { + segment_len = data->ctx.tx_len; + } + + if (segment_len == 0) { + return false; + } + + /* Ensure the segment length does not exceed the max allowed value + */ + segment_len = MIN(segment_len, 65535); + + data->dma_segment_len = segment_len; + + return true; +} + +static int spi_mchp_dma_setup_buffers(const struct device *dev) +{ + struct spi_mchp_dev_data *data = dev->data; + int retval; + + if (data->dma_segment_len == 0) { + return -EINVAL; + } + + /* Load receive buffer first to prepare for incoming data */ + if (data->ctx.rx_len != 0U) { + retval = spi_mchp_dma_rx_load(dev, data->ctx.rx_buf, data->dma_segment_len); + } else { + retval = spi_mchp_dma_rx_load(dev, NULL, data->dma_segment_len); + } + + if (retval != 0) { + return retval; + } + + /* Load transmit buffer, which starts SPI bus clocking */ + if (data->ctx.tx_len != 0U) { + retval = spi_mchp_dma_tx_load(dev, data->ctx.tx_buf, data->dma_segment_len); + } else { + retval = spi_mchp_dma_tx_load(dev, NULL, data->dma_segment_len); + } + + if (retval != 0) { + return retval; + } + + return 0; +} + +static void spi_mchp_dma_rx_done(const struct device *dma_dev, void *arg, uint32_t id, + int error_code) +{ + struct spi_mchp_dev_data *data = arg; + const struct device *dev = data->dev; + const struct spi_mchp_dev_config *cfg = dev->config; + int retval; + + ARG_UNUSED(id); + ARG_UNUSED(error_code); + + /* Update TX and RX context with the completed DMA segment */ + spi_context_update_tx(&data->ctx, 1, data->dma_segment_len); + spi_context_update_rx(&data->ctx, 1, data->dma_segment_len); + + /* Check if more segments need to be transferred */ + if (spi_mchp_dma_select_segment(dev) == false) { + if (spi_context_is_slave(&data->ctx) == false) { + spi_context_cs_control(&data->ctx, false); + } + /* Transmission complete */ + spi_context_complete(&data->ctx, dev, 0); + + return; + } + + /* Load the next DMA segment */ + retval = spi_mchp_dma_setup_buffers(dev); + if (retval != 0) { + /* Stop DMA and terminate the SPI transaction in case of failure */ + dma_stop(cfg->spi_dma.dma_dev, cfg->spi_dma.tx_dma_channel); + dma_stop(cfg->spi_dma.dma_dev, cfg->spi_dma.rx_dma_channel); + if (spi_context_is_slave(&data->ctx) == false) { + spi_context_cs_control(&data->ctx, false); + } + spi_context_complete(&data->ctx, dev, retval); + + return; + } +} +#endif /* CONFIG_SPI_MCHP_DMA_DRIVEN_ASYNC */ + +static int spi_mchp_transceive_async(const struct device *dev, const struct spi_config *config, + const struct spi_buf_set *tx_bufs, + const struct spi_buf_set *rx_bufs, spi_callback_t spi_callback, + void *userdata) +{ + const struct spi_mchp_dev_config *cfg = dev->config; + struct spi_mchp_dev_data *data = dev->data; + int retval; + + retval = spi_mchp_check_buf_len(tx_bufs); + if (retval < 0) { + return retval; + } + + retval = spi_mchp_check_buf_len(rx_bufs); + if (retval < 0) { + return retval; + } + + ARG_UNUSED(cfg); + +/* + * Transmit clocks the output, and we use receive to + * determine when the transmit is done, so we + * always need both TX and RX DMA channels. + */ +#if CONFIG_SPI_MCHP_DMA_DRIVEN_ASYNC + if (cfg->spi_dma.tx_dma_channel == 0xFF || cfg->spi_dma.rx_dma_channel == 0xFF) { + return -ENOTSUP; + } +#endif /* CONFIG_SPI_MCHP_DMA_DRIVEN_ASYNC */ + + spi_context_lock(&data->ctx, true, spi_callback, userdata, config); + + retval = spi_mchp_configure(dev, config); + if (retval != 0) { + spi_context_release(&data->ctx, retval); + + return retval; + } + + if (SPI_OP_MODE_GET(config->operation) == SPI_OP_MODE_MASTER) { + spi_context_cs_control(&data->ctx, true); + } + + spi_context_buffers_setup(&data->ctx, tx_bufs, rx_bufs, 1); + +/* Prepare and start DMA transfers */ +#if CONFIG_SPI_MCHP_DMA_DRIVEN_ASYNC + spi_mchp_dma_select_segment(dev); + retval = spi_mchp_dma_setup_buffers(dev); +#else + if (SPI_OP_MODE_GET(config->operation) == SPI_OP_MODE_MASTER) { + retval = spi_mchp_transceive_interrupt(dev, config, tx_bufs, rx_bufs); + } +#if CONFIG_SPI_SLAVE + if (SPI_OP_MODE_GET(config->operation) == SPI_OP_MODE_SLAVE) { + retval = spi_mchp_slave_transceive_interrupt(dev, config, tx_bufs, rx_bufs); + } +#endif /* CONFIG_SPI_SLAVE */ +#endif /* CONFIG_SPI_MCHP_DMA_DRIVEN_ASYNC */ + + if (retval != 0) { + /* Stop DMA transfers in case of failure */ +#if CONFIG_SPI_MCHP_DMA_DRIVEN_ASYNC + dma_stop(cfg->spi_dma.dma_dev, cfg->spi_dma.tx_dma_channel); + dma_stop(cfg->spi_dma.dma_dev, cfg->spi_dma.rx_dma_channel); +#endif /* CONFIG_SPI_MCHP_DMA_DRIVEN_ASYNC */ + + if (SPI_OP_MODE_GET(config->operation) == SPI_OP_MODE_MASTER) { + spi_context_cs_control(&data->ctx, false); + } + + spi_context_release(&data->ctx, retval); + } + + return retval; +} +#endif /* CONFIG_SPI_ASYNC */ + +static int spi_mchp_release(const struct device *dev, const struct spi_config *config) +{ + struct spi_mchp_dev_data *data = dev->data; + + spi_context_unlock_unconditionally(&data->ctx); + + return 0; +} + +#if defined(CONFIG_SPI_ASYNC) || defined(CONFIG_SPI_MCHP_INTERRUPT_DRIVEN) +#if (CONFIG_SPI_SLAVE) +static void spi_mchp_isr_slave(const struct device *dev) +{ + struct spi_mchp_dev_data *data = dev->data; + const struct spi_mchp_dev_config *cfg = dev->config; + const struct mchp_spi_reg_config *spi_reg_cfg = &cfg->reg_cfg; + uint8_t intFlag = spi_reg_cfg->regs->SPIS.SERCOM_INTFLAG; + static bool transaction_complete; + uint8_t tx_data = 0U; + uint8_t rx_data = 0U; + + /* Reset transaction_complete if there is data to send or receive */ + if ((spi_context_tx_buf_on(&data->ctx) == true) || + (spi_context_rx_buf_on(&data->ctx) == true)) { + transaction_complete = false; + } + + /* Check if data empty bit is set*/ + if (spi_slave_is_data_empty(spi_reg_cfg) == true) { + tx_data = *data->ctx.tx_buf; + if (spi_slave_is_tx_comp(spi_reg_cfg) == true) { + intFlag = (uint8_t)SERCOM_SPIS_INTFLAG_TXC_Msk; + } + spi_slave_write_data(spi_reg_cfg, tx_data); + if (spi_context_tx_on(&data->ctx) == true) { + spi_context_update_tx(&data->ctx, 1, 1); + } else { + /* Disable DRE interrupt. The last byte sent by the master will be + * shifted out automatically + */ + spi_slave_disable_dre_int(spi_reg_cfg); + } + } + + /* Check if slave select bit is set*/ + if (spi_slave_select_line(spi_reg_cfg) == true) { + spi_slave_clr_slave_select_line(spi_reg_cfg); + spi_slave_enable_txc_interrupt(spi_reg_cfg); + } + + /* Check if buffer overflow error bit is set*/ + if ((spi_reg_cfg->regs->SPIS.SERCOM_STATUS & SERCOM_SPIS_STATUS_BUFOVF_Msk) == + SERCOM_SPIS_STATUS_BUFOVF_Msk) { + spi_slave_clr_buf_overflow(spi_reg_cfg); + spi_slave_clr_data(spi_reg_cfg); + spi_slave_clr_error_int_flag(spi_reg_cfg); + } + + /* Check if data is available in the receive buffer */ + if (spi_slave_is_rx_comp(spi_reg_cfg) == true) { + rx_data = spi_slave_read_data(spi_reg_cfg); + if (spi_context_rx_buf_on(&data->ctx) == true) { + *data->ctx.rx_buf = rx_data; + spi_context_update_rx(&data->ctx, 1, 1); + } + } + + /* If TX complete, finish transaction if all done */ + if ((intFlag & SERCOM_SPIS_INTFLAG_TXC_Msk) == SERCOM_SPIS_INTFLAG_TXC_Msk) { + intFlag = 0; + spi_slave_clr_tx_comp_flag(spi_reg_cfg); + if ((spi_context_rx_on(&data->ctx) == false) && + (spi_context_tx_on(&data->ctx) == false)) { + spi_slave_disable_interrupts(spi_reg_cfg); + spi_slave_clr_interrupts(spi_reg_cfg); + /* Release the semaphore to unblock waiting threads */ + if (transaction_complete == false) { + spi_context_complete(&data->ctx, dev, 0); + transaction_complete = true; + } + } + } +} +#endif /* CONFIG_SPI_SLAVE */ + +static void spi_mchp_isr_master(const struct device *dev) +{ + struct spi_mchp_dev_data *data = dev->data; + const struct spi_mchp_dev_config *cfg = dev->config; + const struct mchp_spi_reg_config *spi_reg_cfg = &cfg->reg_cfg; + uint8_t dummy_data = 0U; + bool last_byte = false; + uint8_t tx_data = 0U; + uint8_t rx_data = 0U; + + /* Check if the transmit buffer is empty and send the next byte */ + if (spi_reg_cfg->regs->SPIM.SERCOM_INTENSET == 0) { + return; + } + /* Check if data is available in the receive buffer */ + if (spi_is_rx_comp(spi_reg_cfg) == true) { + if (spi_context_rx_buf_on(&data->ctx) == true) { + rx_data = spi_read_data(spi_reg_cfg); + *data->ctx.rx_buf = rx_data; + spi_context_update_rx(&data->ctx, 1, 1); + } + } + /* If data register is empty, send next byte or dummy */ + if (spi_is_data_empty(spi_reg_cfg) == true) { + spi_disable_data_empty_interrupt(spi_reg_cfg); + if (spi_context_tx_on(&data->ctx) == true) { + tx_data = *data->ctx.tx_buf; + spi_write_data(spi_reg_cfg, tx_data); + spi_context_update_tx(&data->ctx, 1, 1); + } else if (data->dummysize > 0) { + spi_write_data(spi_reg_cfg, dummy_data); + data->dummysize--; + } else { + /* Do Nothing */ + } + + if ((data->dummysize == 0) && (spi_context_tx_on(&data->ctx) == false)) { + last_byte = true; + } else if (spi_context_rx_on(&data->ctx) == false) { + spi_enable_data_empty_interrupt(spi_reg_cfg); + spi_disable_rxc_interrupt(spi_reg_cfg); + } else { + /* Do Nothing */ + } + } + /* If TX complete and last byte, finish transaction */ + if ((spi_is_tx_comp(spi_reg_cfg) == true) && (last_byte == true)) { + if (spi_context_rx_on(&data->ctx) == false) { + spi_disable_rxc_interrupt(spi_reg_cfg); + spi_disable_txc_interrupt(spi_reg_cfg); + spi_disable_data_empty_interrupt(spi_reg_cfg); + last_byte = false; + if (spi_context_is_slave(&data->ctx) == false) { + /* Control chip select for SPI slave mode */ + spi_context_cs_control(&data->ctx, false); + } + /* Release the semaphore to unblock waiting threads */ + spi_context_complete(&data->ctx, dev, 0); + } + } + /* Enable TX complete interrupt if last byte */ + if (last_byte == true) { + spi_enable_txc_interrupt(spi_reg_cfg); + } +} + +static void spi_mchp_isr(const struct device *dev) +{ +#if CONFIG_SPI_SLAVE + struct spi_mchp_dev_data *data = dev->data; + + if (spi_context_is_slave(&data->ctx) == true) { + spi_mchp_isr_slave(dev); + + return; + } +#endif /* CONFIG_SPI_SLAVE */ + + spi_mchp_isr_master(dev); +} +#endif /* CONFIG_SPI_ASYNC || CONFIG_SPI_MCHP_INTERRUPT_DRIVEN */ + +static int spi_mchp_init(const struct device *dev) +{ + int retval; + const struct spi_mchp_dev_config *cfg = dev->config; + const struct mchp_spi_reg_config *spi_reg_cfg = &cfg->reg_cfg; + struct spi_mchp_dev_data *const data = dev->data; + + retval = clock_control_on(cfg->spi_clock.clock_dev, cfg->spi_clock.gclk_sys); + if ((retval < 0) && (retval != -EALREADY)) { + LOG_ERR("Failed to enable the gclk_sys for SPI: %d", retval); + + return retval; + } + + retval = clock_control_on(cfg->spi_clock.clock_dev, cfg->spi_clock.mclk_sys); + if ((retval < 0) && (retval != -EALREADY)) { + LOG_ERR("Failed to enable the mclk_sys for SPI: %d", retval); + + return retval; + } + + /* Disable all SPI Interrupts*/ + spi_reg_cfg->regs->SPIM.SERCOM_INTENCLR = SERCOM_SPIM_INTENCLR_Msk; + + retval = pinctrl_apply_state(cfg->pcfg, PINCTRL_STATE_DEFAULT); + if (retval < 0) { + LOG_ERR("pinctrl_apply_state Failed for SPI: %d", retval); + + return retval; + } + + spi_context_unlock_unconditionally(&data->ctx); + + return 0; +} + +static DEVICE_API(spi, spi_mchp_api) = { + .transceive = spi_mchp_transceive_sync, + +#if CONFIG_SPI_ASYNC + .transceive_async = spi_mchp_transceive_async, +#endif /*CONFIG_SPI_ASYNC*/ + +#if CONFIG_SPI_RTIO + .iodev_submit = spi_rtio_iodev_default_submit, +#endif /*CONFIG_SPI_RTIO*/ + + .release = spi_mchp_release, +}; + +#define SPI_MCHP_SERCOM_PADS(n) \ + SERCOM_SPIM_CTRLA_DIPO(DT_INST_PROP(n, dipo)) | \ + SERCOM_SPIM_CTRLA_DOPO(DT_INST_PROP(n, dopo)) + +#define SPI_MCHP_REG_CFG_DEFN(n) \ + .reg_cfg.regs = (sercom_registers_t *)DT_INST_REG_ADDR(n), \ + .reg_cfg.pads = SPI_MCHP_SERCOM_PADS(n), + +#if CONFIG_SPI_MCHP_INTERRUPT_DRIVEN || CONFIG_SPI_ASYNC +#if DT_INST_IRQ_HAS_IDX(0, 3) +#define SPI_MCHP_IRQ_HANDLER(n) \ + static void spi_mchp_irq_config_##n(const struct device *dev) \ + { \ + MCHP_SPI_IRQ_CONNECT(n, 0); \ + MCHP_SPI_IRQ_CONNECT(n, 1); \ + MCHP_SPI_IRQ_CONNECT(n, 2); \ + MCHP_SPI_IRQ_CONNECT(n, 3); \ + } +#else +#define SPI_MCHP_IRQ_HANDLER(n) \ + static void spi_mchp_irq_config_##n(const struct device *dev) \ + { \ + MCHP_SPI_IRQ_CONNECT(n, 0); \ + } +#endif +#else +#define SPI_MCHP_IRQ_HANDLER(n) +#endif /* CONFIG_SPI_MCHP_INTERRUPT_DRIVEN || CONFIG_SPI_ASYNC */ + +#define SPI_MCHP_CLOCK_DEFN(n) \ + .spi_clock.clock_dev = DEVICE_DT_GET(DT_NODELABEL(clock)), \ + .spi_clock.mclk_sys = (void *)(DT_INST_CLOCKS_CELL_BY_NAME(n, mclk, subsystem)), \ + .spi_clock.gclk_sys = (void *)(DT_INST_CLOCKS_CELL_BY_NAME(n, gclk, subsystem)) + +#if CONFIG_SPI_MCHP_INTERRUPT_DRIVEN || CONFIG_SPI_ASYNC +#define MCHP_SPI_IRQ_CONNECT(n, m) \ + do { \ + IRQ_CONNECT(DT_INST_IRQ_BY_IDX(n, m, irq), DT_INST_IRQ_BY_IDX(n, m, priority), \ + spi_mchp_isr, DEVICE_DT_INST_GET(n), 0); \ + irq_enable(DT_INST_IRQ_BY_IDX(n, m, irq)); \ + } while (false) + +#define SPI_MCHP_IRQ_HANDLER_DECL(n) static void spi_mchp_irq_config_##n(const struct device *dev) +#define SPI_MCHP_IRQ_HANDLER_FUNC(n) .irq_config_func = spi_mchp_irq_config_##n, +#else +#define SPI_MCHP_IRQ_HANDLER_DECL(n) +#define SPI_MCHP_IRQ_HANDLER_FUNC(n) +#endif /* CONFIG_SPI_MCHP_INTERRUPT_DRIVEN || CONFIG_SPI_ASYNC */ + +#if CONFIG_SPI_MCHP_DMA_DRIVEN_ASYNC +#define SPI_MCHP_DMA_CHANNELS(n) \ + .spi_dma.dma_dev = DEVICE_DT_GET(MCHP_DT_INST_DMA_CTLR(n, tx)), \ + .spi_dma.tx_dma_request = MCHP_DT_INST_DMA_TRIGSRC(n, tx), \ + .spi_dma.tx_dma_channel = MCHP_DT_INST_DMA_CHANNEL(n, tx), \ + .spi_dma.rx_dma_request = MCHP_DT_INST_DMA_TRIGSRC(n, rx), \ + .spi_dma.rx_dma_channel = MCHP_DT_INST_DMA_CHANNEL(n, rx), +#else +#define SPI_MCHP_DMA_CHANNELS(n) +#endif /* CONFIG_SPI_MCHP_DMA_DRIVEN_ASYNC */ + +#define SPI_MCHP_CONFIG_DEFN(n) \ + static const struct spi_mchp_dev_config spi_mchp_config_##n = { \ + .pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(n), \ + SPI_MCHP_REG_CFG_DEFN(n) SPI_MCHP_IRQ_HANDLER_FUNC(n) SPI_MCHP_DMA_CHANNELS(n) \ + SPI_MCHP_CLOCK_DEFN(n)} + +#define SPI_MCHP_DEVICE_INIT(n) \ + PINCTRL_DT_INST_DEFINE(n); \ + SPI_MCHP_IRQ_HANDLER_DECL(n); \ + SPI_MCHP_CONFIG_DEFN(n); \ + static struct spi_mchp_dev_data spi_mchp_data_##n = { \ + SPI_CONTEXT_INIT_LOCK(spi_mchp_data_##n, ctx), \ + SPI_CONTEXT_INIT_SYNC(spi_mchp_data_##n, ctx), \ + SPI_CONTEXT_CS_GPIOS_INITIALIZE(DT_DRV_INST(n), ctx)}; \ + DEVICE_DT_INST_DEFINE(n, spi_mchp_init, NULL, &spi_mchp_data_##n, &spi_mchp_config_##n, \ + POST_KERNEL, CONFIG_SPI_INIT_PRIORITY, &spi_mchp_api); \ + SPI_MCHP_IRQ_HANDLER(n) + +DT_INST_FOREACH_STATUS_OKAY(SPI_MCHP_DEVICE_INIT) From 29493ced6f73c1f9ecad364afc05ee59a91bf111 Mon Sep 17 00:00:00 2001 From: Mohamed Azhar Date: Mon, 5 Jan 2026 19:33:28 +0530 Subject: [PATCH 0209/6328] boards: sam_e54_xpro: Update dts files for spi support Add required DTS and pinctrl changes to enable SPI on sam_e54_xpro. Signed-off-by: Mohamed Azhar --- .../sam/sam_e54_xpro/sam_e54_xpro-pinctrl.dtsi | 9 +++++++++ boards/microchip/sam/sam_e54_xpro/sam_e54_xpro.dts | 14 ++++++++++++++ .../microchip/sam/sam_e54_xpro/sam_e54_xpro.yaml | 1 + 3 files changed, 24 insertions(+) diff --git a/boards/microchip/sam/sam_e54_xpro/sam_e54_xpro-pinctrl.dtsi b/boards/microchip/sam/sam_e54_xpro/sam_e54_xpro-pinctrl.dtsi index c5e73896785d..861cb695a6d9 100644 --- a/boards/microchip/sam/sam_e54_xpro/sam_e54_xpro-pinctrl.dtsi +++ b/boards/microchip/sam/sam_e54_xpro/sam_e54_xpro-pinctrl.dtsi @@ -14,6 +14,15 @@ }; }; + sercom6_spi_default: sercom6_spi_default { + group1 { + pinmux = , + , + , + ; + }; + }; + sercom7_i2c_default: sercom7_i2c_default { group1 { pinmux = , diff --git a/boards/microchip/sam/sam_e54_xpro/sam_e54_xpro.dts b/boards/microchip/sam/sam_e54_xpro/sam_e54_xpro.dts index 27e329db4b40..8fdee6a6529c 100644 --- a/boards/microchip/sam/sam_e54_xpro/sam_e54_xpro.dts +++ b/boards/microchip/sam/sam_e54_xpro/sam_e54_xpro.dts @@ -216,6 +216,20 @@ status = "okay"; }; +&sercom6 { + compatible = "microchip,sercom-g1-spi"; + + dipo = <3>; + dopo = <0>; + + #address-cells = <1>; + #size-cells = <0>; + + pinctrl-0 = <&sercom6_spi_default>; + pinctrl-names = "default"; + status = "okay"; +}; + &sercom7 { compatible = "microchip,sercom-g1-i2c"; #address-cells = <1>; diff --git a/boards/microchip/sam/sam_e54_xpro/sam_e54_xpro.yaml b/boards/microchip/sam/sam_e54_xpro/sam_e54_xpro.yaml index d359f36d098d..082077483428 100644 --- a/boards/microchip/sam/sam_e54_xpro/sam_e54_xpro.yaml +++ b/boards/microchip/sam/sam_e54_xpro/sam_e54_xpro.yaml @@ -27,6 +27,7 @@ supported: - reset - rtc - shell + - spi - uart - watchdog vendor: microchip From e18a048c8499d859163a25c89a7cc98b15431833 Mon Sep 17 00:00:00 2001 From: Peter Mitsis Date: Wed, 14 Jan 2026 15:23:00 -0800 Subject: [PATCH 0210/6328] kernel: Add K_TIMEOUT_SUM() macro The K_TIMEOUT_SUM() macro is intended as a means to add two k_timeout_t values together. This may be useful for a developer applying an exponential backoff algorithm. Signed-off-by: Peter Mitsis --- include/zephyr/kernel.h | 17 ++- include/zephyr/sys/clock.h | 43 ++++++ tests/kernel/timer/timeout/CMakeLists.txt | 8 + tests/kernel/timer/timeout/prj.conf | 1 + tests/kernel/timer/timeout/src/main.c | 173 ++++++++++++++++++++++ tests/kernel/timer/timeout/testcase.yaml | 5 + 6 files changed, 246 insertions(+), 1 deletion(-) create mode 100644 tests/kernel/timer/timeout/CMakeLists.txt create mode 100644 tests/kernel/timer/timeout/prj.conf create mode 100644 tests/kernel/timer/timeout/src/main.c create mode 100644 tests/kernel/timer/timeout/testcase.yaml diff --git a/include/zephyr/kernel.h b/include/zephyr/kernel.h index bfde2db11006..17ca435f63b8 100644 --- a/include/zephyr/kernel.h +++ b/include/zephyr/kernel.h @@ -1665,6 +1665,22 @@ const char *k_thread_state_str(k_tid_t thread_id, char *buf, size_t buf_size); */ #define K_FOREVER Z_FOREVER +/** + * @brief Add two k_timeout_t values together + * + * This macro adds two k_timeout_t values together. If only one value is an + * absolute timeout, the result will be an absolute timeout. If both are + * relative timeouts, the result will be a relative timeout. If the calculation + * overflows, underflows or if both values are absolute timeouts, K_FOREVER + * is returned. + * + * @param timeout1 First k_timeout_t value + * @param timeout2 Second k_timeout_t value + * + * @return Sum of the two timeout values, or K_FOREVER if incalculable + */ +#define K_TIMEOUT_SUM(timeout1, timeout2) K_TICKS(z_timeout_sum(timeout1, timeout2)) + #ifdef CONFIG_TIMEOUT_64BIT /** @@ -1748,7 +1764,6 @@ const char *k_thread_state_str(k_tid_t thread_id, char *buf, size_t buf_size); * @return Timeout delay value */ #define K_TIMEOUT_ABS_CYC(t) K_TIMEOUT_ABS_TICKS(k_cyc_to_ticks_ceil64(t)) - #endif /** diff --git a/include/zephyr/sys/clock.h b/include/zephyr/sys/clock.h index c11935995835..d977fa4ff3fc 100644 --- a/include/zephyr/sys/clock.h +++ b/include/zephyr/sys/clock.h @@ -172,6 +172,49 @@ typedef struct { /* The maximum duration in ticks strictly and semantically "less than" K_FOREVER */ #define K_TICK_MAX ((k_ticks_t)(IS_ENABLED(CONFIG_TIMEOUT_64BIT) ? INT64_MAX : UINT32_MAX - 1)) +/** + * @brief Sum the ticks from two timeout values + * + * This routine determines the resulting tick value when adding two k_timeout_t + * values together. If only one k_timeout_t value is an absolute timeout, the + * result will be an absolute timeout. If both are relative timeouts, the + * result will be a relative timeout. If the calculated tick value overflows, + * underflows or if both values are absolute timeouts, it returns K_TICKS_FOREVER. + * + * @param t1 First k_timeout_t value + * @param t2 Second k_timeout_t value + * + * @return Sum of the two timeout values in ticks, or val K_TICKS_FOREVER if incalculable + */ +static inline k_ticks_t z_timeout_sum(k_timeout_t t1, k_timeout_t t2) +{ + k_ticks_t ticks1 = t1.ticks; + k_ticks_t ticks2 = t2.ticks; + +#ifdef CONFIG_TIMEOUT_64BIT + if ((ticks1 == K_TICKS_FOREVER) || (ticks2 == K_TICKS_FOREVER)) { + return K_TICKS_FOREVER; + } + + if (ticks1 < 0) { + if (ticks2 < 0) { + return K_TICKS_FOREVER; /* Both absolute timeouts */ + } + + return ((ticks1 - INT64_MIN) < ticks2) ? + K_TICKS_FOREVER : (ticks1 - ticks2); + } else if (ticks2 < 0) { + return ((ticks2 - INT64_MIN) < ticks1) ? + K_TICKS_FOREVER : (ticks2 - ticks1); + } else { + return ((INT64_MAX - ticks1) < ticks2) ? + K_TICKS_FOREVER : ticks1 + ticks2; + } +#else + return ((UINT32_MAX - ticks1) < ticks2) ? K_TICKS_FOREVER : ticks1 + ticks2; +#endif +} + /** @endcond */ #ifndef CONFIG_TIMER_READS_ITS_FREQUENCY_AT_RUNTIME diff --git a/tests/kernel/timer/timeout/CMakeLists.txt b/tests/kernel/timer/timeout/CMakeLists.txt new file mode 100644 index 000000000000..ba9a308c5d3f --- /dev/null +++ b/tests/kernel/timer/timeout/CMakeLists.txt @@ -0,0 +1,8 @@ +# SPDX-License-Identifier: Apache-2.0 + +cmake_minimum_required(VERSION 3.20.0) +find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) +project(timer_timeout) + +FILE(GLOB app_sources src/*.c) +target_sources(app PRIVATE ${app_sources}) diff --git a/tests/kernel/timer/timeout/prj.conf b/tests/kernel/timer/timeout/prj.conf new file mode 100644 index 000000000000..9467c2926896 --- /dev/null +++ b/tests/kernel/timer/timeout/prj.conf @@ -0,0 +1 @@ +CONFIG_ZTEST=y diff --git a/tests/kernel/timer/timeout/src/main.c b/tests/kernel/timer/timeout/src/main.c new file mode 100644 index 000000000000..b598e381bf44 --- /dev/null +++ b/tests/kernel/timer/timeout/src/main.c @@ -0,0 +1,173 @@ +/* + * Copyright (c) 2026 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +#ifdef CONFIG_TIMEOUT_64BIT +/** + * Verify that absolute timeout sums are handled correctly + */ +ZTEST(timeout, test_timeout_sum_absolute) +{ + k_timeout_t abs_timeout = K_TIMEOUT_ABS_TICKS(1000); + k_timeout_t result; + + /* Two absolute timeouts should result in K_FOREVER */ + + result = K_TIMEOUT_SUM(abs_timeout, abs_timeout); + zassert_true(K_TIMEOUT_EQ(result, K_FOREVER), "Expected K_FOREVER"); + + /* Absolute with K_FOREVER should result in K_FOREVER */ + + result = K_TIMEOUT_SUM(abs_timeout, K_FOREVER); + zassert_true(K_TIMEOUT_EQ(result, K_FOREVER), "Expected K_FOREVER"); + + result = K_TIMEOUT_SUM(K_FOREVER, abs_timeout); + zassert_true(K_TIMEOUT_EQ(result, K_FOREVER), "Expected K_FOREVER"); + + /* Absolute with K_NO_WAIT should return the absolute */ + + result = K_TIMEOUT_SUM(abs_timeout, K_NO_WAIT); + zassert_true(K_TIMEOUT_EQ(result, abs_timeout), + "Expected K_TIMEOUT_ABS_TICKS(1000)"); + + result = K_TIMEOUT_SUM(K_NO_WAIT, abs_timeout); + zassert_true(K_TIMEOUT_EQ(result, abs_timeout), + "Expected K_TIMEOUT_ABS_TICKS(1000)"); + + /* Absolute + relative (no underflow) should return a new absolute */ + + result = K_TIMEOUT_SUM(abs_timeout, K_TICKS(100)); + zassert_true(K_TIMEOUT_EQ(result, K_TIMEOUT_ABS_TICKS(1100)), + "Expected K_TIMEOUT_ABS_TICKS(1100)"); + + result = K_TIMEOUT_SUM(K_TICKS(100), abs_timeout); + zassert_true(K_TIMEOUT_EQ(result, K_TIMEOUT_ABS_TICKS(1100)), + "Expected K_TIMEOUT_ABS_TICKS(1100)"); + + /* Limit testing: small absolute + large relative -- absolute 1st */ + + result = K_TIMEOUT_SUM(K_TIMEOUT_ABS_TICKS(5), K_TICKS(INT64_MAX - 4)); + zassert_true(K_TIMEOUT_EQ(result, K_FOREVER), "Expected K_FOREVER"); + + result = K_TIMEOUT_SUM(K_TIMEOUT_ABS_TICKS(5), K_TICKS(INT64_MAX - 5)); + zassert_true(K_TIMEOUT_EQ(result, K_FOREVER), "Expected K_FOREVER"); + + result = K_TIMEOUT_SUM(K_TIMEOUT_ABS_TICKS(5), K_TICKS(INT64_MAX - 6)); + zassert_true(K_TIMEOUT_EQ(result, K_TICKS(INT64_MIN)), + "Expected INT64_MIN ticks"); + + result = K_TIMEOUT_SUM(K_TIMEOUT_ABS_TICKS(5), K_TICKS(INT64_MAX - 7)); + zassert_true(K_TIMEOUT_EQ(result, K_TICKS(INT64_MIN + 1)), + "Expected INT64_MIN + 1 ticks"); + + /* Limit testing: small absolute + large relative -- relative 1st */ + + result = K_TIMEOUT_SUM(K_TICKS(INT64_MAX - 4), K_TIMEOUT_ABS_TICKS(5)); + zassert_true(K_TIMEOUT_EQ(result, K_FOREVER), "Expected K_FOREVER"); + + result = K_TIMEOUT_SUM(K_TICKS(INT64_MAX - 5), K_TIMEOUT_ABS_TICKS(5)); + zassert_true(K_TIMEOUT_EQ(result, K_FOREVER), "Expected K_FOREVER"); + + result = K_TIMEOUT_SUM(K_TICKS(INT64_MAX - 6), K_TIMEOUT_ABS_TICKS(5)); + zassert_true(K_TIMEOUT_EQ(result, K_TICKS(INT64_MIN)), + "Expected INT64_MIN ticks"); + + result = K_TIMEOUT_SUM(K_TICKS(INT64_MAX - 7), K_TIMEOUT_ABS_TICKS(5)); + zassert_true(K_TIMEOUT_EQ(result, K_TICKS(INT64_MIN + 1)), + "Expected INT64_MIN + 1 ticks"); + + /* Limit testing large absolute + small relative -- absolute 1st */ + + result = K_TIMEOUT_SUM(K_TIMEOUT_ABS_TICKS(INT64_MAX - 5), K_TICKS(6)); + zassert_true(K_TIMEOUT_EQ(result, K_FOREVER), "Expected K_FOREVER"); + + result = K_TIMEOUT_SUM(K_TIMEOUT_ABS_TICKS(INT64_MAX - 6), K_TICKS(6)); + zassert_true(K_TIMEOUT_EQ(result, K_FOREVER), "Expected K_FOREVER"); + + result = K_TIMEOUT_SUM(K_TIMEOUT_ABS_TICKS(INT64_MAX - 7), K_TICKS(6)); + zassert_true(K_TIMEOUT_EQ(result, K_TICKS(INT64_MIN)), + "Expected INT64_MIN ticks"); + + result = K_TIMEOUT_SUM(K_TIMEOUT_ABS_TICKS(INT64_MAX - 8), K_TICKS(6)); + zassert_true(K_TIMEOUT_EQ(result, K_TICKS(INT64_MIN + 1)), + "Expected INT64_MIN + 1 ticks"); + + /* Limit testing large absolute + small relative -- relative 1st */ + + result = K_TIMEOUT_SUM(K_TICKS(6), K_TIMEOUT_ABS_TICKS(INT64_MAX - 5)); + zassert_true(K_TIMEOUT_EQ(result, K_FOREVER), "Expected K_FOREVER"); + + result = K_TIMEOUT_SUM(K_TICKS(6), K_TIMEOUT_ABS_TICKS(INT64_MAX - 6)); + zassert_true(K_TIMEOUT_EQ(result, K_FOREVER), "Expected K_FOREVER"); + + result = K_TIMEOUT_SUM(K_TICKS(6), K_TIMEOUT_ABS_TICKS(INT64_MAX - 7)); + zassert_true(K_TIMEOUT_EQ(result, K_TICKS(INT64_MIN)), + "Expected INT64_MIN ticks"); + + result = K_TIMEOUT_SUM(K_TICKS(6), K_TIMEOUT_ABS_TICKS(INT64_MAX - 8)); + zassert_true(K_TIMEOUT_EQ(result, K_TICKS(INT64_MIN + 1)), + "Expected INT64_MIN + 1 ticks"); +} +#endif + +/** + * Verify that relative timeout sums are handled correctly + */ +ZTEST(timeout, test_timeout_sum_relative) +{ + k_timeout_t result; + + /* Verify that normal sums work as expected */ + + result = K_TIMEOUT_SUM(K_TICKS(1), K_TICKS(2)); + zassert_true(K_TIMEOUT_EQ(result, K_TICKS(3)), "Expected 3 ticks"); + + /* K_NO_WAIT + X should return X */ + + result = K_TIMEOUT_SUM(K_NO_WAIT, K_TICKS(1)); + zassert_true(K_TIMEOUT_EQ(result, K_TICKS(1)), "Expected 1 tick"); + + result = K_TIMEOUT_SUM(K_TICKS(1), K_NO_WAIT); + zassert_true(K_TIMEOUT_EQ(result, K_TICKS(1)), "Expected 1 tick"); + + result = K_TIMEOUT_SUM(K_NO_WAIT, K_NO_WAIT); + zassert_true(K_TIMEOUT_EQ(result, K_NO_WAIT), "Expected K_NO_WAIT"); + + /* K_FOREVER + anything should return K_FOREVER */ + + result = K_TIMEOUT_SUM(K_TICKS(1), K_FOREVER); + zassert_true(K_TIMEOUT_EQ(result, K_FOREVER), "Expected K_FOREVER"); + + result = K_TIMEOUT_SUM(K_FOREVER, K_TICKS(1)); + zassert_true(K_TIMEOUT_EQ(result, K_FOREVER), "Expected K_FOREVER"); + + result = K_TIMEOUT_SUM(K_FOREVER, K_NO_WAIT); + zassert_true(K_TIMEOUT_EQ(result, K_FOREVER), "Expected K_FOREVER"); + + result = K_TIMEOUT_SUM(K_NO_WAIT, K_FOREVER); + zassert_true(K_TIMEOUT_EQ(result, K_FOREVER), "Expected K_FOREVER"); + + result = K_TIMEOUT_SUM(K_FOREVER, K_FOREVER); + zassert_true(K_TIMEOUT_EQ(result, K_FOREVER), "Expected K_FOREVER"); + + /* Behavior at limits */ + + result = K_TIMEOUT_SUM(K_TICKS(K_TICK_MAX - 1), K_TICKS(1)); + zassert_true(K_TIMEOUT_EQ(result, K_TICKS(K_TICK_MAX)), "Expected K_TICK_MAX ticks"); + + result = K_TIMEOUT_SUM(K_TICKS(K_TICK_MAX - 1), K_TICKS(2)); + zassert_true(K_TIMEOUT_EQ(result, K_FOREVER), "Expected K_FOREVER"); + + result = K_TIMEOUT_SUM(K_TICKS(K_TICK_MAX), K_NO_WAIT); + zassert_true(K_TIMEOUT_EQ(result, K_TICKS(K_TICK_MAX)), "Expected K_TICK_MAX ticks"); + + result = K_TIMEOUT_SUM(K_TICKS(K_TICK_MAX), K_TICKS(1)); + zassert_true(K_TIMEOUT_EQ(result, K_FOREVER), "Expected K_FOREVER"); +} + +ZTEST_SUITE(timeout, NULL, NULL, NULL, NULL, NULL); diff --git a/tests/kernel/timer/timeout/testcase.yaml b/tests/kernel/timer/timeout/testcase.yaml new file mode 100644 index 000000000000..3b9637ca2290 --- /dev/null +++ b/tests/kernel/timer/timeout/testcase.yaml @@ -0,0 +1,5 @@ +tests: + kernel.timer.timeout: + tags: + - kernel + - timer From 09ffa475c9331d1d157b157c9668f7a6b1931475 Mon Sep 17 00:00:00 2001 From: Kevin Chan Date: Fri, 16 Jan 2026 09:55:49 -0800 Subject: [PATCH 0211/6328] drivers: dma: fix channel_state channelState depends on descriptor count Signed-off-by: Kevin Chan --- drivers/dma/dma_infineon_pdl.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/dma/dma_infineon_pdl.c b/drivers/dma/dma_infineon_pdl.c index dbca67bc6942..dab52f31da86 100644 --- a/drivers/dma/dma_infineon_pdl.c +++ b/drivers/dma/dma_infineon_pdl.c @@ -192,8 +192,7 @@ static int ifx_cat1_dma_config(const struct device *dev, uint32_t channel, descriptor_config.interruptType = CY_DMA_DESCR; } - /* Keep CHANNEL_ENABLED if BURST transfer (config->dest_burst_length != 0) */ - if (config->dest_burst_length != 0) { + if (config->block_count > 1U) { descriptor_config.channelState = CY_DMA_CHANNEL_ENABLED; } else { descriptor_config.channelState = CY_DMA_CHANNEL_DISABLED; From aa58db66226477c82328e30cd208e48ff0d0b64e Mon Sep 17 00:00:00 2001 From: Kevin Chan Date: Fri, 16 Jan 2026 09:58:50 -0800 Subject: [PATCH 0212/6328] tests: drivers: spi: spi_loopback: support SPI-DMA on PSE84 Added SPI-DMA overlay Signed-off-by: Kevin Chan --- .../spi/spi_loopback/boards/kit_pse84_eval_common.overlay | 7 +++++++ .../boards/kit_pse84_eval_pse846gps2dbzc4a_m33.conf | 6 ++++++ .../boards/kit_pse84_eval_pse846gps2dbzc4a_m55.conf | 6 ++++++ 3 files changed, 19 insertions(+) create mode 100644 tests/drivers/spi/spi_loopback/boards/kit_pse84_eval_pse846gps2dbzc4a_m33.conf create mode 100644 tests/drivers/spi/spi_loopback/boards/kit_pse84_eval_pse846gps2dbzc4a_m55.conf diff --git a/tests/drivers/spi/spi_loopback/boards/kit_pse84_eval_common.overlay b/tests/drivers/spi/spi_loopback/boards/kit_pse84_eval_common.overlay index 535ff0c02725..77360500287c 100644 --- a/tests/drivers/spi/spi_loopback/boards/kit_pse84_eval_common.overlay +++ b/tests/drivers/spi/spi_loopback/boards/kit_pse84_eval_common.overlay @@ -28,6 +28,9 @@ spi1: &scb10 { reg = <0>; spi-max-frequency = <3000000>; }; + + dmas = <&dma0 0>, <&dma0 1>; + dma-names = "tx", "rx"; }; &peri0_group1_16bit_2 { @@ -50,3 +53,7 @@ spi1: &scb10 { drive-strength = "full"; drive-push-pull; }; + +&dma0 { + status = "okay"; +}; diff --git a/tests/drivers/spi/spi_loopback/boards/kit_pse84_eval_pse846gps2dbzc4a_m33.conf b/tests/drivers/spi/spi_loopback/boards/kit_pse84_eval_pse846gps2dbzc4a_m33.conf new file mode 100644 index 000000000000..c91b39ef80a2 --- /dev/null +++ b/tests/drivers/spi/spi_loopback/boards/kit_pse84_eval_pse846gps2dbzc4a_m33.conf @@ -0,0 +1,6 @@ +# Copyright (c) 2025 Infineon Technologies AG, +# or an affiliate of Infineon Technologies AG. +# +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_SPI_INFINEON_DMA=y diff --git a/tests/drivers/spi/spi_loopback/boards/kit_pse84_eval_pse846gps2dbzc4a_m55.conf b/tests/drivers/spi/spi_loopback/boards/kit_pse84_eval_pse846gps2dbzc4a_m55.conf new file mode 100644 index 000000000000..c91b39ef80a2 --- /dev/null +++ b/tests/drivers/spi/spi_loopback/boards/kit_pse84_eval_pse846gps2dbzc4a_m55.conf @@ -0,0 +1,6 @@ +# Copyright (c) 2025 Infineon Technologies AG, +# or an affiliate of Infineon Technologies AG. +# +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_SPI_INFINEON_DMA=y From 72b13523f62c69e902d2ec4699afd0e813cb2c9e Mon Sep 17 00:00:00 2001 From: Kevin Chan Date: Fri, 16 Jan 2026 09:59:51 -0800 Subject: [PATCH 0213/6328] drivers: spi: add SPI-DMA logic support SPI-DMA logic Signed-off-by: Kevin Chan --- drivers/spi/Kconfig.infineon | 12 +-- drivers/spi/spi_infineon_pdl.c | 179 +++++++++++++++++++-------------- 2 files changed, 104 insertions(+), 87 deletions(-) diff --git a/drivers/spi/Kconfig.infineon b/drivers/spi/Kconfig.infineon index 40339a29d907..83a1e534a55d 100644 --- a/drivers/spi/Kconfig.infineon +++ b/drivers/spi/Kconfig.infineon @@ -27,18 +27,10 @@ config SPI_INFINEON_CAT1_PDL if USE_INFINEON_SPI -config IFX_CAT1_SPI_DMA - bool "Infineon CAT1 SPI Interrupt Support" +config SPI_INFINEON_DMA + bool "Infineon SPI DMA Support" select DMA help Enable DMA during usage of SPI driver. -config IFX_CAT1_SPI_DMA_TX_AUTO_TRIGGER - bool "Infineon CAT1 SPI Tx DMA channel trigger mechanism" - default y - depends on IFX_CAT1_SPI_DMA - select DMA - help - Automatically trigger SPI Tx DMA after config - endif # USE_INFINEON_SPI diff --git a/drivers/spi/spi_infineon_pdl.c b/drivers/spi/spi_infineon_pdl.c index 22849fab9048..1cb2368a9e29 100644 --- a/drivers/spi/spi_infineon_pdl.c +++ b/drivers/spi/spi_infineon_pdl.c @@ -10,6 +10,8 @@ #include LOG_MODULE_REGISTER(cat1_spi, CONFIG_SPI_LOG_LEVEL); +#include + #include "spi_context.h" #include @@ -18,7 +20,7 @@ LOG_MODULE_REGISTER(cat1_spi, CONFIG_SPI_LOG_LEVEL); #include #include -#ifdef CONFIG_IFX_CAT1_SPI_DMA +#ifdef CONFIG_SPI_INFINEON_DMA #include #endif @@ -50,12 +52,14 @@ LOG_MODULE_REGISTER(cat1_spi, CONFIG_SPI_LOG_LEVEL); #define IFX_CAT1_SPI_ASYMM_PDL_FUNC_AVAIL #endif -#ifdef CONFIG_IFX_CAT1_SPI_DMA +#ifdef CONFIG_SPI_INFINEON_DMA /* dummy buffers to be used by driver for DMA operations when app gives a NULL buffer * during an asymmetric transfer */ static uint32_t tx_dummy_data; static uint32_t rx_dummy_data; + +#define IFX_CAT1_SPI_DMA_BURST_SIZE 256 #endif typedef void (*ifx_cat1_spi_event_callback_t)(void *callback_arg, uint32_t event); @@ -75,7 +79,7 @@ struct ifx_cat1_spi_config { uint8_t cs_oversample_cnt; }; -#ifdef CONFIG_IFX_CAT1_SPI_DMA +#ifdef CONFIG_SPI_INFINEON_DMA struct ifx_cat1_dma_stream { const struct device *dev_dma; uint32_t dma_channel; @@ -96,11 +100,9 @@ struct ifx_cat1_spi_data { size_t chunk_len; bool dma_configured; -#ifdef CONFIG_IFX_CAT1_SPI_DMA +#ifdef CONFIG_SPI_INFINEON_DMA struct ifx_cat1_dma_stream dma_rx; struct ifx_cat1_dma_stream dma_tx; - en_peri0_trig_input_pdma0_tr_t spi_rx_trigger; - en_peri0_trig_output_pdma0_tr_t dma_rx_trigger; #endif #if defined(COMPONENT_CAT1B) || defined(COMPONENT_CAT1C) || defined(CONFIG_SOC_FAMILY_INFINEON_EDGE) @@ -166,69 +168,85 @@ static void transfer_chunk(const struct device *dev) if (chunk_len == 0) { goto exit; } - data->chunk_len = chunk_len; -#ifdef CONFIG_IFX_CAT1_SPI_DMA +#ifdef CONFIG_SPI_INFINEON_DMA const struct ifx_cat1_spi_config *const config = dev->config; - CySCB_Type *spi_reg = config->reg_addr; - - Cy_SCB_SetRxFifoLevel(spi_reg, chunk_len - 1); - register struct ifx_cat1_dma_stream *dma_tx = &data->dma_tx; register struct ifx_cat1_dma_stream *dma_rx = &data->dma_rx; - if (data->dma_configured && spi_context_rx_buf_on(ctx) && spi_context_tx_buf_on(ctx)) { - /* Optimization to reduce config time if only buffer and size - * are changing from the previous DMA configuration - */ - dma_reload(dma_tx->dev_dma, dma_tx->dma_channel, (uint32_t)ctx->tx_buf, - dma_tx->blk_cfg.dest_address, chunk_len); - dma_reload(dma_rx->dev_dma, dma_rx->dma_channel, dma_rx->blk_cfg.source_address, - (uint32_t)ctx->rx_buf, chunk_len); - return; - } + if (chunk_len <= Cy_SCB_GetFifoSize(config->reg_addr)) { - if (spi_context_rx_buf_on(ctx)) { - dma_rx->blk_cfg.dest_address = (uint32_t)ctx->rx_buf; - dma_rx->blk_cfg.dest_addr_adj = DMA_ADDR_ADJ_INCREMENT; + cy_rslt_t result = ifx_cat1_spi_transfer_async( + dev, ctx->tx_buf, spi_context_tx_buf_on(ctx) ? chunk_len : 0, ctx->rx_buf, + spi_context_rx_buf_on(ctx) ? chunk_len : 0); + if (result == CY_RSLT_SUCCESS) { + return; + } + ret = -EIO; } else { - dma_rx->blk_cfg.dest_address = (uint32_t)&rx_dummy_data; - dma_rx->blk_cfg.dest_addr_adj = DMA_ADDR_ADJ_NO_CHANGE; - } + Cy_SCB_SetTxFifoLevel(config->reg_addr, 1U); + Cy_SCB_SetRxFifoLevel(config->reg_addr, 0U); + + if (chunk_len > IFX_CAT1_SPI_DMA_BURST_SIZE) { + dma_rx->dma_cfg.source_burst_length = dma_tx->dma_cfg.source_burst_length = + IFX_CAT1_SPI_DMA_BURST_SIZE; + dma_rx->dma_cfg.dest_burst_length = dma_tx->dma_cfg.dest_burst_length = + IFX_CAT1_SPI_DMA_BURST_SIZE; + if (chunk_len % IFX_CAT1_SPI_DMA_BURST_SIZE != 0) { + LOG_ERR("DMA (DW) only supports lengths is multiple of burst " + "length (%d)", + IFX_CAT1_SPI_DMA_BURST_SIZE); + goto exit; + } + dma_rx->dma_cfg.block_count = dma_tx->dma_cfg.block_count = 1; + } else { + dma_rx->dma_cfg.source_burst_length = dma_tx->dma_cfg.source_burst_length = + 0; + dma_rx->dma_cfg.dest_burst_length = dma_tx->dma_cfg.dest_burst_length = 0; + dma_rx->dma_cfg.block_count = dma_tx->dma_cfg.block_count = 1; + } - if (spi_context_tx_buf_on(ctx)) { - dma_tx->blk_cfg.source_address = (uint32_t)ctx->tx_buf; - dma_tx->blk_cfg.source_addr_adj = DMA_ADDR_ADJ_INCREMENT; + dma_rx->blk_cfg.block_size = dma_tx->blk_cfg.block_size = chunk_len; - } else { - tx_dummy_data = 0; - dma_tx->blk_cfg.source_address = (uint32_t)&tx_dummy_data; - dma_tx->blk_cfg.source_addr_adj = DMA_ADDR_ADJ_NO_CHANGE; - } + if (spi_context_rx_buf_on(ctx)) { + dma_rx->blk_cfg.dest_address = (uint32_t)ctx->rx_buf; + dma_rx->blk_cfg.dest_addr_adj = DMA_ADDR_ADJ_INCREMENT; + } else { + dma_rx->blk_cfg.dest_address = (uint32_t)&rx_dummy_data; + dma_rx->blk_cfg.dest_addr_adj = DMA_ADDR_ADJ_NO_CHANGE; + } - dma_rx->blk_cfg.block_size = dma_tx->blk_cfg.block_size = chunk_len; - ret = dma_config(dma_rx->dev_dma, dma_rx->dma_channel, &dma_rx->dma_cfg); - if (ret < 0) { - goto exit; - } + if (spi_context_tx_buf_on(ctx)) { + dma_tx->blk_cfg.source_address = (uint32_t)ctx->tx_buf; + dma_tx->blk_cfg.source_addr_adj = DMA_ADDR_ADJ_INCREMENT; - ret = dma_config(dma_tx->dev_dma, dma_tx->dma_channel, &dma_tx->dma_cfg); - if (ret < 0) { - goto exit; - } + } else { + tx_dummy_data = 0; + dma_tx->blk_cfg.source_address = (uint32_t)&tx_dummy_data; + dma_tx->blk_cfg.source_addr_adj = DMA_ADDR_ADJ_NO_CHANGE; + } -#ifdef CONFIG_IFX_CAT1_SPI_DMA_TX_AUTO_TRIGGER - ret = dma_start(dma_tx->dev_dma, dma_tx->dma_channel); - if (ret == 0) { - return; - } -#else - if (ret == 0) { - data->dma_configured = 1; - return; + ret = dma_config(dma_rx->dev_dma, dma_rx->dma_channel, &dma_rx->dma_cfg); + if (ret < 0) { + goto exit; + } + + ret = dma_config(dma_tx->dev_dma, dma_tx->dma_channel, &dma_tx->dma_cfg); + if (ret < 0) { + goto exit; + } + + ret = dma_start(dma_rx->dev_dma, dma_rx->dma_channel); + if (ret < 0) { + goto exit; + } + + ret = dma_start(dma_tx->dev_dma, dma_tx->dma_channel); + if (ret == 0) { + return; + } } -#endif #else cy_rslt_t result = ifx_cat1_spi_transfer_async( dev, ctx->tx_buf, spi_context_tx_buf_on(ctx) ? chunk_len : 0, ctx->rx_buf, @@ -236,9 +254,14 @@ static void transfer_chunk(const struct device *dev) if (result == CY_RSLT_SUCCESS) { return; } -#endif ret = -EIO; +#endif + exit: +#ifdef CONFIG_SPI_INFINEON_DMA + dma_stop(data->dma_tx.dev_dma, data->dma_tx.dma_channel); + dma_stop(data->dma_rx.dev_dma, data->dma_rx.dma_channel); +#endif spi_context_cs_control(ctx, false); spi_context_complete(ctx, dev, ret); } @@ -264,7 +287,7 @@ static void spi_interrupt_callback(void *arg, uint32_t event) } } -#ifdef CONFIG_IFX_CAT1_SPI_DMA +#ifdef CONFIG_SPI_INFINEON_DMA static void dma_callback(const struct device *dma_dev, void *arg, uint32_t channel, int status) { struct device *dev = arg; @@ -394,6 +417,12 @@ int spi_config(const struct device *dev, const struct spi_config *spi_cfg) ctx->config = spi_cfg; data->dfs_value = get_dfs_value(ctx); +#ifdef CONFIG_SPI_INFINEON_DMA + data->dma_rx.dma_cfg.source_data_size = data->dfs_value; + data->dma_rx.dma_cfg.dest_data_size = data->dfs_value; + data->dma_tx.dma_cfg.source_data_size = data->dfs_value; + data->dma_tx.dma_cfg.dest_data_size = data->dfs_value; +#endif return 0; } @@ -447,10 +476,11 @@ static int ifx_cat1_spi_release(const struct device *dev, const struct spi_confi { spi_free(dev); -#ifdef CONFIG_IFX_CAT1_SPI_DMA +#ifdef CONFIG_SPI_INFINEON_DMA struct ifx_cat1_spi_data *const data = dev->data; dma_stop(data->dma_tx.dev_dma, data->dma_tx.dma_channel); + dma_stop(data->dma_rx.dev_dma, data->dma_rx.dma_channel); #endif return 0; @@ -474,13 +504,7 @@ static int ifx_cat1_spi_init(const struct device *dev) data->resource.type = IFX_RSC_SCB; data->resource.block_num = ifx_cat1_uart_get_hw_block_num(config->reg_addr); -#ifdef CONFIG_IFX_CAT1_SPI_DMA - /* spi_rx_trigger is initialized to PERI_0_TRIG_IN_MUX_0_SCB_RX_TR_OUT0, - * this is incremented by the resource.block_num to get the trigger for the selected SCB - * from the trigmux enumeration (en_peri0_trig_input_pdma0_tr_t) - */ - data->spi_rx_trigger += data->resource.block_num; - +#ifdef CONFIG_SPI_INFINEON_DMA if (data->dma_rx.dev_dma != NULL) { if (!device_is_ready(data->dma_rx.dev_dma)) { return -ENODEV; @@ -491,6 +515,11 @@ static int ifx_cat1_spi_init(const struct device *dev) data->dma_rx.dma_cfg.head_block = &data->dma_rx.blk_cfg; data->dma_rx.dma_cfg.user_data = (void *)dev; data->dma_rx.dma_cfg.dma_callback = dma_callback; +#if defined(CONFIG_SOC_FAMILY_INFINEON_EDGE) + Cy_TrigMux_Connect(PERI_0_TRIG_IN_MUX_0_SCB_RX_TR_OUT0 + data->resource.block_num, + PERI_0_TRIG_OUT_MUX_0_PDMA0_TR_IN0 + data->dma_rx.dma_channel, + false, TRIGGER_TYPE_LEVEL); +#endif } if (data->dma_tx.dev_dma != NULL) { @@ -503,9 +532,12 @@ static int ifx_cat1_spi_init(const struct device *dev) data->dma_tx.dma_cfg.head_block = &data->dma_tx.blk_cfg; data->dma_tx.dma_cfg.user_data = (void *)dev; data->dma_tx.dma_cfg.dma_callback = dma_callback; +#if defined(CONFIG_SOC_FAMILY_INFINEON_EDGE) + Cy_TrigMux_Connect(PERI_0_TRIG_IN_MUX_0_SCB_TX_TR_OUT0 + data->resource.block_num, + PERI_0_TRIG_OUT_MUX_0_PDMA0_TR_IN0 + data->dma_tx.dma_channel, + false, TRIGGER_TYPE_EDGE); +#endif } - - Cy_TrigMux_Connect(data->spi_rx_trigger, data->dma_rx_trigger, false, TRIGGER_TYPE_LEVEL); #endif /* Configure dt provided device signals when available */ @@ -527,7 +559,7 @@ static int ifx_cat1_spi_init(const struct device *dev) return 0; } -#if defined(CONFIG_IFX_CAT1_SPI_DMA) +#if defined(CONFIG_SPI_INFINEON_DMA) #define SPI_DMA_CHANNEL_INIT(index, dir, ch_dir, src_data_size, dst_data_size) \ .dev_dma = DEVICE_DT_GET(DT_INST_DMAS_CTLR_BY_NAME(index, dir)), \ .dma_channel = DT_INST_DMAS_CELL_BY_NAME(index, dir, channel), \ @@ -546,15 +578,8 @@ static int ifx_cat1_spi_init(const struct device *dev) DT_INST_DMAS_HAS_NAME(index, dir), \ (SPI_DMA_CHANNEL_INIT(index, dir, ch_dir, src_data_size, dst_data_size)), \ (NULL))}, - -#define SPI_DMA_TRIGGERS(index) \ - .spi_rx_trigger = (en_peri0_trig_input_pdma0_tr_t)(PERI_0_TRIG_IN_MUX_0_SCB_RX_TR_OUT0), \ - .dma_rx_trigger = \ - (en_peri0_trig_output_pdma0_tr_t)(PERI_0_TRIG_OUT_MUX_0_PDMA0_TR_IN0 + \ - DT_INST_DMAS_CELL_BY_NAME(index, rx, channel)), #else #define SPI_DMA_CHANNEL(index, dir, ch_dir, src_data_size, dst_data_size) -#define SPI_DMA_TRIGGERS(index) #endif #if defined(COMPONENT_CAT1B) || defined(COMPONENT_CAT1C) || defined(CONFIG_SOC_FAMILY_INFINEON_EDGE) @@ -631,7 +656,7 @@ static int ifx_cat1_spi_init(const struct device *dev) .ssPolarity = DT_INST_PROP_OR(n, ss_polarity, CY_SCB_SPI_ACTIVE_LOW), \ .rxFifoTriggerLevel = DT_INST_PROP_OR(n, rx_fifo_trigger_level, 0), \ .rxFifoIntEnableMask = DT_INST_PROP_OR(n, rx_fifo_int_enable_mask, 0), \ - .txFifoTriggerLevel = DT_INST_PROP_OR(n, tx_fifo_trigger_level, 0), \ + .txFifoTriggerLevel = DT_INST_PROP_OR(n, tx_fifo_trigger_level, 1), \ .txFifoIntEnableMask = DT_INST_PROP_OR(n, tx_fifo_int_enable_mask, 0), \ .masterSlaveIntEnableMask = \ DT_INST_PROP_OR(n, master_slave_int_enable_mask, 0)}, \ @@ -647,7 +672,7 @@ static int ifx_cat1_spi_init(const struct device *dev) SPI_CONTEXT_INIT_LOCK(spi_cat1_data_##n, ctx), \ SPI_CONTEXT_INIT_SYNC(spi_cat1_data_##n, ctx), \ SPI_DMA_CHANNEL(n, tx, MEMORY_TO_PERIPHERAL, 1, 1) \ - SPI_DMA_CHANNEL(n, rx, PERIPHERAL_TO_MEMORY, 1, 1) SPI_DMA_TRIGGERS(n) \ + SPI_DMA_CHANNEL(n, rx, PERIPHERAL_TO_MEMORY, 1, 1) \ SPI_CONTEXT_CS_GPIOS_INITIALIZE(DT_DRV_INST(n), ctx) \ SPI_PERI_CLOCK_INIT(n) \ .spi_deep_sleep = { \ From 554a765de92aa9ca10f268f589e2b3ca79919682 Mon Sep 17 00:00:00 2001 From: Brandon Edmonds Date: Tue, 20 Jan 2026 16:20:28 -0500 Subject: [PATCH 0214/6328] drivers: sensor: shell: Add SENSOR_TRIG_TIMER to the sensor stream shell. In sensor_shell_stream.c, cmd_sensor_stream() checks for valid trigger types, but it is missing SENSOR_TRIG_TIMER option. Signed-off-by: Brandon Edmonds --- drivers/sensor/sensor_shell_stream.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/sensor/sensor_shell_stream.c b/drivers/sensor/sensor_shell_stream.c index e4a7e68cfb10..5ad6275376ba 100644 --- a/drivers/sensor/sensor_shell_stream.c +++ b/drivers/sensor/sensor_shell_stream.c @@ -90,6 +90,8 @@ int cmd_sensor_stream(const struct shell *sh, size_t argc, char *argv[]) iodev_sensor_shell_trigger.trigger = SENSOR_TRIG_FIFO_FULL; } else if (strcmp("tap", argv[3]) == 0) { iodev_sensor_shell_trigger.trigger = SENSOR_TRIG_TAP; + } else if (strcmp("timer", argv[3]) == 0) { + iodev_sensor_shell_trigger.trigger = SENSOR_TRIG_TIMER; } else { shell_error(sh, "Invalid trigger (%s)", argv[3]); return -EINVAL; From 705fc203e59ab660c54ab1b155ad245d209c7e05 Mon Sep 17 00:00:00 2001 From: Scott Worley Date: Tue, 20 Jan 2026 11:14:48 -0500 Subject: [PATCH 0215/6328] soc: microchip: mec: Disable deprecated MEC5 HAL for MEC165xB/174x/175x Due to multiple customer requests we are deprecating the MEC5 HAL. Customers prefer all code to be in the main Zephyr tree. They do not want a dependency on an outside SoC HAL. These changes remove the MEC5_HAL select from MEC165xB, MEC174x, and MEC175x. The SoC code calling the HAL for debug configuration was replaced with a small amount of code common to all SoC's. We also moved all the common header includes into a common SoC header to prevent changing multiple files if new common headers are added. Note: the in-tree drivers: kernel timer, GPIO, PINCTRL, and UART are all non-HAL. Signed-off-by: Scott Worley --- soc/microchip/mec/Kconfig | 2 +- soc/microchip/mec/common/CMakeLists.txt | 5 +- soc/microchip/mec/common/soc_cmn_init.c | 106 +++++++++++++++++++----- soc/microchip/mec/common/soc_common.h | 35 ++++++++ soc/microchip/mec/mec165xb/Kconfig | 1 - soc/microchip/mec/mec165xb/soc.h | 49 ++++++----- soc/microchip/mec/mec174x/Kconfig | 1 - soc/microchip/mec/mec174x/soc.h | 49 ++++++----- soc/microchip/mec/mec175x/Kconfig | 1 - soc/microchip/mec/mec175x/soc.h | 49 ++++++----- 10 files changed, 195 insertions(+), 103 deletions(-) create mode 100644 soc/microchip/mec/common/soc_common.h diff --git a/soc/microchip/mec/Kconfig b/soc/microchip/mec/Kconfig index c44f7e0500fe..e01a80a2a350 100644 --- a/soc/microchip/mec/Kconfig +++ b/soc/microchip/mec/Kconfig @@ -218,7 +218,7 @@ endif # MCHP_MEC_UNSIGNED_HEADER choice prompt "MEC debug interface general configuration" default SOC_MEC_DEBUG_AND_TRACING - depends on SOC_SERIES_MEC174X || SOC_SERIES_MEC175X + depends on SOC_SERIES_MEC174X || SOC_SERIES_MEC175X || SOC_SERIES_MEC165XB help Select Debug SoC interface support for MEC SoC family diff --git a/soc/microchip/mec/common/CMakeLists.txt b/soc/microchip/mec/common/CMakeLists.txt index 0f19288ae785..db7c071aff6b 100644 --- a/soc/microchip/mec/common/CMakeLists.txt +++ b/soc/microchip/mec/common/CMakeLists.txt @@ -1,13 +1,10 @@ # SPDX-License-Identifier: Apache-2.0 zephyr_include_directories(.) -zephyr_library_sources(soc_ecia.c soc_pcr.c) +zephyr_library_sources(soc_ecia.c soc_pcr.c soc_cmn_init.c) zephyr_library_sources_ifdef(CONFIG_SOC_SERIES_MEC172X soc_i2c.c ) -zephyr_library_sources_ifdef(CONFIG_HAS_MEC5_HAL - soc_cmn_init.c -) if(DEFINED CONFIG_MCHP_HEADER_VERBOSE_OUTPUT) set(MCHP_HEADER_VERBOSE_OPTION "-v") diff --git a/soc/microchip/mec/common/soc_cmn_init.c b/soc/microchip/mec/common/soc_cmn_init.c index ffb55dd9567a..f59032884b96 100644 --- a/soc/microchip/mec/common/soc_cmn_init.c +++ b/soc/microchip/mec/common/soc_cmn_init.c @@ -4,36 +4,102 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include +#include +#include +#include #include #include -#include -#include +#include + +#define XEC_ECS_ETM_CR_OFS 0x1cu +#define XEC_ECS_ETM_PINS_EN_POS 0 + +#define XEC_ECS_DGB_CR_OFS 0x20u +#define XEC_ECS_DBG_CR_EN_POS 0 +#define XEC_ECS_DBG_CR_PIN_CFG_POS 1 +#define XEC_ECS_DBG_CR_PIN_CFG_MSK GENMASK(2, 1) +#define XEC_ECS_DBG_CR_PIN_CFG_JTAG 0 +#define XEC_ECS_DBG_CR_PIN_CFG_SWD_SWV 1 +#define XEC_ECS_DBG_CR_PIN_CFG_SWD 2 +#define XEC_ECS_DBG_CR_PIN_CFG_SET(c) FIELD_PREP(XEC_ECS_DBG_CR_PIN_CFG_MSK, (c)) +#define XEC_ECS_DBG_CR_PIN_CFG_GET(r) FIELD_GET(XEC_ECS_DBG_CR_PIN_CFG_MSK, (r)) +#define XEC_ECS_DBG_CR_PU_EN_POS 3 +#define XEC_ECS_DBG_CR_EN_LOCK_POS 5 + +#define XEC_ECS_BASE_ADDR DT_REG_ADDR(DT_NODELABEL(ecs)) + +#define XEC_DEBUG_FLAG_EN_POS 0 +#define XEC_DEBUG_FLAG_ETM_EN_POS 1 +#define XEC_DEBUG_IFC_SWD_POS 2 +#define XEC_DEBUG_SWD_SWV_POS 3 +#define XEC_DEBUG_IFC_LOCK_POS 4 + +void mec_soc_debug_ifc_init(uint32_t flags) +{ + uint32_t msk = 0, val = 0; + + if ((flags & BIT(XEC_DEBUG_FLAG_ETM_EN_POS)) != 0) { + /* Switch shared GPIOs to ETM mode */ + sys_set_bit(XEC_ECS_BASE_ADDR + XEC_ECS_ETM_CR_OFS, XEC_ECS_ETM_PINS_EN_POS); + } else { + /* Disable ETM. ETM pins can be used as GPIOs */ + sys_clear_bit(XEC_ECS_BASE_ADDR + XEC_ECS_ETM_CR_OFS, XEC_ECS_ETM_PINS_EN_POS); + } + + if ((flags & BIT(XEC_DEBUG_FLAG_EN_POS)) != 0) { + msk = BIT(XEC_ECS_DBG_CR_EN_POS) | XEC_ECS_DBG_CR_PIN_CFG_MSK; + val = BIT(XEC_ECS_DBG_CR_EN_POS); + + if ((flags & BIT(XEC_DEBUG_IFC_LOCK_POS)) != 0) { + msk |= BIT(XEC_ECS_DBG_CR_EN_LOCK_POS); + val |= BIT(XEC_ECS_DBG_CR_EN_LOCK_POS); + } -static void mec5_soc_init_debug_interface(void) + if ((flags & BIT(XEC_DEBUG_IFC_SWD_POS)) != 0) { + if ((flags & BIT(XEC_DEBUG_SWD_SWV_POS)) != 0) { + val |= XEC_ECS_DBG_CR_PIN_CFG_SET(XEC_ECS_DBG_CR_PIN_CFG_SWD_SWV); + } else { + val |= XEC_ECS_DBG_CR_PIN_CFG_SET(XEC_ECS_DBG_CR_PIN_CFG_SWD); + } + } else { + val |= XEC_ECS_DBG_CR_PIN_CFG_SET(XEC_ECS_DBG_CR_PIN_CFG_JTAG); + } + + soc_mmcr_mask_set(XEC_ECS_BASE_ADDR + XEC_ECS_DGB_CR_OFS, val, msk); + } else { + sys_clear_bit(XEC_ECS_BASE_ADDR + XEC_ECS_DGB_CR_OFS, XEC_ECS_DBG_CR_EN_POS); + } +} + +int mec5_soc_common_init(void) { + uint32_t dbg_flags = 0; /* disabled */ + bool config_debug = false; + + /* Kconfig choice items. Only one will be defined */ #if defined(CONFIG_SOC_MEC_DEBUG_DISABLED) - mec_ecs_etm_pins(ECS_ETM_PINS_DISABLE); - mec_hal_ecs_debug_port(MEC_DEBUG_MODE_DISABLE); -#else + config_debug = true; +#endif #if defined(SOC_MEC_DEBUG_WITHOUT_TRACING) - mec_ecs_etm_pins(ECS_ETM_PINS_DISABLE); - mec_hal_ecs_debug_port(MEC_DEBUG_MODE_SWD); -#elif defined(SOC_MEC_DEBUG_AND_TRACING) -#if defined(SOC_MEC_DEBUG_AND_ETM_TRACING) - mec_ecs_etm_pins(ECS_ETM_PINS_DISABLE); - mec_hal_ecs_debug_port(MEC_DEBUG_MODE_SWD_SWV); -#elif defined(CONFIG_SOC_MEC_DEBUG_AND_ETM_TRACING) - mec_ecs_debug_port(MEC_DEBUG_MODE_SWD); - mec_hal_ecs_etm_pins(ECS_ETM_PINS_ENABLE); + config_debug = true; + dbg_flags = BIT(XEC_DEBUG_FLAG_EN_POS) | BIT(XEC_DEBUG_IFC_SWD_POS); #endif +#if defined(SOC_MEC_DEBUG_AND_TRACING) + config_debug = true; +#if defined(CONFIG_SOC_MEC_DEBUG_AND_SWV_TRACING) + dbg_flags = (BIT(XEC_DEBUG_FLAG_EN_POS) | BIT(XEC_DEBUG_IFC_SWD_POS) | + BIT(XEC_DEBUG_SWD_SWV_POS)); +#endif +#if defined(config SOC_MEC_DEBUG_AND_ETM_TRACING) + dbg_flags = (BIT(XEC_DEBUG_FLAG_EN_POS) | BIT(XEC_DEBUG_IFC_SWD_POS) | + BIT(XEC_DEBUG_FLAG_ETM_EN_POS)); #endif #endif -} -int mec5_soc_common_init(void) -{ - mec5_soc_init_debug_interface(); + if (config_debug == true) { + mec_soc_debug_ifc_init(dbg_flags); + } + soc_ecia_init(MCHP_MEC_ECIA_GIRQ_AGGR_ONLY_BM, MCHP_MEC_ECIA_GIRQ_DIRECT_CAP_BM, 0); return 0; diff --git a/soc/microchip/mec/common/soc_common.h b/soc/microchip/mec/common/soc_common.h new file mode 100644 index 000000000000..e45d965dc453 --- /dev/null +++ b/soc/microchip/mec/common/soc_common.h @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2026 Microchip Technology Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef __SOC_MICROCHIP_MEC_COMMON_SOC_COMMON_H +#define __SOC_MICROCHIP_MEC_COMMON_SOC_COMMON_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* common SoC API */ +#include +#include +#include +#include +#include +#include +#include + +#endif /* __SOC_MICROCHIP_MEC_COMMON_SOC_COMMON_H */ diff --git a/soc/microchip/mec/mec165xb/Kconfig b/soc/microchip/mec/mec165xb/Kconfig index 79ff7dd7e0fb..615c549f6c7e 100644 --- a/soc/microchip/mec/mec165xb/Kconfig +++ b/soc/microchip/mec/mec165xb/Kconfig @@ -9,5 +9,4 @@ config SOC_SERIES_MEC165XB select CPU_CORTEX_M_HAS_DWT select CPU_HAS_ARM_MPU select HAS_SWO - select HAS_MEC5_HAL select SOC_PREP_HOOK diff --git a/soc/microchip/mec/mec165xb/soc.h b/soc/microchip/mec/mec165xb/soc.h index 545b8a1d102f..7352a64c9332 100644 --- a/soc/microchip/mec/mec165xb/soc.h +++ b/soc/microchip/mec/mec165xb/soc.h @@ -13,33 +13,32 @@ #define MCHP_HAS_UART_LSR2 -#include +/* Minimal ARM CMSIS requirements */ +typedef enum { + Reset_IRQn = -15, + NonMaskableInt_IRQn = -14, + HardFault_IRQn = -13, + MemoryManagement_IRQn = -12, + BusFault_IRQn = -11, + UsageFault_IRQn = -10, + SVCall_IRQn = -5, + DebugMonitor_IRQn = -4, + PendSV_IRQn = -2, + SysTick_IRQn = -1, + FirstPeriph_IRQn = 0, + LastPeriph_IRQn = 197, +} IRQn_Type; + +#define __CM4_REV 0x0201U /* CM4 Core Revision */ +#define __NVIC_PRIO_BITS 3 /* Number of Bits used for Priority Levels */ +#define __Vendor_SysTickConfig 0 /* Set to 1 if different SysTick Config is used */ +#define __MPU_PRESENT 1 /* MPU present */ +#define __FPU_PRESENT 0 /* FPU present */ + +#include /* common peripheral register defines */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* common SoC API */ -#include -#include -#include -#include -#include -#include -#include +#include #endif #endif diff --git a/soc/microchip/mec/mec174x/Kconfig b/soc/microchip/mec/mec174x/Kconfig index bdee97015bc6..82182478c59b 100644 --- a/soc/microchip/mec/mec174x/Kconfig +++ b/soc/microchip/mec/mec174x/Kconfig @@ -10,7 +10,6 @@ config SOC_SERIES_MEC174X select CPU_HAS_FPU select CPU_HAS_ARM_MPU select HAS_SWO - select HAS_MEC5_HAL select SOC_PREP_HOOK if SOC_SERIES_MEC174X diff --git a/soc/microchip/mec/mec174x/soc.h b/soc/microchip/mec/mec174x/soc.h index cdfc1f228ccd..dc4515e15e1f 100644 --- a/soc/microchip/mec/mec174x/soc.h +++ b/soc/microchip/mec/mec174x/soc.h @@ -13,33 +13,32 @@ #define MCHP_HAS_UART_LSR2 -#include +/* Minimal ARM CMSIS requirements */ +typedef enum { + Reset_IRQn = -15, + NonMaskableInt_IRQn = -14, + HardFault_IRQn = -13, + MemoryManagement_IRQn = -12, + BusFault_IRQn = -11, + UsageFault_IRQn = -10, + SVCall_IRQn = -5, + DebugMonitor_IRQn = -4, + PendSV_IRQn = -2, + SysTick_IRQn = -1, + FirstPeriph_IRQn = 0, + LastPeriph_IRQn = 197, +} IRQn_Type; + +#define __CM4_REV 0x0201U /* CM4 Core Revision */ +#define __NVIC_PRIO_BITS 3 /* Number of Bits used for Priority Levels */ +#define __Vendor_SysTickConfig 0 /* Set to 1 if different SysTick Config is used */ +#define __MPU_PRESENT 1 /* MPU present */ +#define __FPU_PRESENT 1 /* FPU present */ + +#include /* common peripheral register defines */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* common SoC API */ -#include -#include -#include -#include -#include -#include -#include +#include #endif #endif diff --git a/soc/microchip/mec/mec175x/Kconfig b/soc/microchip/mec/mec175x/Kconfig index e2136d7a2df9..4f6b9d93f74d 100644 --- a/soc/microchip/mec/mec175x/Kconfig +++ b/soc/microchip/mec/mec175x/Kconfig @@ -10,7 +10,6 @@ config SOC_SERIES_MEC175X select CPU_HAS_FPU select CPU_HAS_ARM_MPU select HAS_SWO - select HAS_MEC5_HAL select SOC_PREP_HOOK if SOC_SERIES_MEC175X diff --git a/soc/microchip/mec/mec175x/soc.h b/soc/microchip/mec/mec175x/soc.h index 93b1987e033b..8174038d8277 100644 --- a/soc/microchip/mec/mec175x/soc.h +++ b/soc/microchip/mec/mec175x/soc.h @@ -13,33 +13,32 @@ #define MCHP_HAS_UART_LSR2 -#include +/* Minimal ARM CMSIS requirements */ +typedef enum { + Reset_IRQn = -15, + NonMaskableInt_IRQn = -14, + HardFault_IRQn = -13, + MemoryManagement_IRQn = -12, + BusFault_IRQn = -11, + UsageFault_IRQn = -10, + SVCall_IRQn = -5, + DebugMonitor_IRQn = -4, + PendSV_IRQn = -2, + SysTick_IRQn = -1, + FirstPeriph_IRQn = 0, + LastPeriph_IRQn = 197, +} IRQn_Type; + +#define __CM4_REV 0x0201U /* CM4 Core Revision */ +#define __NVIC_PRIO_BITS 3 /* Number of Bits used for Priority Levels */ +#define __Vendor_SysTickConfig 0 /* Set to 1 if different SysTick Config is used */ +#define __MPU_PRESENT 1 /* MPU present */ +#define __FPU_PRESENT 1 /* FPU present */ + +#include /* common peripheral register defines */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* common SoC API */ -#include -#include -#include -#include -#include -#include -#include +#include #endif #endif From 64c88e9bb317ddaa13ebef640bf6281ea8c7f9d9 Mon Sep 17 00:00:00 2001 From: Dave Lacerte Date: Thu, 22 Jan 2026 08:39:50 -0500 Subject: [PATCH 0216/6328] boards: arduino: portenta_h7 : Update doc about WiFi functionality Removes a forgotten note about the WiFi feature, which is now supported. Signed-off-by: Dave Lacerte --- boards/arduino/portenta_h7/doc/index.rst | 2 -- 1 file changed, 2 deletions(-) diff --git a/boards/arduino/portenta_h7/doc/index.rst b/boards/arduino/portenta_h7/doc/index.rst index b0eca10b6ec4..c4604b28f91f 100644 --- a/boards/arduino/portenta_h7/doc/index.rst +++ b/boards/arduino/portenta_h7/doc/index.rst @@ -36,8 +36,6 @@ information on how to build for specific revisions of the board). Applications that intend to use BLE must specify hardware revision at build time. -Currently only BLE is supported on this board, WiFi is not supported. - Fetch Binary Blobs ****************** From 0f80ee260de73464ca4f783744f6882f93d7a980 Mon Sep 17 00:00:00 2001 From: Thinh Le Cong Date: Wed, 24 Sep 2025 12:43:21 +0700 Subject: [PATCH 0217/6328] drivers: spi: Initial support for SCI SPI driver on Renesas RA Add SCI SPI driver support on Renesas RA devices Signed-off-by: Thinh Le Cong --- drivers/spi/CMakeLists.txt | 1 + drivers/spi/Kconfig.renesas_ra | 27 + drivers/spi/spi_renesas_ra_sci.c | 723 +++++++++++++++++++++++ dts/bindings/spi/renesas,ra-spi-sci.yaml | 13 + modules/Kconfig.renesas | 5 + 5 files changed, 769 insertions(+) create mode 100644 drivers/spi/spi_renesas_ra_sci.c create mode 100644 dts/bindings/spi/renesas,ra-spi-sci.yaml diff --git a/drivers/spi/CMakeLists.txt b/drivers/spi/CMakeLists.txt index ca5652b60acd..c629c45c7046 100644 --- a/drivers/spi/CMakeLists.txt +++ b/drivers/spi/CMakeLists.txt @@ -57,6 +57,7 @@ zephyr_library_sources_ifdef(CONFIG_SPI_PW spi_pw.c) zephyr_library_sources_ifdef(CONFIG_SPI_REALTEK_RTS5912 spi_rts5912_spi.c) zephyr_library_sources_ifdef(CONFIG_SPI_RENESAS_RA spi_renesas_ra.c) zephyr_library_sources_ifdef(CONFIG_SPI_RENESAS_RA8 spi_b_renesas_ra8.c) +zephyr_library_sources_ifdef(CONFIG_SPI_RENESAS_RA_SCI spi_renesas_ra_sci.c) zephyr_library_sources_ifdef(CONFIG_SPI_RENESAS_RA_SCI_B spi_renesas_ra_sci_b.c) zephyr_library_sources_ifdef(CONFIG_SPI_RENESAS_RX spi_renesas_rx.c) zephyr_library_sources_ifdef(CONFIG_SPI_RENESAS_RZ spi_renesas_rz.c) diff --git a/drivers/spi/Kconfig.renesas_ra b/drivers/spi/Kconfig.renesas_ra index 9ad2d670fff8..33aabcccf188 100644 --- a/drivers/spi/Kconfig.renesas_ra +++ b/drivers/spi/Kconfig.renesas_ra @@ -34,6 +34,33 @@ config SPI_USE_HW_SS endif # SPI_RENESAS_RA +config SPI_RENESAS_RA_SCI + bool "Renesas RA SCI SPI" + default y + depends on DT_HAS_RENESAS_RA_SPI_SCI_ENABLED + select SPI_RENESAS_RA_SCI_INTERRUPT if SPI_ASYNC + select USE_RA_FSP_SCI_SPI + select PINCTRL + help + Enable Renesas RA SCI SPI Driver. + +if SPI_RENESAS_RA_SCI + +config SPI_RENESAS_RA_SCI_INTERRUPT + bool "RENESAS RA SCI SPI Interrupt Support" + depends on SPI_ASYNC + help + Enable Interrupt support for the SCI SPI Driver of RA family. + +config SPI_RENESAS_RA_SCI_DTC + bool "RA MCU SCI SPI DTC Support" + depends on SPI_RENESAS_RA_SCI_INTERRUPT + select USE_RA_FSP_DTC + help + Enable DTC support for the SCI SPI Driver of RA family. + +endif # SPI_RENESAS_RA_SCI + config SPI_RENESAS_RA_SCI_B bool "Renesas RA SCI B SPI" default y diff --git a/drivers/spi/spi_renesas_ra_sci.c b/drivers/spi/spi_renesas_ra_sci.c new file mode 100644 index 000000000000..68621b060250 --- /dev/null +++ b/drivers/spi/spi_renesas_ra_sci.c @@ -0,0 +1,723 @@ +/* + * Copyright (c) 2024-2025 Renesas Electronics Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT renesas_ra_spi_sci + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +LOG_MODULE_REGISTER(renesas_ra_spi_sci); + +#include "spi_context.h" + +struct renesas_ra_sci_spi_config { + const struct pinctrl_dev_config *pcfg; + const struct device *clock_dev; + const struct clock_control_ra_subsys_cfg clock_subsys; + void (*irq_configure)(const struct device *dev); +}; + +struct renesas_ra_sci_spi_data { + struct spi_context ctx; + struct spi_config config; + sci_spi_instance_ctrl_t fsp_ctrl; + spi_cfg_t fsp_cfg; + sci_spi_extended_cfg_t fsp_ext_cfg; + bool is_cs_active_state_same; +#ifdef CONFIG_SPI_RENESAS_RA_SCI_INTERRUPT + uint32_t data_len; +#endif +#ifdef CONFIG_SPI_RENESAS_RA_SCI_DTC + /* RX */ + struct st_transfer_instance rx_transfer; + struct st_dtc_instance_ctrl rx_transfer_ctrl; + struct st_transfer_info rx_transfer_info DTC_TRANSFER_INFO_ALIGNMENT; + struct st_transfer_cfg rx_transfer_cfg; + struct st_dtc_extended_cfg rx_transfer_cfg_extend; + + /* TX */ + struct st_transfer_instance tx_transfer; + struct st_dtc_instance_ctrl tx_transfer_ctrl; + struct st_transfer_info tx_transfer_info DTC_TRANSFER_INFO_ALIGNMENT; + struct st_transfer_cfg tx_transfer_cfg; + struct st_dtc_extended_cfg tx_transfer_cfg_extend; +#endif /* CONFIG_SPI_RENESAS_RA_SCI_DTC */ +}; + +#ifdef CONFIG_SPI_RENESAS_RA_SCI_INTERRUPT +extern void sci_spi_txi_isr(void); +extern void sci_spi_rxi_isr(void); +extern void sci_spi_tei_isr(void); +extern void sci_spi_eri_isr(void); +#endif + +#define CS_GPIO_LOW_WHEN_ACTIVE true +#define CS_GPIO_HIGH_WHEN_ACTIVE false + +#define SCI_RENESAS_RA_IRQ_GET(id, name, cell) \ + COND_CODE_1(DT_IRQ_HAS_NAME(id, name), (DT_IRQ_BY_NAME(id, name, cell)), \ + ((IRQn_Type) FSP_INVALID_VECTOR)) +/* + * This function help to control the cs gpio when changing the CS GPIO active state in + * runtime. + */ +static inline void _renesas_ra_spi_context_cs_control(const struct device *dev, bool on, + bool force_off) +{ + struct renesas_ra_sci_spi_data *data = dev->data; + struct spi_context *ctx = &data->ctx; + + if ((ctx->config) && spi_cs_is_gpio(ctx->config)) { + if (on) { + gpio_pin_set_dt(&ctx->config->cs.gpio, + (data->is_cs_active_state_same) ? 1 : 0); + k_busy_wait(ctx->config->cs.delay); + } else { + if ((!force_off) && (ctx->config->operation & SPI_HOLD_ON_CS)) { + return; + } + k_busy_wait(ctx->config->cs.delay); + gpio_pin_set_dt(&ctx->config->cs.gpio, + (data->is_cs_active_state_same) ? 0 : 1); + } + } +} + +/* + * This function should be called by drivers to control the chip select line in master mode + * in the case of the CS being a GPIO, help to control the cs gpio when changing the CS GPIO + * active state in runtime. + */ +static inline void renesas_ra_spi_context_cs_control(const struct device *dev, bool on) +{ + _renesas_ra_spi_context_cs_control(dev, on, false); +} + +/* + * Forcefully releases the spi context and removes the owner, allowing taking the lock + * with spi_context_lock without the previous owner releasing the lock. + * This function help to control the cs gpio when changing the CS GPIO active state in + * runtime. + */ +static inline void renesas_ra_spi_context_unlock_unconditionally(const struct device *dev) +{ + struct renesas_ra_sci_spi_data *data = dev->data; + struct spi_context *ctx = &data->ctx; + + /* Forcing CS to go to inactive status */ + _renesas_ra_spi_context_cs_control(dev, false, true); + +#ifdef CONFIG_MULTITHREADING + if (!k_sem_count_get(&ctx->lock)) { + ctx->owner = NULL; + k_sem_give(&ctx->lock); + } +#endif /* CONFIG_MULTITHREADING */ +} + +/* Check whether the configuration is similar */ +static inline bool renesas_ra_sci_context_configured(const struct device *dev, + const struct spi_config *config) +{ + struct renesas_ra_sci_spi_data *data = dev->data; + + if ((data->config.frequency == config->frequency) && + (data->config.operation == config->operation) && + (data->config.slave == config->slave)) { + return true; + } + + return false; +} + +#ifdef CONFIG_SPI_RENESAS_RA_SCI_INTERRUPT +static bool renesas_ra_sci_spi_transfer_ongoing(struct renesas_ra_sci_spi_data *data) +{ + return (spi_context_tx_on(&data->ctx) || spi_context_rx_on(&data->ctx)); +} + +static void renesas_ra_sci_spi_retransmit(struct renesas_ra_sci_spi_data *data) +{ + fsp_err_t fsp_err; + + data->data_len = spi_context_max_continuous_chunk(&data->ctx); + + if (data->ctx.rx_buf == NULL) { + fsp_err = R_SCI_SPI_Write(&data->fsp_ctrl, data->ctx.tx_buf, data->data_len, + SPI_BIT_WIDTH_8_BITS); + } else if (data->ctx.tx_buf == NULL) { + fsp_err = R_SCI_SPI_Read(&data->fsp_ctrl, data->ctx.rx_buf, data->data_len, + SPI_BIT_WIDTH_8_BITS); + } else { + fsp_err = R_SCI_SPI_WriteRead(&data->fsp_ctrl, data->ctx.tx_buf, data->ctx.rx_buf, + data->data_len, SPI_BIT_WIDTH_8_BITS); + } + + if (fsp_err != FSP_SUCCESS) { + LOG_ERR("SCI SPI transfer failed %d", fsp_err); + return; + } +} + +static void renesas_ra_sci_spi_callback(spi_callback_args_t *p_args) +{ + struct device *dev = (struct device *)p_args->p_context; + struct renesas_ra_sci_spi_data *data = dev->data; + uint32_t data_receive_len; + + switch (p_args->event) { + case SPI_EVENT_TRANSFER_COMPLETE: + if (!spi_context_is_slave(&data->ctx)) { + if (data->fsp_ctrl.rx_count == data->fsp_ctrl.count || + data->fsp_ctrl.tx_count == data->fsp_ctrl.count) { + + data_receive_len = !!data->fsp_ctrl.rx_count + ? data->fsp_ctrl.rx_count + : data->ctx.rx_len; + + spi_context_update_rx(&data->ctx, 1, data_receive_len); + } + + if (data->fsp_ctrl.tx_count == data->fsp_ctrl.count) { + spi_context_update_tx(&data->ctx, 1, data->data_len); + } + + if (renesas_ra_sci_spi_transfer_ongoing(data)) { + renesas_ra_sci_spi_retransmit(data); + return; + } + } +#ifdef CONFIG_SPI_SLAVE + else if (data->fsp_ctrl.rx_count == data->fsp_ctrl.count) { + if (data->ctx.rx_buf != NULL && data->ctx.tx_buf != NULL) { + data->ctx.recv_frames = MIN(spi_context_total_tx_len(&data->ctx), + spi_context_total_rx_len(&data->ctx)); + } else if (data->ctx.tx_buf == NULL) { + data->ctx.recv_frames = data->data_len; + } else { + /* Do nothing */ + } + } +#endif /* CONFIG_SPI_SLAVE */ + renesas_ra_spi_context_cs_control(dev, false); + spi_context_complete(&data->ctx, dev, 0); + break; + case SPI_EVENT_ERR_READ_OVERFLOW: + renesas_ra_spi_context_cs_control(dev, false); + spi_context_complete(&data->ctx, dev, -EIO); + break; + default: + break; + } +} +#endif + +static int renesas_ra_sci_spi_configure(const struct device *dev, const struct spi_config *config) +{ + struct renesas_ra_sci_spi_data *data = dev->data; + fsp_err_t fsp_err; + + /* Check whether the congiguration is changed */ + if (renesas_ra_sci_context_configured(dev, config)) { + return 0; + } + + if ((config->operation & SPI_FRAME_FORMAT_TI) == SPI_FRAME_FORMAT_TI) { + LOG_ERR("TI frame format is not supported"); + return -ENOTSUP; + } + + if (SPI_MODE_GET(config->operation) & SPI_MODE_LOOP) { + LOG_ERR("Internal hardware loopback is not supported"); + return -ENOTSUP; + } + + if (SPI_WORD_SIZE_GET(config->operation) != 8) { + LOG_ERR("Word sizes other than 8 bits are not supported"); + return -ENOTSUP; + } + + if ((config->operation & SPI_OP_MODE_SLAVE) && !IS_ENABLED(CONFIG_SPI_SLAVE)) { + LOG_ERR("Kconfig for enable SPI in slave mode is not enabled"); + return -ENOTSUP; + } + + if (config->operation & SPI_HALF_DUPLEX) { + LOG_ERR("Half-duplex not supported"); + return -ENOTSUP; + } + + if ((SPI_OP_MODE_GET(config->operation) == SPI_OP_MODE_MASTER) && + (config->frequency == 0)) { + LOG_ERR("Invalid frequency value"); + return -EINVAL; + } + + if (config->frequency > 2500000) { + LOG_ERR("Frequencies more than 2,5 MHz are not supported"); + return -EINVAL; + } + + if (SPI_OP_MODE_GET(config->operation) == SPI_OP_MODE_SLAVE) { + data->fsp_cfg.operating_mode = SPI_MODE_SLAVE; + } else { + data->fsp_cfg.operating_mode = SPI_MODE_MASTER; + } + + if (SPI_MODE_GET(config->operation) & SPI_MODE_CPOL) { + data->fsp_cfg.clk_polarity = SPI_CLK_POLARITY_HIGH; + } else { + data->fsp_cfg.clk_polarity = SPI_CLK_POLARITY_LOW; + } + + if (SPI_MODE_GET(config->operation) & SPI_MODE_CPHA) { + data->fsp_cfg.clk_phase = SPI_CLK_PHASE_EDGE_EVEN; + } else { + data->fsp_cfg.clk_phase = SPI_CLK_PHASE_EDGE_ODD; + } + + if (config->operation & SPI_TRANSFER_LSB) { + data->fsp_cfg.bit_order = SPI_BIT_ORDER_LSB_FIRST; + } else { + data->fsp_cfg.bit_order = SPI_BIT_ORDER_MSB_FIRST; + } + + if (SPI_OP_MODE_GET(config->operation) == SPI_OP_MODE_MASTER) { + fsp_err = R_SCI_SPI_CalculateBitrate(config->frequency, &data->fsp_ext_cfg.clk_div, + true); + if (fsp_err != FSP_SUCCESS) { + return -EINVAL; + } + } + + data->fsp_cfg.p_extend = &data->fsp_ext_cfg; +#ifdef CONFIG_SPI_RENESAS_RA_SCI_INTERRUPT + data->fsp_cfg.p_callback = renesas_ra_sci_spi_callback; +#else + data->fsp_cfg.p_callback = NULL; +#endif /* CONFIG_SPI_RENESAS_RA_SCI_INTERRUPT */ + data->fsp_cfg.p_context = (void *)dev; + + if (data->fsp_ctrl.open != 0) { + fsp_err = R_SCI_SPI_Close(&data->fsp_ctrl); + if (fsp_err != FSP_SUCCESS) { + return -EIO; + } + + memset(&data->config, 0, sizeof(struct spi_config)); + } + + fsp_err = R_SCI_SPI_Open(&data->fsp_ctrl, &data->fsp_cfg); + if (fsp_err != FSP_SUCCESS) { + LOG_ERR("Failed to apply spi configuration"); + return -EINVAL; + } + + memcpy(&data->config, config, sizeof(struct spi_config)); + data->ctx.config = &data->config; + + return 0; +} + +static int transceive(const struct device *dev, const struct spi_config *config, + const struct spi_buf_set *tx_bufs, const struct spi_buf_set *rx_bufs, + bool asynchronous, spi_callback_t cb, void *userdata) +{ + struct renesas_ra_sci_spi_data *data = dev->data; + bool cs_gpio_logic_when_active; + bool cs_active_logic_config; + int ret; + fsp_err_t fsp_err; +#ifndef CONFIG_SPI_RENESAS_RA_SCI_INTERRUPT + size_t len; +#endif + + if (!tx_bufs && !rx_bufs) { + return 0; + } + +#ifndef CONFIG_SPI_RENESAS_RA_SCI_INTERRUPT + if (asynchronous) { + return -ENOTSUP; + } +#endif /* CONFIG_SPI_RENESAS_RA_SCI_INTERRUPT */ + + spi_context_lock(&data->ctx, asynchronous, cb, userdata, config); + + ret = renesas_ra_sci_spi_configure(dev, config); + if (ret) { + goto release; + } + + /* + * For SCI SPI, the hardware only supports 8-bit frames, + * so the data frame size must be 1 byte + */ + spi_context_buffers_setup(&data->ctx, tx_bufs, rx_bufs, 1); + + /* + * The GPIO flags GPIO_ACTIVE_LOW/GPIO_ACTIVE_HIGH should be equivalent + * to SPI_CS_ACTIVE_HIGH/SPI_CS_ACTIVE_LOW options in struct spi_config. + * In runtime, there are some peripherals that need the CS level contrast + * to the CS defined in the device tree to make some actions such as + * initialization. Ex: PMOD SD_CARD + */ + cs_gpio_logic_when_active = !!(data->ctx.config->cs.gpio.dt_flags & GPIO_ACTIVE_LOW) + ? CS_GPIO_LOW_WHEN_ACTIVE + : CS_GPIO_HIGH_WHEN_ACTIVE; + cs_active_logic_config = !!(data->ctx.config->operation & SPI_CS_ACTIVE_HIGH) + ? CS_GPIO_HIGH_WHEN_ACTIVE + : CS_GPIO_LOW_WHEN_ACTIVE; + if (cs_gpio_logic_when_active == cs_active_logic_config) { + data->is_cs_active_state_same = true; + } else { + data->is_cs_active_state_same = false; + } + + renesas_ra_spi_context_cs_control(dev, true); + + /* If current buffer has no data, do nothing */ + if (!spi_context_tx_buf_on(&data->ctx) && !spi_context_rx_buf_on(&data->ctx)) { + goto release; + } + +#ifdef CONFIG_SPI_RENESAS_RA_SCI_INTERRUPT + if (data->ctx.rx_len == 0) { + data->data_len = spi_context_is_slave(&data->ctx) + ? spi_context_total_tx_len(&data->ctx) + : data->ctx.tx_len; + } else if (data->ctx.tx_len == 0) { + data->data_len = spi_context_is_slave(&data->ctx) + ? spi_context_total_rx_len(&data->ctx) + : data->ctx.rx_len; + } else { + data->data_len = spi_context_is_slave(&data->ctx) + ? MAX(spi_context_total_tx_len(&data->ctx), + spi_context_total_rx_len(&data->ctx)) + : MIN(data->ctx.tx_len, data->ctx.rx_len); + } + + if (data->ctx.rx_buf == NULL) { + fsp_err = R_SCI_SPI_Write(&data->fsp_ctrl, data->ctx.tx_buf, data->data_len, + SPI_BIT_WIDTH_8_BITS); + } else if (data->ctx.tx_buf == NULL) { + fsp_err = R_SCI_SPI_Read(&data->fsp_ctrl, data->ctx.rx_buf, data->data_len, + SPI_BIT_WIDTH_8_BITS); + } else { + fsp_err = R_SCI_SPI_WriteRead(&data->fsp_ctrl, data->ctx.tx_buf, data->ctx.rx_buf, + data->data_len, SPI_BIT_WIDTH_8_BITS); + } + + if (fsp_err != FSP_SUCCESS) { + ret = -EIO; + goto release; + } + + ret = spi_context_wait_for_completion(&data->ctx); +#else + fsp_err = RP_SCI_SPI_StartTransferPolling(&data->fsp_ctrl); + if (fsp_err != FSP_SUCCESS) { + ret = -EIO; + goto release; + } + + while (spi_context_tx_on(&data->ctx) || spi_context_rx_on(&data->ctx)) { + size_t tx_len = data->ctx.tx_len; + size_t rx_len = data->ctx.rx_len; + + len = MIN(tx_len, rx_len); + if (len > 0) { + fsp_err = RP_SCI_SPI_WriteReadPolling(&data->fsp_ctrl, data->ctx.tx_buf, + data->ctx.rx_buf, len); + if (fsp_err != FSP_SUCCESS) { + ret = -EIO; + break; + } + + if (spi_context_tx_buf_on(&data->ctx)) { + spi_context_update_tx(&data->ctx, 1, len); + } + + if (spi_context_rx_on(&data->ctx)) { + spi_context_update_rx(&data->ctx, 1, len); + } + } + + if (spi_context_tx_on(&data->ctx) && !spi_context_rx_on(&data->ctx)) { + fsp_err = RP_SCI_SPI_WritePolling(&data->fsp_ctrl, data->ctx.tx_buf, + data->ctx.tx_len); + if (fsp_err != FSP_SUCCESS) { + ret = -EIO; + break; + } + + spi_context_update_tx(&data->ctx, 1, data->ctx.tx_len); + } + + if (spi_context_rx_on(&data->ctx) && !spi_context_tx_on(&data->ctx)) { + fsp_err = RP_SCI_SPI_ReadPolling(&data->fsp_ctrl, data->ctx.rx_buf, + data->ctx.rx_len); + if (fsp_err != FSP_SUCCESS) { + ret = -EIO; + break; + } + + spi_context_update_rx(&data->ctx, 1, data->ctx.rx_len); + } + } + + fsp_err = RP_SCI_SPI_EndTransferPolling(&data->fsp_ctrl); + if (fsp_err != FSP_SUCCESS) { + ret = -EIO; + } + + spi_context_complete(&data->ctx, dev, ret); +#endif /* CONFIG_SPI_RENESAS_RA_SCI_INTERRUPT */ + +#ifdef CONFIG_SPI_SLAVE + if (spi_context_is_slave(&data->ctx) && !ret) { + ret = data->ctx.recv_frames; + } +#endif /* CONFIG_SPI_SLAVE */ + +release: + if ((ret < 0) || !IS_ENABLED(CONFIG_SPI_RENESAS_RA_SCI_INTERRUPT)) { + renesas_ra_spi_context_cs_control(dev, false); + } + + spi_context_release(&data->ctx, ret); + + return ret; +} + +static int renesas_ra_sci_spi_transceive(const struct device *dev, const struct spi_config *config, + const struct spi_buf_set *tx_bufs, + const struct spi_buf_set *rx_bufs) +{ + return transceive(dev, config, tx_bufs, rx_bufs, false, NULL, NULL); +} + +#ifdef CONFIG_SPI_ASYNC +static int renesas_ra_sci_spi_transceive_async(const struct device *dev, + const struct spi_config *config, + const struct spi_buf_set *tx_bufs, + const struct spi_buf_set *rx_bufs, spi_callback_t cb, + void *userdata) +{ + return transceive(dev, config, tx_bufs, rx_bufs, true, cb, userdata); +} +#endif /* CONFIG_SPI_ASYNC */ + +static int renesas_ra_sci_spi_release(const struct device *dev, const struct spi_config *config) +{ + ARG_UNUSED(config); + renesas_ra_spi_context_unlock_unconditionally(dev); + + return 0; +} + +static int renesas_ra_sci_spi_init(const struct device *dev) +{ + const struct renesas_ra_sci_spi_config *config = dev->config; + struct renesas_ra_sci_spi_data *data = dev->data; + const struct device *clock_dev = config->clock_dev; + int ret; +#ifdef DT_SPI_CTX_HAS_NO_CS_GPIOS + ARG_UNUSED(data); +#endif + +#ifdef CONFIG_SPI_RENESAS_RA_SCI_DTC + data->fsp_cfg.p_transfer_rx = &data->rx_transfer; + data->fsp_cfg.p_transfer_tx = &data->tx_transfer; +#endif + + if (!device_is_ready(clock_dev)) { + return -ENODEV; + } + + ret = clock_control_on(config->clock_dev, (clock_control_subsys_t)&config->clock_subsys); + if (ret < 0) { + return ret; + } + + ret = pinctrl_apply_state(config->pcfg, PINCTRL_STATE_DEFAULT); + if (ret < 0) { + return ret; + } + + ret = spi_context_cs_configure_all(&data->ctx); + if (ret < 0) { + return ret; + } + + config->irq_configure(dev); + + renesas_ra_spi_context_unlock_unconditionally(dev); + + return 0; +} + +static DEVICE_API(spi, renesas_ra_sci_spi_driver_api) = { + .transceive = renesas_ra_sci_spi_transceive, +#ifdef CONFIG_SPI_ASYNC + .transceive_async = renesas_ra_sci_spi_transceive_async, +#endif /* CONFIG_SPI_ASYNC */ + .release = renesas_ra_sci_spi_release, +}; + +#define EVENT_SCI_RXI(channel) BSP_PRV_IELS_ENUM(CONCAT(EVENT_SCI, channel, _RXI)) +#define EVENT_SCI_TXI(channel) BSP_PRV_IELS_ENUM(CONCAT(EVENT_SCI, channel, _TXI)) +#define EVENT_SCI_TEI(channel) BSP_PRV_IELS_ENUM(CONCAT(EVENT_SCI, channel, _TEI)) +#define EVENT_SCI_ERI(channel) BSP_PRV_IELS_ENUM(CONCAT(EVENT_SCI, channel, _ERI)) + +#ifdef CONFIG_SPI_RENESAS_RA_SCI_INTERRUPT + +#define RENESAS_RA_IRQ_CONFIG_FUNC(index) \ + static void sci_spi_config_func_##index(const struct device *dev) \ + { \ + ARG_UNUSED(dev); \ + \ + R_ICU->IELSR[DT_IRQ_BY_NAME(DT_INST_PARENT(index), rxi, irq)] = \ + EVENT_SCI_RXI(DT_INST_PROP(index, channel)); \ + R_ICU->IELSR[DT_IRQ_BY_NAME(DT_INST_PARENT(index), txi, irq)] = \ + EVENT_SCI_TXI(DT_INST_PROP(index, channel)); \ + R_ICU->IELSR[DT_IRQ_BY_NAME(DT_INST_PARENT(index), tei, irq)] = \ + EVENT_SCI_TEI(DT_INST_PROP(index, channel)); \ + R_ICU->IELSR[DT_IRQ_BY_NAME(DT_INST_PARENT(index), eri, irq)] = \ + EVENT_SCI_ERI(DT_INST_PROP(index, channel)); \ + \ + IRQ_CONNECT(DT_IRQ_BY_NAME(DT_INST_PARENT(index), rxi, irq), \ + DT_IRQ_BY_NAME(DT_INST_PARENT(index), rxi, priority), sci_spi_rxi_isr, \ + DEVICE_DT_INST_GET(index), 0); \ + IRQ_CONNECT(DT_IRQ_BY_NAME(DT_INST_PARENT(index), txi, irq), \ + DT_IRQ_BY_NAME(DT_INST_PARENT(index), txi, priority), sci_spi_txi_isr, \ + DEVICE_DT_INST_GET(index), 0); \ + IRQ_CONNECT(DT_IRQ_BY_NAME(DT_INST_PARENT(index), tei, irq), \ + DT_IRQ_BY_NAME(DT_INST_PARENT(index), tei, priority), sci_spi_tei_isr, \ + DEVICE_DT_INST_GET(index), 0); \ + IRQ_CONNECT(DT_IRQ_BY_NAME(DT_INST_PARENT(index), eri, irq), \ + DT_IRQ_BY_NAME(DT_INST_PARENT(index), eri, priority), sci_spi_eri_isr, \ + DEVICE_DT_INST_GET(index), 0); \ + \ + irq_enable(DT_IRQ_BY_NAME(DT_INST_PARENT(index), rxi, irq)); \ + irq_enable(DT_IRQ_BY_NAME(DT_INST_PARENT(index), txi, irq)); \ + irq_enable(DT_IRQ_BY_NAME(DT_INST_PARENT(index), eri, irq)); \ + irq_enable(DT_IRQ_BY_NAME(DT_INST_PARENT(index), tei, irq)); \ + } +#else + +#define RENESAS_RA_IRQ_CONFIG_FUNC(index) \ + static void sci_spi_config_func_##index(const struct device *dev) \ + { \ + } +#endif + +/* clang-format off */ + +#ifndef CONFIG_SPI_RENESAS_RA_SCI_DTC +#define RA_SCI_SPI_DTC_STRUCT_INIT(index) +#else +#define RA_SCI_SPI_DTC_STRUCT_INIT(index) \ + .rx_transfer_info = { \ + .transfer_settings_word_b.dest_addr_mode = TRANSFER_ADDR_MODE_INCREMENTED, \ + .transfer_settings_word_b.repeat_area = TRANSFER_REPEAT_AREA_DESTINATION, \ + .transfer_settings_word_b.irq = TRANSFER_IRQ_END, \ + .transfer_settings_word_b.chain_mode = TRANSFER_CHAIN_MODE_DISABLED, \ + .transfer_settings_word_b.src_addr_mode = TRANSFER_ADDR_MODE_FIXED, \ + .transfer_settings_word_b.size = TRANSFER_SIZE_1_BYTE, \ + .transfer_settings_word_b.mode = TRANSFER_MODE_NORMAL, \ + .p_dest = (void *)NULL, \ + .p_src = (void const *)NULL, \ + .num_blocks = 0, \ + .length = 0, \ + }, \ + .rx_transfer_cfg_extend = { \ + .activation_source = DT_IRQ_BY_NAME(DT_INST_PARENT(index), rxi, irq), \ + }, \ + .rx_transfer_cfg = { \ + .p_info = &renesas_ra_sci_spi_data_##index.rx_transfer_info, \ + .p_extend = &renesas_ra_sci_spi_data_##index.rx_transfer_cfg_extend, \ + }, \ + .rx_transfer = { \ + .p_ctrl = &renesas_ra_sci_spi_data_##index.rx_transfer_ctrl, \ + .p_cfg = &renesas_ra_sci_spi_data_##index.rx_transfer_cfg, \ + .p_api = &g_transfer_on_dtc, \ + }, \ + .tx_transfer_info = { \ + .transfer_settings_word_b.dest_addr_mode = TRANSFER_ADDR_MODE_FIXED, \ + .transfer_settings_word_b.repeat_area = TRANSFER_REPEAT_AREA_SOURCE, \ + .transfer_settings_word_b.irq = TRANSFER_IRQ_END, \ + .transfer_settings_word_b.chain_mode = TRANSFER_CHAIN_MODE_DISABLED, \ + .transfer_settings_word_b.src_addr_mode = TRANSFER_ADDR_MODE_INCREMENTED, \ + .transfer_settings_word_b.size = TRANSFER_SIZE_1_BYTE, \ + .transfer_settings_word_b.mode = TRANSFER_MODE_NORMAL, \ + .p_dest = (void *)NULL, \ + .p_src = (void const *)NULL, \ + .num_blocks = 0, \ + .length = 0, \ + }, \ + .tx_transfer_cfg_extend = { \ + .activation_source = DT_IRQ_BY_NAME(DT_INST_PARENT(index), txi, irq), \ + }, \ + .tx_transfer_cfg = { \ + .p_info = &renesas_ra_sci_spi_data_##index.tx_transfer_info, \ + .p_extend = &renesas_ra_sci_spi_data_##index.tx_transfer_cfg_extend, \ + }, \ + .tx_transfer = { \ + .p_ctrl = &renesas_ra_sci_spi_data_##index.tx_transfer_ctrl, \ + .p_cfg = &renesas_ra_sci_spi_data_##index.tx_transfer_cfg, \ + .p_api = &g_transfer_on_dtc, \ + }, +#endif + +#define RENESAS_RA_SPI_SCI_INIT(index) \ + RENESAS_RA_IRQ_CONFIG_FUNC(index) \ + PINCTRL_DT_DEFINE(DT_INST_PARENT(index)); \ + \ + static const struct renesas_ra_sci_spi_config renesas_ra_sci_spi_config_##index = { \ + .pcfg = PINCTRL_DT_DEV_CONFIG_GET(DT_INST_PARENT(index)), \ + .clock_dev = DEVICE_DT_GET(DT_CLOCKS_CTLR(DT_INST_PARENT(index))), \ + .clock_subsys = { \ + .mstp = DT_CLOCKS_CELL_BY_IDX(DT_INST_PARENT(index), 0, mstp), \ + .stop_bit = DT_CLOCKS_CELL_BY_IDX(DT_INST_PARENT(index), 0, stop_bit), \ + }, \ + .irq_configure = sci_spi_config_func_##index, \ + }; \ + \ + static struct renesas_ra_sci_spi_data renesas_ra_sci_spi_data_##index = { \ + .is_cs_active_state_same = true, \ + .fsp_cfg = { \ + .channel = DT_INST_PROP(index, channel), \ + .rxi_ipl = SCI_RENESAS_RA_IRQ_GET(DT_INST_PARENT(index), rxi, priority), \ + .rxi_irq = SCI_RENESAS_RA_IRQ_GET(DT_INST_PARENT(index), rxi, irq), \ + .txi_ipl = SCI_RENESAS_RA_IRQ_GET(DT_INST_PARENT(index), txi, priority), \ + .txi_irq = SCI_RENESAS_RA_IRQ_GET(DT_INST_PARENT(index), txi, irq), \ + .tei_ipl = SCI_RENESAS_RA_IRQ_GET(DT_INST_PARENT(index), tei, priority), \ + .tei_irq = SCI_RENESAS_RA_IRQ_GET(DT_INST_PARENT(index), tei, irq), \ + .eri_ipl = SCI_RENESAS_RA_IRQ_GET(DT_INST_PARENT(index), eri, priority), \ + .eri_irq = SCI_RENESAS_RA_IRQ_GET(DT_INST_PARENT(index), eri, irq), \ + }, \ + SPI_CONTEXT_INIT_LOCK(renesas_ra_sci_spi_data_##index, ctx), \ + SPI_CONTEXT_INIT_SYNC(renesas_ra_sci_spi_data_##index, ctx), \ + SPI_CONTEXT_CS_GPIOS_INITIALIZE(DT_DRV_INST(index), ctx) \ + RA_SCI_SPI_DTC_STRUCT_INIT(index) \ + }; \ + \ + SPI_DEVICE_DT_INST_DEFINE(index, renesas_ra_sci_spi_init, NULL, \ + &renesas_ra_sci_spi_data_##index, \ + &renesas_ra_sci_spi_config_##index, POST_KERNEL, \ + CONFIG_SPI_INIT_PRIORITY, &renesas_ra_sci_spi_driver_api); + +/* clang-format on */ + +DT_INST_FOREACH_STATUS_OKAY(RENESAS_RA_SPI_SCI_INIT) diff --git a/dts/bindings/spi/renesas,ra-spi-sci.yaml b/dts/bindings/spi/renesas,ra-spi-sci.yaml new file mode 100644 index 000000000000..8a814a18dcfd --- /dev/null +++ b/dts/bindings/spi/renesas,ra-spi-sci.yaml @@ -0,0 +1,13 @@ +# Copyright (c) 2025 Renesas Electronics Corporation +# SPDX-License-Identifier: Apache-2.0 + +description: Renesas RA SCI SPI controller + +compatible: "renesas,ra-spi-sci" + +include: [spi-controller.yaml, pinctrl-device.yaml] + +properties: + channel: + type: int + required: true diff --git a/modules/Kconfig.renesas b/modules/Kconfig.renesas index 25870af170e0..37f07a830057 100644 --- a/modules/Kconfig.renesas +++ b/modules/Kconfig.renesas @@ -134,6 +134,11 @@ config USE_RA_FSP_SPI_B help Enable RA FSP SPI-B driver +config USE_RA_FSP_SCI_SPI + bool + help + Enable RA FSP SCI SPI driver + config USE_RA_FSP_SCI_B_SPI bool help From 642127e1d744465adc0bba2c964ac23973314d0c Mon Sep 17 00:00:00 2001 From: Thinh Le Cong Date: Wed, 24 Sep 2025 12:50:51 +0700 Subject: [PATCH 0218/6328] dts: arm: renesas: add SCI SPI node for Renesas RA Add SCI SPI nodes for Renesas RA SoCs Signed-off-by: Thinh Le Cong --- dts/arm/renesas/ra/ra2/ra2l1.dtsi | 45 +++++++++++++ dts/arm/renesas/ra/ra2/ra2xx.dtsi | 27 ++++++++ dts/arm/renesas/ra/ra4/r7fa4e10x.dtsi | 18 ++++++ dts/arm/renesas/ra/ra4/r7fa4l1bx.dtsi | 54 ++++++++++++++++ dts/arm/renesas/ra/ra4/r7fa4m1ax.dtsi | 9 +++ dts/arm/renesas/ra/ra4/r7fa4m2ax.dtsi | 36 +++++++++++ dts/arm/renesas/ra/ra4/r7fa4m3ax.dtsi | 36 +++++++++++ dts/arm/renesas/ra/ra4/r7fa4w1ad2cng.dtsi | 9 +++ dts/arm/renesas/ra/ra4/ra4-cm33-common.dtsi | 18 ++++++ dts/arm/renesas/ra/ra4/ra4-cm4-common.dtsi | 27 ++++++++ dts/arm/renesas/ra/ra6/r7fa6e10x.dtsi | 36 +++++++++++ dts/arm/renesas/ra/ra6/r7fa6m2ax.dtsi | 27 ++++++++ dts/arm/renesas/ra/ra6/r7fa6m3ax.dtsi | 33 +++++++++- dts/arm/renesas/ra/ra6/r7fa6m4ax.dtsi | 72 +++++++++++++++++++++ dts/arm/renesas/ra/ra6/r7fa6m5xh.dtsi | 72 +++++++++++++++++++++ dts/arm/renesas/ra/ra6/ra6-cm33-common.dtsi | 18 ++++++ dts/arm/renesas/ra/ra6/ra6-cm4-common.dtsi | 63 ++++++++++++++++++ 17 files changed, 597 insertions(+), 3 deletions(-) diff --git a/dts/arm/renesas/ra/ra2/ra2l1.dtsi b/dts/arm/renesas/ra/ra2/ra2l1.dtsi index 53bb8257108e..475d1f05b994 100644 --- a/dts/arm/renesas/ra/ra2/ra2l1.dtsi +++ b/dts/arm/renesas/ra/ra2/ra2l1.dtsi @@ -189,6 +189,15 @@ channel = <0>; status = "disabled"; }; + + spi { + compatible = "renesas,ra-spi-sci"; + #address-cells = <1>; + #size-cells = <0>; + channel = <0>; + overrun-character = <0x00>; + status = "disabled"; + }; }; sci1: sci1@40070020 { @@ -210,6 +219,15 @@ channel = <1>; status = "disabled"; }; + + spi { + compatible = "renesas,ra-spi-sci"; + #address-cells = <1>; + #size-cells = <0>; + channel = <1>; + overrun-character = <0x00>; + status = "disabled"; + }; }; sci2: sci2@40070040 { @@ -231,6 +249,15 @@ channel = <2>; status = "disabled"; }; + + spi { + compatible = "renesas,ra-spi-sci"; + #address-cells = <1>; + #size-cells = <0>; + channel = <2>; + overrun-character = <0x00>; + status = "disabled"; + }; }; sci3: sci3@40070060 { @@ -252,6 +279,15 @@ channel = <3>; status = "disabled"; }; + + spi { + compatible = "renesas,ra-spi-sci"; + #address-cells = <1>; + #size-cells = <0>; + channel = <3>; + overrun-character = <0x00>; + status = "disabled"; + }; }; sci9: sci9@40070120 { @@ -275,6 +311,15 @@ channel = <9>; status = "disabled"; }; + + spi { + compatible = "renesas,ra-spi-sci"; + #address-cells = <1>; + #size-cells = <0>; + channel = <9>; + overrun-character = <0x00>; + status = "disabled"; + }; }; wdt: wdt@40044200 { diff --git a/dts/arm/renesas/ra/ra2/ra2xx.dtsi b/dts/arm/renesas/ra/ra2/ra2xx.dtsi index 2a52836e01ef..a041db7a99f4 100644 --- a/dts/arm/renesas/ra/ra2/ra2xx.dtsi +++ b/dts/arm/renesas/ra/ra2/ra2xx.dtsi @@ -166,6 +166,15 @@ channel = <0>; status = "disabled"; }; + + spi { + compatible = "renesas,ra-spi-sci"; + #address-cells = <1>; + #size-cells = <0>; + channel = <0>; + overrun-character = <0x00>; + status = "disabled"; + }; }; sci1: sci@40070020 { @@ -189,6 +198,15 @@ channel = <1>; status = "disabled"; }; + + spi { + compatible = "renesas,ra-spi-sci"; + #address-cells = <1>; + #size-cells = <0>; + channel = <1>; + overrun-character = <0x00>; + status = "disabled"; + }; }; sci2: sci@40070040 { @@ -258,6 +276,15 @@ channel = <9>; status = "disabled"; }; + + spi { + compatible = "renesas,ra-spi-sci"; + #address-cells = <1>; + #size-cells = <0>; + channel = <9>; + overrun-character = <0x00>; + status = "disabled"; + }; }; spi0: spi@40072000 { diff --git a/dts/arm/renesas/ra/ra4/r7fa4e10x.dtsi b/dts/arm/renesas/ra/ra4/r7fa4e10x.dtsi index b184c7fbf88b..66a5756857b9 100644 --- a/dts/arm/renesas/ra/ra4/r7fa4e10x.dtsi +++ b/dts/arm/renesas/ra/ra4/r7fa4e10x.dtsi @@ -43,6 +43,15 @@ channel = <3>; status = "disabled"; }; + + spi { + compatible = "renesas,ra-spi-sci"; + #address-cells = <1>; + #size-cells = <0>; + channel = <3>; + overrun-character = <0x00>; + status = "disabled"; + }; }; sci4: sci4@40118400 { @@ -64,6 +73,15 @@ channel = <4>; status = "disabled"; }; + + spi { + compatible = "renesas,ra-spi-sci"; + #address-cells = <1>; + #size-cells = <0>; + channel = <4>; + overrun-character = <0x00>; + status = "disabled"; + }; }; adc@40170000 { diff --git a/dts/arm/renesas/ra/ra4/r7fa4l1bx.dtsi b/dts/arm/renesas/ra/ra4/r7fa4l1bx.dtsi index a22606f22921..ae03e9884519 100644 --- a/dts/arm/renesas/ra/ra4/r7fa4l1bx.dtsi +++ b/dts/arm/renesas/ra/ra4/r7fa4l1bx.dtsi @@ -178,6 +178,15 @@ channel = <0>; status = "disabled"; }; + + spi { + compatible = "renesas,ra-spi-sci"; + #address-cells = <1>; + #size-cells = <0>; + channel = <0>; + overrun-character = <0x00>; + status = "disabled"; + }; }; sci1: sci@40118100 { @@ -199,6 +208,15 @@ channel = <1>; status = "disabled"; }; + + spi { + compatible = "renesas,ra-spi-sci"; + #address-cells = <1>; + #size-cells = <0>; + channel = <1>; + overrun-character = <0x00>; + status = "disabled"; + }; }; sci3: sci@40118300 { @@ -220,6 +238,15 @@ channel = <3>; status = "disabled"; }; + + spi { + compatible = "renesas,ra-spi-sci"; + #address-cells = <1>; + #size-cells = <0>; + channel = <3>; + overrun-character = <0x00>; + status = "disabled"; + }; }; sci4: sci@40118400 { @@ -241,6 +268,15 @@ channel = <4>; status = "disabled"; }; + + spi { + compatible = "renesas,ra-spi-sci"; + #address-cells = <1>; + #size-cells = <0>; + channel = <4>; + overrun-character = <0x00>; + status = "disabled"; + }; }; sci5: sci@40118500 { @@ -264,6 +300,15 @@ channel = <5>; status = "disabled"; }; + + spi { + compatible = "renesas,ra-spi-sci"; + #address-cells = <1>; + #size-cells = <0>; + channel = <5>; + overrun-character = <0x00>; + status = "disabled"; + }; }; sci9: sci@40118900 { @@ -287,6 +332,15 @@ channel = <9>; status = "disabled"; }; + + spi { + compatible = "renesas,ra-spi-sci"; + #address-cells = <1>; + #size-cells = <0>; + channel = <9>; + overrun-character = <0x00>; + status = "disabled"; + }; }; spi0: spi@4011a000 { diff --git a/dts/arm/renesas/ra/ra4/r7fa4m1ax.dtsi b/dts/arm/renesas/ra/ra4/r7fa4m1ax.dtsi index 628fc8c442b6..d65d309dbb50 100644 --- a/dts/arm/renesas/ra/ra4/r7fa4m1ax.dtsi +++ b/dts/arm/renesas/ra/ra4/r7fa4m1ax.dtsi @@ -66,6 +66,15 @@ channel = <2>; status = "disabled"; }; + + spi { + compatible = "renesas,ra-spi-sci"; + #address-cells = <1>; + #size-cells = <0>; + channel = <2>; + overrun-character = <0x00>; + status = "disabled"; + }; }; adc@4005c000 { diff --git a/dts/arm/renesas/ra/ra4/r7fa4m2ax.dtsi b/dts/arm/renesas/ra/ra4/r7fa4m2ax.dtsi index e0c4e598dad8..855907085831 100644 --- a/dts/arm/renesas/ra/ra4/r7fa4m2ax.dtsi +++ b/dts/arm/renesas/ra/ra4/r7fa4m2ax.dtsi @@ -61,6 +61,15 @@ channel = <1>; status = "disabled"; }; + + spi { + compatible = "renesas,ra-spi-sci"; + #address-cells = <1>; + #size-cells = <0>; + channel = <1>; + overrun-character = <0x00>; + status = "disabled"; + }; }; sci2: sci2@40118200 { @@ -84,6 +93,15 @@ channel = <2>; status = "disabled"; }; + + spi { + compatible = "renesas,ra-spi-sci"; + #address-cells = <1>; + #size-cells = <0>; + channel = <2>; + overrun-character = <0x00>; + status = "disabled"; + }; }; sci3: sci3@40118300 { @@ -107,6 +125,15 @@ channel = <3>; status = "disabled"; }; + + spi { + compatible = "renesas,ra-spi-sci"; + #address-cells = <1>; + #size-cells = <0>; + channel = <3>; + overrun-character = <0x00>; + status = "disabled"; + }; }; sci4: sci4@40118400 { @@ -130,6 +157,15 @@ channel = <4>; status = "disabled"; }; + + spi { + compatible = "renesas,ra-spi-sci"; + #address-cells = <1>; + #size-cells = <0>; + channel = <4>; + overrun-character = <0x00>; + status = "disabled"; + }; }; adc@40170000 { diff --git a/dts/arm/renesas/ra/ra4/r7fa4m3ax.dtsi b/dts/arm/renesas/ra/ra4/r7fa4m3ax.dtsi index 9bf6ed7324ad..d54d35ec86b2 100644 --- a/dts/arm/renesas/ra/ra4/r7fa4m3ax.dtsi +++ b/dts/arm/renesas/ra/ra4/r7fa4m3ax.dtsi @@ -70,6 +70,15 @@ channel = <1>; status = "disabled"; }; + + spi { + compatible = "renesas,ra-spi-sci"; + #address-cells = <1>; + #size-cells = <0>; + channel = <1>; + overrun-character = <0x00>; + status = "disabled"; + }; }; sci2: sci2@40118200 { @@ -93,6 +102,15 @@ channel = <2>; status = "disabled"; }; + + spi { + compatible = "renesas,ra-spi-sci"; + #address-cells = <1>; + #size-cells = <0>; + channel = <2>; + overrun-character = <0x00>; + status = "disabled"; + }; }; sci3: sci3@40118300 { @@ -116,6 +134,15 @@ channel = <3>; status = "disabled"; }; + + spi { + compatible = "renesas,ra-spi-sci"; + #address-cells = <1>; + #size-cells = <0>; + channel = <3>; + overrun-character = <0x00>; + status = "disabled"; + }; }; sci4: sci4@40118400 { @@ -139,6 +166,15 @@ channel = <4>; status = "disabled"; }; + + spi { + compatible = "renesas,ra-spi-sci"; + #address-cells = <1>; + #size-cells = <0>; + channel = <4>; + overrun-character = <0x00>; + status = "disabled"; + }; }; adc@40170000 { diff --git a/dts/arm/renesas/ra/ra4/r7fa4w1ad2cng.dtsi b/dts/arm/renesas/ra/ra4/r7fa4w1ad2cng.dtsi index ab77c8e22a62..991300e792fa 100644 --- a/dts/arm/renesas/ra/ra4/r7fa4w1ad2cng.dtsi +++ b/dts/arm/renesas/ra/ra4/r7fa4w1ad2cng.dtsi @@ -59,6 +59,15 @@ channel = <4>; status = "disabled"; }; + + spi { + compatible = "renesas,ra-spi-sci"; + #address-cells = <1>; + #size-cells = <0>; + channel = <4>; + overrun-character = <0x00>; + status = "disabled"; + }; }; trng: trng { diff --git a/dts/arm/renesas/ra/ra4/ra4-cm33-common.dtsi b/dts/arm/renesas/ra/ra4/ra4-cm33-common.dtsi index e181195da0f4..9ff1c7fa9eec 100644 --- a/dts/arm/renesas/ra/ra4/ra4-cm33-common.dtsi +++ b/dts/arm/renesas/ra/ra4/ra4-cm33-common.dtsi @@ -154,6 +154,15 @@ channel = <0>; status = "disabled"; }; + + spi { + compatible = "renesas,ra-spi-sci"; + #address-cells = <1>; + #size-cells = <0>; + channel = <0>; + overrun-character = <0x00>; + status = "disabled"; + }; }; sci9: sci9@40118900 { @@ -177,6 +186,15 @@ channel = <9>; status = "disabled"; }; + + spi { + compatible = "renesas,ra-spi-sci"; + #address-cells = <1>; + #size-cells = <0>; + channel = <9>; + overrun-character = <0x00>; + status = "disabled"; + }; }; spi0: spi@4011a000 { diff --git a/dts/arm/renesas/ra/ra4/ra4-cm4-common.dtsi b/dts/arm/renesas/ra/ra4/ra4-cm4-common.dtsi index 2e70d63e9986..bbed1a4431c2 100644 --- a/dts/arm/renesas/ra/ra4/ra4-cm4-common.dtsi +++ b/dts/arm/renesas/ra/ra4/ra4-cm4-common.dtsi @@ -161,6 +161,15 @@ channel = <0>; status = "disabled"; }; + + spi { + compatible = "renesas,ra-spi-sci"; + #address-cells = <1>; + #size-cells = <0>; + channel = <0>; + overrun-character = <0x00>; + status = "disabled"; + }; }; sci1: sci1@40070020 { @@ -184,6 +193,15 @@ channel = <1>; status = "disabled"; }; + + spi { + compatible = "renesas,ra-spi-sci"; + #address-cells = <1>; + #size-cells = <0>; + channel = <1>; + overrun-character = <0x00>; + status = "disabled"; + }; }; sci9: sci9@40070120 { @@ -205,6 +223,15 @@ channel = <9>; status = "disabled"; }; + + spi { + compatible = "renesas,ra-spi-sci"; + #address-cells = <1>; + #size-cells = <0>; + channel = <9>; + overrun-character = <0x00>; + status = "disabled"; + }; }; spi0: spi@40072000 { diff --git a/dts/arm/renesas/ra/ra6/r7fa6e10x.dtsi b/dts/arm/renesas/ra/ra6/r7fa6e10x.dtsi index e918669da284..c58f742ed8e8 100644 --- a/dts/arm/renesas/ra/ra6/r7fa6e10x.dtsi +++ b/dts/arm/renesas/ra/ra6/r7fa6e10x.dtsi @@ -60,6 +60,15 @@ channel = <1>; status = "disabled"; }; + + spi { + compatible = "renesas,ra-spi-sci"; + #address-cells = <1>; + #size-cells = <0>; + channel = <1>; + overrun-character = <0x00>; + status = "disabled"; + }; }; sci2: sci2@40118200 { @@ -83,6 +92,15 @@ channel = <2>; status = "disabled"; }; + + spi { + compatible = "renesas,ra-spi-sci"; + #address-cells = <1>; + #size-cells = <0>; + channel = <2>; + overrun-character = <0x00>; + status = "disabled"; + }; }; sci3: sci3@40118300 { @@ -106,6 +124,15 @@ channel = <3>; status = "disabled"; }; + + spi { + compatible = "renesas,ra-spi-sci"; + #address-cells = <1>; + #size-cells = <0>; + channel = <3>; + overrun-character = <0x00>; + status = "disabled"; + }; }; sci4: sci4@40118400 { @@ -129,6 +156,15 @@ channel = <4>; status = "disabled"; }; + + spi { + compatible = "renesas,ra-spi-sci"; + #address-cells = <1>; + #size-cells = <0>; + channel = <4>; + overrun-character = <0x00>; + status = "disabled"; + }; }; adc@40170000 { diff --git a/dts/arm/renesas/ra/ra6/r7fa6m2ax.dtsi b/dts/arm/renesas/ra/ra6/r7fa6m2ax.dtsi index 7d209dcf7077..90a22695c300 100644 --- a/dts/arm/renesas/ra/ra6/r7fa6m2ax.dtsi +++ b/dts/arm/renesas/ra/ra6/r7fa6m2ax.dtsi @@ -39,6 +39,15 @@ channel = <5>; status = "disabled"; }; + + spi { + compatible = "renesas,ra-spi-sci"; + #address-cells = <1>; + #size-cells = <0>; + channel = <5>; + overrun-character = <0x00>; + status = "disabled"; + }; }; sci6: sci6@400700c0 { @@ -60,6 +69,15 @@ channel = <6>; status = "disabled"; }; + + spi { + compatible = "renesas,ra-spi-sci"; + #address-cells = <1>; + #size-cells = <0>; + channel = <6>; + overrun-character = <0x00>; + status = "disabled"; + }; }; sci7: sci7@400700e0 { @@ -83,6 +101,15 @@ channel = <7>; status = "disabled"; }; + + spi { + compatible = "renesas,ra-spi-sci"; + #address-cells = <1>; + #size-cells = <0>; + channel = <7>; + overrun-character = <0x00>; + status = "disabled"; + }; }; iic2: iic2@40053200 { diff --git a/dts/arm/renesas/ra/ra6/r7fa6m3ax.dtsi b/dts/arm/renesas/ra/ra6/r7fa6m3ax.dtsi index 9e892aff69b6..6b79034a09c1 100644 --- a/dts/arm/renesas/ra/ra6/r7fa6m3ax.dtsi +++ b/dts/arm/renesas/ra/ra6/r7fa6m3ax.dtsi @@ -58,7 +58,7 @@ sci5: sci5@400700a0 { compatible = "renesas,ra-sci"; - interrupts = <20 1>, <21 1>, <22 1>, <23 1>; + interrupts = <92 1>, <93 1>, <94 1>, <95 1>; interrupt-names = "rxi", "txi", "tei", "eri"; reg = <0x400700a0 0x20>; clocks = <&pclka MSTPB 26>; @@ -77,11 +77,20 @@ channel = <5>; status = "disabled"; }; + + spi { + compatible = "renesas,ra-spi-sci"; + #address-cells = <1>; + #size-cells = <0>; + channel = <5>; + overrun-character = <0x00>; + status = "disabled"; + }; }; sci6: sci6@400700c0 { compatible = "renesas,ra-sci"; - interrupts = <24 1>, <25 1>, <26 1>, <27 1>; + interrupts = <88 1>, <89 1>, <90 1>, <91 1>; interrupt-names = "rxi", "txi", "tei", "eri"; reg = <0x400700c0 0x20>; clocks = <&pclka MSTPB 25>; @@ -100,11 +109,20 @@ channel = <6>; status = "disabled"; }; + + spi { + compatible = "renesas,ra-spi-sci"; + #address-cells = <1>; + #size-cells = <0>; + channel = <6>; + overrun-character = <0x00>; + status = "disabled"; + }; }; sci7: sci7@400700e0 { compatible = "renesas,ra-sci"; - interrupts = <28 1>, <29 1>, <30 1>, <31 1>; + interrupts = <84 1>, <85 1>, <86 1>, <87 1>; interrupt-names = "rxi", "txi", "tei", "eri"; reg = <0x400700e0 0x20>; clocks = <&pclka MSTPB 24>; @@ -123,6 +141,15 @@ channel = <7>; status = "disabled"; }; + + spi { + compatible = "renesas,ra-spi-sci"; + #address-cells = <1>; + #size-cells = <0>; + channel = <7>; + overrun-character = <0x00>; + status = "disabled"; + }; }; iic2: iic2@40053200 { diff --git a/dts/arm/renesas/ra/ra6/r7fa6m4ax.dtsi b/dts/arm/renesas/ra/ra6/r7fa6m4ax.dtsi index cfd22d2ab8bc..8ae93bd7bc4d 100644 --- a/dts/arm/renesas/ra/ra6/r7fa6m4ax.dtsi +++ b/dts/arm/renesas/ra/ra6/r7fa6m4ax.dtsi @@ -37,6 +37,15 @@ channel = <1>; status = "disabled"; }; + + spi { + compatible = "renesas,ra-spi-sci"; + #address-cells = <1>; + #size-cells = <0>; + channel = <1>; + overrun-character = <0x00>; + status = "disabled"; + }; }; sci2: sci2@40118200 { @@ -60,6 +69,15 @@ channel = <2>; status = "disabled"; }; + + spi { + compatible = "renesas,ra-spi-sci"; + #address-cells = <1>; + #size-cells = <0>; + channel = <2>; + overrun-character = <0x00>; + status = "disabled"; + }; }; sci3: sci3@40118300 { @@ -83,6 +101,15 @@ channel = <3>; status = "disabled"; }; + + spi { + compatible = "renesas,ra-spi-sci"; + #address-cells = <1>; + #size-cells = <0>; + channel = <3>; + overrun-character = <0x00>; + status = "disabled"; + }; }; sci4: sci4@40118400 { @@ -106,6 +133,15 @@ channel = <4>; status = "disabled"; }; + + spi { + compatible = "renesas,ra-spi-sci"; + #address-cells = <1>; + #size-cells = <0>; + channel = <4>; + overrun-character = <0x00>; + status = "disabled"; + }; }; sci5: sci5@40118500 { @@ -129,6 +165,15 @@ channel = <5>; status = "disabled"; }; + + spi { + compatible = "renesas,ra-spi-sci"; + #address-cells = <1>; + #size-cells = <0>; + channel = <5>; + overrun-character = <0x00>; + status = "disabled"; + }; }; sci6: sci6@40118600 { @@ -152,6 +197,15 @@ channel = <6>; status = "disabled"; }; + + spi { + compatible = "renesas,ra-spi-sci"; + #address-cells = <1>; + #size-cells = <0>; + channel = <6>; + overrun-character = <0x00>; + status = "disabled"; + }; }; sci7: sci7@40118700 { @@ -175,6 +229,15 @@ channel = <7>; status = "disabled"; }; + + spi { + compatible = "renesas,ra-spi-sci"; + #address-cells = <1>; + #size-cells = <0>; + channel = <7>; + overrun-character = <0x00>; + status = "disabled"; + }; }; sci8: sci8@40118800 { @@ -198,6 +261,15 @@ channel = <8>; status = "disabled"; }; + + spi { + compatible = "renesas,ra-spi-sci"; + #address-cells = <1>; + #size-cells = <0>; + channel = <8>; + overrun-character = <0x00>; + status = "disabled"; + }; }; adc@40170000 { diff --git a/dts/arm/renesas/ra/ra6/r7fa6m5xh.dtsi b/dts/arm/renesas/ra/ra6/r7fa6m5xh.dtsi index 6cbc0c6f4117..538418e941bd 100644 --- a/dts/arm/renesas/ra/ra6/r7fa6m5xh.dtsi +++ b/dts/arm/renesas/ra/ra6/r7fa6m5xh.dtsi @@ -97,6 +97,15 @@ channel = <1>; status = "disabled"; }; + + spi { + compatible = "renesas,ra-spi-sci"; + #address-cells = <1>; + #size-cells = <0>; + channel = <1>; + overrun-character = <0x00>; + status = "disabled"; + }; }; sci2: sci2@40118200 { @@ -120,6 +129,15 @@ channel = <2>; status = "disabled"; }; + + spi { + compatible = "renesas,ra-spi-sci"; + #address-cells = <1>; + #size-cells = <0>; + channel = <2>; + overrun-character = <0x00>; + status = "disabled"; + }; }; sci3: sci3@40118300 { @@ -143,6 +161,15 @@ channel = <3>; status = "disabled"; }; + + spi { + compatible = "renesas,ra-spi-sci"; + #address-cells = <1>; + #size-cells = <0>; + channel = <3>; + overrun-character = <0x00>; + status = "disabled"; + }; }; sci4: sci4@40118400 { @@ -166,6 +193,15 @@ channel = <4>; status = "disabled"; }; + + spi { + compatible = "renesas,ra-spi-sci"; + #address-cells = <1>; + #size-cells = <0>; + channel = <4>; + overrun-character = <0x00>; + status = "disabled"; + }; }; sci5: sci5@40118500 { @@ -189,6 +225,15 @@ channel = <5>; status = "disabled"; }; + + spi { + compatible = "renesas,ra-spi-sci"; + #address-cells = <1>; + #size-cells = <0>; + channel = <5>; + overrun-character = <0x00>; + status = "disabled"; + }; }; sci6: sci6@40118600 { @@ -212,6 +257,15 @@ channel = <6>; status = "disabled"; }; + + spi { + compatible = "renesas,ra-spi-sci"; + #address-cells = <1>; + #size-cells = <0>; + channel = <6>; + overrun-character = <0x00>; + status = "disabled"; + }; }; sci7: sci7@40118700 { @@ -235,6 +289,15 @@ channel = <7>; status = "disabled"; }; + + spi { + compatible = "renesas,ra-spi-sci"; + #address-cells = <1>; + #size-cells = <0>; + channel = <7>; + overrun-character = <0x00>; + status = "disabled"; + }; }; sci8: sci8@40118800 { @@ -258,6 +321,15 @@ channel = <8>; status = "disabled"; }; + + spi { + compatible = "renesas,ra-spi-sci"; + #address-cells = <1>; + #size-cells = <0>; + channel = <8>; + overrun-character = <0x00>; + status = "disabled"; + }; }; iic2: iic2@4009f200 { diff --git a/dts/arm/renesas/ra/ra6/ra6-cm33-common.dtsi b/dts/arm/renesas/ra/ra6/ra6-cm33-common.dtsi index 44537c60b809..2138c46fa4dd 100644 --- a/dts/arm/renesas/ra/ra6/ra6-cm33-common.dtsi +++ b/dts/arm/renesas/ra/ra6/ra6-cm33-common.dtsi @@ -145,6 +145,15 @@ channel = <0>; status = "disabled"; }; + + spi { + compatible = "renesas,ra-spi-sci"; + #address-cells = <1>; + #size-cells = <0>; + channel = <0>; + overrun-character = <0x00>; + status = "disabled"; + }; }; sci9: sci9@40118900 { @@ -168,6 +177,15 @@ channel = <9>; status = "disabled"; }; + + spi { + compatible = "renesas,ra-spi-sci"; + #address-cells = <1>; + #size-cells = <0>; + channel = <9>; + overrun-character = <0x00>; + status = "disabled"; + }; }; iic0: iic0@4009f000 { diff --git a/dts/arm/renesas/ra/ra6/ra6-cm4-common.dtsi b/dts/arm/renesas/ra/ra6/ra6-cm4-common.dtsi index 8a5f28691373..2fa4568f5d5e 100644 --- a/dts/arm/renesas/ra/ra6/ra6-cm4-common.dtsi +++ b/dts/arm/renesas/ra/ra6/ra6-cm4-common.dtsi @@ -163,6 +163,15 @@ channel = <0>; status = "disabled"; }; + + spi { + compatible = "renesas,ra-spi-sci"; + #address-cells = <1>; + #size-cells = <0>; + channel = <0>; + overrun-character = <0x00>; + status = "disabled"; + }; }; sci1: sci1@40070020 { @@ -184,6 +193,15 @@ channel = <1>; status = "disabled"; }; + + spi { + compatible = "renesas,ra-spi-sci"; + #address-cells = <1>; + #size-cells = <0>; + channel = <1>; + overrun-character = <0x00>; + status = "disabled"; + }; }; sci2: sci2@40070040 { @@ -205,6 +223,15 @@ channel = <2>; status = "disabled"; }; + + spi { + compatible = "renesas,ra-spi-sci"; + #address-cells = <1>; + #size-cells = <0>; + channel = <2>; + overrun-character = <0x00>; + status = "disabled"; + }; }; sci3: sci3@40070060 { @@ -226,6 +253,15 @@ channel = <3>; status = "disabled"; }; + + spi { + compatible = "renesas,ra-spi-sci"; + #address-cells = <1>; + #size-cells = <0>; + channel = <3>; + overrun-character = <0x00>; + status = "disabled"; + }; }; sci4: sci4@40070080 { @@ -247,6 +283,15 @@ channel = <4>; status = "disabled"; }; + + spi { + compatible = "renesas,ra-spi-sci"; + #address-cells = <1>; + #size-cells = <0>; + channel = <4>; + overrun-character = <0x00>; + status = "disabled"; + }; }; sci8: sci8@40070100 { @@ -270,6 +315,15 @@ channel = <8>; status = "disabled"; }; + + spi { + compatible = "renesas,ra-spi-sci"; + #address-cells = <1>; + #size-cells = <0>; + channel = <8>; + overrun-character = <0x00>; + status = "disabled"; + }; }; sci9: sci9@40070120 { @@ -293,6 +347,15 @@ channel = <9>; status = "disabled"; }; + + spi { + compatible = "renesas,ra-spi-sci"; + #address-cells = <1>; + #size-cells = <0>; + channel = <9>; + overrun-character = <0x00>; + status = "disabled"; + }; }; iic0: iic0@40053000 { From 0c950801d37c3473c58fce7fba3ac39ae367010d Mon Sep 17 00:00:00 2001 From: Kevin Chan Date: Fri, 12 Dec 2025 14:51:57 -0800 Subject: [PATCH 0219/6328] drivers: sdhc: add SDHC driver for PSE84 & cy8cproto_062_4343w - add SDHC driver code to support both SDMMC and SDIO fucntion - add SDHC dts node and Kconfig - add clock configuration for SDHC Signed-off-by: Kevin Chan --- .../cy8cproto_062_4343w.dts | 13 + .../infineon/kit_pse84_eval/kconfig.defconfig | 30 + .../kit_pse84_eval_common-pinctrl.dtsi | 72 ++ .../kit_pse84_eval/kit_pse84_eval_common.dtsi | 8 + .../kit_pse84_eval/kit_pse84_eval_m55.dts | 65 + .../kit_pse84_eval/kit_pse84_eval_m55.yaml | 1 + .../clock_control_infineon_peri_clock.c | 27 + drivers/sdhc/CMakeLists.txt | 2 +- drivers/sdhc/Kconfig.infineon | 24 +- drivers/sdhc/infineon_sdio.c | 341 ----- drivers/sdhc/sdhc_infineon.c | 1141 +++++++++++++++++ drivers/wifi/infineon/Kconfig.airoc | 10 +- dts/bindings/sdhc/infineon,sdhc-sdio.yaml | 25 +- modules/hal_infineon/CMakeLists.txt | 7 +- 14 files changed, 1406 insertions(+), 360 deletions(-) create mode 100644 boards/infineon/kit_pse84_eval/kconfig.defconfig delete mode 100644 drivers/sdhc/infineon_sdio.c create mode 100644 drivers/sdhc/sdhc_infineon.c diff --git a/boards/infineon/cy8cproto_062_4343w/cy8cproto_062_4343w.dts b/boards/infineon/cy8cproto_062_4343w/cy8cproto_062_4343w.dts index 3aefe67c863d..e1014cf7ed23 100644 --- a/boards/infineon/cy8cproto_062_4343w/cy8cproto_062_4343w.dts +++ b/boards/infineon/cy8cproto_062_4343w/cy8cproto_062_4343w.dts @@ -77,6 +77,12 @@ uart2: &scb2 { }; }; +&clk_hf4 { + clock-div = <1>; + clocks = <&fll0>; + status = "okay"; +}; + &sdhc0 { status = "okay"; @@ -85,6 +91,13 @@ uart2: &scb2 { &p2_1_sdio_data1 &p2_2_sdio_data2 &p2_3_sdio_data3>; pinctrl-names = "default"; + bus-width = <4>; + max-bus-freq = <50000000>; + min-bus-freq = <400000>; + power-delay-ms = <1000>; + no-1-8-v; + clocks = <&clk_hf4>; + /* Wi-Fi configuration */ airoc-wifi { status = "okay"; diff --git a/boards/infineon/kit_pse84_eval/kconfig.defconfig b/boards/infineon/kit_pse84_eval/kconfig.defconfig new file mode 100644 index 000000000000..8962ddd2959a --- /dev/null +++ b/boards/infineon/kit_pse84_eval/kconfig.defconfig @@ -0,0 +1,30 @@ +# Copyright (c) 2025 Infineon Technologies AG, +# or an affiliate of Infineon Technologies AG. +# +# SPDX-License-Identifier: Apache-2.0 + +if BOARD_KIT_PSE84_EVAL_PSE846GPS2DBZC4A_M55 + +if WIFI + +# Select AIROC part and module +choice AIROC_PART + default CYW55500 +endchoice + +choice CYW55500_MODULE + default CYW55513IUBG_SM +endchoice + +# Enable L2 Ethernet +config NET_L2_ETHERNET + default y + +# Heap Pool Size +config HEAP_MEM_POOL_ADD_SIZE_BOARD + int + default 15000 + +endif # WIFI + +endif # BOARD_KIT_PSE84_EVAL_PSE846GPS2DBZC4A_M55 diff --git a/boards/infineon/kit_pse84_eval/kit_pse84_eval_common-pinctrl.dtsi b/boards/infineon/kit_pse84_eval/kit_pse84_eval_common-pinctrl.dtsi index e536b8c9b1ed..5faf08fd3a6b 100644 --- a/boards/infineon/kit_pse84_eval/kit_pse84_eval_common-pinctrl.dtsi +++ b/boards/infineon/kit_pse84_eval/kit_pse84_eval_common-pinctrl.dtsi @@ -13,3 +13,75 @@ &p6_5_scb2_uart_rx { input-enable; }; + +&p21_0_sdhc0_card_cmd { + drive-push-pull; + input-enable; + drive-strength = "half"; +}; + +&p12_0_sdhc0_clk_card { + drive-push-pull; + input-enable; + drive-strength = "half"; +}; + +&p12_1_sdhc0_card_dat_3to0 { + drive-push-pull; + input-enable; + drive-strength = "half"; +}; + +&p12_2_sdhc0_card_dat_3to0 { + drive-push-pull; + input-enable; + drive-strength = "half"; +}; + +&p12_4_sdhc0_card_dat_3to0 { + drive-push-pull; + input-enable; + drive-strength = "half"; +}; + +&p12_5_sdhc0_card_dat_3to0 { + drive-push-pull; + input-enable; + drive-strength = "half"; +}; + +&p7_0_sdhc1_card_cmd { + drive-push-pull; + input-enable; + drive-strength = "half"; +}; + +&p7_1_sdhc1_clk_card { + drive-push-pull; + input-enable; + drive-strength = "half"; +}; + +&p7_3_sdhc1_card_dat_3to0 { + drive-push-pull; + input-enable; + drive-strength = "half"; +}; + +&p7_5_sdhc1_card_dat_3to0 { + drive-push-pull; + input-enable; + drive-strength = "half"; +}; + +&p7_6_sdhc1_card_dat_3to0 { + drive-push-pull; + input-enable; + drive-strength = "half"; +}; + +&p7_7_sdhc1_card_dat_3to0 { + drive-push-pull; + input-enable; + drive-strength = "half"; +}; diff --git a/boards/infineon/kit_pse84_eval/kit_pse84_eval_common.dtsi b/boards/infineon/kit_pse84_eval/kit_pse84_eval_common.dtsi index c4cfcaa1a9e4..307a4861594a 100644 --- a/boards/infineon/kit_pse84_eval/kit_pse84_eval_common.dtsi +++ b/boards/infineon/kit_pse84_eval/kit_pse84_eval_common.dtsi @@ -78,6 +78,10 @@ uart2: &scb2 { status = "okay"; }; +&gpio_prt11 { + status = "okay"; +}; + &gpio_prt13 { status = "okay"; }; @@ -89,3 +93,7 @@ uart2: &scb2 { &gpio_prt16 { status = "okay"; }; + +&gpio_prt17 { + status = "okay"; +}; diff --git a/boards/infineon/kit_pse84_eval/kit_pse84_eval_m55.dts b/boards/infineon/kit_pse84_eval/kit_pse84_eval_m55.dts index 7710376534c5..eed1ea8763f1 100644 --- a/boards/infineon/kit_pse84_eval/kit_pse84_eval_m55.dts +++ b/boards/infineon/kit_pse84_eval/kit_pse84_eval_m55.dts @@ -61,3 +61,68 @@ &mcwdt1 { status = "okay"; }; + +&peri1_group2_8bit_0 { + status = "okay"; + resource-type = ; + resource-instance = <0>; + clock-div = <2>; +}; + +&peri1_group3_8bit_0 { + status = "okay"; + resource-type = ; + resource-instance = <1>; + clock-div = <2>; +}; + +&sdhc0 { + status = "okay"; + + /* SDIO pins */ + pinctrl-0 = <&p21_0_sdhc0_card_cmd &p12_0_sdhc0_clk_card &p12_1_sdhc0_card_dat_3to0 + &p12_2_sdhc0_card_dat_3to0 &p12_4_sdhc0_card_dat_3to0 + &p12_5_sdhc0_card_dat_3to0>; + pinctrl-names = "default"; + + clocks = <&peri1_group2_8bit_0>; + bus-width = <4>; + max-bus-freq = <50000000>; + min-bus-freq = <400000>; + power-delay-ms = <1000>; + no-1-8-v; + + /* Wi-Fi configuration */ + airoc-wifi { + status = "okay"; + compatible = "infineon,airoc-wifi"; + + /* Wi-Fi control gpios */ + wifi-reg-on-gpios = <&gpio_prt11 6 GPIO_ACTIVE_HIGH>; + wifi-host-wake-gpios = <&gpio_prt11 4 GPIO_ACTIVE_HIGH>; + }; +}; + +&sdhc1 { + status = "okay"; + + /* SDHC pins */ + pinctrl-0 = <&p7_0_sdhc1_card_cmd &p7_1_sdhc1_clk_card &p7_3_sdhc1_card_dat_3to0 + &p7_5_sdhc1_card_dat_3to0 &p7_6_sdhc1_card_dat_3to0 + &p7_7_sdhc1_card_dat_3to0>; + pinctrl-names = "default"; + + clocks = <&peri1_group3_8bit_0>; + bus-width = <4>; + max-bus-freq = <100000000>; + min-bus-freq = <400000>; + power-delay-ms = <1000>; + /* Card detect gpios */ + cd-gpios = <&gpio_prt17 7 GPIO_PULL_UP>; + + sdmmc { + compatible = "zephyr,sdmmc-disk"; + disk-name = "SD"; + status = "okay"; + }; +}; diff --git a/boards/infineon/kit_pse84_eval/kit_pse84_eval_m55.yaml b/boards/infineon/kit_pse84_eval/kit_pse84_eval_m55.yaml index ee241e89804b..333e396cb7a3 100644 --- a/boards/infineon/kit_pse84_eval/kit_pse84_eval_m55.yaml +++ b/boards/infineon/kit_pse84_eval/kit_pse84_eval_m55.yaml @@ -18,3 +18,4 @@ supported: - pinctrl - uart - spi + - sdhc diff --git a/drivers/clock_control/clock_control_infineon_peri_clock.c b/drivers/clock_control/clock_control_infineon_peri_clock.c index 9923ab626dd3..858ba4dc52cc 100644 --- a/drivers/clock_control/clock_control_infineon_peri_clock.c +++ b/drivers/clock_control/clock_control_infineon_peri_clock.c @@ -50,6 +50,11 @@ struct ifx_peri_clock_data { #define IFX_SCB5_PCLK_CLOCK PCLK_SCB5_CLOCK_SCB_EN #endif +#if defined(CY_IP_MXSDHC) +#define IFX_SDHC0_PCLK_CLOCK PCLK_SDHC0_CLK_HF +#define IFX_SDHC1_PCLK_CLOCK PCLK_SDHC1_CLK_HF +#endif + #define CLK_FRAC_DIV_MODE 0x02 en_clk_dst_t ifx_cat1_scb_get_clock_index(uint32_t block_num) @@ -101,6 +106,21 @@ en_clk_dst_t ifx_cat1_tcpwm_get_clock_index(uint32_t block_num, uint32_t channel return clk; } +en_clk_dst_t ifx_cat1_sdhc_get_clock_index(uint32_t block_num, uint32_t channel) +{ + en_clk_dst_t clk = -EINVAL; + +#if defined(CY_IP_MXSDHC) + if (block_num == 0) { + clk = (en_clk_dst_t)((uint32_t)IFX_SDHC0_PCLK_CLOCK); + } else { + clk = (en_clk_dst_t)((uint32_t)IFX_SDHC1_PCLK_CLOCK); + } +#endif + + return clk; +} + static int ifx_cat1_peri_clock_init(const struct device *dev) { struct ifx_peri_clock_data *const data = dev->data; @@ -134,6 +154,13 @@ static int ifx_cat1_peri_clock_init(const struct device *dev) en_clk_dst_t clk_idx = ifx_cat1_tcpwm_get_clock_index( data->hw_resource.block_num, data->hw_resource.channel_num); + ifx_cat1_utils_peri_pclk_set_divider(clk_idx, &data->clock, data->divider - 1); + ifx_cat1_utils_peri_pclk_assign_divider(clk_idx, &data->clock); + ifx_cat1_utils_peri_pclk_enable_divider(clk_idx, &data->clock); + } else if (data->hw_resource.type == IFX_RSC_SDHC) { + en_clk_dst_t clk_idx = ifx_cat1_sdhc_get_clock_index(data->hw_resource.block_num, + data->hw_resource.channel_num); + ifx_cat1_utils_peri_pclk_set_divider(clk_idx, &data->clock, data->divider - 1); ifx_cat1_utils_peri_pclk_assign_divider(clk_idx, &data->clock); ifx_cat1_utils_peri_pclk_enable_divider(clk_idx, &data->clock); diff --git a/drivers/sdhc/CMakeLists.txt b/drivers/sdhc/CMakeLists.txt index b2d3229e4a2a..33eda238ecaa 100644 --- a/drivers/sdhc/CMakeLists.txt +++ b/drivers/sdhc/CMakeLists.txt @@ -14,7 +14,7 @@ zephyr_library_sources_ifdef(CONFIG_SAM_HSMCI sam_hsmci.c) zephyr_library_sources_ifdef(CONFIG_SAM_SDMMC sam_sdmmc.c) zephyr_library_sources_ifdef(CONFIG_SDHC_AMBIQ sdhc_ambiq.c) zephyr_library_sources_ifdef(CONFIG_SDHC_ESP32 sdhc_esp32.c) -zephyr_library_sources_ifdef(CONFIG_SDHC_INFINEON_CAT1 infineon_sdio.c) +zephyr_library_sources_ifdef(CONFIG_SDHC_INFINEON_CAT1_PDL sdhc_infineon.c) zephyr_library_sources_ifdef(CONFIG_SDHC_MAX32 sdhc_max32.c) zephyr_library_sources_ifdef(CONFIG_SDHC_RENESAS_RA sdhc_renesas_ra.c) zephyr_library_sources_ifdef(CONFIG_SDHC_STM32_SDIO sdhc_stm32.c) diff --git a/drivers/sdhc/Kconfig.infineon b/drivers/sdhc/Kconfig.infineon index efa86bfae04e..d9de87a26d73 100644 --- a/drivers/sdhc/Kconfig.infineon +++ b/drivers/sdhc/Kconfig.infineon @@ -1,23 +1,29 @@ -# Infineon CAT1 SDHC configuration options - -# Copyright (c) 2023 Cypress Semiconductor Corporation (an Infineon company) or -# an affiliate of Cypress Semiconductor Corporation +# Copyright (c) 2025 Infineon Technologies AG, +# or an affiliate of Infineon Technologies AG. # # SPDX-License-Identifier: Apache-2.0 -config SDHC_INFINEON_CAT1 - bool "Infineon CAT1 SDHC driver" + +config SDHC_INFINEON_CAT1_PDL + bool "Infineon SDHC driver" default y depends on DT_HAS_INFINEON_SDHC_SDIO_ENABLED select USE_INFINEON_SDIO select SDHC_SUPPORTS_NATIVE_MODE + select SDHC_SUPPORTS_UHS select PINCTRL help - This option enables the SDHC driver for Infineon CAT1 family. + This option enables the PDL based SDHC driver for Infineon family. -if SDHC_INFINEON_CAT1 +if SDHC_INFINEON_CAT1_PDL config SDHC_INIT_PRIORITY default 70 -endif +config SDHC_BUFFER_ALIGNMENT + default DCACHE_LINE_SIZE if DCACHE + default 1 + help + SDHC buffer should aligned to the value of DCACHE_LINE_SIZE when placed in a cacheable region. + +endif #SDHC_INFINEON_CAT1_PDL diff --git a/drivers/sdhc/infineon_sdio.c b/drivers/sdhc/infineon_sdio.c deleted file mode 100644 index f2ef5f03f397..000000000000 --- a/drivers/sdhc/infineon_sdio.c +++ /dev/null @@ -1,341 +0,0 @@ -/* - * Copyright (c) 2023 Cypress Semiconductor Corporation (an Infineon company) or - * an affiliate of Cypress Semiconductor Corporation - * - * SPDX-License-Identifier: Apache-2.0 - * - */ - -/** - * @brief SDIO driver for Infineon CAT1 MCU family. - * - * This driver support only SDIO protocol of the SD interface for general - * I/O functions. - * - * Refer to the SD Specifications Part 1 SDIO Specifications Version 4.10 for more - * information on the SDIO protocol and specifications. - * - * Features - * - Supports 4-bit interface - * - Supports Ultra High Speed (UHS-I) mode - * - Supports Default Speed (DS), High Speed (HS), SDR12, SDR25 and SDR50 speed modes - * - Supports SDIO card interrupts in both 1-bit SD and 4-bit SD modes - * - Supports Standard capacity (SDSC), High capacity (SDHC) and - * Extended capacity (SDXC) memory - * - * Note (limitations): - * - current version of ifx_cat1_sdio supports only following set of commands: - * > GO_IDLE_STATE (CMD0) - * > SEND_RELATIVE_ADDR (CMD3) - * > IO_SEND_OP_COND (CMD5) - * > SELECT_CARD (CMD7) - * > VOLTAGE_SWITCH (CMD11) - * > GO_INACTIVE_STATE (CMD15) - * > IO_RW_DIRECT (CMD52) - * > IO_RW_EXTENDED (CMD53) - */ - -#define DT_DRV_COMPAT infineon_sdhc_sdio - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -LOG_MODULE_REGISTER(ifx_cat1_sdio, CONFIG_SDHC_LOG_LEVEL); - -#include - -#define IFX_CAT1_SDIO_F_MIN (SDMMC_CLOCK_400KHZ) -#define IFX_CAT1_SDIO_F_MAX (SD_CLOCK_50MHZ) - -struct ifx_cat1_sdio_config { - const struct pinctrl_dev_config *pincfg; - SDHC_Type *reg_addr; - uint8_t irq_priority; -}; - -struct ifx_cat1_sdio_data { - cyhal_sdio_t sdio_obj; - cyhal_resource_inst_t hw_resource; - cyhal_sdio_configurator_t cyhal_sdio_config; - enum sdhc_clock_speed clock_speed; - enum sdhc_bus_width bus_width; - - void *sdio_cb_user_data; - sdhc_interrupt_cb_t sdio_cb; -}; - -static uint32_t sdio_rca; -static const cy_stc_sd_host_init_config_t host_config = {false, CY_SD_HOST_DMA_ADMA2, false}; -static cy_en_sd_host_card_capacity_t sd_host_card_capacity = CY_SD_HOST_SDSC; -static cy_en_sd_host_card_type_t sd_host_card_type = CY_SD_HOST_NOT_EMMC; -static cy_stc_sd_host_sd_card_config_t sd_host_sd_card_config = { - .lowVoltageSignaling = false, - .busWidth = CY_SD_HOST_BUS_WIDTH_4_BIT, - .cardType = &sd_host_card_type, - .rca = &sdio_rca, - .cardCapacity = &sd_host_card_capacity, -}; - -/* List of available SDHC instances */ -static SDHC_Type *const IFX_CAT1_SDHC_BASE_ADDRESSES[CY_IP_MXSDHC_INSTANCES] = { -#ifdef SDHC0 - SDHC0, -#endif /* ifdef SDHC0 */ - -#ifdef SDHC1 - SDHC1, -#endif /* ifdef SDHC1 */ -}; - -static int32_t _get_hw_block_num(SDHC_Type *reg_addr) -{ - uint32_t i; - - for (i = 0u; i < CY_IP_MXSDHC_INSTANCES; i++) { - if (IFX_CAT1_SDHC_BASE_ADDRESSES[i] == reg_addr) { - return i; - } - } - - return -EINVAL; -} - -static int ifx_cat1_sdio_reset(const struct device *dev) -{ - struct ifx_cat1_sdio_data *dev_data = dev->data; - - cyhal_sdhc_software_reset((cyhal_sdhc_t *)&dev_data->sdio_obj); - - return 0; -} - -static int ifx_cat1_sdio_set_io(const struct device *dev, struct sdhc_io *ios) -{ - cy_rslt_t ret; - struct ifx_cat1_sdio_data *dev_data = dev->data; - cyhal_sdio_cfg_t config = {.frequencyhal_hz = ios->clock}; - - /* NOTE: Set bus width, set card power, set host signal voltage, - * set I/O timing does not support in current version of driver - */ - - /* Set host clock */ - if ((dev_data->clock_speed != ios->clock) && (ios->clock != 0)) { - - if ((ios->clock > IFX_CAT1_SDIO_F_MAX) || (ios->clock < IFX_CAT1_SDIO_F_MIN)) { - return -EINVAL; - } - - ret = cyhal_sdio_configure(&dev_data->sdio_obj, &config); - if (ret != CY_RSLT_SUCCESS) { - return -ENOTSUP; - } - - dev_data->clock_speed = ios->clock; - } - - return 0; -} - -static int ifx_cat1_sdio_card_busy(const struct device *dev) -{ - struct ifx_cat1_sdio_data *dev_data = dev->data; - - return cyhal_sdio_is_busy(&dev_data->sdio_obj) ? 1 : 0; -} - -static int ifx_cat1_sdio_request(const struct device *dev, struct sdhc_command *cmd, - struct sdhc_data *data) -{ - struct ifx_cat1_sdio_data *dev_data = dev->data; - int ret; - - switch (cmd->opcode) { - case CYHAL_SDIO_CMD_GO_IDLE_STATE: - case CYHAL_SDIO_CMD_SEND_RELATIVE_ADDR: - case CYHAL_SDIO_CMD_IO_SEND_OP_COND: - case CYHAL_SDIO_CMD_SELECT_CARD: - case CYHAL_SDIO_CMD_VOLTAGE_SWITCH: - case CYHAL_SDIO_CMD_GO_INACTIVE_STATE: - case CYHAL_SDIO_CMD_IO_RW_DIRECT: - ret = cyhal_sdio_send_cmd(&dev_data->sdio_obj, CYHAL_SDIO_XFER_TYPE_READ, - cmd->opcode, cmd->arg, cmd->response); - if (ret != CY_RSLT_SUCCESS) { - LOG_ERR("cyhal_sdio_send_cmd failed ret = %d \r\n", ret); - } - break; - - case CYHAL_SDIO_CMD_IO_RW_EXTENDED: - cyhal_sdio_transfer_type_t direction; - - direction = (cmd->arg & BIT(SDIO_CMD_ARG_RW_SHIFT)) ? CYHAL_SDIO_XFER_TYPE_WRITE - : CYHAL_SDIO_XFER_TYPE_READ; - - ret = cyhal_sdio_bulk_transfer(&dev_data->sdio_obj, direction, cmd->arg, data->data, - data->blocks * data->block_size, cmd->response); - - if (ret != CY_RSLT_SUCCESS) { - LOG_ERR("cyhal_sdio_bulk_transfer failed ret = %d \r\n", ret); - } - break; - - default: - ret = -ENOTSUP; - } - - return ret; -} - -static int ifx_cat1_sdio_get_card_present(const struct device *dev) -{ - return 1; -} - -static int ifx_cat1_sdio_get_host_props(const struct device *dev, struct sdhc_host_props *props) -{ - memset(props, 0, sizeof(*props)); - props->f_max = IFX_CAT1_SDIO_F_MAX; - props->f_min = IFX_CAT1_SDIO_F_MIN; - props->host_caps.bus_4_bit_support = true; - props->host_caps.high_spd_support = true; - props->host_caps.sdr50_support = true; - props->host_caps.sdio_async_interrupt_support = true; - props->host_caps.vol_330_support = true; - - return 0; -} - -static int ifx_cat1_sdio_enable_interrupt(const struct device *dev, sdhc_interrupt_cb_t callback, - int sources, void *user_data) -{ - struct ifx_cat1_sdio_data *data = dev->data; - const struct ifx_cat1_sdio_config *cfg = dev->config; - - if (sources != SDHC_INT_SDIO) { - return -ENOTSUP; - } - - if (callback == NULL) { - return -EINVAL; - } - - /* Record SDIO callback parameters */ - data->sdio_cb = callback; - data->sdio_cb_user_data = user_data; - - /* Enable CARD INTERRUPT event */ - cyhal_sdio_enable_event(&data->sdio_obj, CYHAL_SDIO_CARD_INTERRUPT, - cfg->irq_priority, true); - - return 0; -} - -static int ifx_cat1_sdio_disable_interrupt(const struct device *dev, int sources) -{ - struct ifx_cat1_sdio_data *data = dev->data; - const struct ifx_cat1_sdio_config *cfg = dev->config; - - if (sources != SDHC_INT_SDIO) { - return -ENOTSUP; - } - - data->sdio_cb = NULL; - data->sdio_cb_user_data = NULL; - - /* Disable CARD INTERRUPT event */ - cyhal_sdio_enable_event(&data->sdio_obj, CYHAL_SDIO_CARD_INTERRUPT, - cfg->irq_priority, false); - - return 0; -} - -static void ifx_cat1_sdio_event_callback(void *callback_arg, cyhal_sdio_event_t event) -{ - const struct device *dev = callback_arg; - struct ifx_cat1_sdio_data *data = dev->data; - - if ((event == CYHAL_SDIO_CARD_INTERRUPT) && (data->sdio_cb != NULL)) { - data->sdio_cb(dev, SDHC_INT_SDIO, data->sdio_cb_user_data); - } -} - -static int ifx_cat1_sdio_init(const struct device *dev) -{ - cy_rslt_t ret; - struct ifx_cat1_sdio_data *data = dev->data; - const struct ifx_cat1_sdio_config *config = dev->config; - - /* Configure dt provided device signals when available */ - ret = pinctrl_apply_state(config->pincfg, PINCTRL_STATE_DEFAULT); - if (ret) { - return ret; - } - - /* Dedicate SDIO HW resource */ - data->hw_resource.type = CYHAL_RSC_SDHC; - data->hw_resource.block_num = _get_hw_block_num(config->reg_addr); - data->hw_resource.channel_num = 0; - - /* Initialize the SDIO peripheral */ - data->cyhal_sdio_config.resource = &data->hw_resource; - data->cyhal_sdio_config.host_config = &host_config, - data->cyhal_sdio_config.card_config = &sd_host_sd_card_config, - data->cyhal_sdio_config.gpios.cmd = NC; - data->cyhal_sdio_config.gpios.clk = NC; - data->cyhal_sdio_config.gpios.data[0] = NC; - data->cyhal_sdio_config.gpios.data[1] = NC; - data->cyhal_sdio_config.gpios.data[2] = NC; - data->cyhal_sdio_config.gpios.data[3] = NC; - data->cyhal_sdio_config.clock = NULL; - - ret = cyhal_sdio_init_cfg(&data->sdio_obj, &data->cyhal_sdio_config); - if (ret != CY_RSLT_SUCCESS) { - LOG_ERR("cyhal_sdio_init_cfg failed ret = %d \r\n", ret); - return ret; - } - - /* Register callback for SDIO events */ - cyhal_sdio_register_callback(&data->sdio_obj, ifx_cat1_sdio_event_callback, (void *)dev); - - return 0; -} - -static DEVICE_API(sdhc, ifx_cat1_sdio_api) = { - .reset = ifx_cat1_sdio_reset, - .request = ifx_cat1_sdio_request, - .set_io = ifx_cat1_sdio_set_io, - .get_card_present = ifx_cat1_sdio_get_card_present, - .card_busy = ifx_cat1_sdio_card_busy, - .get_host_props = ifx_cat1_sdio_get_host_props, - .enable_interrupt = ifx_cat1_sdio_enable_interrupt, - .disable_interrupt = ifx_cat1_sdio_disable_interrupt, -}; - -#define IFX_CAT1_SDHC_INIT(n) \ - \ - PINCTRL_DT_INST_DEFINE(n); \ - \ - static const struct ifx_cat1_sdio_config ifx_cat1_sdio_##n##_config = { \ - .pincfg = PINCTRL_DT_INST_DEV_CONFIG_GET(n), \ - .reg_addr = (SDHC_Type *)DT_INST_REG_ADDR(n), \ - .irq_priority = DT_INST_IRQ(n, priority)}; \ - \ - static struct ifx_cat1_sdio_data ifx_cat1_sdio_##n##_data; \ - \ - DEVICE_DT_INST_DEFINE(n, &ifx_cat1_sdio_init, NULL, &ifx_cat1_sdio_##n##_data, \ - &ifx_cat1_sdio_##n##_config, POST_KERNEL, CONFIG_SDHC_INIT_PRIORITY, \ - &ifx_cat1_sdio_api); - -DT_INST_FOREACH_STATUS_OKAY(IFX_CAT1_SDHC_INIT) diff --git a/drivers/sdhc/sdhc_infineon.c b/drivers/sdhc/sdhc_infineon.c new file mode 100644 index 000000000000..fc7c7f843729 --- /dev/null +++ b/drivers/sdhc/sdhc_infineon.c @@ -0,0 +1,1141 @@ +/* + * Copyright (c) 2025 Infineon Technologies AG, + * or an affiliate of Infineon Technologies AG. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @brief SDHC driver for Infineon MCU family. + * + * This driver support only SD protocol of the SD interface. + * + * + * Features: + * * Supports data transfer using CPU, SDMA, ADMA2 and ADMA3 modes + * * Supports a configurable block size (1 to 65,535 Bytes) + * * Supports interrupt enabling and masking + * * Supports SD-HCI Host version 4 mode or less + * * Compliant with the SD 6.0, SDIO 4.10 and earlier versions + * * SD interface features: + * * - Supports the 4-bit interface + * * - Supports Ultra High Speed (UHS-I) mode + * * - Supports Default Speed (DS), High Speed (HS), SDR12, SDR25, SDR50, and DDR50 speed modes + * * - Supports SDIO card interrupts in both 1-bit and 4-bit modes + * * - Supports Standard capacity (SDSC), High capacity (SDHC) and Extended capacity (SDXC) memory + * * - Supports CRC and check for command and data packets + * * - Supports packet timeouts + * + */ + +#define DT_DRV_COMPAT infineon_sdhc_sdio + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "cy_sd_host.h" +#include "cy_sysclk.h" + +LOG_MODULE_REGISTER(sdhc_infineon, CONFIG_SDHC_LOG_LEVEL); + +#include + +#define IFX_SDHC_RETRY_TIMES (1000U) /* The number loops to make timeout in us */ +#define IFX_SDHC_CMD_CMPLT_DELAY_US (5U) /* The Command complete delay in us */ +#define IFX_SDHC_MAX_TIMEOUT (0x0EU) /* The data max timeout for TOUT_CTRL_R */ +#define IFX_SDHC_RETRY_TIME (1000U) /* The number loops to make timeout in us */ +#define IFX_SDHC_BUFFER_RDY_TIMEOUT_US (150U) /* The Buffer read ready timeout in us */ +#define IFX_SDHC_RD_WR_ENABLE_TIMEOUT_US (1U) /* The valid data in the Host buffer timeout */ +#define IFX_SDHC_WRITE_TIMEOUT_US (250U) /* The Write timeout for one block */ +#define IFX_SDHC_SD_ACMD_OFFSET (0x40U) +#define IFX_SDHC_SDIO_TRANSFER_TRIES (50U) +#define IFX_SDHC_SET_ALL_INTERRUPTS_MASK (0x61FFU) +#define IFX_SDHC_1_8_REG_STABLE_TIME_MS (200U) /* The 1.8 voltage regulator stable time in ms */ + +struct sdhc_infineon_config { + const struct pinctrl_dev_config *pincfg; + struct gpio_dt_spec cd_gpio; + SDHC_Type *reg_addr; + uint8_t irq_priority; + IRQn_Type irq; +}; + +/* + * Keep DMA descriptor's memory location as D-cache alignment, so that + * when cleaning its cache line before DMA transfer, it would not affect other + * memory data in same cache line, which is used by other DMA. + */ +struct __aligned(CONFIG_SDHC_BUFFER_ALIGNMENT) sdhc_infineon_data { + uint32_t adma_descriptor_tbl[2]; + struct k_sem thread_lock; + struct k_sem transfer_sem; + struct sdhc_host_props props; +#if defined(CONFIG_SOC_FAMILY_INFINEON_EDGE) + struct ifx_cat1_clock clock; +#endif + uint32_t irq_cause; + void *sdio_cb_user_data; + sdhc_interrupt_cb_t sdio_cb; + uint32_t bus_clock; /* Value in Hz */ + cy_en_sd_host_bus_width_t bus_width; + enum sdhc_power power_mode; + cy_en_sd_host_bus_speed_mode_t speed_mode; + enum sd_voltage signal_voltage; +#if defined(CONFIG_SOC_FAMILY_INFINEON_EDGE) + uint8_t clock_peri_group; +#endif + bool app_cmd; +}; + +static const cy_stc_sd_host_init_config_t sdhc_config = { + .emmc = false, + .dmaType = CY_SD_HOST_DMA_ADMA2, + .enableLedControl = false, +}; + +static void sdhc_infineon_irq_handler(const struct device *dev) +{ + const struct sdhc_infineon_config *const config = dev->config; + struct sdhc_infineon_data *const sdhc_data = dev->data; + + /* Clear all interrupts that could have been configured */ + SDHC_Type *base = config->reg_addr; + uint32_t int_status = Cy_SD_Host_GetNormalInterruptStatus(base); + uint32_t int_enable_status = Cy_SD_Host_GetNormalInterruptEnable(base); + uint32_t int_mask = Cy_SD_Host_GetNormalInterruptMask(base); + uint32_t user_int_status = int_status & sdhc_data->irq_cause; + + /* CY_SD_HOST_XFER_COMPLETE occurred and appropriate bit in interrupt mask is enabled */ + if (int_status & Cy_SD_Host_GetNormalInterruptMask(base) & CY_SD_HOST_XFER_COMPLETE) { + /* Clearing transfer complete status */ + Cy_SD_Host_ClearNormalInterruptStatus(base, CY_SD_HOST_XFER_COMPLETE); + + k_sem_give(&sdhc_data->transfer_sem); + + /* Disabling transfer complete interrupt mask */ + Cy_SD_Host_SetNormalInterruptMask(base, + Cy_SD_Host_GetNormalInterruptMask(base) & + (uint32_t)~CY_SD_HOST_XFER_COMPLETE); + + /* Transfer is no more active. If card interrupt was not yet enabled after it was + * disabled in interrupt handler, enable it. + */ + if ((int_enable_status & CY_SD_HOST_CARD_INTERRUPT) == 0) { + Cy_SD_Host_SetNormalInterruptEnable( + base, (int_enable_status | CY_SD_HOST_CARD_INTERRUPT)); + } + } + + /* To clear Card Interrupt need to disable Card Interrupt Enable bit. + * The Card Interrupt is enabled after the current transfer is complete + */ + if ((int_status & CY_SD_HOST_CARD_INTERRUPT) != 0U) { + int_enable_status = Cy_SD_Host_GetNormalInterruptEnable(base); + int_enable_status &= (uint32_t)~CY_SD_HOST_CARD_INTERRUPT; + /* Disable Card Interrupt */ + Cy_SD_Host_SetNormalInterruptEnable(base, int_enable_status); + } + + if ((sdhc_data->sdio_cb != NULL) && ((user_int_status & int_mask) > 0U)) { + sdhc_data->sdio_cb(dev, SDHC_INT_SDIO, sdhc_data->sdio_cb_user_data); + } +} + +static void sdhc_normal_reset(SDHC_Type *base) +{ + uint32_t int_status; /* The normal events mask. */ + + int_status = Cy_SD_Host_GetNormalInterruptStatus(base); + + /* Check the normal event. */ + if (int_status > 0U) { + /* Clear the normal event. */ + Cy_SD_Host_ClearNormalInterruptStatus(base, int_status); + } +} + +static void sdhc_error_reset(SDHC_Type *base) +{ + uint32_t err_status; /* The error events mask. */ + + err_status = Cy_SD_Host_GetErrorInterruptStatus(base); + + /* Check the error event. */ + if (err_status > 0U) { + /* Clear the error event. */ + Cy_SD_Host_ClearErrorInterruptStatus(base, err_status); + + Cy_SD_Host_SoftwareReset(base, CY_SD_HOST_RESET_CMD_LINE); + } +} + +static int sdhc_infineon_reset(const struct device *dev) +{ + const struct sdhc_infineon_config *config = dev->config; + uint32_t timeout_us = 1000U; + + Cy_SD_Host_SoftwareReset(config->reg_addr, CY_SD_HOST_RESET_DATALINE); + Cy_SD_Host_SoftwareReset(config->reg_addr, CY_SD_HOST_RESET_CMD_LINE); + + if (!WAIT_FOR(config->reg_addr->CORE.SW_RST_R == 0, timeout_us, k_busy_wait(1))) { + /* Reset was not cleared by SDHC IP Block. Something wrong. Are clocks enabled? */ + LOG_ERR("Software reset is not completed...timeout, reg:0x%08X", + config->reg_addr->CORE.SW_RST_R); + return -ETIMEDOUT; + } + + return 0; +} + +static inline cy_en_sd_host_response_type_t sdhc_resp_type(uint32_t response_type) +{ + switch (response_type & SDHC_NATIVE_RESPONSE_MASK) { + case SD_RSP_TYPE_NONE: + return CY_SD_HOST_RESPONSE_NONE; + case SD_RSP_TYPE_R1b: + case SD_RSP_TYPE_R5b: + return CY_SD_HOST_RESPONSE_LEN_48B; + case SD_RSP_TYPE_R2: + return CY_SD_HOST_RESPONSE_LEN_136; + default: + return CY_SD_HOST_RESPONSE_LEN_48; + } +} + +static inline cy_en_sd_host_cmd_type_t sdhc_cmd_type(uint32_t opcode) +{ + switch (opcode) { + case SD_GO_IDLE_STATE: + case SD_STOP_TRANSMISSION: + return CY_SD_HOST_CMD_ABORT; + default: + return CY_SD_HOST_CMD_NORMAL; + } +} + +static inline bool sdhc_dma_enable(cy_stc_sd_host_cmd_config_t *cmd_config) +{ + switch (cmd_config->commandIndex) { + case SD_SWITCH: + case SD_SEND_STATUS: + case (SD_APP_SEND_SCR + IFX_SDHC_SD_ACMD_OFFSET): + return false; + default: + return true; + } +} + +static inline cy_en_sd_host_auto_cmd_t sdhc_autocommand(cy_stc_sd_host_cmd_config_t *cmd_config, + struct sdhc_data *data) +{ + return (data->blocks > 1U) ? CY_SD_HOST_AUTO_CMD_AUTO : CY_SD_HOST_AUTO_CMD_NONE; +} + +static inline cy_en_sd_host_auto_cmd_t sdhc_int_at_blockgap(cy_stc_sd_host_cmd_config_t *cmd_config, + struct sdhc_data *data) +{ + return data->blocks > 1U; +} + +static inline int sdhc_prepare_for_transfer(const struct device *dev) +{ + const struct sdhc_infineon_config *config = dev->config; + + /* Enabling transfer complete interrupt as it takes part in write / read processes */ + Cy_SD_Host_SetNormalInterruptMask(config->reg_addr, + Cy_SD_Host_GetNormalInterruptMask(config->reg_addr) | + CY_SD_HOST_XFER_COMPLETE); + + return 0; +} + +static int sdhc_poll_cmd_complete(const struct device *dev) +{ + const struct sdhc_infineon_config *config = dev->config; + uint32_t timeout_us = IFX_SDHC_RETRY_TIMES * IFX_SDHC_CMD_CMPLT_DELAY_US; + + if (!WAIT_FOR((CY_SD_HOST_CMD_COMPLETE & + Cy_SD_Host_GetNormalInterruptStatus(config->reg_addr)) == + CY_SD_HOST_CMD_COMPLETE, + timeout_us, k_busy_wait(1))) { + return -ETIMEDOUT; + } + + /* Clear interrupt flag */ + Cy_SD_Host_ClearNormalInterruptStatus(config->reg_addr, CY_SD_HOST_CMD_COMPLETE); + + return 0; +} + +static int sdhc_host_poll_transfer_complete(SDHC_Type *base) +{ + /* Transfer Complete */ + if (!WAIT_FOR(_FLD2BOOL(SDHC_CORE_NORMAL_INT_STAT_R_XFER_COMPLETE, + SDHC_CORE_NORMAL_INT_STAT_R(base)), + IFX_SDHC_RETRY_TIME, k_busy_wait(IFX_SDHC_WRITE_TIMEOUT_US))) { + return -ETIMEDOUT; + } + + /* Clear the interrupt flag */ + SDHC_CORE_NORMAL_INT_STAT_R(base) = CY_SD_HOST_XFER_COMPLETE; + + return 0; +} + +static int sdhc_poll_buf_read_ready(SDHC_Type *base) +{ + /* Check the Buffer Read ready */ + if (!WAIT_FOR(_FLD2BOOL(SDHC_CORE_NORMAL_INT_STAT_R_BUF_RD_READY, + SDHC_CORE_NORMAL_INT_STAT_R(base)), + IFX_SDHC_RETRY_TIME, k_busy_wait(IFX_SDHC_BUFFER_RDY_TIMEOUT_US))) { + return -ETIMEDOUT; + } + + /* Clear the interrupt flag */ + SDHC_CORE_NORMAL_INT_STAT_R(base) = CY_SD_HOST_BUF_RD_READY; + + return 0; +} + +static int sdhc_cmd_rx_data(SDHC_Type *base, cy_stc_sd_host_data_config_t *pcmd) +{ + uint32_t blk_size = pcmd->blockSize; + uint32_t blk_cnt = pcmd->numberOfBlock; + uint32_t i; + + while (blk_cnt > 0U) { + /* Wait for the Buffer Read ready. */ + if (sdhc_poll_buf_read_ready(base) != 0) { + LOG_WRN("%s Buffer read is not ready", __func__); + break; + } + + for (i = blk_size >> 2U; i != 0U; i--) { + /* Wait if valid data exists in the Host buffer. */ + WAIT_FOR(_FLD2BOOL(SDHC_CORE_PSTATE_REG_BUF_RD_ENABLE, + SDHC_CORE_PSTATE_REG(base)), + IFX_SDHC_RETRY_TIME, + k_busy_wait(IFX_SDHC_RD_WR_ENABLE_TIMEOUT_US)); + + if (false == _FLD2BOOL(SDHC_CORE_PSTATE_REG_BUF_RD_ENABLE, + SDHC_CORE_PSTATE_REG(base))) { + break; + } + + /* Read data from the Host buffer. */ + *pcmd->data = Cy_SD_Host_BufferRead(base); + pcmd->data++; + } + blk_cnt--; + } + + /* Wait for the Transfer Complete. */ + return sdhc_host_poll_transfer_complete(base); +} + +static int sdhc_config_data_transfer(const struct device *dev, struct sdhc_data *data, + cy_stc_sd_host_data_config_t *data_config) +{ + const struct sdhc_infineon_config *config = dev->config; + struct sdhc_infineon_data *const sdhc_data = dev->data; + uint32_t length; + + data_config->blockSize = data->block_size; + data_config->numberOfBlock = data->blocks; + data_config->dataTimeout = IFX_SDHC_MAX_TIMEOUT; + data_config->enReliableWrite = false; + + if (data_config->enableDma == true) { + /* ADMA2 mode. */ + length = data->block_size * data->blocks; + sdhc_data->adma_descriptor_tbl[0] = + (1U << CY_SD_HOST_ADMA_ATTR_VALID_POS) | /* Attr Valid */ + (1U << CY_SD_HOST_ADMA_ATTR_END_POS) | /* Attr End */ + (0U << CY_SD_HOST_ADMA_ATTR_INT_POS) | /* Attr Int */ + (CY_SD_HOST_ADMA_TRAN << CY_SD_HOST_ADMA_ACT_POS) | + (length << CY_SD_HOST_ADMA_LEN_POS); /* Len */ + + /* SDHC needs to be able to access the data_ptr that is in DTCM when using CM55. + * Remap this address for access. + */ +#if defined(CORE_NAME_CM55_0) + sdhc_data->adma_descriptor_tbl[1] = (uint32_t)cy_DTCMRemapAddr(data->data); + data_config->data = + (uint32_t *)cy_DTCMRemapAddr(&sdhc_data->adma_descriptor_tbl[0]); +#else + sdhc_data->adma_descriptor_tbl[1] = (uint32_t)data->data; + data_config->data = (uint32_t *)&sdhc_data->adma_descriptor_tbl[0]; +#endif + +#if defined(CONFIG_CPU_HAS_DCACHE) && defined(__DCACHE_PRESENT) && __DCACHE_PRESENT + sys_cache_data_flush_range((void *)sdhc_data->adma_descriptor_tbl, + sizeof(sdhc_data->adma_descriptor_tbl)); +#endif + } else { + data_config->data = (uint32_t *)data->data; + } + + return (int)Cy_SD_Host_InitDataTransfer(config->reg_addr, data_config); +} + +static int sdhc_send_cmd(const struct device *dev, cy_stc_sd_host_cmd_config_t *cmd_config, + struct sdhc_data *data, bool is_read) +{ + const struct sdhc_infineon_config *config = dev->config; + struct sdhc_infineon_data *const sdhc_data = dev->data; + cy_stc_sd_host_data_config_t data_config; + int result = 0; + + data_config.enableDma = sdhc_dma_enable(cmd_config); +#if defined(CONFIG_CPU_HAS_DCACHE) && defined(__DCACHE_PRESENT) && __DCACHE_PRESENT + if ((cmd_config->dataPresent) && (data_config.enableDma == true)) { + sys_cache_data_flush_range(data->data, data->block_size * data->blocks); + } +#endif + + /* First clear out the transfer and command complete statuses */ + Cy_SD_Host_ClearNormalInterruptStatus(config->reg_addr, + (CY_SD_HOST_XFER_COMPLETE | CY_SD_HOST_CMD_COMPLETE)); + + if (cmd_config->dataPresent) { + data_config.read = is_read; + data_config.autoCommand = sdhc_autocommand(cmd_config, data); + data_config.enableIntAtBlockGap = sdhc_int_at_blockgap(cmd_config, data); + result = sdhc_config_data_transfer(dev, data, &data_config); + + if (result == 0 && data_config.enableDma == true) { + result = sdhc_prepare_for_transfer(dev); + } + } + + if (result == 0) { + result = (int)Cy_SD_Host_SendCommand(config->reg_addr, cmd_config); + } + + if (result == 0) { + result = sdhc_poll_cmd_complete(dev); + } + + if (result == 0) { + if (cmd_config->dataPresent) { + if (data_config.enableDma == true) { + result = k_sem_take(&sdhc_data->transfer_sem, + K_MSEC(data->timeout_ms)); + if (result != 0U) { + LOG_ERR("Cannot take sem!"); + } + +#if defined(CONFIG_CPU_HAS_DCACHE) && defined(__DCACHE_PRESENT) && __DCACHE_PRESENT + if (data_config.read == true) { + sys_cache_data_invd_range(data->data, + data->block_size * data->blocks); + } +#endif + } else { + /* DMA is not used - wait until all data is read. */ + result = sdhc_cmd_rx_data(config->reg_addr, &data_config); + } + } + } + + return result; +} + +static int sdhc_send_cmd53(const struct device *dev, cy_stc_sd_host_cmd_config_t *cmd_Config, + struct sdhc_data *data, bool is_read) +{ + const struct sdhc_infineon_config *config = dev->config; + struct sdhc_infineon_data *const sdhc_data = dev->data; + cy_stc_sd_host_data_config_t data_Config; + int result = 0; + uint32_t retry = IFX_SDHC_SDIO_TRANSFER_TRIES; + +#if defined(CONFIG_CPU_HAS_DCACHE) && defined(__DCACHE_PRESENT) && __DCACHE_PRESENT + sys_cache_data_flush_range(data->data, data->block_size * data->blocks); +#endif + + do { + /* Add SDIO Error Handling + * SDIO write timeout is expected when doing first write to register + * after KSO bit disable (as it goes to AOS core). + * This timeout, however, triggers an error state in the hardware. + * So, check for the error and then recover from it + * as needed via reset issuance. This is the only time known that + * a write timeout occurs. + */ + + /* First clear out the transfer and command complete statuses */ + Cy_SD_Host_ClearNormalInterruptStatus( + config->reg_addr, (CY_SD_HOST_XFER_COMPLETE | CY_SD_HOST_CMD_COMPLETE)); + + /* Check if an error occurred on any previous transactions or reset after the first + * unsuccessful transfer try. + */ + if ((Cy_SD_Host_GetNormalInterruptStatus(config->reg_addr) & + CY_SD_HOST_ERR_INTERRUPT) || + (retry < IFX_SDHC_SDIO_TRANSFER_TRIES)) { + /* Reset the block if there was an error. Note a full reset usually + * requires more time, but this short version is working quite well and + * successfully clears out the error state. + */ + Cy_SD_Host_ClearErrorInterruptStatus(config->reg_addr, + IFX_SDHC_SET_ALL_INTERRUPTS_MASK); + sdhc_infineon_reset(dev); + } + + data_Config.read = is_read; + data_Config.enableDma = true; + data_Config.autoCommand = CY_SD_HOST_AUTO_CMD_NONE; + data_Config.enableIntAtBlockGap = false; + result = sdhc_config_data_transfer(dev, data, &data_Config); + + if (result == 0) { + result = sdhc_prepare_for_transfer(dev); + } + + if (result == 0) { + result = (cy_rslt_t)Cy_SD_Host_SendCommand(config->reg_addr, cmd_Config); + } + + if (result == 0) { + result = (cy_rslt_t)sdhc_poll_cmd_complete(dev); + } + } while ((result != 0) && (--retry > 0UL)); + + if (result == 0) { + result = k_sem_take(&sdhc_data->transfer_sem, K_MSEC(data->timeout_ms)); + if (result != 0U) { + LOG_ERR("Cannot take sem!"); + } + +#if defined(CONFIG_CPU_HAS_DCACHE) && defined(__DCACHE_PRESENT) && __DCACHE_PRESENT + if (data_Config.read == true) { + sys_cache_data_invd_range(data->data, data->block_size * data->blocks); + } +#endif + } + + return result; +} + +static int sdhc_infineon_request(const struct device *dev, struct sdhc_command *cmd, + struct sdhc_data *data) +{ + const struct sdhc_infineon_config *config = dev->config; + struct sdhc_infineon_data *const sdhc_data = dev->data; + bool large_response; + int result = 0; + + LOG_DBG("Opcode: %d", cmd->opcode); + + k_sem_take(&sdhc_data->thread_lock, K_FOREVER); + /* Reset semaphore */ + k_sem_reset(&sdhc_data->transfer_sem); + + cy_stc_sd_host_cmd_config_t cmd_config = { + .commandIndex = cmd->opcode, + .commandArgument = cmd->arg, + .enableCrcCheck = true, + .enableAutoResponseErrorCheck = false, + .respType = sdhc_resp_type(cmd->response_type), + .enableIdxCheck = true, + .dataPresent = (data != NULL) ? true : false, + .cmdType = sdhc_cmd_type(cmd->opcode), + }; + + switch (cmd->opcode) { + case SD_GO_IDLE_STATE: + cmd_config.enableCrcCheck = false; + cmd_config.enableIdxCheck = false; + /* No response CMD so no complete interrupt */ + (void)sdhc_send_cmd(dev, &cmd_config, data, true); + + /* Software reset for the CMD line */ + Cy_SD_Host_SoftwareReset(config->reg_addr, CY_SD_HOST_RESET_CMD_LINE); + break; + + case SD_SEND_IF_COND: + result = sdhc_send_cmd(dev, &cmd_config, data, true); + Cy_SD_Host_GetResponse(config->reg_addr, cmd->response, false); + if ((cmd->response[0] & 0xFF) != SD_IF_COND_CHECK) { + /* Reset the error and the CMD line for the case of the SDIO card. */ + sdhc_error_reset(config->reg_addr); + sdhc_normal_reset(config->reg_addr); + } + goto end; + + case MMC_SEND_OP_COND: + case SDIO_SEND_OP_COND: + case SD_SELECT_CARD: + cmd_config.enableCrcCheck = false; + cmd_config.enableIdxCheck = false; + result = sdhc_send_cmd(dev, &cmd_config, data, true); + break; + + case SD_APP_SEND_OP_COND: + cmd_config.commandIndex += IFX_SDHC_SD_ACMD_OFFSET; + cmd_config.enableCrcCheck = false; + cmd_config.enableIdxCheck = false; + result = sdhc_send_cmd(dev, &cmd_config, data, true); + break; + + case SD_ALL_SEND_CID: + case SD_SEND_CSD: + cmd_config.enableCrcCheck = true; + cmd_config.enableIdxCheck = false; + result = sdhc_send_cmd(dev, &cmd_config, data, true); + break; + + case SD_SEND_STATUS: + result = sdhc_send_cmd(dev, &cmd_config, data, true); + break; + + case SD_SEND_RELATIVE_ADDR: + case SD_SET_BLOCK_SIZE: + case SD_ERASE_BLOCK_START: + case SD_ERASE_BLOCK_END: + case SD_ERASE_BLOCK_OPERATION: + case SD_APP_CMD: + result = sdhc_send_cmd(dev, &cmd_config, data, true); + break; + + case SD_VOL_SWITCH: + result = sdhc_send_cmd(dev, &cmd_config, data, true); + k_msleep(IFX_SDHC_1_8_REG_STABLE_TIME_MS); + break; + + case SD_SWITCH: + /* Check app cmd */ + if (sdhc_data->app_cmd && cmd->opcode == SD_APP_SET_BUS_WIDTH) { + cmd_config.commandIndex += IFX_SDHC_SD_ACMD_OFFSET; + cmd_config.enableCrcCheck = false; + cmd_config.enableIdxCheck = false; + result = sdhc_send_cmd(dev, &cmd_config, data, true); + } else { + result = sdhc_send_cmd(dev, &cmd_config, data, true); + } + break; + + case SDIO_RW_DIRECT: + cmd_config.respType = CY_SD_HOST_RESPONSE_LEN_48B; + result = sdhc_send_cmd(dev, &cmd_config, data, true); + break; + + case SDIO_RW_EXTENDED: + result = sdhc_send_cmd53(dev, &cmd_config, data, + !(cmd->arg & BIT(SDIO_CMD_ARG_RW_SHIFT))); + break; + + case SD_APP_SEND_NUM_WRITTEN_BLK: + cmd_config.commandIndex += IFX_SDHC_SD_ACMD_OFFSET; + result = sdhc_send_cmd(dev, &cmd_config, data, true); + break; + + case SD_APP_SEND_SCR: + cmd_config.commandIndex += IFX_SDHC_SD_ACMD_OFFSET; + cmd_config.respType = CY_SD_HOST_RESPONSE_LEN_48B; + result = sdhc_send_cmd(dev, &cmd_config, data, true); + break; + + case SD_READ_SINGLE_BLOCK: + case SD_READ_MULTIPLE_BLOCK: + result = sdhc_send_cmd(dev, &cmd_config, data, true); + break; + + case SD_WRITE_SINGLE_BLOCK: + case SD_WRITE_MULTIPLE_BLOCK: + result = sdhc_send_cmd(dev, &cmd_config, data, false); + break; + + default: + result = -ENOTSUP; + } + + if (cmd_config.respType != CY_SD_HOST_RESPONSE_NONE) { + large_response = (cmd_config.respType == CY_SD_HOST_RESPONSE_LEN_136); + Cy_SD_Host_GetResponse(config->reg_addr, cmd->response, large_response); + } + +end: + if (cmd->opcode == SD_APP_CMD) { + sdhc_data->app_cmd = true; + } else { + sdhc_data->app_cmd = false; + } + k_sem_give(&sdhc_data->thread_lock); + + return result; +} + +static void sdhc_find_best_div(uint32_t hz_src, uint32_t desired_hz, uint32_t *divider) +{ + /* Rounding up for correcting the error in integer division + * to ensure the actual frequency is less than or equal to + * the requested frequency. + * Ensure computed divider is no more than 10-bit. + */ + if (hz_src > desired_hz) { + uint32_t freq = (desired_hz << 1); + uint32_t calculated_divider = ((hz_src + freq - 1) / freq) & 0x3FF; + /* Real divider is 2 x calculated_divider */ + *divider = calculated_divider << 1; + } else { + *divider = 1; + } +} + +static int sdhc_change_clock(const struct device *dev, uint32_t *frequency) +{ + const struct sdhc_infineon_config *config = dev->config; + struct sdhc_infineon_data *const sdhc_data = dev->data; + uint32_t most_suitable_div = 0; + uint32_t bus_freq = 0; + uint32_t source_freq = 0; + en_clk_dst_t clk_idx; + +#if defined(COMPONENT_CAT1A) + (void)clk_idx; + (void)sdhc_data; + source_freq = Cy_SysClk_ClkHfGetFrequency(CLK_HF4); +#elif defined(CONFIG_SOC_FAMILY_INFINEON_EDGE) + if (config->reg_addr == SDHC0) { + clk_idx = PCLK_SDHC0_CLK_HF; + } else if (config->reg_addr == SDHC1) { + clk_idx = PCLK_SDHC1_CLK_HF; + } else { + return -EINVAL; + } + + source_freq = + ifx_cat1_utils_peri_pclk_get_frequency((en_clk_dst_t)clk_idx, &sdhc_data->clock); +#endif + + sdhc_find_best_div(source_freq, *frequency, &most_suitable_div); + bus_freq = source_freq / most_suitable_div; + + Cy_SD_Host_DisableSdClk(config->reg_addr); + if (Cy_SD_Host_SetSdClkDiv(config->reg_addr, most_suitable_div >> 1) == + CY_SD_HOST_SUCCESS) { + Cy_SD_Host_EnableSdClk(config->reg_addr); + *frequency = bus_freq; + return 0; + } + + return -EINVAL; +} + +static void sdhc_card_power_cycle(const struct device *dev, enum sdhc_power power_mode) +{ + const struct sdhc_infineon_config *config = dev->config; + + if (power_mode == SDHC_POWER_ON) { + SDHC_CORE_PWR_CTRL_R(config->reg_addr) = + _CLR_SET_FLD8U(SDHC_CORE_PWR_CTRL_R(config->reg_addr), + SDHC_CORE_PWR_CTRL_R_SD_BUS_PWR_VDD1, 1U); + } +} + +static int sdhc_infineon_set_io(const struct device *dev, struct sdhc_io *ios) +{ + const struct sdhc_infineon_config *config = dev->config; + struct sdhc_infineon_data *const sdhc_data = dev->data; + cy_en_sd_host_bus_width_t bus_width; + cy_en_sd_host_bus_speed_mode_t speed_mode; + int ret = 0; + + LOG_INF("SDHC I/O: bus width %d, clock %dHz, card power %s, voltage %s, timing %d", + ios->bus_width, ios->clock, ios->power_mode == SDHC_POWER_ON ? "ON" : "OFF", + ios->signal_voltage == SD_VOL_1_8_V ? "1.8V" : "3.3V", ios->timing); + + /* Toggle card power supply */ + if (sdhc_data->power_mode != ios->power_mode) { + sdhc_card_power_cycle(dev, ios->power_mode); + sdhc_data->power_mode = ios->power_mode; + } + + if (ios->bus_width > 0U) { + /* Set bus width */ + switch (ios->bus_width) { + case SDHC_BUS_WIDTH1BIT: + bus_width = CY_SD_HOST_BUS_WIDTH_1_BIT; + break; + case SDHC_BUS_WIDTH4BIT: + bus_width = CY_SD_HOST_BUS_WIDTH_4_BIT; + break; + case SDHC_BUS_WIDTH8BIT: + bus_width = CY_SD_HOST_BUS_WIDTH_8_BIT; + return -ENOTSUP; + default: + return -ENOTSUP; + } + + if (sdhc_data->bus_width != bus_width) { + /* Update the host side setting. */ + ret = Cy_SD_Host_SetHostBusWidth(config->reg_addr, bus_width); + + if (ret == 0) { + LOG_INF("Bus width set successfully to %d bit", ios->bus_width); + } else { + LOG_ERR("Error configuring bus width"); + return -EINVAL; + } + + sdhc_data->bus_width = bus_width; + } + } + + if (ios->timing > 0U) { + /* Set I/O timing */ + switch (ios->timing) { + case SDHC_TIMING_LEGACY: + speed_mode = CY_SD_HOST_BUS_SPEED_DEFAULT; + break; + case SDHC_TIMING_HS: + speed_mode = CY_SD_HOST_BUS_SPEED_HIGHSPEED; + break; + case SDHC_TIMING_SDR12: + speed_mode = CY_SD_HOST_BUS_SPEED_SDR12_5; + break; + case SDHC_TIMING_SDR25: + speed_mode = CY_SD_HOST_BUS_SPEED_SDR25; + break; + case SDHC_TIMING_SDR50: + speed_mode = CY_SD_HOST_BUS_SPEED_SDR50; + break; + case SDHC_TIMING_DDR50: + speed_mode = CY_SD_HOST_BUS_SPEED_DDR50; + break; + default: + LOG_ERR("Timing mode not supported for this device"); + return -ENOTSUP; + } + + if (sdhc_data->speed_mode != speed_mode) { + ret = Cy_SD_Host_SetHostSpeedMode(config->reg_addr, speed_mode); + + if (ret == 0) { + LOG_INF("Timing set successfully to %d", ios->timing); + } else { + LOG_ERR("Error configuring Timing"); + return -EINVAL; + } + + sdhc_data->speed_mode = speed_mode; + } + } + + if (ios->clock != sdhc_data->bus_clock) { + if (ios->clock == 0U) { + /* Disable providing the SD Clock. */ + Cy_SD_Host_DisableSdClk(config->reg_addr); + } else { + /* Check for frequency boundaries supported by host */ + if (ios->clock > sdhc_data->props.f_max || + ios->clock < sdhc_data->props.f_min) { + LOG_ERR("Proposed clock outside supported host range"); + return -EINVAL; + } + + uint32_t actual_freq = ios->clock; + + /* Try setting new clock */ + ret = sdhc_change_clock(dev, &actual_freq); + + if (ret == 0) { + LOG_INF("Bus clock successfully set to %d kHz", ios->clock / 1000); + } else { + LOG_ERR("Error configuring card clock"); + return -EINVAL; + } + } + + sdhc_data->bus_clock = (uint32_t)ios->clock; + } + + if (sdhc_data->signal_voltage != ios->signal_voltage) { + switch (ios->signal_voltage) { + case SD_VOL_3_3_V: + Cy_SD_Host_ChangeIoVoltage(config->reg_addr, CY_SD_HOST_IO_VOLT_3_3V); + break; + case SD_VOL_1_8_V: + /* Switch the bus to 1.8 V (Set the IO_VOLT_SEL pin to low)*/ + Cy_SD_Host_ChangeIoVoltage(config->reg_addr, CY_SD_HOST_IO_VOLT_1_8V); + break; + default: + return -ENOTSUP; + } + + sdhc_data->signal_voltage = ios->signal_voltage; + } + + return ret; +} + +static int sdhc_infineon_get_card_present(const struct device *dev) +{ + int res = 1; + const struct sdhc_infineon_config *config = dev->config; + + /* If a CD pin is configured, use it for card detection */ + if (config->cd_gpio.port != NULL) { + res = !gpio_pin_get_dt(&config->cd_gpio); + } + + return res; +} + +static int sdhc_infineon_execute_tuning(const struct device *dev) +{ + return 0; +} + +static int sdhc_infineon_card_busy(const struct device *dev) +{ + const struct sdhc_infineon_config *config = dev->config; + int busy_status = 0; + /* Check DAT Line Active */ + uint32_t state = Cy_SD_Host_GetPresentState(config->reg_addr); + + if (((state & CY_SD_HOST_DAT_3_0) == 0) || + ((state & CY_SD_HOST_DAT_LINE_ACTIVE) == CY_SD_HOST_DAT_LINE_ACTIVE) || + ((state & CY_SD_HOST_CMD_CMD_INHIBIT_DAT) == CY_SD_HOST_CMD_CMD_INHIBIT_DAT)) { + busy_status = 1; + } + + return busy_status; +} + +static int sdhc_infineon_get_host_props(const struct device *dev, struct sdhc_host_props *props) +{ + struct sdhc_infineon_data *sdhc_data = dev->data; + + memcpy(props, &sdhc_data->props, sizeof(struct sdhc_host_props)); + + return 0; +} + +static int sdhc_infineon_enable_interrupt(const struct device *dev, sdhc_interrupt_cb_t callback, + int sources, void *user_data) +{ + struct sdhc_infineon_data *sdhc_data = dev->data; + const struct sdhc_infineon_config *config = dev->config; + uint32_t cur_int_mask = Cy_SD_Host_GetNormalInterruptMask(config->reg_addr); + + if (sources != SDHC_INT_SDIO) { + return -ENOTSUP; + } + + if (callback == NULL) { + return -EINVAL; + } + + /* Record SDIO callback parameters */ + sdhc_data->sdio_cb = callback; + sdhc_data->sdio_cb_user_data = user_data; + + /* Enable CARD INTERRUPT */ + sdhc_data->irq_cause |= CY_SD_HOST_CARD_INTERRUPT; + Cy_SD_Host_SetNormalInterruptMask(config->reg_addr, + cur_int_mask | CY_SD_HOST_CARD_INTERRUPT); + + return 0; +} + +static int sdhc_infineon_disable_interrupt(const struct device *dev, int sources) +{ + struct sdhc_infineon_data *sdhc_data = dev->data; + const struct sdhc_infineon_config *config = dev->config; + uint32_t cur_int_mask = Cy_SD_Host_GetNormalInterruptMask(config->reg_addr); + + if (sources != SDHC_INT_SDIO) { + return -ENOTSUP; + } + + sdhc_data->sdio_cb = NULL; + sdhc_data->sdio_cb_user_data = NULL; + + /* Disable CARD INTERRUPT */ + sdhc_data->irq_cause &= ~CY_SD_HOST_CARD_INTERRUPT; + Cy_SD_Host_SetNormalInterruptMask(config->reg_addr, + cur_int_mask & ~CY_SD_HOST_CARD_INTERRUPT); + + return 0; +} + +static int sdhc_infineon_init(const struct device *dev) +{ + int result = 0; + const struct sdhc_infineon_config *config = dev->config; + struct sdhc_infineon_data *sdhc_data = dev->data; + cy_stc_sd_host_context_t context; + + /* Configure DT provided device signals when available */ + result = pinctrl_apply_state(config->pincfg, PINCTRL_STATE_DEFAULT); + if (result) { + return result; + } + + if (config->cd_gpio.port != NULL) { + if (!device_is_ready(config->cd_gpio.port)) { + LOG_ERR("Card detect GPIO device not ready"); + return -ENODEV; + } + + result = gpio_pin_configure_dt(&config->cd_gpio, GPIO_INPUT); + if (result < 0) { + LOG_ERR("Couldn't configure card-detect pin; (%d)", result); + return result; + } + } + +#if defined(CONFIG_SOC_FAMILY_INFINEON_EDGE) + if (config->reg_addr == SDHC0) { + Cy_SysClk_PeriGroupSlaveInit(CY_MMIO_SDHC0_PERI_NR, CY_MMIO_SDHC0_GROUP_NR, + CY_MMIO_SDHC0_SLAVE_NR, CY_MMIO_SDHC0_CLK_HF_NR); + } else if (config->reg_addr == SDHC1) { + Cy_SysClk_PeriGroupSlaveInit(CY_MMIO_SDHC1_PERI_NR, CY_MMIO_SDHC1_GROUP_NR, + CY_MMIO_SDHC1_SLAVE_NR, CY_MMIO_SDHC1_CLK_HF_NR); + } +#endif + + k_sem_init(&sdhc_data->thread_lock, 1, 1); + k_sem_init(&sdhc_data->transfer_sem, 1, 1); + + /* Enable the SDHC block */ + Cy_SD_Host_Enable(config->reg_addr); + + /* Configure SD Host to operate */ + result = (int)Cy_SD_Host_Init(config->reg_addr, &sdhc_config, &context); + if (result != 0) { + return -EFAULT; + } + + irq_enable(config->irq); + + /* Clear slot data so card is initialized at set_io() */ + sdhc_data->bus_clock = 0U; + sdhc_data->bus_width = CY_SD_HOST_BUS_WIDTH_1_BIT; + sdhc_data->power_mode = SDHC_POWER_OFF; + sdhc_data->speed_mode = CY_SD_HOST_BUS_SPEED_DEFAULT; + sdhc_data->signal_voltage = SD_VOL_3_3_V; + + return 0; +} + +static DEVICE_API(sdhc, sdhc_infineon_api) = { + .reset = sdhc_infineon_reset, + .request = sdhc_infineon_request, + .set_io = sdhc_infineon_set_io, + .get_card_present = sdhc_infineon_get_card_present, + .execute_tuning = sdhc_infineon_execute_tuning, + .card_busy = sdhc_infineon_card_busy, + .get_host_props = sdhc_infineon_get_host_props, + .enable_interrupt = sdhc_infineon_enable_interrupt, + .disable_interrupt = sdhc_infineon_disable_interrupt, +}; + +#if defined(CONFIG_SOC_FAMILY_INFINEON_EDGE) +#define IFX_SDHC_IRQ_INIT(n) \ + void sdhc_infineon_isr_##n(void) \ + { \ + sdhc_infineon_irq_handler(DEVICE_DT_INST_GET(n)); \ + } \ + static void sdhc_infineon_irq_config_##n(void) \ + { \ + IRQ_CONNECT(DT_INST_IRQ_BY_IDX(n, 1, irq), DT_INST_IRQ_BY_IDX(n, 1, priority), \ + sdhc_infineon_isr_##n, DEVICE_DT_INST_GET(n), 0); \ + } + +#define IRQ_INFO(n) \ + .irq = DT_INST_IRQN_BY_IDX(n, 1), .irq_priority = DT_INST_IRQ_BY_IDX(n, 1, priority) + +#define PERI_INFO(n) .clock_peri_group = DT_PROP_BY_IDX(DT_INST_PHANDLE(n, clocks), peri_group, 1), + +#define IFX_SDHC_PERI_CLOCK_INIT(n) \ + .clock = \ + { \ + .block = IFX_CAT1_PERIPHERAL_GROUP_ADJUST( \ + DT_PROP_BY_IDX(DT_INST_PHANDLE(n, clocks), peri_group, 0), \ + DT_PROP_BY_IDX(DT_INST_PHANDLE(n, clocks), peri_group, 1), \ + DT_INST_PROP_BY_PHANDLE(n, clocks, div_type)), \ + }, \ + PERI_INFO(n) +#elif defined(COMPONENT_CAT1A) +#define IFX_SDHC_IRQ_INIT(n) \ + void sdhc_infineon_isr_##n(void) \ + { \ + sdhc_infineon_irq_handler(DEVICE_DT_INST_GET(n)); \ + } \ + static void sdhc_infineon_irq_config_##n(void) \ + { \ + IRQ_CONNECT(DT_INST_IRQ_BY_IDX(n, 0, irq) + 1, DT_INST_IRQ_BY_IDX(n, 0, priority), \ + sdhc_infineon_isr_##n, DEVICE_DT_INST_GET(n), 0); \ + } +#define IRQ_INFO(n) \ + .irq = DT_INST_IRQN_BY_IDX(n, 0) + 1, .irq_priority = DT_INST_IRQ_BY_IDX(n, 0, priority) +#define PERI_INFO(n) +#define IFX_SDHC_PERI_CLOCK_INIT(n) +#endif + +#define IFX_SDHC_IRQ_CONFIG(n) sdhc_infineon_irq_config_##n(); + +#define IFX_SDHC_INIT(n) \ + \ + PINCTRL_DT_INST_DEFINE(n); \ + IFX_SDHC_IRQ_INIT(n) \ + \ + static int sdhc_infineon_init##n(const struct device *dev) \ + { \ + IFX_SDHC_IRQ_CONFIG(n); \ + return sdhc_infineon_init(dev); \ + } \ + \ + static const struct sdhc_infineon_config sdhc_infineon_##n##_config = { \ + .pincfg = PINCTRL_DT_INST_DEV_CONFIG_GET(n), \ + .cd_gpio = GPIO_DT_SPEC_INST_GET_OR(n, cd_gpios, {0}), \ + .reg_addr = (SDHC_Type *)DT_INST_REG_ADDR(n), \ + .irq_priority = DT_INST_IRQ(n, priority), \ + IRQ_INFO(n)}; \ + \ + static struct sdhc_infineon_data sdhc_infineon_##n##_data = { \ + .power_mode = SDHC_POWER_ON, \ + .speed_mode = CY_SD_HOST_BUS_SPEED_DEFAULT, \ + .props = {.is_spi = false, \ + .f_max = DT_INST_PROP(n, max_bus_freq), \ + .f_min = DT_INST_PROP(n, min_bus_freq), \ + .power_delay = DT_INST_PROP(n, power_delay_ms), \ + .host_caps = {.vol_180_support = !DT_INST_PROP(n, no_1_8_v), \ + .vol_300_support = false, \ + .vol_330_support = true, \ + .suspend_res_support = false, \ + .sdma_support = true, \ + .high_spd_support = \ + (DT_INST_PROP(n, bus_width) == 4) ? true : false, \ + .adma_2_support = true, \ + .adma3_support = true, \ + .sdio_async_interrupt_support = true, \ + .ddr50_support = false, \ + .sdr104_support = false, \ + .sdr50_support = true, \ + .bus_8_bit_support = false, \ + .bus_4_bit_support = \ + (DT_INST_PROP(n, bus_width) == 4) ? true : false, \ + .hs200_support = false, \ + .hs400_support = false}}, \ + IFX_SDHC_PERI_CLOCK_INIT(n)}; \ + \ + DEVICE_DT_INST_DEFINE(n, &sdhc_infineon_init##n, NULL, &sdhc_infineon_##n##_data, \ + &sdhc_infineon_##n##_config, POST_KERNEL, CONFIG_SDHC_INIT_PRIORITY, \ + &sdhc_infineon_api); + +DT_INST_FOREACH_STATUS_OKAY(IFX_SDHC_INIT) diff --git a/drivers/wifi/infineon/Kconfig.airoc b/drivers/wifi/infineon/Kconfig.airoc index 44ad9b1a0260..6366f43b8b05 100644 --- a/drivers/wifi/infineon/Kconfig.airoc +++ b/drivers/wifi/infineon/Kconfig.airoc @@ -244,6 +244,11 @@ config CYW955513SDM2WLIPA_SM bool "CYW955513SDM2WLIPA_SM" help Infineon CYW955513SDM2WLIPA (SM) module + +config CYW55513IUBG_SM + bool "CYW55513IUBG_SM" + help + Infineon CYW55513IUBG (SM) module endchoice choice CYW55572_MODULE @@ -254,11 +259,6 @@ config CYW955573M2IPA1_SM bool "CYW955573M2IPA1_SM" help Infineon CYW955573M2IPA1 (SM) module - -config CYW55513IUBG_SM - bool "CYW55513IUBG_SM" - help - Infineon CYW55513IUBG (SM) module endchoice endif # AIROC_WIFI diff --git a/dts/bindings/sdhc/infineon,sdhc-sdio.yaml b/dts/bindings/sdhc/infineon,sdhc-sdio.yaml index e32efeff5703..215cffff5e56 100644 --- a/dts/bindings/sdhc/infineon,sdhc-sdio.yaml +++ b/dts/bindings/sdhc/infineon,sdhc-sdio.yaml @@ -1,5 +1,5 @@ -# Copyright (c) 2023 Cypress Semiconductor Corporation (an Infineon company) or -# an affiliate of Cypress Semiconductor Corporation +# Copyright (c) 2025 Infineon Technologies AG, +# or an affiliate of Infineon Technologies AG. # # SPDX-License-Identifier: Apache-2.0 @@ -24,3 +24,24 @@ properties: system-interrupts: description: Required for cat1c devices + + bus-width: + type: int + default: 4 + description: | + bus width for SDMMC access, defaults to the minimum necessary + number of bus lines + enum: + - 1 + - 4 + - 8 + + no-1-8-v: + type: boolean + description: | + The SD/MMC bus on the board doesn't support the 1.8V voltage, + Which disables UHS-I, HS200 and HS400 support. + + cd-gpios: + type: phandle-array + description: Card Detect pin diff --git a/modules/hal_infineon/CMakeLists.txt b/modules/hal_infineon/CMakeLists.txt index c3071524e6fc..9750fd7690ee 100644 --- a/modules/hal_infineon/CMakeLists.txt +++ b/modules/hal_infineon/CMakeLists.txt @@ -85,8 +85,11 @@ endif() if(CONFIG_WIFI_AIROC) add_subdirectory(whd-expansion) - ## Add core-lib sources for CAT1 devices - add_subdirectory_ifndef(CONFIG_SOC_FAMILY_INFINEON_CAT1 core-lib) + if(NOT CONFIG_SOC_FAMILY_INFINEON_CAT1 + AND NOT CONFIG_SOC_FAMILY_PSOC6_LEGACY + AND NOT CONFIG_SOC_FAMILY_INFINEON_EDGE) + add_subdirectory(core-lib) + endif() ## Add abstraction-rtos sources add_subdirectory_ifndef(CONFIG_SOC_FAMILY_INFINEON_CAT1 abstraction-rtos) From 2e8b47462afcdd421458afa691343c367294e61f Mon Sep 17 00:00:00 2001 From: Kevin Chan Date: Thu, 18 Dec 2025 14:32:46 -0800 Subject: [PATCH 0220/6328] samples: net: wifi: shell: support PSE84 - add conf. file Signed-off-by: Kevin Chan --- .../boards/kit_pse84_eval_pse846gps2dbzc4a_m55.conf | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 samples/net/wifi/shell/boards/kit_pse84_eval_pse846gps2dbzc4a_m55.conf diff --git a/samples/net/wifi/shell/boards/kit_pse84_eval_pse846gps2dbzc4a_m55.conf b/samples/net/wifi/shell/boards/kit_pse84_eval_pse846gps2dbzc4a_m55.conf new file mode 100644 index 000000000000..7dbd1add6ee6 --- /dev/null +++ b/samples/net/wifi/shell/boards/kit_pse84_eval_pse846gps2dbzc4a_m55.conf @@ -0,0 +1,10 @@ +# Copyright (c) 2025 Infineon Technologies AG, +# or an affiliate of Infineon Technologies AG. +# +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_SHELL_STACK_SIZE=6144 +CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=2048 +CONFIG_NET_MGMT_EVENT_STACK_SIZE=4608 +CONFIG_NET_TCP_WORKQ_STACK_SIZE=2048 +CONFIG_IDLE_STACK_SIZE=1024 From 365ce110669c99f34f3a0c19860ef8bf76e1bbf5 Mon Sep 17 00:00:00 2001 From: Kevin Chan Date: Fri, 12 Dec 2025 14:50:46 -0800 Subject: [PATCH 0221/6328] samples: subsys: fs: fs_sample: support PSE84 - add overlay and conf file Signed-off-by: Kevin Chan --- .../kit_pse84_eval_pse846gps2dbzc4a_m55.conf | 6 ++++++ .../kit_pse84_eval_pse846gps2dbzc4a_m55.overlay | 16 ++++++++++++++++ 2 files changed, 22 insertions(+) create mode 100644 samples/subsys/fs/fs_sample/boards/kit_pse84_eval_pse846gps2dbzc4a_m55.conf create mode 100644 samples/subsys/fs/fs_sample/boards/kit_pse84_eval_pse846gps2dbzc4a_m55.overlay diff --git a/samples/subsys/fs/fs_sample/boards/kit_pse84_eval_pse846gps2dbzc4a_m55.conf b/samples/subsys/fs/fs_sample/boards/kit_pse84_eval_pse846gps2dbzc4a_m55.conf new file mode 100644 index 000000000000..f485769f88c2 --- /dev/null +++ b/samples/subsys/fs/fs_sample/boards/kit_pse84_eval_pse846gps2dbzc4a_m55.conf @@ -0,0 +1,6 @@ +# Copyright (c) 2025 Infineon Technologies AG, +# or an affiliate of Infineon Technologies AG. +# +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_LOG=n diff --git a/samples/subsys/fs/fs_sample/boards/kit_pse84_eval_pse846gps2dbzc4a_m55.overlay b/samples/subsys/fs/fs_sample/boards/kit_pse84_eval_pse846gps2dbzc4a_m55.overlay new file mode 100644 index 000000000000..ab83f8fd3165 --- /dev/null +++ b/samples/subsys/fs/fs_sample/boards/kit_pse84_eval_pse846gps2dbzc4a_m55.overlay @@ -0,0 +1,16 @@ +/* + * Copyright (c) 2025 Infineon Technologies AG, + * or an affiliate of Infineon Technologies AG. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + aliases { + sdhc0 = &sdhc1; + }; +}; + +&sdhc1 { + status = "okay"; +}; From ac0ad06f9e30bb1141552c6eaa08316a0bbd0f1d Mon Sep 17 00:00:00 2001 From: Kevin Chan Date: Fri, 12 Dec 2025 14:42:03 -0800 Subject: [PATCH 0222/6328] tests: subsys: sd: sdmmc: support PSE84 - add overlay file for CM55 Signed-off-by: Kevin Chan --- .../kit_pse84_eval_pse846gps2dbzc4a_m55.overlay | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 tests/subsys/sd/sdmmc/boards/kit_pse84_eval_pse846gps2dbzc4a_m55.overlay diff --git a/tests/subsys/sd/sdmmc/boards/kit_pse84_eval_pse846gps2dbzc4a_m55.overlay b/tests/subsys/sd/sdmmc/boards/kit_pse84_eval_pse846gps2dbzc4a_m55.overlay new file mode 100644 index 000000000000..ab83f8fd3165 --- /dev/null +++ b/tests/subsys/sd/sdmmc/boards/kit_pse84_eval_pse846gps2dbzc4a_m55.overlay @@ -0,0 +1,16 @@ +/* + * Copyright (c) 2025 Infineon Technologies AG, + * or an affiliate of Infineon Technologies AG. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + aliases { + sdhc0 = &sdhc1; + }; +}; + +&sdhc1 { + status = "okay"; +}; From e7720307ef651602d91c1caa41c173a6712edfb9 Mon Sep 17 00:00:00 2001 From: Kevin Chan Date: Fri, 12 Dec 2025 14:25:42 -0800 Subject: [PATCH 0223/6328] tests: drivers: sdhc: support PSE84 - add overlay files for CM55 in order to run sdhc app. Signed-off-by: Kevin Chan --- .../kit_pse84_eval_pse846gps2dbzc4a_m55.overlay | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 tests/drivers/sdhc/boards/kit_pse84_eval_pse846gps2dbzc4a_m55.overlay diff --git a/tests/drivers/sdhc/boards/kit_pse84_eval_pse846gps2dbzc4a_m55.overlay b/tests/drivers/sdhc/boards/kit_pse84_eval_pse846gps2dbzc4a_m55.overlay new file mode 100644 index 000000000000..ab83f8fd3165 --- /dev/null +++ b/tests/drivers/sdhc/boards/kit_pse84_eval_pse846gps2dbzc4a_m55.overlay @@ -0,0 +1,16 @@ +/* + * Copyright (c) 2025 Infineon Technologies AG, + * or an affiliate of Infineon Technologies AG. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + aliases { + sdhc0 = &sdhc1; + }; +}; + +&sdhc1 { + status = "okay"; +}; From 3836420f2f7cd49d13ca474836bb524d8211d042 Mon Sep 17 00:00:00 2001 From: Dat Nguyen Duy Date: Fri, 26 Dec 2025 10:11:04 +0700 Subject: [PATCH 0224/6328] dts: nxp: add watchdog devicetree nodes for s32k566 Add watchdog devicetree nodes for S32K566 Signed-off-by: Dat Nguyen Duy --- dts/arm/nxp/nxp_s32k566.dtsi | 16 ++++++++++++ dts/arm/nxp/nxp_s32k566_m7.dtsi | 45 ++++++++++++++++++++++++++++++++ dts/arm/nxp/nxp_s32k566_r52.dtsi | 26 ++++++++++++++++++ 3 files changed, 87 insertions(+) diff --git a/dts/arm/nxp/nxp_s32k566.dtsi b/dts/arm/nxp/nxp_s32k566.dtsi index 201148656739..314a3483ccd1 100644 --- a/dts/arm/nxp/nxp_s32k566.dtsi +++ b/dts/arm/nxp/nxp_s32k566.dtsi @@ -780,6 +780,22 @@ status = "disabled"; }; + lpe_swt: watchdog@4207c000 { + compatible = "nxp,s32-swt"; + reg = <0x4207c000 0x4000>; + clocks = <&clock NXP_S32_SAFE_CLK>; + service-mode = "fixed"; + status = "disabled"; + }; + + swt_startup: watchdog@404a8000 { + compatible = "nxp,s32-swt"; + reg = <0x404a8000 0x4000>; + clocks = <&clock NXP_S32_SWT_STARTUP_IPG_COUNTER_CLK>; + service-mode = "fixed"; + status = "disabled"; + }; + sar_adc0: adc@40698000 { compatible = "nxp,s32-adc-sar"; reg = <0x40698000 0x4000>; diff --git a/dts/arm/nxp/nxp_s32k566_m7.dtsi b/dts/arm/nxp/nxp_s32k566_m7.dtsi index 34112665aebf..7cc20ab46203 100644 --- a/dts/arm/nxp/nxp_s32k566_m7.dtsi +++ b/dts/arm/nxp/nxp_s32k566_m7.dtsi @@ -216,6 +216,43 @@ status = "disabled"; }; }; + + /* SWT_0 -> SWT_3 for Cortex-M7_0 -> Cortex-M7_3 */ + swt0: watchdog@40b18000 { + compatible = "nxp,s32-swt"; + reg = <0x40b18000 0x4000>; + interrupts = <28 0>; + clocks = <&clock NXP_S32_SWT0_IPG_COUNTER_CLK>; + service-mode = "fixed"; + status = "disabled"; + }; + + swt1: watchdog@40b1c000 { + compatible = "nxp,s32-swt"; + reg = <0x40b1c000 0x4000>; + interrupts = <28 0>; + clocks = <&clock NXP_S32_SWT1_IPG_COUNTER_CLK>; + service-mode = "fixed"; + status = "disabled"; + }; + + swt2: watchdog@40b20000 { + compatible = "nxp,s32-swt"; + reg = <0x40b20000 0x4000>; + interrupts = <28 0>; + clocks = <&clock NXP_S32_SWT2_IPG_COUNTER_CLK>; + service-mode = "fixed"; + status = "disabled"; + }; + + swt3: watchdog@40b24000 { + compatible = "nxp,s32-swt"; + reg = <0x40b24000 0x4000>; + interrupts = <28 0>; + clocks = <&clock NXP_S32_SWT3_IPG_COUNTER_CLK>; + service-mode = "fixed"; + status = "disabled"; + }; }; }; @@ -466,3 +503,11 @@ interrupts = <97 0>; interrupt-names = "rx_tx_mru_error"; }; + +&lpe_swt { + interrupts = <210 0>; +}; + +&swt_startup { + interrupts = <27 0>; +}; diff --git a/dts/arm/nxp/nxp_s32k566_r52.dtsi b/dts/arm/nxp/nxp_s32k566_r52.dtsi index f674b44b63b4..e05de06a814b 100644 --- a/dts/arm/nxp/nxp_s32k566_r52.dtsi +++ b/dts/arm/nxp/nxp_s32k566_r52.dtsi @@ -140,6 +140,24 @@ status = "disabled"; }; }; + + swt0: watchdog@4105c000 { + compatible = "nxp,s32-swt"; + reg = <0x4105c000 0x4000>; + interrupts = ; + clocks = <&clock NXP_S32_SWT0_IPG_COUNTER_CLK>; + service-mode = "fixed"; + status = "disabled"; + }; + + swt1: watchdog@4113c000 { + compatible = "nxp,s32-swt"; + reg = <0x4113c000 0x4000>; + interrupts = ; + clocks = <&clock NXP_S32_SWT1_IPG_COUNTER_CLK>; + service-mode = "fixed"; + status = "disabled"; + }; }; }; @@ -416,3 +434,11 @@ interrupts = ; interrupt-names = "rx_tx_mru_error"; }; + +&lpe_swt { + interrupts = ; +}; + +&swt_startup { + interrupts = ; +}; From 640c4d1ba30786f798b59e86b18ae52aaa2f7593 Mon Sep 17 00:00:00 2001 From: Ha Duong Quang Date: Thu, 6 Nov 2025 15:36:57 +0700 Subject: [PATCH 0225/6328] boards: nxp: s32k5xxcvb: add support for watchdog Add support for Watchdog (SWT) Signed-off-by: Ha Duong Quang Co-authored-by: Dat Nguyen Duy Signed-off-by: Dat Nguyen Duy --- boards/nxp/s32k5xxcvb/s32k5xxcvb_s32k566.dtsi | 4 ++++ boards/nxp/s32k5xxcvb/s32k5xxcvb_s32k566_m7.yaml | 1 + boards/nxp/s32k5xxcvb/s32k5xxcvb_s32k566_r52.yaml | 1 + 3 files changed, 6 insertions(+) diff --git a/boards/nxp/s32k5xxcvb/s32k5xxcvb_s32k566.dtsi b/boards/nxp/s32k5xxcvb/s32k5xxcvb_s32k566.dtsi index 993107561b78..178f9a5c007d 100644 --- a/boards/nxp/s32k5xxcvb/s32k5xxcvb_s32k566.dtsi +++ b/boards/nxp/s32k5xxcvb/s32k5xxcvb_s32k566.dtsi @@ -15,6 +15,7 @@ led2 = &user_led_blue; sw0 = &user_button_0; sw1 = &user_button_1; + watchdog0 = &swt_startup; }; chosen { @@ -82,5 +83,8 @@ &flexcan0 { pinctrl-0 = <&flexcan0_default>; pinctrl-names = "default"; +}; + +&swt_startup { status = "okay"; }; diff --git a/boards/nxp/s32k5xxcvb/s32k5xxcvb_s32k566_m7.yaml b/boards/nxp/s32k5xxcvb/s32k5xxcvb_s32k566_m7.yaml index 35be8009dad9..1810ae7bd4c3 100644 --- a/boards/nxp/s32k5xxcvb/s32k5xxcvb_s32k566_m7.yaml +++ b/boards/nxp/s32k5xxcvb/s32k5xxcvb_s32k566_m7.yaml @@ -16,4 +16,5 @@ supported: - pwm - counter - i2c + - watchdog vendor: nxp diff --git a/boards/nxp/s32k5xxcvb/s32k5xxcvb_s32k566_r52.yaml b/boards/nxp/s32k5xxcvb/s32k5xxcvb_s32k566_r52.yaml index 41d218e21581..4e9a944aa011 100644 --- a/boards/nxp/s32k5xxcvb/s32k5xxcvb_s32k566_r52.yaml +++ b/boards/nxp/s32k5xxcvb/s32k5xxcvb_s32k566_r52.yaml @@ -16,4 +16,5 @@ supported: - pwm - counter - i2c + - watchdog vendor: nxp From 2d019f163d77ce454b90be72093402bd61d25db7 Mon Sep 17 00:00:00 2001 From: Dat Nguyen Duy Date: Fri, 26 Dec 2025 10:14:54 +0700 Subject: [PATCH 0226/6328] samples: support watchdog samples for s32k5xxvcb Only enable watchdog sample for cm7. For cr52, because the SoC set the cores in Thumb mode after reset, so a debugger is always needed to switch the core to Arm state before loading zephyr application. Signed-off-by: Dat Nguyen Duy --- samples/drivers/watchdog/sample.yaml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/samples/drivers/watchdog/sample.yaml b/samples/drivers/watchdog/sample.yaml index c7fffc99001a..2c24caf2eee6 100644 --- a/samples/drivers/watchdog/sample.yaml +++ b/samples/drivers/watchdog/sample.yaml @@ -22,6 +22,7 @@ tests: - s32z2xxdc2/s32z270/rtu1 - s32z2xxdc2@D/s32z270/rtu0 - s32z2xxdc2@D/s32z270/rtu1 + - s32k5xxcvb/s32k566/r52 - panb611evb/nrf54l15/cpuapp - panb611evb/nrf54l15/cpuapp/ns - panb611evb/nrf54l15/cpuflpr @@ -149,12 +150,13 @@ tests: - longan_nano integration_platforms: - gd32e103v_eval - sample.drivers.watchdog.s32z270dc2_r52: + sample.drivers.watchdog.nxp_s32_swt: build_only: true platform_allow: - s32z2xxdc2/s32z270/rtu0 - s32z2xxdc2/s32z270/rtu1 - s32z2xxdc2@D/s32z270/rtu0 - s32z2xxdc2@D/s32z270/rtu1 + - s32k5xxcvb/s32k566/r52 integration_platforms: - s32z2xxdc2/s32z270/rtu0 From 2247f4dc7a0e7a8afa9bd9bf47387742f94c088e Mon Sep 17 00:00:00 2001 From: Dat Nguyen Duy Date: Fri, 26 Dec 2025 10:27:12 +0700 Subject: [PATCH 0227/6328] tests: drivers: support watchdog tests for s32k5xxcvb Enable wdt_basic_api watchdog only for cm7. For cr52, because the SoC set the cores in Thumb mode after reset, so a debugger is always needed to switch the core to Arm state before loading zephyr application. wdt_basic_reset_none test can be enabled for both. Signed-off-by: Dat Nguyen Duy --- tests/drivers/watchdog/wdt_basic_api/testcase.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/drivers/watchdog/wdt_basic_api/testcase.yaml b/tests/drivers/watchdog/wdt_basic_api/testcase.yaml index 75cdc5da40e3..fdeb2ecfcbd0 100644 --- a/tests/drivers/watchdog/wdt_basic_api/testcase.yaml +++ b/tests/drivers/watchdog/wdt_basic_api/testcase.yaml @@ -18,6 +18,7 @@ tests: - s32z2xxdc2/s32z270/rtu1 - s32z2xxdc2@D/s32z270/rtu0 - s32z2xxdc2@D/s32z270/rtu1 + - s32k5xxcvb/s32k566/r52 - mps2/an383 - mps2/an385 - mps2/an386 @@ -147,6 +148,7 @@ tests: - s32z2xxdc2/s32z270/rtu1 - s32z2xxdc2@D/s32z270/rtu0 - s32z2xxdc2@D/s32z270/rtu1 + - s32k5xxcvb/s32k566/r52 - mr_canhubk3 integration_platforms: - s32z2xxdc2/s32z270/rtu0 From cc18a23ec91e40a1633758a7dbcfe183430298fa Mon Sep 17 00:00:00 2001 From: Lyle Zhu Date: Wed, 31 Dec 2025 11:51:36 +0800 Subject: [PATCH 0228/6328] bluetooth: classic: GOEP: fix L2CAP MTU calculation Correct the minimum MTU calculation for GOEP over L2CAP to account for the L2CAP I-frame overhead. - Update BT_BUF_ACL_RX_SIZE default from 264 to 265 bytes for GOEP - Update BT_GOEP_L2CAP_MTU minimum range from 259 to 265 bytes - Add detailed comment explaining L2CAP I-frame field length (6 bytes): * 4 bytes for extended control field * 2 bytes for FCS field The previous calculation only accounted for the L2CAP header (4 bytes) but missed the 6-byte L2CAP I-frame overhead (extended control field and FCS), resulting in an incorrect minimum of 264 bytes instead of the correct 265 bytes. And it causes the minimum MTU of L2CAP to be incorrectly set to 254. The MTU cannot meet the minimum requirement of GOEP MOPL. The correct calculation for GOEP over L2CAP is: 255 bytes (GOEP minimum MTU) + 4 bytes (L2CAP header) + 6 bytes (L2CAP I-frame) = 265 bytes total. Set the default value of CONFIG_BT_BUF_ACL_RX_SIZE to 265 if GOEP is enabled. Signed-off-by: Lyle Zhu --- subsys/bluetooth/common/Kconfig | 10 ++++++++-- subsys/bluetooth/host/classic/Kconfig | 5 ++++- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/subsys/bluetooth/common/Kconfig b/subsys/bluetooth/common/Kconfig index 9ba9cb325855..f9eb4b622027 100644 --- a/subsys/bluetooth/common/Kconfig +++ b/subsys/bluetooth/common/Kconfig @@ -50,11 +50,17 @@ config BT_BUF_ACL_TX_COUNT config BT_BUF_ACL_RX_SIZE int "Maximum supported ACL size for incoming data" - # For GOEP over RFCOMM, including, + # For GOEP over RFCOMM, the minimum MTU of GOEP is 264, including, # 255 bytes - the minimum MTU of GOEP, # 4 bytes - L2CAP Header, # 5 bytes - 4 bytes for RFCOMM header with extended length, 1 byte for FCS. - default 264 if BT_CLASSIC && BT_GOEP + # For GOEP over L2CAP, the minimum MTU of GOEP is 265, including, + # 255 bytes - the minimum MTU of GOEP, + # 4 bytes - L2CAP Header, + # 6 bytes - Field length of L2CAP I-frame, including, + # 4 bytes - extended control field, + # 2 bytes - FCS field. + default 265 if BT_CLASSIC && BT_GOEP default 200 if BT_CLASSIC default 70 if BT_EATT default 69 if BT_SMP diff --git a/subsys/bluetooth/host/classic/Kconfig b/subsys/bluetooth/host/classic/Kconfig index bf8222da6444..b1059ff5c6f1 100644 --- a/subsys/bluetooth/host/classic/Kconfig +++ b/subsys/bluetooth/host/classic/Kconfig @@ -685,7 +685,10 @@ config BT_GOEP_L2CAP_MTU # For GOEP over L2CAP, including, # 255 bytes - the minimum MTU of GOEP, # 4 bytes - L2CAP Header, - range 259 BT_BUF_ACL_RX_SIZE + # 6 bytes - Field length of L2CAP I-frame, including, + # 4 bytes - extended control field, + # 2 bytes - FCS field. + range 265 BT_BUF_ACL_RX_SIZE help Maximum size of L2CAP MTU for GOEP. RX MTU will be truncated to account for ACL data and type overhead, and the L2CAP PDU From a2b583081a85022bf0bf93ff9ae5b6170f828633 Mon Sep 17 00:00:00 2001 From: David Jewsbury Date: Fri, 21 Nov 2025 15:18:14 +0000 Subject: [PATCH 0229/6328] drivers: mspi_dw: fix DMA transfer size logic Fixing of erroneous RXTRANSFERLENGTH and number of transfer frames calculation. Signed-off-by: David Jewsbury --- drivers/mspi/mspi_dw.c | 15 +++++++++------ drivers/mspi/mspi_dw_vendor_specific.h | 5 ++--- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/drivers/mspi/mspi_dw.c b/drivers/mspi/mspi_dw.c index d26a537e8af9..bb91ec984d35 100644 --- a/drivers/mspi/mspi_dw.c +++ b/drivers/mspi/mspi_dw.c @@ -160,6 +160,9 @@ DEFINE_MM_REG_WR(xip_write_wrap_inst, 0x144) DEFINE_MM_REG_WR(xip_write_ctrl, 0x148) #endif +/* Ceiling division by 32 */ +#define CEIL_DIV_32(x) (((x) + 31U) >> 5) + #include "mspi_dw_vendor_specific.h" static int start_next_packet(const struct device *dev); @@ -1274,16 +1277,16 @@ static int start_next_packet(const struct device *dev) #if defined(CONFIG_MSPI_DMA) if (dev_data->xfer.xfer_mode == MSPI_DMA) { /* For DMA mode, set start level based on transfer length to prevent underflow */ - uint32_t total_transfer_bytes = packet->num_bytes + dev_data->xfer.addr_length + - dev_data->xfer.cmd_length; - uint32_t transfer_frames = total_transfer_bytes >> dev_data->bytes_per_frame_exp; + uint32_t transfer_frames = (packet->num_bytes >> dev_data->bytes_per_frame_exp) + + CEIL_DIV_32(dev_data->xfer.addr_length) + + CEIL_DIV_32(dev_data->xfer.cmd_length); - /* Use minimum of transfer length or FIFO depth, but at least 1 */ + /* Above dma_start_level, the transfer will start. + * Use minimum of transfer length and FIFO depth. + */ uint8_t dma_start_level = MIN(transfer_frames - 1, dev_config->tx_fifo_depth_minus_1); - dma_start_level = (dma_start_level > 0 ? dma_start_level : 1); - /* Only TXFTHR needs to be set to the minimum number of frames */ write_txftlr(dev, FIELD_PREP(TXFTLR_TXFTHR_MASK, dma_start_level)); write_dmatdlr(dev, FIELD_PREP(DMATDLR_DMATDL_MASK, dev_config->dma_tx_data_level)); diff --git a/drivers/mspi/mspi_dw_vendor_specific.h b/drivers/mspi/mspi_dw_vendor_specific.h index d994f579ad8e..2c26cfa1b1ee 100644 --- a/drivers/mspi/mspi_dw_vendor_specific.h +++ b/drivers/mspi/mspi_dw_vendor_specific.h @@ -251,9 +251,8 @@ static inline void vendor_specific_start_dma_xfer(const struct device *dev) transfer_list->rx_job = &joblist[job_idx]; tmod = QSPI_TMOD_TX_ONLY; } else { - preg->CONFIG.RXTRANSFERLENGTH = ((packet->num_bytes + dev_data->xfer.addr_length + - dev_data->xfer.cmd_length) >> - dev_data->bytes_per_frame_exp) - 1; + preg->CONFIG.RXTRANSFERLENGTH = ((packet->num_bytes) >> + dev_data->bytes_per_frame_exp); /* If sending address or command while being configured as controller */ if (job_idx > 0 && config->op_mode == MSPI_OP_MODE_CONTROLLER) { From 2043119bcc346a4f60c1a2bc516d8103d2b1f6b5 Mon Sep 17 00:00:00 2001 From: David Jewsbury Date: Fri, 21 Nov 2025 15:27:02 +0000 Subject: [PATCH 0230/6328] drivers: mspi_dw: nrf_qspi_v2: Add ifdef to include DMA code if enabled DMA functions will not only be included if enabled for the nrf_qspi_v2 peripheral Signed-off-by: David Jewsbury --- drivers/mspi/mspi_dw_vendor_specific.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/mspi/mspi_dw_vendor_specific.h b/drivers/mspi/mspi_dw_vendor_specific.h index 2c26cfa1b1ee..fbdd0119d383 100644 --- a/drivers/mspi/mspi_dw_vendor_specific.h +++ b/drivers/mspi/mspi_dw_vendor_specific.h @@ -138,6 +138,7 @@ static inline void vendor_specific_irq_clear(const struct device *dev) preg->EVENTS_DMA.DONE = 0; } +#if defined(CONFIG_MSPI_DMA) /* DMA support */ #define EVDMA_ATTR_LEN_Pos (0UL) @@ -308,6 +309,7 @@ static inline bool vendor_specific_read_dma_irq(const struct device *dev) return (bool) preg->EVENTS_DMA.DONE; } +#endif /*defined(CONFIG_MSPI_DMA)*/ #else /* Supply empty vendor specific macros for generic case */ From 1cbaa5f3f516ece44d7ce8d4c95633d1ff7273bc Mon Sep 17 00:00:00 2001 From: David Jewsbury Date: Mon, 24 Nov 2025 17:59:41 +0000 Subject: [PATCH 0231/6328] drivers: mspi_dw: nrf_qspi_v2: Remove redundant EVDMA definitions EVDMA register access has been cleaned up to remove redundant macros. EVDMA_PLAIN_DATA enum has also been added of value 0x3F which previously had been assumed to be a masking of all the other values but isn't, it's its own distinct value. Other enums still exist for future use. Signed-off-by: David Jewsbury --- drivers/mspi/mspi_dw_vendor_specific.h | 29 +++++++------------------- 1 file changed, 8 insertions(+), 21 deletions(-) diff --git a/drivers/mspi/mspi_dw_vendor_specific.h b/drivers/mspi/mspi_dw_vendor_specific.h index fbdd0119d383..f3627132f669 100644 --- a/drivers/mspi/mspi_dw_vendor_specific.h +++ b/drivers/mspi/mspi_dw_vendor_specific.h @@ -140,19 +140,9 @@ static inline void vendor_specific_irq_clear(const struct device *dev) #if defined(CONFIG_MSPI_DMA) /* DMA support */ - -#define EVDMA_ATTR_LEN_Pos (0UL) -#define EVDMA_ATTR_LEN_Msk (0x00FFFFFFUL) - #define EVDMA_ATTR_ATTR_Pos (24UL) #define EVDMA_ATTR_ATTR_Msk (0x3FUL << EVDMA_ATTR_ATTR_Pos) -#define EVDMA_ATTR_32AXI_Pos (30UL) -#define EVDMA_ATTR_32AXI_Msk (0x1UL << EVDMA_ATTR_32AXI_Pos) - -#define EVDMA_ATTR_EVENTS_Pos (31UL) -#define EVDMA_ATTR_EVENTS_Msk (0x1UL << EVDMA_ATTR_EVENTS_Pos) - typedef enum { EVDMA_BYTE_SWAP = 0, EVDMA_JOBLIST = 1, @@ -160,13 +150,9 @@ typedef enum { EVDMA_FIXED_ATTR = 3, EVDMA_STATIC_ADDR = 4, EVDMA_PLAIN_DATA_BUF_WR = 5, + EVDMA_PLAIN_DATA = 0x3f, } EVDMA_ATTR_Type; -/* Setup EVDMA attribute with the following configuratrion */ -#define EVDMA_ATTRIBUTE (BIT(EVDMA_BYTE_SWAP) | BIT(EVDMA_JOBLIST) | \ - BIT(EVDMA_BUFFER_FILL) | BIT(EVDMA_FIXED_ATTR) | \ - BIT(EVDMA_STATIC_ADDR) | BIT(EVDMA_PLAIN_DATA_BUF_WR)) - typedef struct { uint8_t *addr; uint32_t attr; @@ -229,13 +215,14 @@ static inline void vendor_specific_start_dma_xfer(const struct device *dev) /* * The Command and Address will always have a length of 4 from the DMA's - * perspective. QSPI peripheral will use length of data specified in core registers + * perspective. QSPI peripheral will use length of data specified in core registers. + * Since the cmd and address are stored as uint32_t, byte swap is never needed. */ if (dev_data->xfer.cmd_length > 0) { - joblist[job_idx++] = EVDMA_JOB(&packet->cmd, 4, EVDMA_ATTRIBUTE); + joblist[job_idx++] = EVDMA_JOB(&packet->cmd, 4, EVDMA_PLAIN_DATA); } if (dev_data->xfer.addr_length > 0) { - joblist[job_idx++] = EVDMA_JOB(&packet->address, 4, EVDMA_ATTRIBUTE); + joblist[job_idx++] = EVDMA_JOB(&packet->address, 4, EVDMA_PLAIN_DATA); } if (packet->dir == MSPI_TX) { @@ -243,7 +230,7 @@ static inline void vendor_specific_start_dma_xfer(const struct device *dev) if (packet->num_bytes > 0) { joblist[job_idx++] = EVDMA_JOB(packet->data_buf, packet->num_bytes, - EVDMA_ATTRIBUTE); + EVDMA_PLAIN_DATA); } /* Always terminate with null job */ @@ -263,7 +250,7 @@ static inline void vendor_specific_start_dma_xfer(const struct device *dev) joblist[job_idx++] = EVDMA_NULL_JOB(); transfer_list->rx_job = &joblist[job_idx]; joblist[job_idx++] = EVDMA_JOB(packet->data_buf, packet->num_bytes, - EVDMA_ATTRIBUTE); + EVDMA_PLAIN_DATA); joblist[job_idx] = EVDMA_NULL_JOB(); } else { /* Sending command or address while configured as target isn't supported */ @@ -271,7 +258,7 @@ static inline void vendor_specific_start_dma_xfer(const struct device *dev) transfer_list->rx_job = &joblist[0]; joblist[0] = EVDMA_JOB(packet->data_buf, packet->num_bytes, - EVDMA_ATTRIBUTE); + EVDMA_PLAIN_DATA); joblist[1] = EVDMA_NULL_JOB(); transfer_list->tx_job = &joblist[1]; } From f8f94fd6cdeea46afb27b1f68cfce2222e3fbfc8 Mon Sep 17 00:00:00 2001 From: Camille BAUD Date: Wed, 7 Jan 2026 12:32:01 +0100 Subject: [PATCH 0232/6328] drivers: rp2: Add support for RP2350 for vreg Adds support for RP2350 in vreg regulator driver Signed-off-by: Camille BAUD --- drivers/regulator/regulator_rpi_pico.c | 83 +++++++++++++++---- .../raspberrypi,core-supply-regulator.yaml | 3 + dts/vendor/raspberrypi/rpi_pico/rp2350.dtsi | 7 ++ 3 files changed, 79 insertions(+), 14 deletions(-) diff --git a/drivers/regulator/regulator_rpi_pico.c b/drivers/regulator/regulator_rpi_pico.c index 7ea44fb4440b..ff40492d355e 100644 --- a/drivers/regulator/regulator_rpi_pico.c +++ b/drivers/regulator/regulator_rpi_pico.c @@ -10,19 +10,51 @@ #include #include #include + +#ifdef CONFIG_SOC_SERIES_RP2350 +#include +#include +#else #include #include +#endif static const struct linear_range core_ranges[] = { +#ifdef CONFIG_SOC_SERIES_RP2350 + LINEAR_RANGE_INIT(550000u, 50000u, 0u, 17u), + LINEAR_RANGE_INIT(1500000u, 100000u, 18u, 19u), + LINEAR_RANGE_INIT(1650000u, 50000u, 20u, 21u), + LINEAR_RANGE_INIT(1800000u, 100000u, 22u, 24u), + LINEAR_RANGE_INIT(2350000u, 50000u, 25u, 25u), + LINEAR_RANGE_INIT(2500000u, 150000u, 26u, 28u), + LINEAR_RANGE_INIT(3000000u, 150000u, 29u, 31u), +#else LINEAR_RANGE_INIT(800000u, 0u, 0u, 5u), LINEAR_RANGE_INIT(850000u, 50000u, 6u, 15u), +#endif }; static const size_t num_core_ranges = ARRAY_SIZE(core_ranges); +#ifdef CONFIG_SOC_SERIES_RP2350 +#define REG_PICO_TYPE powman_hw_t +#define REG_VSEL_POS POWMAN_VREG_VSEL_LSB +#define REG_VSEL_MSK POWMAN_VREG_VSEL_BITS +#define REG_VALIN(value) (POWMAN_PASSWORD_BITS | (value)) +#define REG_BOD_VSEL_POS POWMAN_BOD_VSEL_LSB +#define REG_BOD_EN_POS POWMAN_BOD_EN_LSB +#else +#define REG_PICO_TYPE vreg_and_chip_reset_hw_t +#define REG_VSEL_POS VREG_AND_CHIP_RESET_VREG_VSEL_LSB +#define REG_VSEL_MSK VREG_AND_CHIP_RESET_VREG_VSEL_BITS +#define REG_VALIN(value) (value) +#define REG_BOD_VSEL_POS VREG_AND_CHIP_RESET_BOD_VSEL_LSB +#define REG_BOD_EN_POS VREG_AND_CHIP_RESET_BOD_EN_LSB +#endif + struct regulator_rpi_pico_config { struct regulator_common_config common; - vreg_and_chip_reset_hw_t * const reg; + REG_PICO_TYPE * const reg; const bool brown_out_detection; const uint32_t brown_out_threshold; }; @@ -31,6 +63,17 @@ struct regulator_rpi_pico_data { struct regulator_common_data data; }; +#ifdef CONFIG_SOC_SERIES_RP2350 +static void regulator_rpi_pico_wait_powman(const struct device *dev) +{ + const struct regulator_rpi_pico_config *config = dev->config; + + while (config->reg->vreg & POWMAN_VREG_UPDATE_IN_PROGRESS_BITS) { + k_usleep(10); + } +} +#endif + /* * APIs */ @@ -57,8 +100,16 @@ static int regulator_rpi_pico_set_voltage(const struct device *dev, int32_t min_ return ret; } - config->reg->vreg = ((config->reg->vreg & ~VREG_AND_CHIP_RESET_VREG_VSEL_BITS) | - (idx << VREG_AND_CHIP_RESET_VREG_VSEL_LSB)); +#ifdef CONFIG_SOC_SERIES_RP2350 + config->reg->vreg_ctrl |= REG_VALIN(POWMAN_VREG_CTRL_UNLOCK_BITS); + regulator_rpi_pico_wait_powman(dev); +#endif + + config->reg->vreg = REG_VALIN((config->reg->vreg & ~REG_VSEL_MSK) | idx << REG_VSEL_POS); + +#ifdef CONFIG_SOC_SERIES_RP2350 + regulator_rpi_pico_wait_powman(dev); +#endif return 0; } @@ -69,25 +120,27 @@ static int regulator_rpi_pico_get_voltage(const struct device *dev, int32_t *vol return linear_range_group_get_value( core_ranges, num_core_ranges, - ((config->reg->vreg & VREG_AND_CHIP_RESET_VREG_VSEL_BITS) >> - VREG_AND_CHIP_RESET_VREG_VSEL_LSB), - volt_uv); + ((config->reg->vreg & REG_VSEL_MSK) >> REG_VSEL_POS), volt_uv); } static int regulator_rpi_pico_enable(const struct device *dev) { +#ifdef CONFIG_SOC_SERIES_RP2040 const struct regulator_rpi_pico_config *config = dev->config; config->reg->vreg |= BIT(VREG_AND_CHIP_RESET_VREG_EN_LSB); +#endif return 0; } static int regulator_rpi_pico_disable(const struct device *dev) { +#ifdef CONFIG_SOC_SERIES_RP2040 const struct regulator_rpi_pico_config *config = dev->config; config->reg->vreg &= ~BIT(VREG_AND_CHIP_RESET_VREG_EN_LSB); +#endif return 0; } @@ -97,9 +150,9 @@ static int regulator_rpi_pico_set_mode(const struct device *dev, regulator_mode_ const struct regulator_rpi_pico_config *config = dev->config; if (mode & REGULATOR_RPI_PICO_MODE_HI_Z) { - config->reg->vreg |= REGULATOR_RPI_PICO_MODE_HI_Z; + config->reg->vreg |= REG_VALIN(REGULATOR_RPI_PICO_MODE_HI_Z); } else { - config->reg->vreg &= (~REGULATOR_RPI_PICO_MODE_HI_Z); + config->reg->vreg = REG_VALIN(config->reg->vreg & ~REGULATOR_RPI_PICO_MODE_HI_Z); } return 0; @@ -119,11 +172,10 @@ static int regulator_rpi_pico_init(const struct device *dev) const struct regulator_rpi_pico_config *config = dev->config; if (config->brown_out_detection) { - config->reg->bod = - (BIT(VREG_AND_CHIP_RESET_BOD_EN_LSB) | - (config->brown_out_threshold << VREG_AND_CHIP_RESET_BOD_VSEL_LSB)); + config->reg->bod = REG_VALIN(BIT(REG_BOD_EN_POS) | + (config->brown_out_threshold << REG_BOD_VSEL_POS)); } else { - config->reg->bod &= ~BIT(VREG_AND_CHIP_RESET_BOD_EN_LSB); + config->reg->bod = REG_VALIN(config->reg->bod & ~BIT(REG_BOD_EN_POS)); } regulator_common_data_init(dev); @@ -147,12 +199,15 @@ static DEVICE_API(regulator, api) = { \ static const struct regulator_rpi_pico_config config_##inst = { \ .common = REGULATOR_DT_COMMON_CONFIG_INIT(inst), \ - .reg = (vreg_and_chip_reset_hw_t * const)DT_INST_REG_ADDR(inst), \ + .reg = (REG_PICO_TYPE * const)DT_INST_REG_ADDR(inst), \ .brown_out_detection = DT_INST_PROP(inst, raspberrypi_brown_out_detection), \ .brown_out_threshold = DT_INST_ENUM_IDX(inst, raspberrypi_brown_out_threshold), \ }; \ \ DEVICE_DT_INST_DEFINE(inst, regulator_rpi_pico_init, NULL, &data_##inst, &config_##inst, \ - POST_KERNEL, CONFIG_REGULATOR_RPI_PICO_INIT_PRIORITY, &api); + POST_KERNEL, CONFIG_REGULATOR_RPI_PICO_INIT_PRIORITY, &api); \ + IF_ENABLED(CONFIG_SOC_SERIES_RP2040, \ + (BUILD_ASSERT(DT_INST_ENUM_IDX(inst, raspberrypi_brown_out_threshold) < 16, \ + "On RP2040, BOD threshold must be lower than 1161000");)) \ DT_INST_FOREACH_STATUS_OKAY(REGULATOR_RPI_PICO_DEFINE_ALL) diff --git a/dts/bindings/regulator/raspberrypi,core-supply-regulator.yaml b/dts/bindings/regulator/raspberrypi,core-supply-regulator.yaml index c0f95e77351f..40c1e6fd683b 100644 --- a/dts/bindings/regulator/raspberrypi,core-supply-regulator.yaml +++ b/dts/bindings/regulator/raspberrypi,core-supply-regulator.yaml @@ -43,6 +43,9 @@ properties: - 1032000 - 1075000 - 1118000 + - 1161000 + - 1204000 description: | Reset if the core voltage drops below this threshold for a particular time (determined by the 'brown-out detection assertion delay'). + On RP2040, the threshold must be less than 1.161V. diff --git a/dts/vendor/raspberrypi/rpi_pico/rp2350.dtsi b/dts/vendor/raspberrypi/rpi_pico/rp2350.dtsi index a3ef3230eb4a..480692549b0d 100644 --- a/dts/vendor/raspberrypi/rpi_pico/rp2350.dtsi +++ b/dts/vendor/raspberrypi/rpi_pico/rp2350.dtsi @@ -405,6 +405,13 @@ status = "disabled"; }; + vreg: vreg@40100000 { + compatible = "raspberrypi,core-supply-regulator"; + reg = <0x40100000 0x200>; + status = "okay"; + raspberrypi,brown-out-detection; + }; + dma: dma@50000000 { compatible = "raspberrypi,pico-dma"; reg = <0x50000000 DT_SIZE_K(64)>; From 59ffa602b412016194ed9449c206e11d689814ba Mon Sep 17 00:00:00 2001 From: Albort Xue Date: Tue, 13 Jan 2026 16:02:32 +0800 Subject: [PATCH 0233/6328] drivers: counter: mcux_lpit: Add clock configuration and enable Add explicit clock configuration and enable calls during driver initialization. The driver now attempts to configure the clock subsystem before enabling it. Note: -ENOSYS is temporarily ignored as not all clock control drivers currently implement the configure API. This handling should be removed once all clock drivers support configure. Signed-off-by: Albort Xue --- drivers/counter/counter_mcux_lpit.c | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/drivers/counter/counter_mcux_lpit.c b/drivers/counter/counter_mcux_lpit.c index 714a2d7bf653..b99f8aa4ff03 100644 --- a/drivers/counter/counter_mcux_lpit.c +++ b/drivers/counter/counter_mcux_lpit.c @@ -1,5 +1,5 @@ /* - * Copyright 2023, 2025 NXP + * Copyright 2023, 2025-2026 NXP * * SPDX-License-Identifier: Apache-2.0 */ @@ -171,12 +171,31 @@ static int mcux_lpit_init(const struct device *dev) const struct mcux_lpit_config *config = dev->config; lpit_config_t lpit_config; uint32_t clock_rate; + int ret; if (!device_is_ready(config->clock_dev)) { LOG_ERR("Clock control device not ready"); return -ENODEV; } + ret = clock_control_configure(config->clock_dev, config->clock_subsys, NULL); + if (ret != 0) { + /* Check if error is due to lack of support */ + if (ret != -ENOSYS) { + /* Real error occurred */ + LOG_ERR("Failed to configure clock: %d", ret); + return ret; + } + } + +#if FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL + ret = clock_control_on(config->clock_dev, config->clock_subsys); + if (ret != 0) { + LOG_ERR("Failed to enable clock: %d", ret); + return ret; + } +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ + LPIT_GetDefaultConfig(&lpit_config); lpit_config.enableRunInDebug = config->lpit_config.enableRunInDebug; lpit_config.enableRunInDoze = config->lpit_config.enableRunInDoze; From 6f350ae64d1216e1bfca8dca96538f0d9df1633c Mon Sep 17 00:00:00 2001 From: Vincent Tardy Date: Tue, 13 Jan 2026 17:14:49 +0100 Subject: [PATCH 0234/6328] soc: st: stm32wba: adjust thread size if BT enabled SYSTEM_WORKQUEUE_STACK_SIZE KConfig is setting to 1024 in case of BT_TX_PROCESSOR_THREAD is enabled, else 2048. BT_TX_PROCESSOR_STACK_SIZE KConfig is setting to 2048 in case of BT_TX_PROCESSOR_THREAD is enabled. Signed-off-by: Vincent Tardy --- soc/st/stm32/stm32wbax/Kconfig.defconfig | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/soc/st/stm32/stm32wbax/Kconfig.defconfig b/soc/st/stm32/stm32wbax/Kconfig.defconfig index dd0b65d71553..cda74b163f46 100644 --- a/soc/st/stm32/stm32wbax/Kconfig.defconfig +++ b/soc/st/stm32/stm32wbax/Kconfig.defconfig @@ -46,7 +46,11 @@ config FPU default y config SYSTEM_WORKQUEUE_STACK_SIZE - default 2048 + default 2048 if !BT_TX_PROCESSOR_THREAD + default 1024 + +config BT_TX_PROCESSOR_STACK_SIZE + default 2048 if BT_TX_PROCESSOR_THREAD endif From 80c2beff83b3b7ceebe5c025cd08e2b7e3982995 Mon Sep 17 00:00:00 2001 From: Peter van der Perk Date: Tue, 20 Jan 2026 10:21:32 +0100 Subject: [PATCH 0235/6328] drivers: watchdog: FS26 watchdog support RTIO Under RTIO SPI behaves differently and thus FS26 didn't work and would reset the board. This changes to add 8-bit transfer support and doesn't lock the irq anymore since the SPI driver got changed. Which would yield an assertion, best it ensure feed callee priority is high enough. Signed-off-by: Peter van der Perk --- drivers/watchdog/Kconfig.nxp_fs26 | 15 ++++++ drivers/watchdog/wdt_nxp_fs26.c | 89 +++++++++++++++++-------------- 2 files changed, 63 insertions(+), 41 deletions(-) diff --git a/drivers/watchdog/Kconfig.nxp_fs26 b/drivers/watchdog/Kconfig.nxp_fs26 index 933cd96530f1..231f692f710b 100644 --- a/drivers/watchdog/Kconfig.nxp_fs26 +++ b/drivers/watchdog/Kconfig.nxp_fs26 @@ -73,4 +73,19 @@ config WDT_NXP_FS26_INT_THREAD_PRIO Priority level for internal cooperative thread which is ran for interrupt processing. +config WDT_NXP_FS26_SPI_8BIT_TRANSFER + bool "Use 8-bit SPI transfer mode for FS26" + default y if SPI_RTIO + help + Enable this to force the FS26 driver to use 8-bit SPI transfers + instead of the default 32-bit transfers. + + This is required when using SPI controllers that do not support + 32-bit word sizes (e.g. SPI_RTIO), or when an application requires + strictly byte-sized transfers. + + When disabled, the FS26 driver will continue to use 32-bit SPI + transfers as defined by the original implementation. + + endif # WDT_NXP_FS26 diff --git a/drivers/watchdog/wdt_nxp_fs26.c b/drivers/watchdog/wdt_nxp_fs26.c index 26ffca172e7a..ff2dda49828d 100644 --- a/drivers/watchdog/wdt_nxp_fs26.c +++ b/drivers/watchdog/wdt_nxp_fs26.c @@ -1,5 +1,5 @@ /* - * Copyright 2023 NXP + * Copyright 2023, 2026 NXP * * SPDX-License-Identifier: Apache-2.0 */ @@ -17,10 +17,16 @@ LOG_MODULE_REGISTER(wdt_nxp_fs26); #include "wdt_nxp_fs26.h" -#if defined(CONFIG_BIG_ENDIAN) +#if defined(CONFIG_BIG_ENDIAN) || defined(CONFIG_WDT_NXP_FS26_SPI_8BIT_TRANSFER) #define SWAP_ENDIANNESS #endif +#ifdef CONFIG_WDT_NXP_FS26_SPI_8BIT_TRANSFER +#define FS26_SPI_TRANSFER_WIDTH 8 +#else +#define FS26_SPI_TRANSFER_WIDTH 32 +#endif + #define FS26_CRC_TABLE_SIZE 256U #define FS26_CRC_INIT 0xff #define FS26_FS_WD_TOKEN_DEFAULT 0x5ab2 @@ -279,7 +285,6 @@ static int fs26_wd_refresh(const struct device *dev) const struct wdt_nxp_fs26_config *config = dev->config; struct wdt_nxp_fs26_data *data = dev->data; int retval = 0; - int key; uint16_t answer; struct fs26_spi_rx_frame rx_frame; @@ -289,8 +294,6 @@ static int fs26_wd_refresh(const struct device *dev) retval = -EIO; } } else if (config->wd_type == FS26_WD_CHALLENGER) { - key = irq_lock(); - /* Read challenge token generated by the device */ if (fs26_getreg(&config->spi, FS26_FS_WD_TOKEN, &rx_frame)) { LOG_ERR("Failed to obtain watchdog token"); @@ -305,8 +308,6 @@ static int fs26_wd_refresh(const struct device *dev) retval = -EIO; } } - - irq_unlock(key); } else { retval = -EINVAL; } @@ -632,44 +633,13 @@ static int wdt_nxp_fs26_init(const struct device *dev) struct wdt_nxp_fs26_data *data = dev->data; struct fs26_spi_rx_frame rx_frame; uint32_t regval; + int ret; /* Validate bus is ready */ if (!spi_is_ready_dt(&config->spi)) { return -ENODEV; } - k_sem_init(&data->int_sem, 0, 1); - - /* Configure GPIO used for INTB signal */ - if (!gpio_is_ready_dt(&config->int_gpio)) { - LOG_ERR("GPIO port %s not ready", config->int_gpio.port->name); - return -ENODEV; - } - - if (gpio_pin_configure_dt(&config->int_gpio, GPIO_INPUT)) { - LOG_ERR("Unable to configure GPIO pin %u", config->int_gpio.pin); - return -EIO; - } - - gpio_init_callback(&(data->int_gpio_cb), wdt_nxp_fs26_int_callback, - BIT(config->int_gpio.pin)); - - if (gpio_add_callback(config->int_gpio.port, &(data->int_gpio_cb))) { - return -EINVAL; - } - - if (gpio_pin_interrupt_configure_dt(&config->int_gpio, - GPIO_INT_EDGE_FALLING)) { - return -EINVAL; - } - - k_thread_create(&data->int_thread, data->int_thread_stack, - CONFIG_WDT_NXP_FS26_INT_THREAD_STACK_SIZE, - wdt_nxp_fs26_int_thread, - (void *)dev, NULL, NULL, - K_PRIO_COOP(CONFIG_WDT_NXP_FS26_INT_THREAD_PRIO), - 0, K_NO_WAIT); - /* Verify FS BIST before proceeding */ if (fs26_getreg(&config->spi, FS26_FS_DIAG_SAFETY1, &rx_frame)) { return -EIO; @@ -801,6 +771,43 @@ static int wdt_nxp_fs26_init(const struct device *dev) } } + k_sem_init(&data->int_sem, 0, 1); + + /* Configure GPIO used for INTB signal */ + if (!gpio_is_ready_dt(&config->int_gpio)) { + LOG_ERR("GPIO port %s not ready", config->int_gpio.port->name); + return -ENODEV; + } + + if (gpio_pin_configure_dt(&config->int_gpio, GPIO_INPUT)) { + LOG_ERR("Unable to configure GPIO pin %u", config->int_gpio.pin); + return -EIO; + } + + gpio_init_callback(&(data->int_gpio_cb), wdt_nxp_fs26_int_callback, + BIT(config->int_gpio.pin)); + + ret = gpio_add_callback(config->int_gpio.port, &(data->int_gpio_cb)); + + if (ret) { + LOG_ERR("Failed to add GPIO callback: %d\n", ret); + return ret; + } + + ret = gpio_pin_interrupt_configure_dt(&config->int_gpio, GPIO_INT_EDGE_FALLING); + + if (ret) { + LOG_ERR("Failed to configure GPIO interrupt: %d", ret); + return ret; + } + + k_tid_t tid = k_thread_create( + &data->int_thread, data->int_thread_stack, + CONFIG_WDT_NXP_FS26_INT_THREAD_STACK_SIZE, wdt_nxp_fs26_int_thread, (void *)dev, + NULL, NULL, K_PRIO_COOP(CONFIG_WDT_NXP_FS26_INT_THREAD_PRIO), 0, K_NO_WAIT); + + k_thread_name_set(tid, "wdt_nxp_fs26"); + return 0; } @@ -824,8 +831,8 @@ static DEVICE_API(wdt, wdt_nxp_fs26_api) = { }; \ \ static const struct wdt_nxp_fs26_config wdt_nxp_fs26_config_##n = { \ - .spi = SPI_DT_SPEC_INST_GET(n, \ - SPI_OP_MODE_MASTER | SPI_MODE_CPHA | SPI_WORD_SET(32)), \ + .spi = SPI_DT_SPEC_INST_GET(n, SPI_OP_MODE_MASTER | SPI_MODE_CPHA | \ + SPI_WORD_SET(FS26_SPI_TRANSFER_WIDTH)), \ .wd_type = _CONCAT(FS26_WD_, DT_INST_STRING_UPPER_TOKEN(n, type)), \ .int_gpio = GPIO_DT_SPEC_INST_GET(n, int_gpios), \ }; \ From b76f37c5da45e6c14a60562f79512a721d3a6055 Mon Sep 17 00:00:00 2001 From: Peter van der Perk Date: Tue, 20 Jan 2026 11:04:01 +0100 Subject: [PATCH 0236/6328] boards: nxp: mr_canhubk3: Increase FS26 init priority We've to ensure nothing blocks the watchdog init on startup, otherwise we'll get into bootloop. Hence increase the piority. Signed-off-by: Peter van der Perk --- boards/nxp/mr_canhubk3/Kconfig.defconfig | 7 +++++-- .../build_all/ethernet/boards/mr_canhubk3_s32k344.conf | 1 + .../ethernet/boards/mr_canhubk3_s32k344_mcuboot.conf | 1 + 3 files changed, 7 insertions(+), 2 deletions(-) create mode 100644 tests/drivers/build_all/ethernet/boards/mr_canhubk3_s32k344.conf create mode 100644 tests/drivers/build_all/ethernet/boards/mr_canhubk3_s32k344_mcuboot.conf diff --git a/boards/nxp/mr_canhubk3/Kconfig.defconfig b/boards/nxp/mr_canhubk3/Kconfig.defconfig index 86a0fbbdb667..9773db8b68df 100644 --- a/boards/nxp/mr_canhubk3/Kconfig.defconfig +++ b/boards/nxp/mr_canhubk3/Kconfig.defconfig @@ -12,13 +12,16 @@ endif # SERIAL if SPI +config GPIO_INIT_PRIORITY + default 10 + config SPI_INIT_PRIORITY - default 50 + default 10 if WDT_NXP_FS26 config WDT_NXP_FS26_INIT_PRIORITY - default 51 + default 10 endif # WDT_NXP_FS26 endif # SPI diff --git a/tests/drivers/build_all/ethernet/boards/mr_canhubk3_s32k344.conf b/tests/drivers/build_all/ethernet/boards/mr_canhubk3_s32k344.conf new file mode 100644 index 000000000000..dfd66e436cba --- /dev/null +++ b/tests/drivers/build_all/ethernet/boards/mr_canhubk3_s32k344.conf @@ -0,0 +1 @@ +CONFIG_SPI_INIT_PRIORITY=10 diff --git a/tests/drivers/build_all/ethernet/boards/mr_canhubk3_s32k344_mcuboot.conf b/tests/drivers/build_all/ethernet/boards/mr_canhubk3_s32k344_mcuboot.conf new file mode 100644 index 000000000000..dfd66e436cba --- /dev/null +++ b/tests/drivers/build_all/ethernet/boards/mr_canhubk3_s32k344_mcuboot.conf @@ -0,0 +1 @@ +CONFIG_SPI_INIT_PRIORITY=10 From 8135c56cf6a2d4523e0e08f3d4ea016df40ece2d Mon Sep 17 00:00:00 2001 From: Ryan Wiebe Date: Tue, 20 Jan 2026 11:53:30 +0000 Subject: [PATCH 0237/6328] modbus: Fixed serial RX enablement for ASYNC and client mode Modbus is failing to turn on RX when using serial ASYNC mode. This causes modbus to never receive inbound requests, leaving it inoperable. Additionally, modbus also enables RX when in client mode, leading to issues when running as a client. These have been fixed by enabling rx only when serial init is successful and modbus is in server mode during initialisation. Signed-off-by: Ryan Wiebe --- subsys/modbus/modbus_serial.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/subsys/modbus/modbus_serial.c b/subsys/modbus/modbus_serial.c index 0f7410b59b86..9723d08d0f5c 100644 --- a/subsys/modbus/modbus_serial.c +++ b/subsys/modbus/modbus_serial.c @@ -693,10 +693,13 @@ int modbus_serial_init(struct modbus_context *ctx, if (!err) { k_timer_init(&cfg->rtu_timer, rtu_tmr_handler, NULL); k_timer_user_data_set(&cfg->rtu_timer, ctx); - modbus_serial_rx_on(ctx); } } + if (!err && !ctx->client) { + modbus_serial_rx_on(ctx); + } + LOG_INF("RTU timeout %u us", cfg->rtu_timeout); return err; From e18e1c06c857dec4d629047920b9106d3caa5c35 Mon Sep 17 00:00:00 2001 From: Gaetan Perrot Date: Wed, 21 Jan 2026 04:20:38 +0900 Subject: [PATCH 0238/6328] drivers: dai: intel: dmic: make dai_dmic_probe void dai_dmic_probe() and dai_dmic_probe_wrapper() never reports errors and always returns 0. The error check at the call site is therefore dead code. Make functions void and drop the unused error handling. Signed-off-by: Gaetan Perrot --- drivers/dai/intel/dmic/dmic.c | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/drivers/dai/intel/dmic/dmic.c b/drivers/dai/intel/dmic/dmic.c index a53e0f957e62..10d192b08cb3 100644 --- a/drivers/dai/intel/dmic/dmic.c +++ b/drivers/dai/intel/dmic/dmic.c @@ -322,7 +322,7 @@ static inline void dai_dmic_dis_power(const struct dai_intel_dmic *dmic) base + DMICLCTL_OFFSET); } -static int dai_dmic_probe(struct dai_intel_dmic *dmic) +static void dai_dmic_probe(struct dai_intel_dmic *dmic) { LOG_INF("dmic_probe()"); @@ -340,8 +340,6 @@ static int dai_dmic_probe(struct dai_intel_dmic *dmic) /* DMIC Owner Select to DSP */ dai_dmic_claim_ownership(dmic); - - return 0; } static int dai_dmic_remove(struct dai_intel_dmic *dmic) @@ -806,25 +804,20 @@ static int dai_dmic_set_config(const struct device *dev, return ret; } -static int dai_dmic_probe_wrapper(const struct device *dev) +static void dai_dmic_probe_wrapper(const struct device *dev) { struct dai_intel_dmic *dmic = (struct dai_intel_dmic *)dev->data; k_spinlock_key_t key; - int ret = 0; key = k_spin_lock(&dmic->lock); if (dmic->sref == 0) { - ret = dai_dmic_probe(dmic); + dai_dmic_probe(dmic); } - if (!ret) { - dmic->sref++; - } + dmic->sref++; k_spin_unlock(&dmic->lock, key); - - return ret; } static int dai_dmic_remove_wrapper(const struct device *dev) From 67ac1ddd77e60790161a63d1de685930b0144774 Mon Sep 17 00:00:00 2001 From: Maochen Wang Date: Wed, 21 Jan 2026 14:53:13 +0800 Subject: [PATCH 0239/6328] manifest: hal_nxp: upgrade wifi version to r53.p2 Upgrade wifi driver version to r53.p2. Support static ipv4 address connection for STA interface. Improved throughput value for SDIO case. Support event based FW dump for IW61x. Fix several bugs. Signed-off-by: Maochen Wang --- west.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/west.yml b/west.yml index cf1eafd0dc20..de9a40ee46ea 100644 --- a/west.yml +++ b/west.yml @@ -210,7 +210,7 @@ manifest: groups: - hal - name: hal_nxp - revision: 2f8883b3358e7be2101075cd0f00dd2e0fa68050 + revision: af5d95d3e6be13f1b993d2c466595e7cc71ba57b path: modules/hal/nxp groups: - hal From 288802461ca1548c7350fdb208162b3a5b70a17a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Mo=C5=84?= Date: Wed, 21 Jan 2026 08:55:41 +0100 Subject: [PATCH 0240/6328] dts: bindings: clock: fix reference audio frequencies MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reference audio clock frequencies are supposed to be integer multiplies of sampling frequency (44100 * 256 = 11289600, 48000 * 256 = 12288000) and not some arbitrary numbers. Signed-off-by: Tomasz Moń --- include/zephyr/dt-bindings/clock/nrfs-audiopll.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/zephyr/dt-bindings/clock/nrfs-audiopll.h b/include/zephyr/dt-bindings/clock/nrfs-audiopll.h index b4c3975b5e15..a79a4061f266 100644 --- a/include/zephyr/dt-bindings/clock/nrfs-audiopll.h +++ b/include/zephyr/dt-bindings/clock/nrfs-audiopll.h @@ -8,8 +8,8 @@ #define ZEPHYR_INCLUDE_DT_BINDINGS_CLOCK_NRFS_AUDIOPLL_H_ #define NRFS_AUDIOPLL_FREQ_MIN 10666707 -#define NRFS_AUDIOPLL_FREQ_AUDIO_44K1 11289591 -#define NRFS_AUDIOPLL_FREQ_AUDIO_48K 12287963 +#define NRFS_AUDIOPLL_FREQ_AUDIO_44K1 11289600 +#define NRFS_AUDIOPLL_FREQ_AUDIO_48K 12288000 #define NRFS_AUDIOPLL_FREQ_MAX 13333292 #endif /* #define ZEPHYR_INCLUDE_DT_BINDINGS_CLOCK_NRFS_AUDIOPLL_H_ */ From f1c1ef170d9db209f5ff9144f27560899236392c Mon Sep 17 00:00:00 2001 From: Ren Chen Date: Wed, 21 Jan 2026 14:21:12 +0800 Subject: [PATCH 0241/6328] dts: riscv: it51xxx: omit pinctrl and wuc nodes if not referenced This commit prefixes pre-generated nodes with `/omit-if-no-ref/` to keep the generated devicetree C headers minimal. Signed-off-by: Ren Chen --- dts/riscv/ite/it51xxx-pinctrl-map.dtsi | 198 ++++++++++++------------- dts/riscv/ite/it51xxx-wuc-map.dtsi | 196 ++++++++++++------------ 2 files changed, 197 insertions(+), 197 deletions(-) diff --git a/dts/riscv/ite/it51xxx-pinctrl-map.dtsi b/dts/riscv/ite/it51xxx-pinctrl-map.dtsi index f4810536dc4e..061e66dac700 100644 --- a/dts/riscv/ite/it51xxx-pinctrl-map.dtsi +++ b/dts/riscv/ite/it51xxx-pinctrl-map.dtsi @@ -8,451 +8,451 @@ &pinctrl { /* ADC alternate function */ - adc0_ch0_gpi0_default: adc0_ch0_gpi0_default { + /omit-if-no-ref/ adc0_ch0_gpi0_default: adc0_ch0_gpi0_default { pinmuxs = <&pinctrli 0 IT8XXX2_ALT_FUNC_1>; }; - adc0_ch1_gpi1_default: adc0_ch1_gpi1_default { + /omit-if-no-ref/ adc0_ch1_gpi1_default: adc0_ch1_gpi1_default { pinmuxs = <&pinctrli 1 IT8XXX2_ALT_FUNC_1>; }; - adc0_ch2_gpi2_default: adc0_ch2_gpi2_default { + /omit-if-no-ref/ adc0_ch2_gpi2_default: adc0_ch2_gpi2_default { pinmuxs = <&pinctrli 2 IT8XXX2_ALT_FUNC_1>; }; - adc0_ch3_gpi3_default: adc0_ch3_gpi3_default { + /omit-if-no-ref/ adc0_ch3_gpi3_default: adc0_ch3_gpi3_default { pinmuxs = <&pinctrli 3 IT8XXX2_ALT_FUNC_1>; }; - adc0_ch4_gpi4_default: adc0_ch4_gpi4_default { + /omit-if-no-ref/ adc0_ch4_gpi4_default: adc0_ch4_gpi4_default { pinmuxs = <&pinctrli 4 IT8XXX2_ALT_FUNC_1>; }; - adc0_ch5_gpi5_default: adc0_ch5_gpi5_default { + /omit-if-no-ref/ adc0_ch5_gpi5_default: adc0_ch5_gpi5_default { pinmuxs = <&pinctrli 5 IT8XXX2_ALT_FUNC_1>; }; - adc0_ch6_gpi6_default: adc0_ch6_gpi6_default { + /omit-if-no-ref/ adc0_ch6_gpi6_default: adc0_ch6_gpi6_default { pinmuxs = <&pinctrli 6 IT8XXX2_ALT_FUNC_1>; }; - adc0_ch7_gpi7_default: adc0_ch7_gpi7_default { + /omit-if-no-ref/ adc0_ch7_gpi7_default: adc0_ch7_gpi7_default { pinmuxs = <&pinctrli 7 IT8XXX2_ALT_FUNC_1>; }; /* FSPI alternate function */ - fspi_fsce_gpg3_default: fspi_fsce_gpg3_default { + /omit-if-no-ref/ fspi_fsce_gpg3_default: fspi_fsce_gpg3_default { pinmuxs = <&pinctrlg 3 IT8XXX2_ALT_FUNC_1>; }; - fspi_fmosi_gpg4_default: fspi_fmosi_gpg4_default { + /omit-if-no-ref/ fspi_fmosi_gpg4_default: fspi_fmosi_gpg4_default { pinmuxs = <&pinctrlg 4 IT8XXX2_ALT_FUNC_1>; }; - fspi_fmiso_gpg5_default: fspi_fmiso_gpg5_default { + /omit-if-no-ref/ fspi_fmiso_gpg5_default: fspi_fmiso_gpg5_default { pinmuxs = <&pinctrlg 5 IT8XXX2_ALT_FUNC_1>; }; - fspi_fsce1_gpg6_default: fspi_fsce1_gpg6_default { + /omit-if-no-ref/ fspi_fsce1_gpg6_default: fspi_fsce1_gpg6_default { pinmuxs = <&pinctrlg 6 IT8XXX2_ALT_FUNC_1>; }; - fspi_fsck_gpg7_default: fspi_fsck_gpg7_default { + /omit-if-no-ref/ fspi_fsck_gpg7_default: fspi_fsck_gpg7_default { pinmuxs = <&pinctrlg 7 IT8XXX2_ALT_FUNC_1>; }; - fspi_fdio2_gph5_default: fspi_fdio2_gph5_default { + /omit-if-no-ref/ fspi_fdio2_gph5_default: fspi_fdio2_gph5_default { pinmuxs = <&pinctrlh 5 IT8XXX2_ALT_FUNC_1>; }; - fspi_fdio3_gph6_default: fspi_fdio3_gph6_default { + /omit-if-no-ref/ fspi_fdio3_gph6_default: fspi_fdio3_gph6_default { pinmuxs = <&pinctrlh 6 IT8XXX2_ALT_FUNC_1>; }; /* I2C alternate function */ - i2c0_clk_gpf2_default: i2c0_clk_gpf2_default { + /omit-if-no-ref/ i2c0_clk_gpf2_default: i2c0_clk_gpf2_default { pinmuxs = <&pinctrlf 2 IT8XXX2_ALT_FUNC_1>; }; - i2c0_data_gpf3_default: i2c0_data_gpf3_default { + /omit-if-no-ref/ i2c0_data_gpf3_default: i2c0_data_gpf3_default { pinmuxs = <&pinctrlf 3 IT8XXX2_ALT_FUNC_1>; }; - i2c1_clk_gpc1_default: i2c1_clk_gpc1_default { + /omit-if-no-ref/ i2c1_clk_gpc1_default: i2c1_clk_gpc1_default { pinmuxs = <&pinctrlc 1 IT8XXX2_ALT_FUNC_1>; }; - i2c1_data_gpc2_default: i2c1_data_gpc2_default { + /omit-if-no-ref/ i2c1_data_gpc2_default: i2c1_data_gpc2_default { pinmuxs = <&pinctrlc 2 IT8XXX2_ALT_FUNC_1>; }; - i2c2_clk_gpf6_default: i2c2_clk_gpf6_default { + /omit-if-no-ref/ i2c2_clk_gpf6_default: i2c2_clk_gpf6_default { pinmuxs = <&pinctrlf 6 IT8XXX2_ALT_FUNC_1>; }; - i2c2_data_gpf7_default: i2c2_data_gpf7_default { + /omit-if-no-ref/ i2c2_data_gpf7_default: i2c2_data_gpf7_default { pinmuxs = <&pinctrlf 7 IT8XXX2_ALT_FUNC_1>; }; - i2c3_clk_gph1_default: i2c3_clk_gph1_default { + /omit-if-no-ref/ i2c3_clk_gph1_default: i2c3_clk_gph1_default { pinmuxs = <&pinctrlh 1 IT8XXX2_ALT_FUNC_4>; }; - i2c3_data_gph2_default: i2c3_data_gph2_default { + /omit-if-no-ref/ i2c3_data_gph2_default: i2c3_data_gph2_default { pinmuxs = <&pinctrlh 2 IT8XXX2_ALT_FUNC_4>; }; - i2c4_clk_gpe0_default: i2c4_clk_gpe0_default { + /omit-if-no-ref/ i2c4_clk_gpe0_default: i2c4_clk_gpe0_default { pinmuxs = <&pinctrle 0 IT8XXX2_ALT_FUNC_4>; }; - i2c4_data_gpe7_default: i2c4_data_gpe7_default { + /omit-if-no-ref/ i2c4_data_gpe7_default: i2c4_data_gpe7_default { pinmuxs = <&pinctrle 7 IT8XXX2_ALT_FUNC_3>; }; - i2c5_clk_gpa4_default: i2c5_clk_gpa4_default { + /omit-if-no-ref/ i2c5_clk_gpa4_default: i2c5_clk_gpa4_default { pinmuxs = <&pinctrla 4 IT8XXX2_ALT_FUNC_3>; }; - i2c5_data_gpa5_default: i2c5_data_gpa5_default { + /omit-if-no-ref/ i2c5_data_gpa5_default: i2c5_data_gpa5_default { pinmuxs = <&pinctrla 5 IT8XXX2_ALT_FUNC_3>; }; - i2c6_clk_gpd0_default: i2c6_clk_gpd0_default { + /omit-if-no-ref/ i2c6_clk_gpd0_default: i2c6_clk_gpd0_default { pinmuxs = <&pinctrld 0 IT8XXX2_ALT_FUNC_3>; }; - i2c6_data_gpd1_default: i2c6_data_gpd1_default { + /omit-if-no-ref/ i2c6_data_gpd1_default: i2c6_data_gpd1_default { pinmuxs = <&pinctrld 1 IT8XXX2_ALT_FUNC_3>; }; - i2c7_clk_gpb2_default: i2c7_clk_gpb2_default { + /omit-if-no-ref/ i2c7_clk_gpb2_default: i2c7_clk_gpb2_default { pinmuxs = <&pinctrlb 2 IT8XXX2_ALT_FUNC_4>; }; - i2c7_data_gph0_default: i2c7_data_gph0_default { + /omit-if-no-ref/ i2c7_data_gph0_default: i2c7_data_gph0_default { pinmuxs = <&pinctrlh 0 IT8XXX2_ALT_FUNC_4>; }; - i2c8_clk_gpb5_default: i2c8_clk_gpb5_default { + /omit-if-no-ref/ i2c8_clk_gpb5_default: i2c8_clk_gpb5_default { pinmuxs = <&pinctrlb 5 IT8XXX2_ALT_FUNC_4>; }; - i2c8_data_gpj6_default: i2c8_data_gpj6_default { + /omit-if-no-ref/ i2c8_data_gpj6_default: i2c8_data_gpj6_default { pinmuxs = <&pinctrlj 6 IT8XXX2_ALT_FUNC_4>; }; /* I2C switch to interface */ - i2c9_clk_gpj3_default: i2c9_clk_gpj3_default { + /omit-if-no-ref/ i2c9_clk_gpj3_default: i2c9_clk_gpj3_default { pinmuxs = <&pinctrlj 3 IT8XXX2_ALT_FUNC_3>; }; - i2c9_data_gpj4_default: i2c9_data_gpj4_default { + /omit-if-no-ref/ i2c9_data_gpj4_default: i2c9_data_gpj4_default { pinmuxs = <&pinctrlj 4 IT8XXX2_ALT_FUNC_3>; }; - i2c10_clk_gpj5_default: i2c10_clk_gpj5_default { + /omit-if-no-ref/ i2c10_clk_gpj5_default: i2c10_clk_gpj5_default { pinmuxs = <&pinctrlj 5 IT8XXX2_ALT_FUNC_3>; }; - i2c10_data_gpe1_default: i2c10_data_gpe1_default { + /omit-if-no-ref/ i2c10_data_gpe1_default: i2c10_data_gpe1_default { pinmuxs = <&pinctrle 1 IT8XXX2_ALT_FUNC_3>; }; - i2c11_clk_gpe2_default: i2c11_clk_gpe2_default { + /omit-if-no-ref/ i2c11_clk_gpe2_default: i2c11_clk_gpe2_default { pinmuxs = <&pinctrle 2 IT8XXX2_ALT_FUNC_3>; }; - i2c11_data_gpe3_default: i2c11_data_gpe3_default { + /omit-if-no-ref/ i2c11_data_gpe3_default: i2c11_data_gpe3_default { pinmuxs = <&pinctrle 3 IT8XXX2_ALT_FUNC_3>; }; - i2c12_clk_gpf0_default: i2c12_clk_gpf0_default { + /omit-if-no-ref/ i2c12_clk_gpf0_default: i2c12_clk_gpf0_default { pinmuxs = <&pinctrlf 0 IT8XXX2_ALT_FUNC_3>; }; - i2c12_data_gpf1_default: i2c12_data_gpf1_default { + /omit-if-no-ref/ i2c12_data_gpf1_default: i2c12_data_gpf1_default { pinmuxs = <&pinctrlf 1 IT8XXX2_ALT_FUNC_3>; }; /* I3C alternate function */ - i3c0_clk_gpj3_default: i3c0_clk_gpj3_default { + /omit-if-no-ref/ i3c0_clk_gpj3_default: i3c0_clk_gpj3_default { pinmuxs = <&pinctrlj 3 IT8XXX2_ALT_FUNC_1>; }; - i3c0_data_gpj4_default: i3c0_data_gpj4_default { + /omit-if-no-ref/ i3c0_data_gpj4_default: i3c0_data_gpj4_default { pinmuxs = <&pinctrlj 4 IT8XXX2_ALT_FUNC_1>; }; - i3c1_clk_gpj5_default: i3c1_clk_gpj5_default { + /omit-if-no-ref/ i3c1_clk_gpj5_default: i3c1_clk_gpj5_default { pinmuxs = <&pinctrlj 5 IT8XXX2_ALT_FUNC_1>; }; - i3c1_data_gpe1_default: i3c1_data_gpe1_default { + /omit-if-no-ref/ i3c1_data_gpe1_default: i3c1_data_gpe1_default { pinmuxs = <&pinctrle 1 IT8XXX2_ALT_FUNC_1>; }; - i3c2_clk_gpe2_default: i3c2_clk_gpe2_default { + /omit-if-no-ref/ i3c2_clk_gpe2_default: i3c2_clk_gpe2_default { pinmuxs = <&pinctrle 2 IT8XXX2_ALT_FUNC_1>; }; - i3c2_data_gpe3_default: i3c2_data_gpe3_default { + /omit-if-no-ref/ i3c2_data_gpe3_default: i3c2_data_gpe3_default { pinmuxs = <&pinctrle 3 IT8XXX2_ALT_FUNC_1>; }; - i3c3_clk_gpf0_default: i3c3_clk_gpf0_default { + /omit-if-no-ref/ i3c3_clk_gpf0_default: i3c3_clk_gpf0_default { pinmuxs = <&pinctrlf 0 IT8XXX2_ALT_FUNC_1>; }; - i3c3_data_gpf1_default: i3c3_data_gpf1_default { + /omit-if-no-ref/ i3c3_data_gpf1_default: i3c3_data_gpf1_default { pinmuxs = <&pinctrlf 1 IT8XXX2_ALT_FUNC_1>; }; /* Keyboard alternate function */ - kso0_default: kso0_gpk0_default: kso0_gpk0_default { + /omit-if-no-ref/ kso0_default: kso0_gpk0_default: kso0_gpk0_default { pinmuxs = <&pinctrlk 0 IT8XXX2_ALT_FUNC_1>; drive-open-drain; bias-pull-up; }; - kso1_default: kso1_gpk1_default: kso1_gpk1_default { + /omit-if-no-ref/ kso1_default: kso1_gpk1_default: kso1_gpk1_default { pinmuxs = <&pinctrlk 1 IT8XXX2_ALT_FUNC_1>; drive-open-drain; bias-pull-up; }; - kso2_default: kso2_gpk2_default: kso2_gpk2_default { + /omit-if-no-ref/ kso2_default: kso2_gpk2_default: kso2_gpk2_default { pinmuxs = <&pinctrlk 2 IT8XXX2_ALT_FUNC_1>; drive-open-drain; bias-pull-up; }; - kso3_default: kso3_gpk3_default: kso3_gpk3_default { + /omit-if-no-ref/ kso3_default: kso3_gpk3_default: kso3_gpk3_default { pinmuxs = <&pinctrlk 3 IT8XXX2_ALT_FUNC_1>; drive-open-drain; bias-pull-up; }; - kso4_default: kso4_gpk4_default: kso4_gpk4_default { + /omit-if-no-ref/ kso4_default: kso4_gpk4_default: kso4_gpk4_default { pinmuxs = <&pinctrlk 4 IT8XXX2_ALT_FUNC_1>; drive-open-drain; bias-pull-up; }; - kso5_default: kso5_gpk5_default: kso5_gpk5_default { + /omit-if-no-ref/ kso5_default: kso5_gpk5_default: kso5_gpk5_default { pinmuxs = <&pinctrlk 5 IT8XXX2_ALT_FUNC_1>; drive-open-drain; bias-pull-up; }; - kso6_default: kso6_gpk6_default: kso6_gpk6_default { + /omit-if-no-ref/ kso6_default: kso6_gpk6_default: kso6_gpk6_default { pinmuxs = <&pinctrlk 6 IT8XXX2_ALT_FUNC_1>; drive-open-drain; bias-pull-up; }; - kso7_default: kso7_gpk7_default: kso7_gpk7_default { + /omit-if-no-ref/ kso7_default: kso7_gpk7_default: kso7_gpk7_default { pinmuxs = <&pinctrlk 7 IT8XXX2_ALT_FUNC_1>; drive-open-drain; bias-pull-up; }; - kso8_default: kso8_gpl0_default: kso8_gpl0_default { + /omit-if-no-ref/ kso8_default: kso8_gpl0_default: kso8_gpl0_default { pinmuxs = <&pinctrll 0 IT8XXX2_ALT_FUNC_1>; drive-open-drain; bias-pull-up; }; - kso9_default: kso9_gpl1_default: kso9_gpl1_default { + /omit-if-no-ref/ kso9_default: kso9_gpl1_default: kso9_gpl1_default { pinmuxs = <&pinctrll 1 IT8XXX2_ALT_FUNC_1>; drive-open-drain; bias-pull-up; }; - kso10_default: kso10_gpl2_default: kso10_gpl2_default { + /omit-if-no-ref/ kso10_default: kso10_gpl2_default: kso10_gpl2_default { pinmuxs = <&pinctrll 2 IT8XXX2_ALT_FUNC_1>; drive-open-drain; bias-pull-up; }; - kso11_default: kso11_gpl3_default: kso11_gpl3_default { + /omit-if-no-ref/ kso11_default: kso11_gpl3_default: kso11_gpl3_default { pinmuxs = <&pinctrll 3 IT8XXX2_ALT_FUNC_1>; drive-open-drain; bias-pull-up; }; - kso12_default: kso12_gpl4_default: kso12_gpl4_default { + /omit-if-no-ref/ kso12_default: kso12_gpl4_default: kso12_gpl4_default { pinmuxs = <&pinctrll 4 IT8XXX2_ALT_FUNC_1>; drive-open-drain; bias-pull-up; }; - kso13_default: kso13_gpl5_default: kso13_gpl5_default { + /omit-if-no-ref/ kso13_default: kso13_gpl5_default: kso13_gpl5_default { pinmuxs = <&pinctrll 5 IT8XXX2_ALT_FUNC_1>; drive-open-drain; bias-pull-up; }; - kso14_default: kso14_gpl6_default: kso14_gpl6_default { + /omit-if-no-ref/ kso14_default: kso14_gpl6_default: kso14_gpl6_default { pinmuxs = <&pinctrll 6 IT8XXX2_ALT_FUNC_1>; drive-open-drain; bias-pull-up; }; - kso15_default: kso15_gpl7_default: kso15_gpl7_default { + /omit-if-no-ref/ kso15_default: kso15_gpl7_default: kso15_gpl7_default { pinmuxs = <&pinctrll 7 IT8XXX2_ALT_FUNC_1>; drive-open-drain; bias-pull-up; }; - kso16_default: kso16_gpc3_default: kso16_gpc3_default { + /omit-if-no-ref/ kso16_default: kso16_gpc3_default: kso16_gpc3_default { pinmuxs = <&pinctrlc 3 IT8XXX2_ALT_FUNC_1>; bias-pull-up; }; - kso17_default: kso17_gpc5_default: kso17_gpc5_default { + /omit-if-no-ref/ kso17_default: kso17_gpc5_default: kso17_gpc5_default { pinmuxs = <&pinctrlc 5 IT8XXX2_ALT_FUNC_1>; bias-pull-up; }; - ksi0_default: ksi0_gpn0_default: ksi0_gpn0_default { + /omit-if-no-ref/ ksi0_default: ksi0_gpn0_default: ksi0_gpn0_default { pinmuxs = <&pinctrln 0 IT8XXX2_ALT_FUNC_1>; bias-pull-up; }; - ksi1_default: ksi1_gpn1_default: ksi1_gpn1_default { + /omit-if-no-ref/ ksi1_default: ksi1_gpn1_default: ksi1_gpn1_default { pinmuxs = <&pinctrln 1 IT8XXX2_ALT_FUNC_1>; bias-pull-up; }; - ksi2_default: ksi2_gpn2_default: ksi2_gpn2_default { + /omit-if-no-ref/ ksi2_default: ksi2_gpn2_default: ksi2_gpn2_default { pinmuxs = <&pinctrln 2 IT8XXX2_ALT_FUNC_1>; bias-pull-up; }; - ksi3_default: ksi3_gpn3_default: ksi3_gpn3_default { + /omit-if-no-ref/ ksi3_default: ksi3_gpn3_default: ksi3_gpn3_default { pinmuxs = <&pinctrln 3 IT8XXX2_ALT_FUNC_1>; bias-pull-up; }; - ksi4_default: ksi4_gpn4_default: ksi4_gpn4_default { + /omit-if-no-ref/ ksi4_default: ksi4_gpn4_default: ksi4_gpn4_default { pinmuxs = <&pinctrln 4 IT8XXX2_ALT_FUNC_1>; bias-pull-up; }; - ksi5_default: ksi5_gpn5_default: ksi5_gpn5_default { + /omit-if-no-ref/ ksi5_default: ksi5_gpn5_default: ksi5_gpn5_default { pinmuxs = <&pinctrln 5 IT8XXX2_ALT_FUNC_1>; bias-pull-up; }; - ksi6_default: ksi6_gpn6_default: ksi6_gpn6_default { + /omit-if-no-ref/ ksi6_default: ksi6_gpn6_default: ksi6_gpn6_default { pinmuxs = <&pinctrln 6 IT8XXX2_ALT_FUNC_1>; bias-pull-up; }; - ksi7_default: ksi7_gpn7_default: ksi7_gpn7_default { + /omit-if-no-ref/ ksi7_default: ksi7_gpn7_default: ksi7_gpn7_default { pinmuxs = <&pinctrln 7 IT8XXX2_ALT_FUNC_1>; bias-pull-up; }; /* PECI alternate function */ - peci_gpf6_default: peci_gpf6_default { + /omit-if-no-ref/ peci_gpf6_default: peci_gpf6_default { pinmuxs = <&pinctrlf 6 IT8XXX2_ALT_FUNC_3>; }; /* PWM alternate function */ - pwm0_gpa0_default: pwm0_gpa0_default { + /omit-if-no-ref/ pwm0_gpa0_default: pwm0_gpa0_default { pinmuxs = <&pinctrla 0 IT8XXX2_ALT_FUNC_1>; }; - pwm1_gpa1_default: pwm1_gpa1_default { + /omit-if-no-ref/ pwm1_gpa1_default: pwm1_gpa1_default { pinmuxs = <&pinctrla 1 IT8XXX2_ALT_FUNC_1>; }; - pwm2_gpa2_default: pwm2_gpa2_default { + /omit-if-no-ref/ pwm2_gpa2_default: pwm2_gpa2_default { pinmuxs = <&pinctrla 2 IT8XXX2_ALT_FUNC_1>; }; - pwm3_gpa3_default: pwm3_gpa3_default { + /omit-if-no-ref/ pwm3_gpa3_default: pwm3_gpa3_default { pinmuxs = <&pinctrla 3 IT8XXX2_ALT_FUNC_1>; }; - pwm4_gpa4_default: pwm4_gpa4_default { + /omit-if-no-ref/ pwm4_gpa4_default: pwm4_gpa4_default { pinmuxs = <&pinctrla 4 IT8XXX2_ALT_FUNC_1>; }; - pwm5_gpa5_default: pwm5_gpa5_default { + /omit-if-no-ref/ pwm5_gpa5_default: pwm5_gpa5_default { pinmuxs = <&pinctrla 5 IT8XXX2_ALT_FUNC_1>; }; - pwm6_gpa6_default: pwm6_gpa6_default { + /omit-if-no-ref/ pwm6_gpa6_default: pwm6_gpa6_default { pinmuxs = <&pinctrla 6 IT8XXX2_ALT_FUNC_1>; }; - pwm7_gpa7_default: pwm7_gpa7_default { + /omit-if-no-ref/ pwm7_gpa7_default: pwm7_gpa7_default { pinmuxs = <&pinctrla 7 IT8XXX2_ALT_FUNC_1>; }; /* SSPI alternate function */ - ssce0_gpj7_default: ssce0_gpj7_default { + /omit-if-no-ref/ ssce0_gpj7_default: ssce0_gpj7_default { pinmuxs = <&pinctrlj 7 IT8XXX2_ALT_FUNC_4>; }; - ssce1_gph7_default: ssce1_gph7_default { + /omit-if-no-ref/ ssce1_gph7_default: ssce1_gph7_default { pinmuxs = <&pinctrlh 7 IT8XXX2_ALT_FUNC_3>; }; - ssck_gpa6_default: ssck_gpa6_default { + /omit-if-no-ref/ ssck_gpa6_default: ssck_gpa6_default { pinmuxs = <&pinctrla 6 IT8XXX2_ALT_FUNC_3>; }; - smosi_gpc6_default: smosi_gpc6_default { + /omit-if-no-ref/ smosi_gpc6_default: smosi_gpc6_default { pinmuxs = <&pinctrlc 6 IT8XXX2_ALT_FUNC_3>; }; - smiso_gpc4_default: smiso_gpc4_default { + /omit-if-no-ref/ smiso_gpc4_default: smiso_gpc4_default { pinmuxs = <&pinctrlc 4 IT8XXX2_ALT_FUNC_3>; }; /* Tachometer alternate function */ - tach0a_gpd6_default: tach0a_gpd6_default { + /omit-if-no-ref/ tach0a_gpd6_default: tach0a_gpd6_default { pinmuxs = <&pinctrld 6 IT8XXX2_ALT_FUNC_1>; }; - tach1a_gpd7_default: tach1a_gpd7_default { + /omit-if-no-ref/ tach1a_gpd7_default: tach1a_gpd7_default { pinmuxs = <&pinctrld 7 IT8XXX2_ALT_FUNC_1>; }; - tach2a_gpj0_default: tach2a_gpj0_default { + /omit-if-no-ref/ tach2a_gpj0_default: tach2a_gpj0_default { pinmuxs = <&pinctrlj 0 IT8XXX2_ALT_FUNC_3>; }; - tach0b_gpc6_default: tach0b_gpc6_default { + /omit-if-no-ref/ tach0b_gpc6_default: tach0b_gpc6_default { pinmuxs = <&pinctrlc 6 IT8XXX2_ALT_FUNC_4>; }; - tach1b_gpj6_default: tach1b_gpj6_default { + /omit-if-no-ref/ tach1b_gpj6_default: tach1b_gpj6_default { pinmuxs = <&pinctrlj 6 IT8XXX2_ALT_FUNC_3>; }; - tach2b_gpj1_default: tach2b_gpj1_default { + /omit-if-no-ref/ tach2b_gpj1_default: tach2b_gpj1_default { pinmuxs = <&pinctrlj 1 IT8XXX2_ALT_FUNC_3>; }; /* UART alternate function */ - uart1_rx_gpc7_default: uart1_rx_gpc7_default { + /omit-if-no-ref/ uart1_rx_gpc7_default: uart1_rx_gpc7_default { pinmuxs = <&pinctrlc 7 IT8XXX2_ALT_FUNC_4>; }; - uart1_tx_gpe6_default: uart1_tx_gpe6_default { + /omit-if-no-ref/ uart1_tx_gpe6_default: uart1_tx_gpe6_default { pinmuxs = <&pinctrle 6 IT8XXX2_ALT_FUNC_4>; }; - uart2_rx_gph1_default: uart2_rx_gph1_default { + /omit-if-no-ref/ uart2_rx_gph1_default: uart2_rx_gph1_default { pinmuxs = <&pinctrlh 1 IT8XXX2_ALT_FUNC_3>; }; - uart2_tx_gph2_default: uart2_tx_gph2_default { + /omit-if-no-ref/ uart2_tx_gph2_default: uart2_tx_gph2_default { pinmuxs = <&pinctrlh 2 IT8XXX2_ALT_FUNC_3>; }; }; diff --git a/dts/riscv/ite/it51xxx-wuc-map.dtsi b/dts/riscv/ite/it51xxx-wuc-map.dtsi index 16e82eb0c914..81fbfb8b8b96 100644 --- a/dts/riscv/ite/it51xxx-wuc-map.dtsi +++ b/dts/riscv/ite/it51xxx-wuc-map.dtsi @@ -12,408 +12,408 @@ compatible = "ite,it51xxx-wuc-map"; /* WUC group 2 */ - wuc_wu20: wu20 { + /omit-if-no-ref/ wuc_wu20: wu20 { wucs = <&wuc2 BIT(0)>; /* GPD0 */ }; - wuc_wu21: wu21 { + /omit-if-no-ref/ wuc_wu21: wu21 { wucs = <&wuc2 BIT(1)>; /* GPD1 */ }; - wuc_wu22: wu22 { + /omit-if-no-ref/ wuc_wu22: wu22 { wucs = <&wuc2 BIT(2)>; /* GPC4 */ }; - wuc_wu23: wu23 { + /omit-if-no-ref/ wuc_wu23: wu23 { wucs = <&wuc2 BIT(3)>; /* GPC6 */ }; - wuc_wu24: wu24 { + /omit-if-no-ref/ wuc_wu24: wu24 { wucs = <&wuc2 BIT(4)>; /* GPD2 */ }; - wuc_wu25: wu25 { + /omit-if-no-ref/ wuc_wu25: wu25 { wucs = <&wuc2 BIT(5)>; /* GPB3 */ }; /* WUC group 3 */ - wuc_wu30: wu30 { + /omit-if-no-ref/ wuc_wu30: wu30 { wucs = <&wuc3 BIT(0)>; /* KSI[0] */ }; - wuc_wu31: wu31 { + /omit-if-no-ref/ wuc_wu31: wu31 { wucs = <&wuc3 BIT(1)>; /* KSI[1] */ }; - wuc_wu32: wu32 { + /omit-if-no-ref/ wuc_wu32: wu32 { wucs = <&wuc3 BIT(2)>; /* KSI[2] */ }; - wuc_wu33: wu33 { + /omit-if-no-ref/ wuc_wu33: wu33 { wucs = <&wuc3 BIT(3)>; /* KSI[3] */ }; - wuc_wu34: wu34 { + /omit-if-no-ref/ wuc_wu34: wu34 { wucs = <&wuc3 BIT(4)>; /* KSI[4] */ }; - wuc_wu35: wu35 { + /omit-if-no-ref/ wuc_wu35: wu35 { wucs = <&wuc3 BIT(5)>; /* KSI[5] */ }; - wuc_wu36: wu36 { + /omit-if-no-ref/ wuc_wu36: wu36 { wucs = <&wuc3 BIT(6)>; /* KSI[6] */ }; - wuc_wu37: wu37 { + /omit-if-no-ref/ wuc_wu37: wu37 { wucs = <&wuc3 BIT(7)>; /* KSI[7] */ }; /* WUC group 4 */ - wuc_wu40: wu40 { + /omit-if-no-ref/ wuc_wu40: wu40 { wucs = <&wuc4 BIT(0)>; /* GPE5 */ }; - wuc_wu42: wu42 { + /omit-if-no-ref/ wuc_wu42: wu42 { wucs = <&wuc4 BIT(2)>; /* eSPI transaction */ }; - wuc_wu45: wu45 { + /omit-if-no-ref/ wuc_wu45: wu45 { wucs = <&wuc4 BIT(5)>; /* GPE6 */ }; - wuc_wu46: wu46 { + /omit-if-no-ref/ wuc_wu46: wu46 { wucs = <&wuc4 BIT(6)>; /* GPE7 */ }; /* WUC group 6 */ - wuc_wu60: wu60 { + /omit-if-no-ref/ wuc_wu60: wu60 { wucs = <&wuc6 BIT(0)>; /* GPH0 */ }; - wuc_wu61: wu61 { + /omit-if-no-ref/ wuc_wu61: wu61 { wucs = <&wuc6 BIT(1)>; /* GPH1 */ }; - wuc_wu62: wu62 { + /omit-if-no-ref/ wuc_wu62: wu62 { wucs = <&wuc6 BIT(2)>; /* GPH2 */ }; - wuc_wu63: wu63 { + /omit-if-no-ref/ wuc_wu63: wu63 { wucs = <&wuc6 BIT(3)>; /* GPH3 */ }; - wuc_wu64: wu64 { + /omit-if-no-ref/ wuc_wu64: wu64 { wucs = <&wuc6 BIT(4)>; /* GPF4 */ }; - wuc_wu65: wu65 { + /omit-if-no-ref/ wuc_wu65: wu65 { wucs = <&wuc6 BIT(5)>; /* GPF5 */ }; - wuc_wu66: wu66 { + /omit-if-no-ref/ wuc_wu66: wu66 { wucs = <&wuc6 BIT(6)>; /* GPF6 */ }; - wuc_wu67: wu67 { + /omit-if-no-ref/ wuc_wu67: wu67 { wucs = <&wuc6 BIT(7)>; /* GPF7 */ }; /* WUC group 7 */ - wuc_wu70: wu70 { + /omit-if-no-ref/ wuc_wu70: wu70 { wucs = <&wuc7 BIT(0)>; /* GPE0 */ }; - wuc_wu71: wu71 { + /omit-if-no-ref/ wuc_wu71: wu71 { wucs = <&wuc7 BIT(1)>; /* GPE1 */ }; - wuc_wu72: wu72 { + /omit-if-no-ref/ wuc_wu72: wu72 { wucs = <&wuc7 BIT(2)>; /* GPE2 */ }; - wuc_wu73: wu73 { + /omit-if-no-ref/ wuc_wu73: wu73 { wucs = <&wuc7 BIT(3)>; /* GPE3 */ }; - wuc_wu74: wu74 { + /omit-if-no-ref/ wuc_wu74: wu74 { wucs = <&wuc7 BIT(4)>; /* GPI4 */ }; - wuc_wu75: wu75 { + /omit-if-no-ref/ wuc_wu75: wu75 { wucs = <&wuc7 BIT(5)>; /* GPI5 */ }; - wuc_wu76: wu76 { + /omit-if-no-ref/ wuc_wu76: wu76 { wucs = <&wuc7 BIT(6)>; /* GPI6 */ }; - wuc_wu77: wu77 { + /omit-if-no-ref/ wuc_wu77: wu77 { wucs = <&wuc7 BIT(7)>; /* GPI7 */ }; /* WUC group 8 */ - wuc_wu80: wu80 { + /omit-if-no-ref/ wuc_wu80: wu80 { wucs = <&wuc8 BIT(0)>; /* GPA3 */ }; - wuc_wu81: wu81 { + /omit-if-no-ref/ wuc_wu81: wu81 { wucs = <&wuc8 BIT(1)>; /* GPA4 */ }; - wuc_wu82: wu82 { + /omit-if-no-ref/ wuc_wu82: wu82 { wucs = <&wuc8 BIT(2)>; /* GPA5 */ }; - wuc_wu83: wu83 { + /omit-if-no-ref/ wuc_wu83: wu83 { wucs = <&wuc8 BIT(3)>; /* GPA6 */ }; - wuc_wu84: wu84 { + /omit-if-no-ref/ wuc_wu84: wu84 { wucs = <&wuc8 BIT(4)>; /* GPB2 */ }; - wuc_wu85: wu85 { + /omit-if-no-ref/ wuc_wu85: wu85 { wucs = <&wuc8 BIT(5)>; /* GPC0 */ }; - wuc_wu86: wu86 { + /omit-if-no-ref/ wuc_wu86: wu86 { wucs = <&wuc8 BIT(6)>; /* GPC7 */ }; - wuc_wu87: wu87 { + /omit-if-no-ref/ wuc_wu87: wu87 { wucs = <&wuc8 BIT(7)>; /* GPD7 */ }; /* WUC group 9 */ - wuc_wu88: wu88 { + /omit-if-no-ref/ wuc_wu88: wu88 { wucs = <&wuc9 BIT(0)>; /* GPH4 */ }; - wuc_wu89: wu89 { + /omit-if-no-ref/ wuc_wu89: wu89 { wucs = <&wuc9 BIT(1)>; /* GPH5 */ }; - wuc_wu90: wu90 { + /omit-if-no-ref/ wuc_wu90: wu90 { wucs = <&wuc9 BIT(2)>; /* GPH6 */ }; - wuc_wu91: wu91 { + /omit-if-no-ref/ wuc_wu91: wu91 { wucs = <&wuc9 BIT(3)>; /* GPA0 */ }; - wuc_wu92: wu92 { + /omit-if-no-ref/ wuc_wu92: wu92 { wucs = <&wuc9 BIT(4)>; /* GPA1 */ }; - wuc_wu93: wu93 { + /omit-if-no-ref/ wuc_wu93: wu93 { wucs = <&wuc9 BIT(5)>; /* GPA2 */ }; - wuc_wu95: wu95 { + /omit-if-no-ref/ wuc_wu95: wu95 { wucs = <&wuc9 BIT(7)>; /* GPC2 */ }; /* WUC group 10 */ - wuc_wu96: wu96 { + /omit-if-no-ref/ wuc_wu96: wu96 { wucs = <&wuc10 BIT(0)>; /* GPF0 */ }; - wuc_wu97: wu97 { + /omit-if-no-ref/ wuc_wu97: wu97 { wucs = <&wuc10 BIT(1)>; /* GPF1 */ }; - wuc_wu98: wu98 { + /omit-if-no-ref/ wuc_wu98: wu98 { wucs = <&wuc10 BIT(2)>; /* GPF2 */ }; - wuc_wu99: wu99 { + /omit-if-no-ref/ wuc_wu99: wu99 { wucs = <&wuc10 BIT(3)>; /* GPF3 */ }; - wuc_wu100: wu100 { + /omit-if-no-ref/ wuc_wu100: wu100 { wucs = <&wuc10 BIT(4)>; /* GPA7 */ }; - wuc_wu101: wu101 { + /omit-if-no-ref/ wuc_wu101: wu101 { wucs = <&wuc10 BIT(5)>; /* GPB0 */ }; - wuc_wu102: wu102 { + /omit-if-no-ref/ wuc_wu102: wu102 { wucs = <&wuc10 BIT(6)>; /* GPB1 */ }; - wuc_wu103: wu103 { + /omit-if-no-ref/ wuc_wu103: wu103 { wucs = <&wuc10 BIT(7)>; /* GPB3 */ }; /* WUC group 11 */ - wuc_wu104: wu104 { + /omit-if-no-ref/ wuc_wu104: wu104 { wucs = <&wuc11 BIT(0)>; /* GPB5 */ }; - wuc_wu105: wu105 { + /omit-if-no-ref/ wuc_wu105: wu105 { wucs = <&wuc11 BIT(1)>; /* GPB6 */ }; - wuc_wu107: wu107 { + /omit-if-no-ref/ wuc_wu107: wu107 { wucs = <&wuc11 BIT(3)>; /* GPC1 */ }; - wuc_wu108: wu108 { + /omit-if-no-ref/ wuc_wu108: wu108 { wucs = <&wuc11 BIT(4)>; /* GPC3 */ }; - wuc_wu109: wu109 { + /omit-if-no-ref/ wuc_wu109: wu109 { wucs = <&wuc11 BIT(5)>; /* GPC5 */ }; - wuc_wu110: wu110 { + /omit-if-no-ref/ wuc_wu110: wu110 { wucs = <&wuc11 BIT(6)>; /* GPD3 */ }; - wuc_wu111: wu111 { + /omit-if-no-ref/ wuc_wu111: wu111 { wucs = <&wuc11 BIT(7)>; /* GPD4 */ }; /* WUC group 12 */ - wuc_wu112: wu112 { + /omit-if-no-ref/ wuc_wu112: wu112 { wucs = <&wuc12 BIT(0)>; /* GPD5 */ }; - wuc_wu113: wu113 { + /omit-if-no-ref/ wuc_wu113: wu113 { wucs = <&wuc12 BIT(1)>; /* GPD6 */ }; - wuc_wu114: wu114 { + /omit-if-no-ref/ wuc_wu114: wu114 { wucs = <&wuc12 BIT(2)>; /* GPE4 */ }; - wuc_wu115: wu115 { + /omit-if-no-ref/ wuc_wu115: wu115 { wucs = <&wuc12 BIT(3)>; /* GPG0 */ }; - wuc_wu116: wu116 { + /omit-if-no-ref/ wuc_wu116: wu116 { wucs = <&wuc12 BIT(4)>; /* GPG1 */ }; - wuc_wu117: wu117 { + /omit-if-no-ref/ wuc_wu117: wu117 { wucs = <&wuc12 BIT(5)>; /* GPG2 */ }; - wuc_wu118: wu118 { + /omit-if-no-ref/ wuc_wu118: wu118 { wucs = <&wuc12 BIT(6)>; /* GPG6 */ }; - wuc_wu119: wu119 { + /omit-if-no-ref/ wuc_wu119: wu119 { wucs = <&wuc12 BIT(7)>; /* GPI0 */ }; /* WUC group 13 */ - wuc_wu120: wu120 { + /omit-if-no-ref/ wuc_wu120: wu120 { wucs = <&wuc13 BIT(0)>; /* GPI1 */ }; - wuc_wu121: wu121 { + /omit-if-no-ref/ wuc_wu121: wu121 { wucs = <&wuc13 BIT(1)>; /* GPI2 */ }; - wuc_wu122: wu122 { + /omit-if-no-ref/ wuc_wu122: wu122 { wucs = <&wuc13 BIT(2)>; /* GPI3 */ }; - wuc_wu127: wu127 { + /omit-if-no-ref/ wuc_wu127: wu127 { wucs = <&wuc13 BIT(7)>; /* GPH7 */ }; /* WUC group 14 */ - wuc_wu128: wu128 { + /omit-if-no-ref/ wuc_wu128: wu128 { wucs = <&wuc14 BIT(0)>; /* GPJ0 */ }; - wuc_wu129: wu129 { + /omit-if-no-ref/ wuc_wu129: wu129 { wucs = <&wuc14 BIT(1)>; /* GPJ1 */ }; - wuc_wu131: wu131 { + /omit-if-no-ref/ wuc_wu131: wu131 { wucs = <&wuc14 BIT(3)>; /* GPJ3 */ }; - wuc_wu132: wu132 { + /omit-if-no-ref/ wuc_wu132: wu132 { wucs = <&wuc14 BIT(4)>; /* GPJ4 */ }; - wuc_wu133: wu133 { + /omit-if-no-ref/ wuc_wu133: wu133 { wucs = <&wuc14 BIT(5)>; /* GPJ5 */ }; - wuc_wu134: wu134 { + /omit-if-no-ref/ wuc_wu134: wu134 { wucs = <&wuc14 BIT(6)>; /* GPJ6 */ }; - wuc_wu135: wu135 { + /omit-if-no-ref/ wuc_wu135: wu135 { wucs = <&wuc14 BIT(7)>; /* GPJ7 */ }; /* WUC group 15 */ - wuc_wu136: wu136 { + /omit-if-no-ref/ wuc_wu136: wu136 { wucs = <&wuc15 BIT(0)>; /* GPL0 */ }; - wuc_wu137: wu137 { + /omit-if-no-ref/ wuc_wu137: wu137 { wucs = <&wuc15 BIT(1)>; /* GPL1 */ }; - wuc_wu138: wu138 { + /omit-if-no-ref/ wuc_wu138: wu138 { wucs = <&wuc15 BIT(2)>; /* GPL2 */ }; - wuc_wu139: wu139 { + /omit-if-no-ref/ wuc_wu139: wu139 { wucs = <&wuc15 BIT(3)>; /* GPL3 */ }; - wuc_wu140: wu140 { + /omit-if-no-ref/ wuc_wu140: wu140 { wucs = <&wuc15 BIT(4)>; /* GPL4 */ }; - wuc_wu141: wu141 { + /omit-if-no-ref/ wuc_wu141: wu141 { wucs = <&wuc15 BIT(5)>; /* GPL5 */ }; - wuc_wu142: wu142 { + /omit-if-no-ref/ wuc_wu142: wu142 { wucs = <&wuc15 BIT(6)>; /* GPL6 */ }; /* WUC group 16 */ - wuc_wu144: wu144 { + /omit-if-no-ref/ wuc_wu144: wu144 { wucs = <&wuc16 BIT(0)>; /* GPM0 */ }; - wuc_wu145: wu145 { + /omit-if-no-ref/ wuc_wu145: wu145 { wucs = <&wuc16 BIT(1)>; /* GPM1 */ }; - wuc_wu146: wu146 { + /omit-if-no-ref/ wuc_wu146: wu146 { wucs = <&wuc16 BIT(2)>; /* GPM2 */ }; - wuc_wu147: wu147 { + /omit-if-no-ref/ wuc_wu147: wu147 { wucs = <&wuc16 BIT(3)>; /* GPM3 */ }; - wuc_wu148: wu148 { + /omit-if-no-ref/ wuc_wu148: wu148 { wucs = <&wuc16 BIT(4)>; /* GPM4 */ }; - wuc_wu149: wu149 { + /omit-if-no-ref/ wuc_wu149: wu149 { wucs = <&wuc16 BIT(5)>; /* GPM5 */ }; - wuc_wu150: wu150 { + /omit-if-no-ref/ wuc_wu150: wu150 { wucs = <&wuc16 BIT(6)>; /* GPM6 */ }; - wuc_no_func: no_func { + /omit-if-no-ref/ wuc_no_func: no_func { wucs = <&wuc_fake 0>; }; }; From e13971b79645ab93cefcd9923468bbb0e71dd550 Mon Sep 17 00:00:00 2001 From: Tim Lin Date: Wed, 21 Jan 2026 15:56:14 +0800 Subject: [PATCH 0242/6328] dts: ite/it8xxx2: Reduce devicetree size with omit-if-no-ref Mark unused pinctrl and wuc nodes in it8xxx2 with /omit-if-no-ref/, so that they are omitted from the final devicetree when not referenced. After this change, test: "west build -p always -b it8xxx2_evb" shows a reduction in devicetree size: Before: build/zephyr/zephyr.dts 164,449 bytes build/zephyr/include/generated/zephyr/devicetree_generated.h 3,125,359 bytes After: build/zephyr/zephyr.dts 124,108 bytes build/zephyr/include/generated/zephyr/devicetree_generated.h 1,892,313 bytes Signed-off-by: Tim Lin --- dts/riscv/ite/it8xxx2-pinctrl-map.dtsi | 240 ++++++++++++------------- dts/riscv/ite/it8xxx2-wuc-map.dtsi | 224 +++++++++++------------ 2 files changed, 232 insertions(+), 232 deletions(-) diff --git a/dts/riscv/ite/it8xxx2-pinctrl-map.dtsi b/dts/riscv/ite/it8xxx2-pinctrl-map.dtsi index 55cc27386f0c..258ed7442266 100644 --- a/dts/riscv/ite/it8xxx2-pinctrl-map.dtsi +++ b/dts/riscv/ite/it8xxx2-pinctrl-map.dtsi @@ -8,537 +8,537 @@ &pinctrl { /* ADC alternate function */ - adc0_ch0_gpi0_default: adc0_ch0_gpi0_default { + /omit-if-no-ref/ adc0_ch0_gpi0_default: adc0_ch0_gpi0_default { pinmuxs = <&pinctrli 0 IT8XXX2_ALT_FUNC_1>; }; - adc0_ch1_gpi1_default: adc0_ch1_gpi1_default { + /omit-if-no-ref/ adc0_ch1_gpi1_default: adc0_ch1_gpi1_default { pinmuxs = <&pinctrli 1 IT8XXX2_ALT_FUNC_1>; }; - adc0_ch2_gpi2_default: adc0_ch2_gpi2_default { + /omit-if-no-ref/ adc0_ch2_gpi2_default: adc0_ch2_gpi2_default { pinmuxs = <&pinctrli 2 IT8XXX2_ALT_FUNC_1>; }; - adc0_ch3_gpi3_default: adc0_ch3_gpi3_default { + /omit-if-no-ref/ adc0_ch3_gpi3_default: adc0_ch3_gpi3_default { pinmuxs = <&pinctrli 3 IT8XXX2_ALT_FUNC_1>; }; - adc0_ch4_gpi4_default: adc0_ch4_gpi4_default { + /omit-if-no-ref/ adc0_ch4_gpi4_default: adc0_ch4_gpi4_default { pinmuxs = <&pinctrli 4 IT8XXX2_ALT_FUNC_1>; }; - adc0_ch5_gpi5_default: adc0_ch5_gpi5_default { + /omit-if-no-ref/ adc0_ch5_gpi5_default: adc0_ch5_gpi5_default { pinmuxs = <&pinctrli 5 IT8XXX2_ALT_FUNC_1>; }; - adc0_ch6_gpi6_default: adc0_ch6_gpi6_default { + /omit-if-no-ref/ adc0_ch6_gpi6_default: adc0_ch6_gpi6_default { pinmuxs = <&pinctrli 6 IT8XXX2_ALT_FUNC_1>; }; - adc0_ch7_gpi7_default: adc0_ch7_gpi7_default { + /omit-if-no-ref/ adc0_ch7_gpi7_default: adc0_ch7_gpi7_default { pinmuxs = <&pinctrli 7 IT8XXX2_ALT_FUNC_1>; }; - adc0_ch13_gpl0_default: adc0_ch13_gpl0_default { + /omit-if-no-ref/ adc0_ch13_gpl0_default: adc0_ch13_gpl0_default { pinmuxs = <&pinctrll 0 IT8XXX2_ALT_FUNC_1>; }; - adc0_ch14_gpl1_default: adc0_ch14_gpl1_default { + /omit-if-no-ref/ adc0_ch14_gpl1_default: adc0_ch14_gpl1_default { pinmuxs = <&pinctrll 1 IT8XXX2_ALT_FUNC_1>; }; - adc0_ch15_gpl2_default: adc0_ch15_gpl2_default { + /omit-if-no-ref/ adc0_ch15_gpl2_default: adc0_ch15_gpl2_default { pinmuxs = <&pinctrll 2 IT8XXX2_ALT_FUNC_1>; }; - adc0_ch16_gpl3_default: adc0_ch16_gpl3_default { + /omit-if-no-ref/ adc0_ch16_gpl3_default: adc0_ch16_gpl3_default { pinmuxs = <&pinctrll 3 IT8XXX2_ALT_FUNC_1>; }; /* CEC alternate function */ - cec_gpf0_default: cec_gpf0_default { + /omit-if-no-ref/ cec_gpf0_default: cec_gpf0_default { pinmuxs = <&pinctrlf 0 IT8XXX2_ALT_FUNC_4>; }; - cec_gpf0_sleep: cec_gpf0_sleep { + /omit-if-no-ref/ cec_gpf0_sleep: cec_gpf0_sleep { pinmuxs = <&pinctrlf 0 IT8XXX2_ALT_DEFAULT>; }; /* I2C alternate function */ - i2c0_clk_gpb3_default: i2c0_clk_gpb3_default { + /omit-if-no-ref/ i2c0_clk_gpb3_default: i2c0_clk_gpb3_default { pinmuxs = <&pinctrlb 3 IT8XXX2_ALT_FUNC_1>; }; - i2c0_data_gpb4_default: i2c0_data_gpb4_default { + /omit-if-no-ref/ i2c0_data_gpb4_default: i2c0_data_gpb4_default { pinmuxs = <&pinctrlb 4 IT8XXX2_ALT_FUNC_1>; }; - i2c1_clk_gpc1_default: i2c1_clk_gpc1_default { + /omit-if-no-ref/ i2c1_clk_gpc1_default: i2c1_clk_gpc1_default { pinmuxs = <&pinctrlc 1 IT8XXX2_ALT_FUNC_1>; }; - i2c1_data_gpc2_default: i2c1_data_gpc2_default { + /omit-if-no-ref/ i2c1_data_gpc2_default: i2c1_data_gpc2_default { pinmuxs = <&pinctrlc 2 IT8XXX2_ALT_FUNC_1>; }; - i2c2_clk_gpf6_default: i2c2_clk_gpf6_default { + /omit-if-no-ref/ i2c2_clk_gpf6_default: i2c2_clk_gpf6_default { pinmuxs = <&pinctrlf 6 IT8XXX2_ALT_FUNC_1>; }; - i2c2_data_gpf7_default: i2c2_data_gpf7_default { + /omit-if-no-ref/ i2c2_data_gpf7_default: i2c2_data_gpf7_default { pinmuxs = <&pinctrlf 7 IT8XXX2_ALT_FUNC_1>; }; - i2c3_clk_gph1_default: i2c3_clk_gph1_default { + /omit-if-no-ref/ i2c3_clk_gph1_default: i2c3_clk_gph1_default { pinmuxs = <&pinctrlh 1 IT8XXX2_ALT_FUNC_3>; }; - i2c3_data_gph2_default: i2c3_data_gph2_default { + /omit-if-no-ref/ i2c3_data_gph2_default: i2c3_data_gph2_default { pinmuxs = <&pinctrlh 2 IT8XXX2_ALT_FUNC_3>; }; - i2c3_clk_gpf2_default: i2c3_clk_gpf2_default { + /omit-if-no-ref/ i2c3_clk_gpf2_default: i2c3_clk_gpf2_default { pinmuxs = <&pinctrlf 2 IT8XXX2_ALT_FUNC_4>; }; - i2c3_data_gpf3_default: i2c3_data_gpf3_default { + /omit-if-no-ref/ i2c3_data_gpf3_default: i2c3_data_gpf3_default { pinmuxs = <&pinctrlf 3 IT8XXX2_ALT_FUNC_4>; }; - i2c4_clk_gpe0_default: i2c4_clk_gpe0_default { + /omit-if-no-ref/ i2c4_clk_gpe0_default: i2c4_clk_gpe0_default { pinmuxs = <&pinctrle 0 IT8XXX2_ALT_FUNC_3>; }; - i2c4_data_gpe7_default: i2c4_data_gpe7_default { + /omit-if-no-ref/ i2c4_data_gpe7_default: i2c4_data_gpe7_default { pinmuxs = <&pinctrle 7 IT8XXX2_ALT_FUNC_3>; }; - i2c5_clk_gpa4_default: i2c5_clk_gpa4_default { + /omit-if-no-ref/ i2c5_clk_gpa4_default: i2c5_clk_gpa4_default { pinmuxs = <&pinctrla 4 IT8XXX2_ALT_FUNC_3>; }; - i2c5_data_gpa5_default: i2c5_data_gpa5_default { + /omit-if-no-ref/ i2c5_data_gpa5_default: i2c5_data_gpa5_default { pinmuxs = <&pinctrla 5 IT8XXX2_ALT_FUNC_3>; }; /* I2C alternate function (Mapping pins for IT82XX2) */ - i2c2_clk_gpc7_default: i2c2_clk_gpc7_default { + /omit-if-no-ref/ i2c2_clk_gpc7_default: i2c2_clk_gpc7_default { pinmuxs = <&pinctrlc 7 IT8XXX2_ALT_FUNC_4>; }; - i2c2_data_gpd0_default: i2c2_data_gpd0_default { + /omit-if-no-ref/ i2c2_data_gpd0_default: i2c2_data_gpd0_default { pinmuxs = <&pinctrld 0 IT8XXX2_ALT_FUNC_4>; }; - i2c3_clk_gpb2_default: i2c3_clk_gpb2_default { + /omit-if-no-ref/ i2c3_clk_gpb2_default: i2c3_clk_gpb2_default { pinmuxs = <&pinctrlb 2 IT8XXX2_ALT_FUNC_3>; }; - i2c3_data_gpb5_default: i2c3_data_gpb5_default { + /omit-if-no-ref/ i2c3_data_gpb5_default: i2c3_data_gpb5_default { pinmuxs = <&pinctrlb 5 IT8XXX2_ALT_FUNC_3>; }; - i2c5_clk_gpe1_default: i2c5_clk_gpe1_default { + /omit-if-no-ref/ i2c5_clk_gpe1_default: i2c5_clk_gpe1_default { pinmuxs = <&pinctrle 1 IT8XXX2_ALT_FUNC_3>; }; - i2c5_data_gpe2_default: i2c5_data_gpe2_default { + /omit-if-no-ref/ i2c5_data_gpe2_default: i2c5_data_gpe2_default { pinmuxs = <&pinctrle 2 IT8XXX2_ALT_FUNC_3>; }; /* Keyboard alternate function */ - ksi0_default: ksi0_default { + /omit-if-no-ref/ ksi0_default: ksi0_default { pinmuxs = <&pinctrlksi 0 IT8XXX2_ALT_FUNC_1>; bias-pull-up; }; - ksi1_default: ksi1_default { + /omit-if-no-ref/ ksi1_default: ksi1_default { pinmuxs = <&pinctrlksi 1 IT8XXX2_ALT_FUNC_1>; bias-pull-up; }; - ksi2_default: ksi2_default { + /omit-if-no-ref/ ksi2_default: ksi2_default { pinmuxs = <&pinctrlksi 2 IT8XXX2_ALT_FUNC_1>; bias-pull-up; }; - ksi3_default: ksi3_default { + /omit-if-no-ref/ ksi3_default: ksi3_default { pinmuxs = <&pinctrlksi 3 IT8XXX2_ALT_FUNC_1>; bias-pull-up; }; - ksi4_default: ksi4_default { + /omit-if-no-ref/ ksi4_default: ksi4_default { pinmuxs = <&pinctrlksi 4 IT8XXX2_ALT_FUNC_1>; bias-pull-up; }; - ksi5_default: ksi5_default { + /omit-if-no-ref/ ksi5_default: ksi5_default { pinmuxs = <&pinctrlksi 5 IT8XXX2_ALT_FUNC_1>; bias-pull-up; }; - ksi6_default: ksi6_default { + /omit-if-no-ref/ ksi6_default: ksi6_default { pinmuxs = <&pinctrlksi 6 IT8XXX2_ALT_FUNC_1>; bias-pull-up; }; - ksi7_default: ksi7_default { + /omit-if-no-ref/ ksi7_default: ksi7_default { pinmuxs = <&pinctrlksi 7 IT8XXX2_ALT_FUNC_1>; bias-pull-up; }; - kso0_default: kso0_default { + /omit-if-no-ref/ kso0_default: kso0_default { pinmuxs = <&pinctrlksol 0 IT8XXX2_ALT_FUNC_1>; drive-open-drain; bias-pull-up; }; - kso1_default: kso1_default { + /omit-if-no-ref/ kso1_default: kso1_default { pinmuxs = <&pinctrlksol 1 IT8XXX2_ALT_FUNC_1>; drive-open-drain; bias-pull-up; }; - kso2_default: kso2_default { + /omit-if-no-ref/ kso2_default: kso2_default { pinmuxs = <&pinctrlksol 2 IT8XXX2_ALT_FUNC_1>; drive-open-drain; bias-pull-up; }; - kso3_default: kso3_default { + /omit-if-no-ref/ kso3_default: kso3_default { pinmuxs = <&pinctrlksol 3 IT8XXX2_ALT_FUNC_1>; drive-open-drain; bias-pull-up; }; - kso4_default: kso4_default { + /omit-if-no-ref/ kso4_default: kso4_default { pinmuxs = <&pinctrlksol 4 IT8XXX2_ALT_FUNC_1>; drive-open-drain; bias-pull-up; }; - kso5_default: kso5_default { + /omit-if-no-ref/ kso5_default: kso5_default { pinmuxs = <&pinctrlksol 5 IT8XXX2_ALT_FUNC_1>; drive-open-drain; bias-pull-up; }; - kso6_default: kso6_default { + /omit-if-no-ref/ kso6_default: kso6_default { pinmuxs = <&pinctrlksol 6 IT8XXX2_ALT_FUNC_1>; drive-open-drain; bias-pull-up; }; - kso7_default: kso7_default { + /omit-if-no-ref/ kso7_default: kso7_default { pinmuxs = <&pinctrlksol 7 IT8XXX2_ALT_FUNC_1>; drive-open-drain; bias-pull-up; }; - kso8_default: kso8_default { + /omit-if-no-ref/ kso8_default: kso8_default { pinmuxs = <&pinctrlksoh 0 IT8XXX2_ALT_FUNC_1>; drive-open-drain; bias-pull-up; }; - kso9_default: kso9_default { + /omit-if-no-ref/ kso9_default: kso9_default { pinmuxs = <&pinctrlksoh 1 IT8XXX2_ALT_FUNC_1>; drive-open-drain; bias-pull-up; }; - kso10_default: kso10_default { + /omit-if-no-ref/ kso10_default: kso10_default { pinmuxs = <&pinctrlksoh 2 IT8XXX2_ALT_FUNC_1>; drive-open-drain; bias-pull-up; }; - kso11_default: kso11_default { + /omit-if-no-ref/ kso11_default: kso11_default { pinmuxs = <&pinctrlksoh 3 IT8XXX2_ALT_FUNC_1>; drive-open-drain; bias-pull-up; }; - kso12_default: kso12_default { + /omit-if-no-ref/ kso12_default: kso12_default { pinmuxs = <&pinctrlksoh 4 IT8XXX2_ALT_FUNC_1>; drive-open-drain; bias-pull-up; }; - kso13_default: kso13_default { + /omit-if-no-ref/ kso13_default: kso13_default { pinmuxs = <&pinctrlksoh 5 IT8XXX2_ALT_FUNC_1>; drive-open-drain; bias-pull-up; }; - kso14_default: kso14_default { + /omit-if-no-ref/ kso14_default: kso14_default { pinmuxs = <&pinctrlksoh 6 IT8XXX2_ALT_FUNC_1>; drive-open-drain; bias-pull-up; }; - kso15_default: kso15_default { + /omit-if-no-ref/ kso15_default: kso15_default { pinmuxs = <&pinctrlksoh 7 IT8XXX2_ALT_FUNC_1>; drive-open-drain; bias-pull-up; }; - kso16_default: kso16_gpc3_default: kso16_default { + /omit-if-no-ref/ kso16_default: kso16_gpc3_default: kso16_default { pinmuxs = <&pinctrlc 3 IT8XXX2_ALT_FUNC_1>; bias-pull-up; }; - kso17_default: kso17_gpc5_default: kso17_default { + /omit-if-no-ref/ kso17_default: kso17_gpc5_default: kso17_default { pinmuxs = <&pinctrlc 5 IT8XXX2_ALT_FUNC_1>; bias-pull-up; }; /* Keyboard sleep function */ - ksi0_sleep: ksi0_sleep { + /omit-if-no-ref/ ksi0_sleep: ksi0_sleep { pinmuxs = <&pinctrlksi 0 IT8XXX2_ALT_DEFAULT>; }; - ksi1_sleep: ksi1_sleep { + /omit-if-no-ref/ ksi1_sleep: ksi1_sleep { pinmuxs = <&pinctrlksi 1 IT8XXX2_ALT_DEFAULT>; }; - ksi2_sleep: ksi2_sleep { + /omit-if-no-ref/ ksi2_sleep: ksi2_sleep { pinmuxs = <&pinctrlksi 2 IT8XXX2_ALT_DEFAULT>; }; - ksi3_sleep: ksi3_sleep { + /omit-if-no-ref/ ksi3_sleep: ksi3_sleep { pinmuxs = <&pinctrlksi 3 IT8XXX2_ALT_DEFAULT>; }; - ksi4_sleep: ksi4_sleep { + /omit-if-no-ref/ ksi4_sleep: ksi4_sleep { pinmuxs = <&pinctrlksi 4 IT8XXX2_ALT_DEFAULT>; }; - ksi5_sleep: ksi5_sleep { + /omit-if-no-ref/ ksi5_sleep: ksi5_sleep { pinmuxs = <&pinctrlksi 5 IT8XXX2_ALT_DEFAULT>; }; - ksi6_sleep: ksi6_sleep { + /omit-if-no-ref/ ksi6_sleep: ksi6_sleep { pinmuxs = <&pinctrlksi 6 IT8XXX2_ALT_DEFAULT>; }; - ksi7_sleep: ksi7_sleep { + /omit-if-no-ref/ ksi7_sleep: ksi7_sleep { pinmuxs = <&pinctrlksi 7 IT8XXX2_ALT_DEFAULT>; }; - kso0_sleep: kso0_sleep { + /omit-if-no-ref/ kso0_sleep: kso0_sleep { pinmuxs = <&pinctrlksol 0 IT8XXX2_ALT_DEFAULT>; }; - kso1_sleep: kso1_sleep { + /omit-if-no-ref/ kso1_sleep: kso1_sleep { pinmuxs = <&pinctrlksol 1 IT8XXX2_ALT_DEFAULT>; }; - kso2_sleep: kso2_sleep { + /omit-if-no-ref/ kso2_sleep: kso2_sleep { pinmuxs = <&pinctrlksol 2 IT8XXX2_ALT_DEFAULT>; }; - kso3_sleep: kso3_sleep { + /omit-if-no-ref/ kso3_sleep: kso3_sleep { pinmuxs = <&pinctrlksol 3 IT8XXX2_ALT_DEFAULT>; }; - kso4_sleep: kso4_sleep { + /omit-if-no-ref/ kso4_sleep: kso4_sleep { pinmuxs = <&pinctrlksol 4 IT8XXX2_ALT_DEFAULT>; }; - kso5_sleep: kso5_sleep { + /omit-if-no-ref/ kso5_sleep: kso5_sleep { pinmuxs = <&pinctrlksol 5 IT8XXX2_ALT_DEFAULT>; }; - kso6_sleep: kso6_sleep { + /omit-if-no-ref/ kso6_sleep: kso6_sleep { pinmuxs = <&pinctrlksol 6 IT8XXX2_ALT_DEFAULT>; }; - kso7_sleep: kso7_sleep { + /omit-if-no-ref/ kso7_sleep: kso7_sleep { pinmuxs = <&pinctrlksol 7 IT8XXX2_ALT_DEFAULT>; }; - kso8_sleep: kso8_sleep { + /omit-if-no-ref/ kso8_sleep: kso8_sleep { pinmuxs = <&pinctrlksoh 0 IT8XXX2_ALT_DEFAULT>; }; - kso9_sleep: kso9_sleep { + /omit-if-no-ref/ kso9_sleep: kso9_sleep { pinmuxs = <&pinctrlksoh 1 IT8XXX2_ALT_DEFAULT>; }; - kso10_sleep: kso10_sleep { + /omit-if-no-ref/ kso10_sleep: kso10_sleep { pinmuxs = <&pinctrlksoh 2 IT8XXX2_ALT_DEFAULT>; }; - kso11_sleep: kso11_sleep { + /omit-if-no-ref/ kso11_sleep: kso11_sleep { pinmuxs = <&pinctrlksoh 3 IT8XXX2_ALT_DEFAULT>; }; - kso12_sleep: kso12_sleep { + /omit-if-no-ref/ kso12_sleep: kso12_sleep { pinmuxs = <&pinctrlksoh 4 IT8XXX2_ALT_DEFAULT>; }; - kso13_sleep: kso13_sleep { + /omit-if-no-ref/ kso13_sleep: kso13_sleep { pinmuxs = <&pinctrlksoh 5 IT8XXX2_ALT_DEFAULT>; }; - kso14_sleep: kso14_sleep { + /omit-if-no-ref/ kso14_sleep: kso14_sleep { pinmuxs = <&pinctrlksoh 6 IT8XXX2_ALT_DEFAULT>; }; - kso15_sleep: kso15_sleep { + /omit-if-no-ref/ kso15_sleep: kso15_sleep { pinmuxs = <&pinctrlksoh 7 IT8XXX2_ALT_DEFAULT>; }; - kso16_sleep: kso16_gpc3_sleep: kso16_sleep { + /omit-if-no-ref/ kso16_sleep: kso16_gpc3_sleep: kso16_sleep { pinmuxs = <&pinctrlc 3 IT8XXX2_ALT_DEFAULT>; }; - kso17_sleep: kso17_gpc5_sleep: kso17_sleep { + /omit-if-no-ref/ kso17_sleep: kso17_gpc5_sleep: kso17_sleep { pinmuxs = <&pinctrlc 5 IT8XXX2_ALT_DEFAULT>; }; /* PECI alternate function */ - peci_gpf6_default: peci_gpf6_default { + /omit-if-no-ref/ peci_gpf6_default: peci_gpf6_default { pinmuxs = <&pinctrlf 6 IT8XXX2_ALT_FUNC_3>; }; /* PWM alternate function */ - pwm0_gpa0_default: pwm0_gpa0_default { + /omit-if-no-ref/ pwm0_gpa0_default: pwm0_gpa0_default { pinmuxs = <&pinctrla 0 IT8XXX2_ALT_FUNC_1>; }; - pwm1_gpa1_default: pwm1_gpa1_default { + /omit-if-no-ref/ pwm1_gpa1_default: pwm1_gpa1_default { pinmuxs = <&pinctrla 1 IT8XXX2_ALT_FUNC_1>; }; - pwm2_gpa2_default: pwm2_gpa2_default { + /omit-if-no-ref/ pwm2_gpa2_default: pwm2_gpa2_default { pinmuxs = <&pinctrla 2 IT8XXX2_ALT_FUNC_1>; }; - pwm3_gpa3_default: pwm3_gpa3_default { + /omit-if-no-ref/ pwm3_gpa3_default: pwm3_gpa3_default { pinmuxs = <&pinctrla 3 IT8XXX2_ALT_FUNC_1>; }; - pwm4_gpa4_default: pwm4_gpa4_default { + /omit-if-no-ref/ pwm4_gpa4_default: pwm4_gpa4_default { pinmuxs = <&pinctrla 4 IT8XXX2_ALT_FUNC_1>; }; - pwm5_gpa5_default: pwm5_gpa5_default { + /omit-if-no-ref/ pwm5_gpa5_default: pwm5_gpa5_default { pinmuxs = <&pinctrla 5 IT8XXX2_ALT_FUNC_1>; }; - pwm6_gpa6_default: pwm6_gpa6_default { + /omit-if-no-ref/ pwm6_gpa6_default: pwm6_gpa6_default { pinmuxs = <&pinctrla 6 IT8XXX2_ALT_FUNC_1>; }; - pwm7_gpa7_default: pwm7_gpa7_default { + /omit-if-no-ref/ pwm7_gpa7_default: pwm7_gpa7_default { pinmuxs = <&pinctrla 7 IT8XXX2_ALT_FUNC_1>; }; /* SHI alternate function */ - shi_mosi_gpm0_default: shi_mosi_gpm0_default { + /omit-if-no-ref/ shi_mosi_gpm0_default: shi_mosi_gpm0_default { pinmuxs = <&pinctrlm 0 IT8XXX2_ALT_FUNC_1>; }; - shi_miso_gpm1_default: shi_miso_gpm1_default { + /omit-if-no-ref/ shi_miso_gpm1_default: shi_miso_gpm1_default { pinmuxs = <&pinctrlm 1 IT8XXX2_ALT_FUNC_1>; }; - shi_clk_gpm4_default: shi_clk_gpm4_default { + /omit-if-no-ref/ shi_clk_gpm4_default: shi_clk_gpm4_default { pinmuxs = <&pinctrlm 4 IT8XXX2_ALT_FUNC_1>; }; - shi_cs_gpm5_default: shi_cs_gpm5_default { + /omit-if-no-ref/ shi_cs_gpm5_default: shi_cs_gpm5_default { pinmuxs = <&pinctrlm 5 IT8XXX2_ALT_FUNC_1>; }; /* Tachometer alternate function */ - tach0a_gpd6_default: tach0a_gpd6_default { + /omit-if-no-ref/ tach0a_gpd6_default: tach0a_gpd6_default { pinmuxs = <&pinctrld 6 IT8XXX2_ALT_FUNC_1>; }; - tach0b_gpj2_default: tach0b_gpj2_default { + /omit-if-no-ref/ tach0b_gpj2_default: tach0b_gpj2_default { pinmuxs = <&pinctrlj 2 IT8XXX2_ALT_FUNC_3>; }; - tach1a_gpd7_default: tach1a_gpd7_default { + /omit-if-no-ref/ tach1a_gpd7_default: tach1a_gpd7_default { pinmuxs = <&pinctrld 7 IT8XXX2_ALT_FUNC_1>; }; - tach1b_gpj3_default: tach1b_gpj3_default { + /omit-if-no-ref/ tach1b_gpj3_default: tach1b_gpj3_default { pinmuxs = <&pinctrlj 3 IT8XXX2_ALT_FUNC_3>; }; /* UART alternate function */ - uart1_rx_gpb0_default: uart1_rx_gpb0_default { + /omit-if-no-ref/ uart1_rx_gpb0_default: uart1_rx_gpb0_default { pinmuxs = <&pinctrlb 0 IT8XXX2_ALT_FUNC_3>; }; - uart1_tx_gpb1_default: uart1_tx_gpb1_default { + /omit-if-no-ref/ uart1_tx_gpb1_default: uart1_tx_gpb1_default { pinmuxs = <&pinctrlb 1 IT8XXX2_ALT_FUNC_3>; }; - uart2_rx_gph1_default: uart2_rx_gph1_default { + /omit-if-no-ref/ uart2_rx_gph1_default: uart2_rx_gph1_default { pinmuxs = <&pinctrlh 1 IT8XXX2_ALT_FUNC_4>; }; - uart2_tx_gph2_default: uart2_tx_gph2_default { + /omit-if-no-ref/ uart2_tx_gph2_default: uart2_tx_gph2_default { pinmuxs = <&pinctrlh 2 IT8XXX2_ALT_FUNC_4>; }; - uart2_rx_gph5_default: uart2_rx_gph5_default { + /omit-if-no-ref/ uart2_rx_gph5_default: uart2_rx_gph5_default { pinmuxs = <&pinctrlh 5 IT8XXX2_ALT_FUNC_3>; }; - uart2_tx_gph6_default: uart2_tx_gph6_default { + /omit-if-no-ref/ uart2_tx_gph6_default: uart2_tx_gph6_default { pinmuxs = <&pinctrlh 6 IT8XXX2_ALT_FUNC_3>; }; - uart2_rx_gpf0_default: uart2_rx_gpf0_default { + /omit-if-no-ref/ uart2_rx_gpf0_default: uart2_rx_gpf0_default { pinmuxs = <&pinctrlf 0 IT8XXX2_ALT_FUNC_3>; }; - uart2_tx_gpf1_default: uart2_tx_gpf1_default { + /omit-if-no-ref/ uart2_tx_gpf1_default: uart2_tx_gpf1_default { pinmuxs = <&pinctrlf 1 IT8XXX2_ALT_FUNC_3>; }; /* USB alternate function */ - usb0_dm_gph5_default: usb0_dm_gph5_default { + /omit-if-no-ref/ usb0_dm_gph5_default: usb0_dm_gph5_default { pinmuxs = <&pinctrlh 5 IT8XXX2_ALT_DEFAULT>; }; - usb0_dp_gph6_default: usb0_dp_gph6_default { + /omit-if-no-ref/ usb0_dp_gph6_default: usb0_dp_gph6_default { pinmuxs = <&pinctrlh 6 IT8XXX2_ALT_DEFAULT>; }; /* SPI alternate function */ - spi_ssce0_default: spi_ssce0_default { + /omit-if-no-ref/ spi_ssce0_default: spi_ssce0_default { pinmuxs = <&pinctrlg 2 IT8XXX2_ALT_FUNC_3>; }; - spi_ssce1_default: spi_ssce1_default { + /omit-if-no-ref/ spi_ssce1_default: spi_ssce1_default { pinmuxs = <&pinctrlg 0 IT8XXX2_ALT_FUNC_3>; }; - spi_ssck_default: spi_ssck_default { + /omit-if-no-ref/ spi_ssck_default: spi_ssck_default { pinmuxs = <&pinctrla 6 IT8XXX2_ALT_FUNC_3>; }; - spi_smosi_default: spi_smosi_default { + /omit-if-no-ref/ spi_smosi_default: spi_smosi_default { pinmuxs = <&pinctrlc 3 IT8XXX2_ALT_FUNC_3>; }; - spi_smiso_default: spi_smiso_default { + /omit-if-no-ref/ spi_smiso_default: spi_smiso_default { pinmuxs = <&pinctrlc 5 IT8XXX2_ALT_FUNC_3>; }; - spi_sio2_default: spi_sio2_default { + /omit-if-no-ref/ spi_sio2_default: spi_sio2_default { pinmuxs = <&pinctrlc 0 IT8XXX2_ALT_FUNC_1>; }; - spi_sio3_default: spi_sio3_default { + /omit-if-no-ref/ spi_sio3_default: spi_sio3_default { pinmuxs = <&pinctrlc 6 IT8XXX2_ALT_FUNC_1>; }; }; diff --git a/dts/riscv/ite/it8xxx2-wuc-map.dtsi b/dts/riscv/ite/it8xxx2-wuc-map.dtsi index 6337add5b29f..8fe0f2d7d2f0 100644 --- a/dts/riscv/ite/it8xxx2-wuc-map.dtsi +++ b/dts/riscv/ite/it8xxx2-wuc-map.dtsi @@ -12,465 +12,465 @@ compatible = "ite,it8xxx2-wuc-map"; /* WUC group 2 */ - wuc_wu20: wu20 { + /omit-if-no-ref/ wuc_wu20: wu20 { wucs = <&wuc2 BIT(0)>; /* GPD0 */ }; - wuc_wu21: wu21 { + /omit-if-no-ref/ wuc_wu21: wu21 { wucs = <&wuc2 BIT(1)>; /* GPD1 */ }; - wuc_wu22: wu22 { + /omit-if-no-ref/ wuc_wu22: wu22 { wucs = <&wuc2 BIT(2)>; /* GPC4 */ }; - wuc_wu23: wu23 { + /omit-if-no-ref/ wuc_wu23: wu23 { wucs = <&wuc2 BIT(3)>; /* GPC6 */ }; - wuc_wu24: wu24 { + /omit-if-no-ref/ wuc_wu24: wu24 { wucs = <&wuc2 BIT(4)>; /* GPD2 */ }; - wuc_wu25: wu25 { + /omit-if-no-ref/ wuc_wu25: wu25 { wucs = <&wuc2 BIT(5)>; /* GPE4 */ }; /* WUC group 3 */ - wuc_wu30: wu30 { + /omit-if-no-ref/ wuc_wu30: wu30 { wucs = <&wuc3 BIT(0)>; /* KSI[0] */ }; - wuc_wu31: wu31 { + /omit-if-no-ref/ wuc_wu31: wu31 { wucs = <&wuc3 BIT(1)>; /* KSI[1] */ }; - wuc_wu32: wu32 { + /omit-if-no-ref/ wuc_wu32: wu32 { wucs = <&wuc3 BIT(2)>; /* KSI[2] */ }; - wuc_wu33: wu33 { + /omit-if-no-ref/ wuc_wu33: wu33 { wucs = <&wuc3 BIT(3)>; /* KSI[3] */ }; - wuc_wu34: wu34 { + /omit-if-no-ref/ wuc_wu34: wu34 { wucs = <&wuc3 BIT(4)>; /* KSI[4] */ }; - wuc_wu35: wu35 { + /omit-if-no-ref/ wuc_wu35: wu35 { wucs = <&wuc3 BIT(5)>; /* KSI[5] */ }; - wuc_wu36: wu36 { + /omit-if-no-ref/ wuc_wu36: wu36 { wucs = <&wuc3 BIT(6)>; /* KSI[6] */ }; - wuc_wu37: wu37 { + /omit-if-no-ref/ wuc_wu37: wu37 { wucs = <&wuc3 BIT(7)>; /* KSI[7] */ }; /* WUC group 4 */ - wuc_wu40: wu40 { + /omit-if-no-ref/ wuc_wu40: wu40 { wucs = <&wuc4 BIT(0)>; /* GPE5 */ }; - wuc_wu42: wu42 { + /omit-if-no-ref/ wuc_wu42: wu42 { wucs = <&wuc4 BIT(2)>; /* eSPI transaction */ }; - wuc_wu45: wu45 { + /omit-if-no-ref/ wuc_wu45: wu45 { wucs = <&wuc4 BIT(5)>; /* GPE6 */ }; - wuc_wu46: wu46 { + /omit-if-no-ref/ wuc_wu46: wu46 { wucs = <&wuc4 BIT(6)>; /* GPE7 */ }; /* WUC group 5 */ - wuc_wu50: wu50 { + /omit-if-no-ref/ wuc_wu50: wu50 { wucs = <&wuc5 BIT(0)>; /* GPK0 */ }; - wuc_wu51: wu51 { + /omit-if-no-ref/ wuc_wu51: wu51 { wucs = <&wuc5 BIT(1)>; /* GPK1 */ }; - wuc_wu52: wu52 { + /omit-if-no-ref/ wuc_wu52: wu52 { wucs = <&wuc5 BIT(2)>; /* GPK2 */ }; - wuc_wu53: wu53 { + /omit-if-no-ref/ wuc_wu53: wu53 { wucs = <&wuc5 BIT(3)>; /* GPK3 */ }; - wuc_wu54: wu54 { + /omit-if-no-ref/ wuc_wu54: wu54 { wucs = <&wuc5 BIT(4)>; /* GPK4 */ }; - wuc_wu55: wu55 { + /omit-if-no-ref/ wuc_wu55: wu55 { wucs = <&wuc5 BIT(5)>; /* GPK5 */ }; - wuc_wu56: wu56 { + /omit-if-no-ref/ wuc_wu56: wu56 { wucs = <&wuc5 BIT(6)>; /* GPK6 */ }; - wuc_wu57: wu57 { + /omit-if-no-ref/ wuc_wu57: wu57 { wucs = <&wuc5 BIT(7)>; /* GPK7 */ }; /* WUC group 6 */ - wuc_wu60: wu60 { + /omit-if-no-ref/ wuc_wu60: wu60 { wucs = <&wuc6 BIT(0)>; /* GPH0 */ }; - wuc_wu61: wu61 { + /omit-if-no-ref/ wuc_wu61: wu61 { wucs = <&wuc6 BIT(1)>; /* GPH1 */ }; - wuc_wu62: wu62 { + /omit-if-no-ref/ wuc_wu62: wu62 { wucs = <&wuc6 BIT(2)>; /* GPH2 */ }; - wuc_wu63: wu63 { + /omit-if-no-ref/ wuc_wu63: wu63 { wucs = <&wuc6 BIT(3)>; /* GPH3 */ }; - wuc_wu64: wu64 { + /omit-if-no-ref/ wuc_wu64: wu64 { wucs = <&wuc6 BIT(4)>; /* GPF4 */ }; - wuc_wu65: wu65 { + /omit-if-no-ref/ wuc_wu65: wu65 { wucs = <&wuc6 BIT(5)>; /* GPF5 */ }; - wuc_wu66: wu66 { + /omit-if-no-ref/ wuc_wu66: wu66 { wucs = <&wuc6 BIT(6)>; /* GPF6 */ }; - wuc_wu67: wu67 { + /omit-if-no-ref/ wuc_wu67: wu67 { wucs = <&wuc6 BIT(7)>; /* GPF7 */ }; /* WUC group 7 */ - wuc_wu70: wu70 { + /omit-if-no-ref/ wuc_wu70: wu70 { wucs = <&wuc7 BIT(0)>; /* GPE0 */ }; - wuc_wu71: wu71 { + /omit-if-no-ref/ wuc_wu71: wu71 { wucs = <&wuc7 BIT(1)>; /* GPE1 */ }; - wuc_wu72: wu72 { + /omit-if-no-ref/ wuc_wu72: wu72 { wucs = <&wuc7 BIT(2)>; /* GPE2 */ }; - wuc_wu73: wu73 { + /omit-if-no-ref/ wuc_wu73: wu73 { wucs = <&wuc7 BIT(3)>; /* GPE3 */ }; - wuc_wu74: wu74 { + /omit-if-no-ref/ wuc_wu74: wu74 { wucs = <&wuc7 BIT(4)>; /* GPI4 */ }; - wuc_wu75: wu75 { + /omit-if-no-ref/ wuc_wu75: wu75 { wucs = <&wuc7 BIT(5)>; /* GPI5 */ }; - wuc_wu76: wu76 { + /omit-if-no-ref/ wuc_wu76: wu76 { wucs = <&wuc7 BIT(6)>; /* GPI6 */ }; - wuc_wu77: wu77 { + /omit-if-no-ref/ wuc_wu77: wu77 { wucs = <&wuc7 BIT(7)>; /* GPI7 */ }; /* WUC group 8 */ - wuc_wu80: wu80 { + /omit-if-no-ref/ wuc_wu80: wu80 { wucs = <&wuc8 BIT(0)>; /* GPA3 */ }; - wuc_wu81: wu81 { + /omit-if-no-ref/ wuc_wu81: wu81 { wucs = <&wuc8 BIT(1)>; /* GPA4 */ }; - wuc_wu82: wu82 { + /omit-if-no-ref/ wuc_wu82: wu82 { wucs = <&wuc8 BIT(2)>; /* GPA5 */ }; - wuc_wu83: wu83 { + /omit-if-no-ref/ wuc_wu83: wu83 { wucs = <&wuc8 BIT(3)>; /* GPA6 */ }; - wuc_wu84: wu84 { + /omit-if-no-ref/ wuc_wu84: wu84 { wucs = <&wuc8 BIT(4)>; /* GPB2 */ }; - wuc_wu85: wu85 { + /omit-if-no-ref/ wuc_wu85: wu85 { wucs = <&wuc8 BIT(5)>; /* GPC0 */ }; - wuc_wu86: wu86 { + /omit-if-no-ref/ wuc_wu86: wu86 { wucs = <&wuc8 BIT(6)>; /* GPC7 */ }; - wuc_wu87: wu87 { + /omit-if-no-ref/ wuc_wu87: wu87 { wucs = <&wuc8 BIT(7)>; /* GPD7 */ }; /* WUC group 9 */ - wuc_wu88: wu88 { + /omit-if-no-ref/ wuc_wu88: wu88 { wucs = <&wuc9 BIT(0)>; /* GPH4 */ }; - wuc_wu89: wu89 { + /omit-if-no-ref/ wuc_wu89: wu89 { wucs = <&wuc9 BIT(1)>; /* GPH5 */ }; - wuc_wu90: wu90 { + /omit-if-no-ref/ wuc_wu90: wu90 { wucs = <&wuc9 BIT(2)>; /* GPH6 */ }; - wuc_wu91: wu91 { + /omit-if-no-ref/ wuc_wu91: wu91 { wucs = <&wuc9 BIT(3)>; /* GPA0 */ }; - wuc_wu92: wu92 { + /omit-if-no-ref/ wuc_wu92: wu92 { wucs = <&wuc9 BIT(4)>; /* GPA1 */ }; - wuc_wu93: wu93 { + /omit-if-no-ref/ wuc_wu93: wu93 { wucs = <&wuc9 BIT(5)>; /* GPA2 */ }; - wuc_wu94: wu94 { + /omit-if-no-ref/ wuc_wu94: wu94 { wucs = <&wuc9 BIT(6)>; /* GPB4 */ }; - wuc_wu95: wu95 { + /omit-if-no-ref/ wuc_wu95: wu95 { wucs = <&wuc9 BIT(7)>; /* GPC2 */ }; /* WUC group 10 */ - wuc_wu96: wu96 { + /omit-if-no-ref/ wuc_wu96: wu96 { wucs = <&wuc10 BIT(0)>; /* GPF0 */ }; - wuc_wu97: wu97 { + /omit-if-no-ref/ wuc_wu97: wu97 { wucs = <&wuc10 BIT(1)>; /* GPF1 */ }; - wuc_wu98: wu98 { + /omit-if-no-ref/ wuc_wu98: wu98 { wucs = <&wuc10 BIT(2)>; /* GPF2 */ }; - wuc_wu99: wu99 { + /omit-if-no-ref/ wuc_wu99: wu99 { wucs = <&wuc10 BIT(3)>; /* GPF3 */ }; - wuc_wu100: wu100 { + /omit-if-no-ref/ wuc_wu100: wu100 { wucs = <&wuc10 BIT(4)>; /* GPA7 */ }; - wuc_wu101: wu101 { + /omit-if-no-ref/ wuc_wu101: wu101 { wucs = <&wuc10 BIT(5)>; /* GPB0 */ }; - wuc_wu102: wu102 { + /omit-if-no-ref/ wuc_wu102: wu102 { wucs = <&wuc10 BIT(6)>; /* GPB1 */ }; - wuc_wu103: wu103 { + /omit-if-no-ref/ wuc_wu103: wu103 { wucs = <&wuc10 BIT(7)>; /* GPB3 */ }; /* WUC group 11 */ - wuc_wu104: wu104 { + /omit-if-no-ref/ wuc_wu104: wu104 { wucs = <&wuc11 BIT(0)>; /* GPB5 */ }; - wuc_wu105: wu105 { + /omit-if-no-ref/ wuc_wu105: wu105 { wucs = <&wuc11 BIT(1)>; /* GPB6 */ }; - wuc_wu106: wu106 { + /omit-if-no-ref/ wuc_wu106: wu106 { wucs = <&wuc11 BIT(2)>; /* GPB7 */ }; - wuc_wu107: wu107 { + /omit-if-no-ref/ wuc_wu107: wu107 { wucs = <&wuc11 BIT(3)>; /* GPC1 */ }; - wuc_wu108: wu108 { + /omit-if-no-ref/ wuc_wu108: wu108 { wucs = <&wuc11 BIT(4)>; /* GPC3 */ }; - wuc_wu109: wu109 { + /omit-if-no-ref/ wuc_wu109: wu109 { wucs = <&wuc11 BIT(5)>; /* GPC5 */ }; - wuc_wu110: wu110 { + /omit-if-no-ref/ wuc_wu110: wu110 { wucs = <&wuc11 BIT(6)>; /* GPD3 */ }; - wuc_wu111: wu111 { + /omit-if-no-ref/ wuc_wu111: wu111 { wucs = <&wuc11 BIT(7)>; /* GPD4 */ }; /* WUC group 12 */ - wuc_wu112: wu112 { + /omit-if-no-ref/ wuc_wu112: wu112 { wucs = <&wuc12 BIT(0)>; /* GPD5 */ }; - wuc_wu113: wu113 { + /omit-if-no-ref/ wuc_wu113: wu113 { wucs = <&wuc12 BIT(1)>; /* GPD6 */ }; - wuc_wu114: wu114 { + /omit-if-no-ref/ wuc_wu114: wu114 { wucs = <&wuc12 BIT(2)>; /* GPE4 */ }; - wuc_wu115: wu115 { + /omit-if-no-ref/ wuc_wu115: wu115 { wucs = <&wuc12 BIT(3)>; /* GPG0 */ }; - wuc_wu116: wu116 { + /omit-if-no-ref/ wuc_wu116: wu116 { wucs = <&wuc12 BIT(4)>; /* GPG1 */ }; - wuc_wu117: wu117 { + /omit-if-no-ref/ wuc_wu117: wu117 { wucs = <&wuc12 BIT(5)>; /* GPG2 */ }; - wuc_wu118: wu118 { + /omit-if-no-ref/ wuc_wu118: wu118 { wucs = <&wuc12 BIT(6)>; /* GPG6 */ }; - wuc_wu119: wu119 { + /omit-if-no-ref/ wuc_wu119: wu119 { wucs = <&wuc12 BIT(7)>; /* GPI0 */ }; /* WUC group 13 */ - wuc_wu120: wu120 { + /omit-if-no-ref/ wuc_wu120: wu120 { wucs = <&wuc13 BIT(0)>; /* GPI1 */ }; - wuc_wu121: wu121 { + /omit-if-no-ref/ wuc_wu121: wu121 { wucs = <&wuc13 BIT(1)>; /* GPI2 */ }; - wuc_wu122: wu122 { + /omit-if-no-ref/ wuc_wu122: wu122 { wucs = <&wuc13 BIT(2)>; /* GPI3 */ }; - wuc_wu123: wu123 { + /omit-if-no-ref/ wuc_wu123: wu123 { wucs = <&wuc13 BIT(3)>; /* GPG3 */ }; - wuc_wu124: wu124 { + /omit-if-no-ref/ wuc_wu124: wu124 { wucs = <&wuc13 BIT(4)>; /* GPG4 */ }; - wuc_wu125: wu125 { + /omit-if-no-ref/ wuc_wu125: wu125 { wucs = <&wuc13 BIT(5)>; /* GPG5 */ }; - wuc_wu126: wu126 { + /omit-if-no-ref/ wuc_wu126: wu126 { wucs = <&wuc13 BIT(6)>; /* GPG7 */ }; /* WUC group 14 */ - wuc_wu128: wu128 { + /omit-if-no-ref/ wuc_wu128: wu128 { wucs = <&wuc14 BIT(0)>; /* GPJ0 */ }; - wuc_wu129: wu129 { + /omit-if-no-ref/ wuc_wu129: wu129 { wucs = <&wuc14 BIT(1)>; /* GPJ1 */ }; - wuc_wu130: wu130 { + /omit-if-no-ref/ wuc_wu130: wu130 { wucs = <&wuc14 BIT(2)>; /* GPJ2 */ }; - wuc_wu131: wu131 { + /omit-if-no-ref/ wuc_wu131: wu131 { wucs = <&wuc14 BIT(3)>; /* GPJ3 */ }; - wuc_wu132: wu132 { + /omit-if-no-ref/ wuc_wu132: wu132 { wucs = <&wuc14 BIT(4)>; /* GPJ4 */ }; - wuc_wu133: wu133 { + /omit-if-no-ref/ wuc_wu133: wu133 { wucs = <&wuc14 BIT(5)>; /* GPJ5 */ }; - wuc_wu134: wu134 { + /omit-if-no-ref/ wuc_wu134: wu134 { wucs = <&wuc14 BIT(6)>; /* GPJ6 */ }; - wuc_wu135: wu135 { + /omit-if-no-ref/ wuc_wu135: wu135 { wucs = <&wuc14 BIT(7)>; /* GPJ7 */ }; /* WUC group 15 */ - wuc_wu136: wu136 { + /omit-if-no-ref/ wuc_wu136: wu136 { wucs = <&wuc15 BIT(0)>; /* GPIO L0 */ }; - wuc_wu137: wu137 { + /omit-if-no-ref/ wuc_wu137: wu137 { wucs = <&wuc15 BIT(1)>; /* GPIO L1 */ }; - wuc_wu138: wu138 { + /omit-if-no-ref/ wuc_wu138: wu138 { wucs = <&wuc15 BIT(2)>; /* GPIO L2 */ }; - wuc_wu139: wu139 { + /omit-if-no-ref/ wuc_wu139: wu139 { wucs = <&wuc15 BIT(3)>; /* GPIO L3 */ }; - wuc_wu140: wu140 { + /omit-if-no-ref/ wuc_wu140: wu140 { wucs = <&wuc15 BIT(4)>; /* GPIO L4 */ }; - wuc_wu141: wu141 { + /omit-if-no-ref/ wuc_wu141: wu141 { wucs = <&wuc15 BIT(5)>; /* GPIO L5 */ }; - wuc_wu142: wu142 { + /omit-if-no-ref/ wuc_wu142: wu142 { wucs = <&wuc15 BIT(6)>; /* GPIO L6 */ }; - wuc_wu143: wu143 { + /omit-if-no-ref/ wuc_wu143: wu143 { wucs = <&wuc15 BIT(7)>; /* GPIO L7 */ }; /* WUC group 16 */ - wuc_wu144: wu144 { + /omit-if-no-ref/ wuc_wu144: wu144 { wucs = <&wuc16 BIT(0)>; /* GPM0 */ }; - wuc_wu145: wu145 { + /omit-if-no-ref/ wuc_wu145: wu145 { wucs = <&wuc16 BIT(1)>; /* GPM1 */ }; - wuc_wu146: wu146 { + /omit-if-no-ref/ wuc_wu146: wu146 { wucs = <&wuc16 BIT(2)>; /* GPM2 */ }; - wuc_wu147: wu147 { + /omit-if-no-ref/ wuc_wu147: wu147 { wucs = <&wuc16 BIT(3)>; /* GPM3 */ }; - wuc_wu148: wu148 { + /omit-if-no-ref/ wuc_wu148: wu148 { wucs = <&wuc16 BIT(4)>; /* GPM4 */ }; - wuc_wu149: wu149 { + /omit-if-no-ref/ wuc_wu149: wu149 { wucs = <&wuc16 BIT(5)>; /* GPM5 */ }; - wuc_wu150: wu150 { + /omit-if-no-ref/ wuc_wu150: wu150 { wucs = <&wuc16 BIT(6)>; /* GPM6 */ }; }; From 72a1c9e43e5294a4476094ff92280ac5c6cc9e51 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Thu, 22 Jan 2026 15:07:05 +0100 Subject: [PATCH 0243/6328] doc: _scripts: gen_devicetree_rest: ensure blank lines around transition MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Transition markers ("----") require blank lines before and after, so this ensures that is always the case. Signed-off-by: Benjamin Cabé --- doc/_scripts/gen_devicetree_rest.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/_scripts/gen_devicetree_rest.py b/doc/_scripts/gen_devicetree_rest.py index f66114583d62..55fd7c48dbfd 100644 --- a/doc/_scripts/gen_devicetree_rest.py +++ b/doc/_scripts/gen_devicetree_rest.py @@ -604,7 +604,7 @@ def print_binding_page(binding, base_names, vnd_lookup, driver_sources,dup_compa ''', string_io) blocks = [to_code_block(example, language='dts') for example in binding.examples] - print("\n----\n".join(blocks), file=string_io) + print("\n\n----\n\n".join(blocks), file=string_io) # Properties. print_block('''\ From 42754f8f8dca7a646719e4d04481ada87416c9ed Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Tue, 9 Dec 2025 16:31:09 +0100 Subject: [PATCH 0244/6328] net: sockets: tls: Separate TLS session context from socket context Separate TLS session context from the TLS socket context so that a single DTLS server socket can support multiple client sessions. Other socket types will only have a single session per TLS socket. Signed-off-by: Robert Lubos --- subsys/net/lib/sockets/Kconfig | 11 + subsys/net/lib/sockets/sockets_tls.c | 330 +++++++++++++++++---------- 2 files changed, 216 insertions(+), 125 deletions(-) diff --git a/subsys/net/lib/sockets/Kconfig b/subsys/net/lib/sockets/Kconfig index 8d25302bef27..b0150531db07 100644 --- a/subsys/net/lib/sockets/Kconfig +++ b/subsys/net/lib/sockets/Kconfig @@ -237,6 +237,17 @@ config ZVFS_OPEN_ADD_SIZE_TLS default NET_SOCKETS_TLS_MAX_CONTEXTS if NET_SOCKETS_SOCKOPT_TLS default 0 +config NET_SOCKETS_TLS_MAX_SESSION_CONTEXTS + int "Maximum number of TLS/DTLS sessions" + default NET_SOCKETS_TLS_MAX_CONTEXTS + depends on NET_SOCKETS_SOCKOPT_TLS + help + This variable specifies the maximum number of TLS/DTLS sessions that + can be established at the same time. Typically one session is needed + for a TLS context. DTLS server sockets may use more sessions per socket + to support communication with multiple clients at the same time. + The value should not be lower than NET_SOCKETS_TLS_MAX_CONTEXTS. + config NET_SOCKETS_TLS_MAX_CREDENTIALS int "Maximum number of TLS/DTLS credentials per socket" default 4 diff --git a/subsys/net/lib/sockets/sockets_tls.c b/subsys/net/lib/sockets/sockets_tls.c index 04a599e5af72..252ab85d6431 100644 --- a/subsys/net/lib/sockets/sockets_tls.c +++ b/subsys/net/lib/sockets/sockets_tls.c @@ -122,6 +122,38 @@ struct tls_dtls_cid { }; #endif +struct tls_session_context { + sys_snode_t node; + + /* Handshake completion time. */ + int64_t handshake_timestamp; + + /* Information whether TLS handshake is currently in progress. */ + bool handshake_in_progress : 1; + + /* Session ended at the TLS/DTLS level. */ + bool session_closed : 1; + + /* Information whether TLS handshake is complete or not. */ + struct k_sem tls_established; + +#if defined(CONFIG_MBEDTLS) + /* mbedTLS context. */ + mbedtls_ssl_context ssl; +#endif /* CONFIG_MBEDTLS */ + +#if defined(CONFIG_NET_SOCKETS_ENABLE_DTLS) + /* Context information for DTLS timing. */ + struct dtls_timing_context dtls_timing; + + /* DTLS peer address. */ + struct net_sockaddr dtls_peer_addr; + + /* DTLS peer address length. */ + net_socklen_t dtls_peer_addrlen; +#endif /* CONFIG_NET_SOCKETS_ENABLE_DTLS */ +}; + /** TLS context information. */ __net_socket struct tls_context { /** Underlying TCP/UDP socket. */ @@ -136,11 +168,16 @@ __net_socket struct tls_context { /** Information whether underlying socket is listening. */ bool is_listening : 1; - /** Information whether TLS handshake is currently in progress. */ - bool handshake_in_progress : 1; + /* TLS sessions associated with this socket. In most cases there will + * be one session allocated per TLS context. DTLS server is an exception, + * which can have multiple TLS sessions allocated at the same time. + */ + sys_slist_t sessions; - /** Session ended at the TLS/DTLS level. */ - bool session_closed : 1; + /* Currently active TLS session. For a TLS context in use, this should + * always point to a valid session instance. + */ + struct tls_session_context *active_session; /** Socket type. */ enum net_sock_type type; @@ -154,9 +191,6 @@ __net_socket struct tls_context { /* Indicates whether socket is in error state at TLS/DTLS level. */ int error; - /** Information whether TLS handshake is complete or not. */ - struct k_sem tls_established; - /* TLS socket mutex lock. */ struct k_mutex *lock; @@ -213,23 +247,11 @@ __net_socket struct tls_context { } options; #if defined(CONFIG_NET_SOCKETS_ENABLE_DTLS) - /** Context information for DTLS timing. */ - struct dtls_timing_context dtls_timing; - /** mbedTLS cookie context for DTLS */ mbedtls_ssl_cookie_ctx cookie; - - /** DTLS peer address. */ - struct net_sockaddr dtls_peer_addr; - - /** DTLS peer address length. */ - net_socklen_t dtls_peer_addrlen; #endif /* CONFIG_NET_SOCKETS_ENABLE_DTLS */ #if defined(CONFIG_MBEDTLS) - /** mbedTLS context. */ - mbedtls_ssl_context ssl; - /** mbedTLS configuration. */ mbedtls_ssl_config config; @@ -243,13 +265,19 @@ __net_socket struct tls_context { /** mbedTLS structure for own private key. */ mbedtls_pk_context priv_key; #endif /* MBEDTLS_X509_CRT_PARSE_C */ - #endif /* CONFIG_MBEDTLS */ }; /* A global pool of TLS contexts. */ static struct tls_context tls_contexts[CONFIG_NET_SOCKETS_TLS_MAX_CONTEXTS]; +K_MEM_SLAB_DEFINE_STATIC(tls_session_contexts, sizeof(struct tls_session_context), + CONFIG_NET_SOCKETS_TLS_MAX_SESSION_CONTEXTS, + __alignof__(struct tls_session_context)); + +BUILD_ASSERT(CONFIG_NET_SOCKETS_TLS_MAX_SESSION_CONTEXTS >= CONFIG_NET_SOCKETS_TLS_MAX_CONTEXTS, + "CONFIG_NET_SOCKETS_TLS_MAX_SESSION_CONTEXTS cannot be smaller than " + "CONFIG_NET_SOCKETS_TLS_MAX_CONTEXTS"); static struct tls_session_cache client_cache[CONFIG_NET_SOCKETS_TLS_MAX_CLIENT_SESSION_COUNT]; @@ -339,9 +367,9 @@ static int dtls_timing_get_delay(void *data) return 0; } -static int dtls_get_remaining_timeout(struct tls_context *ctx) +static int dtls_get_remaining_timeout(struct tls_session_context *session_ctx) { - struct dtls_timing_context *timing = &ctx->dtls_timing; + struct dtls_timing_context *timing = &session_ctx->dtls_timing; uint32_t elapsed_ms; elapsed_ms = k_uptime_get_32() - timing->snapshot; @@ -381,9 +409,9 @@ static int tls_init(void) SYS_INIT(tls_init, APPLICATION, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT); -static inline bool is_handshake_complete(struct tls_context *ctx) +static inline bool is_handshake_complete(struct tls_session_context *session_ctx) { - return k_sem_count_get(&ctx->tls_established) != 0; + return k_sem_count_get(&session_ctx->tls_established) != 0; } /* @@ -439,6 +467,29 @@ static inline void tls_set_max_frag_len(mbedtls_ssl_config *config, enum net_soc static inline void tls_set_max_frag_len(mbedtls_ssl_config *config, enum net_sock_type type) {} #endif +static struct tls_session_context *tls_session_alloc(void) +{ + struct tls_session_context *session_ctx = NULL; + + if (k_mem_slab_alloc(&tls_session_contexts, (void **)&session_ctx, + K_NO_WAIT) != 0) { + NET_WARN("Failed to allocate TLS session context"); + return NULL; + } + + (void)memset(session_ctx, 0, sizeof(*session_ctx)); + (void)k_sem_init(&session_ctx->tls_established, 0, 1); + mbedtls_ssl_init(&session_ctx->ssl); + + return session_ctx; +} + +static void tls_session_free(struct tls_session_context *session_ctx) +{ + mbedtls_ssl_free(&session_ctx->ssl); + k_mem_slab_free(&tls_session_contexts, (void *)session_ctx); +} + /* Allocate TLS context. */ static struct tls_context *tls_alloc(void) { @@ -450,13 +501,25 @@ static struct tls_context *tls_alloc(void) for (i = 0; i < ARRAY_SIZE(tls_contexts); i++) { if (!tls_contexts[i].is_used) { tls = &tls_contexts[i]; + (void)memset(tls, 0, sizeof(*tls)); + + /* Allocate initial (and in most cases the only) session context */ + tls->active_session = tls_session_alloc(); + if (tls->active_session == NULL) { + tls = NULL; + break; + } + tls->is_used = true; tls->options.verify_level = -1; tls->options.timeout_tx = K_FOREVER; tls->options.timeout_rx = K_FOREVER; tls->sock = -1; + sys_slist_init(&tls->sessions); + sys_slist_append(&tls->sessions, &tls->active_session->node); + NET_DBG("Allocated TLS context, %p", tls); break; } @@ -465,9 +528,6 @@ static struct tls_context *tls_alloc(void) k_mutex_unlock(&context_lock); if (tls) { - k_sem_init(&tls->tls_established, 0, 1); - - mbedtls_ssl_init(&tls->ssl); mbedtls_ssl_config_init(&tls->config); #if defined(CONFIG_NET_SOCKETS_ENABLE_DTLS) mbedtls_ssl_cookie_init(&tls->cookie); @@ -513,8 +573,8 @@ static struct tls_context *tls_clone(struct tls_context *source_tls) #if defined(MBEDTLS_X509_CRT_PARSE_C) if (target_tls->options.is_hostname_set) { - mbedtls_ssl_set_hostname(&target_tls->ssl, - source_tls->ssl.hostname); + mbedtls_ssl_set_hostname(&target_tls->active_session->ssl, + source_tls->active_session->ssl.hostname); } #endif @@ -524,6 +584,8 @@ static struct tls_context *tls_clone(struct tls_context *source_tls) /* Release TLS context. */ static int tls_release(struct tls_context *tls) { + sys_snode_t *node; + if (!PART_OF_ARRAY(tls_contexts, tls)) { NET_ERR("Invalid TLS context"); return -EBADF; @@ -538,13 +600,19 @@ static int tls_release(struct tls_context *tls) mbedtls_ssl_cookie_free(&tls->cookie); #endif mbedtls_ssl_config_free(&tls->config); - mbedtls_ssl_free(&tls->ssl); #if defined(MBEDTLS_X509_CRT_PARSE_C) mbedtls_x509_crt_free(&tls->ca_chain); mbedtls_x509_crt_free(&tls->own_cert); mbedtls_pk_free(&tls->priv_key); #endif + while ((node = sys_slist_get(&tls->sessions)) != NULL) { + struct tls_session_context *session_ctx = + SYS_SLIST_CONTAINER(node, session_ctx, node); + + tls_session_free(session_ctx); + } + tls->is_used = false; return 0; @@ -680,7 +748,7 @@ static void tls_session_store(struct tls_context *context, memcpy(&peer_addr, addr, addrlen); mbedtls_ssl_session_init(&session); - ret = mbedtls_ssl_get_session(&context->ssl, &session); + ret = mbedtls_ssl_get_session(&context->active_session->ssl, &session); if (ret < 0) { NET_ERR("Failed to obtain session for %p", context); goto exit; @@ -716,7 +784,7 @@ static void tls_session_restore(struct tls_context *context, goto exit; } - ret = mbedtls_ssl_set_session(&context->ssl, &session); + ret = mbedtls_ssl_set_session(&context->active_session->ssl, &session); if (ret < 0) { NET_ERR("Failed to set session for %p", context); } @@ -822,34 +890,34 @@ static void ctx_set_lock(struct tls_context *ctx, struct k_mutex *lock) } #if defined(CONFIG_NET_SOCKETS_ENABLE_DTLS) -static bool dtls_is_peer_addr_valid(struct tls_context *context, +static bool dtls_is_peer_addr_valid(struct tls_session_context *session_ctx, const struct net_sockaddr *peer_addr, net_socklen_t addrlen) { - if (context->dtls_peer_addrlen != addrlen) { + if (session_ctx->dtls_peer_addrlen != addrlen) { return false; } - return peer_addr_cmp(&context->dtls_peer_addr, peer_addr); + return peer_addr_cmp(&session_ctx->dtls_peer_addr, peer_addr); } -static void dtls_peer_address_set(struct tls_context *context, +static void dtls_peer_address_set(struct tls_session_context *session_ctx, const struct net_sockaddr *peer_addr, net_socklen_t addrlen) { - if (addrlen <= sizeof(context->dtls_peer_addr)) { - memcpy(&context->dtls_peer_addr, peer_addr, addrlen); - context->dtls_peer_addrlen = addrlen; + if (addrlen <= sizeof(session_ctx->dtls_peer_addr)) { + memcpy(&session_ctx->dtls_peer_addr, peer_addr, addrlen); + session_ctx->dtls_peer_addrlen = addrlen; } } -static void dtls_peer_address_get(struct tls_context *context, +static void dtls_peer_address_get(struct tls_session_context *session_ctx, struct net_sockaddr *peer_addr, net_socklen_t *addrlen) { - net_socklen_t len = MIN(context->dtls_peer_addrlen, *addrlen); + net_socklen_t len = MIN(session_ctx->dtls_peer_addrlen, *addrlen); - memcpy(peer_addr, &context->dtls_peer_addr, len); + memcpy(peer_addr, &session_ctx->dtls_peer_addr, len); *addrlen = len; } @@ -859,8 +927,8 @@ static int dtls_tx(void *ctx, const unsigned char *buf, size_t len) ssize_t sent; sent = zsock_sendto(tls_ctx->sock, buf, len, ZSOCK_MSG_DONTWAIT, - &tls_ctx->dtls_peer_addr, - tls_ctx->dtls_peer_addrlen); + &tls_ctx->active_session->dtls_peer_addr, + tls_ctx->active_session->dtls_peer_addrlen); if (sent < 0) { if (errno == EAGAIN) { return MBEDTLS_ERR_SSL_WANT_WRITE; @@ -890,13 +958,13 @@ static int dtls_rx(void *ctx, unsigned char *buf, size_t len) return MBEDTLS_ERR_NET_RECV_FAILED; } - if (tls_ctx->dtls_peer_addrlen == 0) { + if (tls_ctx->active_session->dtls_peer_addrlen == 0) { /* Only allow to store peer address for DTLS servers. */ if (tls_ctx->options.role == MBEDTLS_SSL_IS_SERVER) { - dtls_peer_address_set(tls_ctx, &addr, addrlen); + dtls_peer_address_set(tls_ctx->active_session, &addr, addrlen); err = mbedtls_ssl_set_client_transport_id( - &tls_ctx->ssl, + &tls_ctx->active_session->ssl, (const unsigned char *)&addr, addrlen); if (err < 0) { return err; @@ -907,7 +975,7 @@ static int dtls_rx(void *ctx, unsigned char *buf, size_t len) */ return MBEDTLS_ERR_SSL_PEER_VERIFY_FAILED; } - } else if (!dtls_is_peer_addr_valid(tls_ctx, &addr, addrlen)) { + } else if (!dtls_is_peer_addr_valid(tls_ctx->active_session, &addr, addrlen)) { return MBEDTLS_ERR_SSL_WANT_READ; } @@ -1162,16 +1230,18 @@ static int tls_mbedtls_set_credentials(struct tls_context *tls) return err; } -static int tls_mbedtls_reset(struct tls_context *context) +static int tls_mbedtls_reset_session(struct tls_context *context) { int ret; - ret = mbedtls_ssl_session_reset(&context->ssl); + ret = mbedtls_ssl_session_reset(&context->active_session->ssl); if (ret != 0) { return ret; } - k_sem_reset(&context->tls_established); + context->active_session->handshake_timestamp = 0; + + k_sem_reset(&context->active_session->tls_established); #if defined(CONFIG_NET_SOCKETS_ENABLE_DTLS) /* Server role: reset the address so that a new @@ -1180,9 +1250,9 @@ static int tls_mbedtls_reset(struct tls_context *context) * even on handshake timeout */ if (context->options.role == MBEDTLS_SSL_IS_SERVER) { - (void)memset(&context->dtls_peer_addr, 0, - sizeof(context->dtls_peer_addr)); - context->dtls_peer_addrlen = 0; + (void)memset(&context->active_session->dtls_peer_addr, 0, + sizeof(context->active_session->dtls_peer_addr)); + context->active_session->dtls_peer_addrlen = 0; } #endif @@ -1195,11 +1265,11 @@ static int tls_mbedtls_handshake(struct tls_context *context, k_timepoint_t end; int ret; - context->handshake_in_progress = true; + context->active_session->handshake_in_progress = true; end = sys_timepoint_calc(timeout); - while ((ret = mbedtls_ssl_handshake(&context->ssl)) != 0) { + while ((ret = mbedtls_ssl_handshake(&context->active_session->ssl)) != 0) { if (ret == MBEDTLS_ERR_SSL_WANT_READ || ret == MBEDTLS_ERR_SSL_WANT_WRITE || ret == MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS || @@ -1219,7 +1289,7 @@ static int tls_mbedtls_handshake(struct tls_context *context, #if defined(CONFIG_NET_SOCKETS_ENABLE_DTLS) if (context->type == NET_SOCK_DGRAM) { int timeout_dtls = - dtls_get_remaining_timeout(context); + dtls_get_remaining_timeout(context->active_session); if (timeout_dtls != SYS_FOREVER_MS) { if (timeout_ms == SYS_FOREVER_MS) { @@ -1239,7 +1309,7 @@ static int tls_mbedtls_handshake(struct tls_context *context, continue; } else if (ret == MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED) { - ret = tls_mbedtls_reset(context); + ret = tls_mbedtls_reset_session(context); if (ret == 0) { if (!K_TIMEOUT_EQ(timeout, K_NO_WAIT)) { continue; @@ -1252,7 +1322,7 @@ static int tls_mbedtls_handshake(struct tls_context *context, /* MbedTLS API documentation requires session to * be reset in this case */ - ret = tls_mbedtls_reset(context); + ret = tls_mbedtls_reset_session(context); if (ret == 0) { NET_ERR("TLS handshake timeout"); context->error = ETIMEDOUT; @@ -1264,7 +1334,7 @@ static int tls_mbedtls_handshake(struct tls_context *context, * be reset in other error cases */ NET_ERR("TLS handshake error: -0x%x", -ret); - ret = tls_mbedtls_reset(context); + ret = tls_mbedtls_reset_session(context); if (ret == 0) { context->error = ECONNABORTED; ret = -ECONNABORTED; @@ -1272,7 +1342,7 @@ static int tls_mbedtls_handshake(struct tls_context *context, } } - /* Avoid constant loop if tls_mbedtls_reset fails */ + /* Avoid constant loop if tls_mbedtls_reset_session fails */ NET_ERR("TLS reset error: -0x%x", -ret); context->error = ECONNABORTED; ret = -ECONNABORTED; @@ -1280,10 +1350,11 @@ static int tls_mbedtls_handshake(struct tls_context *context, } if (ret == 0) { - k_sem_give(&context->tls_established); + context->active_session->handshake_timestamp = k_uptime_get(); + k_sem_give(&context->active_session->tls_established); } - context->handshake_in_progress = false; + context->active_session->handshake_in_progress = false; return ret; } @@ -1299,11 +1370,11 @@ static int tls_mbedtls_init(struct tls_context *context, bool is_server) MBEDTLS_SSL_TRANSPORT_DATAGRAM; if (type == MBEDTLS_SSL_TRANSPORT_STREAM) { - mbedtls_ssl_set_bio(&context->ssl, context, + mbedtls_ssl_set_bio(&context->active_session->ssl, context, tls_tx, tls_rx, NULL); } else { #if defined(CONFIG_NET_SOCKETS_ENABLE_DTLS) - mbedtls_ssl_set_bio(&context->ssl, context, + mbedtls_ssl_set_bio(&context->active_session->ssl, context, dtls_tx, dtls_rx, NULL); #else return -ENOTSUP; @@ -1349,8 +1420,8 @@ static int tls_mbedtls_init(struct tls_context *context, bool is_server) #if defined(CONFIG_NET_SOCKETS_ENABLE_DTLS) if (type == MBEDTLS_SSL_TRANSPORT_DATAGRAM) { /* DTLS requires timer callbacks to operate */ - mbedtls_ssl_set_timer_cb(&context->ssl, - &context->dtls_timing, + mbedtls_ssl_set_timer_cb(&context->active_session->ssl, + &context->active_session->dtls_timing, dtls_timing_set_delay, dtls_timing_get_delay); mbedtls_ssl_conf_handshake_timeout(&context->config, @@ -1396,7 +1467,7 @@ static int tls_mbedtls_init(struct tls_context *context, bool is_server) * depend on user configuration. */ if (!is_server && !context->options.is_hostname_set) { - mbedtls_ssl_set_hostname(&context->ssl, ""); + mbedtls_ssl_set_hostname(&context->active_session->ssl, ""); } #endif @@ -1454,7 +1525,7 @@ static int tls_mbedtls_init(struct tls_context *context, bool is_server) } #endif /* CONFIG_NET_SOCKETS_TLS_CERT_VERIFY_CALLBACK */ - ret = mbedtls_ssl_setup(&context->ssl, + ret = mbedtls_ssl_setup(&context->active_session->ssl, &context->config); if (ret != 0) { /* According to mbedTLS API documentation, @@ -1466,7 +1537,8 @@ static int tls_mbedtls_init(struct tls_context *context, bool is_server) #if defined(CONFIG_NET_SOCKETS_ENABLE_DTLS) && defined(CONFIG_MBEDTLS_SSL_DTLS_CONNECTION_ID) if (type == MBEDTLS_SSL_TRANSPORT_DATAGRAM) { if (context->options.dtls_cid.enabled) { - ret = mbedtls_ssl_set_cid(&context->ssl, MBEDTLS_SSL_CID_ENABLED, + ret = mbedtls_ssl_set_cid(&context->active_session->ssl, + MBEDTLS_SSL_CID_ENABLED, context->options.dtls_cid.cid, context->options.dtls_cid.cid_len); if (ret != 0) { @@ -1700,7 +1772,7 @@ static int tls_opt_hostname_set(struct tls_context *context, ARG_UNUSED(optlen); #if defined(MBEDTLS_X509_CRT_PARSE_C) - if (mbedtls_ssl_set_hostname(&context->ssl, optval) != 0) { + if (mbedtls_ssl_set_hostname(&context->active_session->ssl, optval) != 0) { return -EINVAL; } #else @@ -1781,7 +1853,8 @@ static int tls_opt_ciphersuite_used_get(struct tls_context *context, return -EINVAL; } - ciph = mbedtls_ssl_get_ciphersuite(&context->ssl); + + ciph = mbedtls_ssl_get_ciphersuite(&context->active_session->ssl); if (ciph == NULL) { return -ENOTCONN; } @@ -1975,7 +2048,8 @@ static int tls_opt_dtls_peer_connection_id_value_get(struct tls_context *context return -ENOTCONN; } - ret = mbedtls_ssl_get_peer_cid(&context->ssl, &enabled, optval, &optlen_local); + ret = mbedtls_ssl_get_peer_cid(&context->active_session->ssl, &enabled, + optval, &optlen_local); if (enabled) { *optlen = optlen_local; } else { @@ -2006,7 +2080,7 @@ static int tls_opt_dtls_connection_id_status_get(struct tls_context *context, return -ENOTCONN; } - ret = mbedtls_ssl_get_peer_cid(&context->ssl, &enabled, + ret = mbedtls_ssl_get_peer_cid(&context->active_session->ssl, &enabled, cid.cid, &cid.cid_len); if (ret) { @@ -2140,7 +2214,7 @@ static int tls_opt_cert_verify_result_get(struct tls_context *context, return -EINVAL; } - *(uint32_t *)optval = mbedtls_ssl_get_verify_result(&context->ssl); + *(uint32_t *)optval = mbedtls_ssl_get_verify_result(&context->active_session->ssl); return 0; } @@ -2351,7 +2425,7 @@ int ztls_close_ctx(struct tls_context *ctx, int sock) /* Try to send close notification. */ ctx->flags = 0; - (void)mbedtls_ssl_close_notify(&ctx->ssl); + (void)mbedtls_ssl_close_notify(&ctx->active_session->ssl); err = tls_release(ctx); ret = zsock_close(ctx->sock); @@ -2401,7 +2475,7 @@ int ztls_connect_ctx(struct tls_context *ctx, const struct net_sockaddr *addr, #if defined(CONFIG_NET_SOCKETS_ENABLE_DTLS) if (ctx->type == NET_SOCK_DGRAM) { - dtls_peer_address_set(ctx, addr, addrlen); + dtls_peer_address_set(ctx->active_session, addr, addrlen); } #endif @@ -2527,7 +2601,7 @@ static ssize_t send_tls(struct tls_context *ctx, const void *buf, return -1; } - if (ctx->session_closed) { + if (ctx->active_session->session_closed) { errno = ECONNABORTED; return -1; } @@ -2541,7 +2615,7 @@ static ssize_t send_tls(struct tls_context *ctx, const void *buf, end = sys_timepoint_calc(timeout); do { - ret = mbedtls_ssl_write(&ctx->ssl, buf, len); + ret = mbedtls_ssl_write(&ctx->active_session->ssl, buf, len); if (ret >= 0) { return ret; } @@ -2577,7 +2651,7 @@ static ssize_t send_tls(struct tls_context *ctx, const void *buf, /* MbedTLS API documentation requires session to * be reset in other error cases */ - ret = tls_mbedtls_reset(ctx); + ret = tls_mbedtls_reset_session(ctx); if (ret != 0) { ctx->error = ENOMEM; errno = ENOMEM; @@ -2605,14 +2679,14 @@ static ssize_t sendto_dtls_client(struct tls_context *ctx, const void *buf, /* No address provided, check if we have stored one, * otherwise return error. */ - if (ctx->dtls_peer_addrlen == 0) { + if (ctx->active_session->dtls_peer_addrlen == 0) { ret = -EDESTADDRREQ; goto error; } - } else if (ctx->dtls_peer_addrlen == 0) { + } else if (ctx->active_session->dtls_peer_addrlen == 0) { /* Address provided and no peer address stored. */ - dtls_peer_address_set(ctx, dest_addr, addrlen); - } else if (!dtls_is_peer_addr_valid(ctx, dest_addr, addrlen) != 0) { + dtls_peer_address_set(ctx->active_session, dest_addr, addrlen); + } else if (!dtls_is_peer_addr_valid(ctx->active_session, dest_addr, addrlen) != 0) { /* Address provided but it does not match stored one */ ret = -EISCONN; goto error; @@ -2625,9 +2699,9 @@ static ssize_t sendto_dtls_client(struct tls_context *ctx, const void *buf, } } - if (!is_handshake_complete(ctx)) { - tls_session_restore(ctx, &ctx->dtls_peer_addr, - ctx->dtls_peer_addrlen); + if (!is_handshake_complete(ctx->active_session)) { + tls_session_restore(ctx, &ctx->active_session->dtls_peer_addr, + ctx->active_session->dtls_peer_addrlen); /* TODO For simplicity, TLS handshake blocks the socket even for * non-blocking socket. @@ -2643,8 +2717,8 @@ static ssize_t sendto_dtls_client(struct tls_context *ctx, const void *buf, /* Client socket ready to use again. */ ctx->error = 0; - tls_session_store(ctx, &ctx->dtls_peer_addr, - ctx->dtls_peer_addrlen); + tls_session_store(ctx, &ctx->active_session->dtls_peer_addr, + ctx->active_session->dtls_peer_addrlen); } return send_tls(ctx, buf, len, flags); @@ -2662,14 +2736,14 @@ static ssize_t sendto_dtls_server(struct tls_context *ctx, const void *buf, /* For DTLS server, require to have established DTLS connection * in order to send data. */ - if (!is_handshake_complete(ctx)) { + if (!is_handshake_complete(ctx->active_session)) { errno = ENOTCONN; return -1; } /* Verify we are sending to a peer that we have connection with. */ if (dest_addr && - !dtls_is_peer_addr_valid(ctx, dest_addr, addrlen) != 0) { + !dtls_is_peer_addr_valid(ctx->active_session, dest_addr, addrlen) != 0) { errno = EISCONN; return -1; } @@ -2821,7 +2895,7 @@ static ssize_t recv_tls(struct tls_context *ctx, void *buf, return -1; } - if (ctx->session_closed) { + if (ctx->active_session->session_closed) { return 0; } @@ -2836,14 +2910,14 @@ static ssize_t recv_tls(struct tls_context *ctx, void *buf, do { size_t read_len = max_len - recv_len; - ret = mbedtls_ssl_read(&ctx->ssl, (uint8_t *)buf + recv_len, + ret = mbedtls_ssl_read(&ctx->active_session->ssl, (uint8_t *)buf + recv_len, read_len); if (ret < 0) { if (ret == MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY) { /* Peer notified that it's closing the * connection. */ - ctx->session_closed = true; + ctx->active_session->session_closed = true; break; } @@ -2852,7 +2926,7 @@ static ssize_t recv_tls(struct tls_context *ctx, void *buf, * supported. See mbedtls_ssl_read API * documentation. */ - ctx->session_closed = true; + ctx->active_session->session_closed = true; break; } @@ -2933,7 +3007,7 @@ static ssize_t recvfrom_dtls_common(struct tls_context *ctx, void *buf, do { size_t remaining; - ret = mbedtls_ssl_read(&ctx->ssl, buf, max_len); + ret = mbedtls_ssl_read(&ctx->active_session->ssl, buf, max_len); if (ret < 0) { if (ret == MBEDTLS_ERR_SSL_WANT_READ || ret == MBEDTLS_ERR_SSL_WANT_WRITE || @@ -2951,7 +3025,7 @@ static ssize_t recvfrom_dtls_common(struct tls_context *ctx, void *buf, return ret; } - timeout_dtls = dtls_get_remaining_timeout(ctx); + timeout_dtls = dtls_get_remaining_timeout(ctx->active_session); timeout_sock = timeout_to_ms(&timeout); if (timeout_dtls == SYS_FOREVER_MS || timeout_sock == SYS_FOREVER_MS) { @@ -2977,13 +3051,13 @@ static ssize_t recvfrom_dtls_common(struct tls_context *ctx, void *buf, } if (src_addr && addrlen) { - dtls_peer_address_get(ctx, src_addr, addrlen); + dtls_peer_address_get(ctx->active_session, src_addr, addrlen); } /* mbedtls_ssl_get_bytes_avail() indicate the data length * remaining in the current datagram. */ - remaining = mbedtls_ssl_get_bytes_avail(&ctx->ssl); + remaining = mbedtls_ssl_get_bytes_avail(&ctx->active_session->ssl); /* No more data in the datagram, or dummy read. */ if ((remaining == 0) || (max_len == 0)) { @@ -2998,7 +3072,7 @@ static ssize_t recvfrom_dtls_common(struct tls_context *ctx, void *buf, uint8_t byte; int err; - err = mbedtls_ssl_read(&ctx->ssl, &byte, sizeof(byte)); + err = mbedtls_ssl_read(&ctx->active_session->ssl, &byte, sizeof(byte)); if (err <= 0) { NET_ERR("Error while flushing the rest of the" " datagram, err %d", err); @@ -3021,7 +3095,7 @@ static ssize_t recvfrom_dtls_client(struct tls_context *ctx, void *buf, { int ret; - if (!is_handshake_complete(ctx)) { + if (!is_handshake_complete(ctx->active_session)) { ret = -ENOTCONN; goto error; } @@ -3034,7 +3108,7 @@ static ssize_t recvfrom_dtls_client(struct tls_context *ctx, void *buf, switch (ret) { case MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY: /* Peer notified that it's closing the connection. */ - ret = tls_mbedtls_reset(ctx); + ret = tls_mbedtls_reset_session(ctx); if (ret == 0) { ctx->error = ENOTCONN; ret = -ENOTCONN; @@ -3045,7 +3119,7 @@ static ssize_t recvfrom_dtls_client(struct tls_context *ctx, void *buf, break; case MBEDTLS_ERR_SSL_TIMEOUT: - (void)mbedtls_ssl_close_notify(&ctx->ssl); + (void)mbedtls_ssl_close_notify(&ctx->active_session->ssl); ctx->error = ETIMEDOUT; ret = -ETIMEDOUT; break; @@ -3063,7 +3137,7 @@ static ssize_t recvfrom_dtls_client(struct tls_context *ctx, void *buf, /* MbedTLS API documentation requires session to * be reset in other error cases */ - ret = tls_mbedtls_reset(ctx); + ret = tls_mbedtls_reset_session(ctx); if (ret != 0) { ctx->error = ENOMEM; errno = ENOMEM; @@ -3108,7 +3182,7 @@ static ssize_t recvfrom_dtls_server(struct tls_context *ctx, void *buf, do { repeat = false; - if (!is_handshake_complete(ctx)) { + if (!is_handshake_complete(ctx->active_session)) { ret = tls_mbedtls_handshake(ctx, timeout); if (ret < 0) { /* In case of EAGAIN, just exit. */ @@ -3116,7 +3190,7 @@ static ssize_t recvfrom_dtls_server(struct tls_context *ctx, void *buf, break; } - ret = tls_mbedtls_reset(ctx); + ret = tls_mbedtls_reset_session(ctx); if (ret == 0) { repeat = true; } else { @@ -3138,13 +3212,13 @@ static ssize_t recvfrom_dtls_server(struct tls_context *ctx, void *buf, switch (ret) { case MBEDTLS_ERR_SSL_TIMEOUT: - (void)mbedtls_ssl_close_notify(&ctx->ssl); + (void)mbedtls_ssl_close_notify(&ctx->active_session->ssl); __fallthrough; /* fallthrough */ case MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY: case MBEDTLS_ERR_SSL_CLIENT_RECONNECT: - ret = tls_mbedtls_reset(ctx); + ret = tls_mbedtls_reset_session(ctx); if (ret == 0) { repeat = true; } else { @@ -3163,7 +3237,7 @@ static ssize_t recvfrom_dtls_server(struct tls_context *ctx, void *buf, default: NET_ERR("DTLS server recv error: -%x", -ret); - ret = tls_mbedtls_reset(ctx); + ret = tls_mbedtls_reset_session(ctx); if (ret != 0) { ctx->error = ENOMEM; errno = ENOMEM; @@ -3223,7 +3297,7 @@ static int ztls_poll_prepare_pollin(struct tls_context *ctx) * so we won't block in the k_poll. */ if (!ctx->is_listening) { - if (mbedtls_ssl_get_bytes_avail(&ctx->ssl) > 0) { + if (mbedtls_ssl_get_bytes_avail(&ctx->active_session->ssl) > 0) { return -EALREADY; } } @@ -3247,8 +3321,8 @@ static int ztls_poll_prepare_ctx(struct tls_context *ctx, */ if ((pfd->events & ZSOCK_POLLIN) && (ctx->type == NET_SOCK_DGRAM) && (ctx->options.role == MBEDTLS_SSL_IS_CLIENT) && - !is_handshake_complete(ctx)) { - (*pev)->obj = &ctx->tls_established; + !is_handshake_complete(ctx->active_session)) { + (*pev)->obj = &ctx->active_session->tls_established; (*pev)->type = K_POLL_TYPE_SEM_AVAILABLE; (*pev)->mode = K_POLL_MODE_NOTIFY_ONLY; (*pev)->state = K_POLL_STATE_NOT_READY; @@ -3310,14 +3384,14 @@ static int ztls_socket_data_check(struct tls_context *ctx) } } - if (!is_handshake_complete(ctx)) { + if (!is_handshake_complete(ctx->active_session)) { ret = tls_mbedtls_handshake(ctx, K_NO_WAIT); if (ret < 0) { if (ret == -EAGAIN) { return 0; } - ret = tls_mbedtls_reset(ctx); + ret = tls_mbedtls_reset_session(ctx); if (ret != 0) { return -ENOMEM; } @@ -3335,7 +3409,7 @@ static int ztls_socket_data_check(struct tls_context *ctx) ctx->flags = ZSOCK_MSG_DONTWAIT; - ret = mbedtls_ssl_read(&ctx->ssl, NULL, 0); + ret = mbedtls_ssl_read(&ctx->active_session->ssl, NULL, 0); if (ret < 0) { if (ret == MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY) { /* Don't reset the context for STREAM socket - the @@ -3344,12 +3418,12 @@ static int ztls_socket_data_check(struct tls_context *ctx) * of 0 in a consecutive recv() call. */ if (ctx->type == NET_SOCK_DGRAM) { - ret = tls_mbedtls_reset(ctx); + ret = tls_mbedtls_reset_session(ctx); if (ret != 0) { return -ENOMEM; } } else { - ctx->session_closed = true; + ctx->active_session->session_closed = true; } return -ENOTCONN; @@ -3365,7 +3439,7 @@ static int ztls_socket_data_check(struct tls_context *ctx) /* MbedTLS API documentation requires session to * be reset in other error cases */ - if (tls_mbedtls_reset(ctx) != 0) { + if (tls_mbedtls_reset_session(ctx) != 0) { return -ENOMEM; } @@ -3378,7 +3452,7 @@ static int ztls_socket_data_check(struct tls_context *ctx) return -ECONNABORTED; } - return mbedtls_ssl_get_bytes_avail(&ctx->ssl); + return mbedtls_ssl_get_bytes_avail(&ctx->active_session->ssl); } static int ztls_poll_update_pollin(int fd, struct tls_context *ctx, @@ -3388,7 +3462,7 @@ static int ztls_poll_update_pollin(int fd, struct tls_context *ctx, if (!ctx->is_listening) { /* Already had TLS data to read on socket. */ - if (mbedtls_ssl_get_bytes_avail(&ctx->ssl) > 0) { + if (mbedtls_ssl_get_bytes_avail(&ctx->active_session->ssl) > 0) { pfd->revents |= ZSOCK_POLLIN; goto next; } @@ -3409,7 +3483,7 @@ static int ztls_poll_update_pollin(int fd, struct tls_context *ctx, /* Perform data check without incoming data for completed DTLS connections. * This allows the connections to timeout with CONFIG_NET_SOCKETS_DTLS_TIMEOUT. */ - if (!is_handshake_complete(ctx) && !(pfd->revents & ZSOCK_POLLIN)) { + if (!is_handshake_complete(ctx->active_session) && !(pfd->revents & ZSOCK_POLLIN)) { goto next; } } @@ -3465,7 +3539,7 @@ static int ztls_poll_update_ctx(struct tls_context *ctx, /* Check if the socket was waiting for the handshake to complete. */ if ((pfd->events & ZSOCK_POLLIN) && - ((*pev)->obj == &ctx->tls_established)) { + ((*pev)->obj == &ctx->active_session->tls_established)) { /* In case handshake is complete, reconfigure the k_poll_event * to monitor the underlying socket now. */ @@ -3529,7 +3603,7 @@ static bool poll_offload_dtls_client_retry(struct tls_context *ctx, return false; } - if (ctx->handshake_in_progress) { + if (ctx->active_session->handshake_in_progress) { /* Add some sleep to allow lower priority threads to proceed * with handshake. */ @@ -3537,7 +3611,7 @@ static bool poll_offload_dtls_client_retry(struct tls_context *ctx, pfd->revents &= ~ZSOCK_POLLIN; return true; - } else if (!is_handshake_complete(ctx)) { + } else if (!is_handshake_complete(ctx->active_session)) { uint8_t byte; int ret; @@ -3919,8 +3993,14 @@ mbedtls_ssl_context *ztls_get_mbedtls_ssl_context(int fd) return NULL; } - return &ctx->ssl; + return &ctx->active_session->ssl; } + +uint32_t ztls_get_session_count(void) +{ + return k_mem_slab_num_used_get(&tls_session_contexts); +} + #endif /* CONFIG_NET_TEST */ static ssize_t tls_sock_read_vmeth(void *obj, void *buffer, size_t count) From 779bfe2e5eee762416d3dbdf50422937ff44375e Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Tue, 9 Dec 2025 16:31:11 +0100 Subject: [PATCH 0245/6328] net: sockets: tls: Split TLS session and context initialization It has to be possible to initialize TLS sessions separately of the TLS socket context. Signed-off-by: Robert Lubos --- subsys/net/lib/sockets/sockets_tls.c | 104 +++++++++++++++------------ 1 file changed, 58 insertions(+), 46 deletions(-) diff --git a/subsys/net/lib/sockets/sockets_tls.c b/subsys/net/lib/sockets/sockets_tls.c index 252ab85d6431..a3d21301645d 100644 --- a/subsys/net/lib/sockets/sockets_tls.c +++ b/subsys/net/lib/sockets/sockets_tls.c @@ -1359,28 +1359,73 @@ static int tls_mbedtls_handshake(struct tls_context *context, return ret; } -static int tls_mbedtls_init(struct tls_context *context, bool is_server) +static int tls_mbedtls_session_init(struct tls_session_context *session_ctx, + struct tls_context *tls_ctx, bool is_server) { - int role, type, ret; + int ret; - role = is_server ? MBEDTLS_SSL_IS_SERVER : MBEDTLS_SSL_IS_CLIENT; +#if defined(MBEDTLS_X509_CRT_PARSE_C) + /* For TLS clients, set hostname to empty string to enforce it's + * verification - only if hostname option was not set. Otherwise + * depend on user configuration. + */ + if (!is_server && !tls_ctx->options.is_hostname_set) { + ret = mbedtls_ssl_set_hostname(&session_ctx->ssl, ""); + if (ret != 0) { + return -ENOMEM; + } + } +#endif - type = (context->type == NET_SOCK_STREAM) ? - MBEDTLS_SSL_TRANSPORT_STREAM : - MBEDTLS_SSL_TRANSPORT_DATAGRAM; + ret = mbedtls_ssl_setup(&session_ctx->ssl, &tls_ctx->config); + if (ret != 0) { + /* According to mbedTLS API documentation, + * mbedtls_ssl_setup can fail due to memory allocation failure + */ + return -ENOMEM; + } - if (type == MBEDTLS_SSL_TRANSPORT_STREAM) { - mbedtls_ssl_set_bio(&context->active_session->ssl, context, + if (tls_ctx->type == NET_SOCK_STREAM) { + mbedtls_ssl_set_bio(&session_ctx->ssl, tls_ctx, tls_tx, tls_rx, NULL); } else { #if defined(CONFIG_NET_SOCKETS_ENABLE_DTLS) - mbedtls_ssl_set_bio(&context->active_session->ssl, context, + mbedtls_ssl_set_bio(&session_ctx->ssl, tls_ctx, dtls_tx, dtls_rx, NULL); -#else + + /* DTLS requires timer callbacks to operate */ + mbedtls_ssl_set_timer_cb(&session_ctx->ssl, + &session_ctx->dtls_timing, + dtls_timing_set_delay, + dtls_timing_get_delay); +#if defined(CONFIG_MBEDTLS_SSL_DTLS_CONNECTION_ID) + if (tls_ctx->options.dtls_cid.enabled) { + ret = mbedtls_ssl_set_cid(&session_ctx->ssl, MBEDTLS_SSL_CID_ENABLED, + tls_ctx->options.dtls_cid.cid, + tls_ctx->options.dtls_cid.cid_len); + if (ret != 0) { + return -EINVAL; + } + } +#endif /* CONFIG_MBEDTLS_SSL_DTLS_CONNECTION_ID */ +#else /* CONFIG_NET_SOCKETS_ENABLE_DTLS */ return -ENOTSUP; #endif /* CONFIG_NET_SOCKETS_ENABLE_DTLS */ } + return 0; +} + +static int tls_mbedtls_init(struct tls_context *context, bool is_server) +{ + int role, type, ret; + + role = is_server ? MBEDTLS_SSL_IS_SERVER : MBEDTLS_SSL_IS_CLIENT; + + type = (context->type == NET_SOCK_STREAM) ? + MBEDTLS_SSL_TRANSPORT_STREAM : + MBEDTLS_SSL_TRANSPORT_DATAGRAM; + ret = mbedtls_ssl_config_defaults(&context->config, role, type, MBEDTLS_SSL_PRESET_DEFAULT); if (ret != 0) { @@ -1419,11 +1464,6 @@ static int tls_mbedtls_init(struct tls_context *context, bool is_server) #if defined(CONFIG_NET_SOCKETS_ENABLE_DTLS) if (type == MBEDTLS_SSL_TRANSPORT_DATAGRAM) { - /* DTLS requires timer callbacks to operate */ - mbedtls_ssl_set_timer_cb(&context->active_session->ssl, - &context->active_session->dtls_timing, - dtls_timing_set_delay, - dtls_timing_get_delay); mbedtls_ssl_conf_handshake_timeout(&context->config, context->options.dtls_handshake_timeout_min, context->options.dtls_handshake_timeout_max); @@ -1461,16 +1501,6 @@ static int tls_mbedtls_init(struct tls_context *context, bool is_server) } #endif /* CONFIG_NET_SOCKETS_ENABLE_DTLS */ -#if defined(MBEDTLS_X509_CRT_PARSE_C) - /* For TLS clients, set hostname to empty string to enforce it's - * verification - only if hostname option was not set. Otherwise - * depend on user configuration. - */ - if (!is_server && !context->options.is_hostname_set) { - mbedtls_ssl_set_hostname(&context->active_session->ssl, ""); - } -#endif - /* If verification level was specified explicitly, set it. Otherwise, * use mbedTLS default values (required for client, none for server) */ @@ -1525,28 +1555,10 @@ static int tls_mbedtls_init(struct tls_context *context, bool is_server) } #endif /* CONFIG_NET_SOCKETS_TLS_CERT_VERIFY_CALLBACK */ - ret = mbedtls_ssl_setup(&context->active_session->ssl, - &context->config); - if (ret != 0) { - /* According to mbedTLS API documentation, - * mbedtls_ssl_setup can fail due to memory allocation failure - */ - return -ENOMEM; - } - -#if defined(CONFIG_NET_SOCKETS_ENABLE_DTLS) && defined(CONFIG_MBEDTLS_SSL_DTLS_CONNECTION_ID) - if (type == MBEDTLS_SSL_TRANSPORT_DATAGRAM) { - if (context->options.dtls_cid.enabled) { - ret = mbedtls_ssl_set_cid(&context->active_session->ssl, - MBEDTLS_SSL_CID_ENABLED, - context->options.dtls_cid.cid, - context->options.dtls_cid.cid_len); - if (ret != 0) { - return -EINVAL; - } - } + ret = tls_mbedtls_session_init(context->active_session, context, is_server); + if (ret < 0) { + return ret; } -#endif /* CONFIG_NET_SOCKETS_ENABLE_DTLS && CONFIG_MBEDTLS_SSL_DTLS_CONNECTION_ID */ context->is_initialized = true; From 9e544a9ec753047eed7b44167c442f6a97ff1a38 Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Tue, 9 Dec 2025 16:31:11 +0100 Subject: [PATCH 0246/6328] net: sockets: tls: Split DTLS BIO functions Split DTLS BIO RX functions for client and server case, given the functionality will differ heavily. DTLS server needs to peek packet before passing it to mbed TLS to allow to switch DTLS sessions in case peer address doesn't match. Signed-off-by: Robert Lubos --- subsys/net/lib/sockets/sockets_tls.c | 86 +++++++++++++++++++++------- 1 file changed, 66 insertions(+), 20 deletions(-) diff --git a/subsys/net/lib/sockets/sockets_tls.c b/subsys/net/lib/sockets/sockets_tls.c index a3d21301645d..f3aa1d0e75cf 100644 --- a/subsys/net/lib/sockets/sockets_tls.c +++ b/subsys/net/lib/sockets/sockets_tls.c @@ -50,6 +50,7 @@ LOG_MODULE_REGISTER(net_sock_tls, CONFIG_NET_SOCKETS_LOG_LEVEL); #include "sockets_internal.h" #include "tls_internal.h" +#include "../../ip/net_private.h" #if defined(CONFIG_MBEDTLS_DEBUG) #include @@ -940,13 +941,66 @@ static int dtls_tx(void *ctx, const unsigned char *buf, size_t len) return sent; } -static int dtls_rx(void *ctx, unsigned char *buf, size_t len) +static int dtls_server_rx(void *ctx, unsigned char *buf, size_t len) { struct tls_context *tls_ctx = ctx; net_socklen_t addrlen = sizeof(struct net_sockaddr); struct net_sockaddr addr; int err; ssize_t received; + uint8_t tmp_buf; + + /* Peek the packet first to check the peer address. */ + received = zsock_recvfrom(tls_ctx->sock, &tmp_buf, sizeof(tmp_buf), + ZSOCK_MSG_DONTWAIT | ZSOCK_MSG_PEEK, + &addr, &addrlen); + if (received < 0) { + if (errno == EAGAIN) { + return MBEDTLS_ERR_SSL_WANT_READ; + } + + NET_ERR("DTLS server RX: failure %d", errno); + return MBEDTLS_ERR_NET_RECV_FAILED; + } + + /* Check if the peer address matches the current session. */ + if (tls_ctx->active_session->dtls_peer_addrlen != 0 && + !dtls_is_peer_addr_valid(tls_ctx->active_session, &addr, addrlen)) { + /* Peer address does not match the current session, exit now + * and try to find the appropriate session or allocate a new one. + */ + return MBEDTLS_ERR_SSL_WANT_READ; + } + + /* If the session matches, read the actual packet. */ + received = zsock_recvfrom(tls_ctx->sock, buf, len, + ZSOCK_MSG_DONTWAIT, &addr, &addrlen); + if (received < 0) { + NET_ERR("DTLS server RX: failure %d", errno); + return MBEDTLS_ERR_NET_RECV_FAILED; + } + + /* Only allow to store peer address for DTLS servers. */ + if (tls_ctx->active_session->dtls_peer_addrlen == 0) { + dtls_peer_address_set(tls_ctx->active_session, &addr, addrlen); + + err = mbedtls_ssl_set_client_transport_id(&tls_ctx->active_session->ssl, + (const unsigned char *)&addr, + addrlen); + if (err < 0) { + return err; + } + } + + return received; +} + +static int dtls_client_rx(void *ctx, unsigned char *buf, size_t len) +{ + struct tls_context *tls_ctx = ctx; + net_socklen_t addrlen = sizeof(struct net_sockaddr); + struct net_sockaddr addr; + ssize_t received; received = zsock_recvfrom(tls_ctx->sock, buf, len, ZSOCK_MSG_DONTWAIT, &addr, &addrlen); @@ -959,23 +1013,14 @@ static int dtls_rx(void *ctx, unsigned char *buf, size_t len) } if (tls_ctx->active_session->dtls_peer_addrlen == 0) { - /* Only allow to store peer address for DTLS servers. */ - if (tls_ctx->options.role == MBEDTLS_SSL_IS_SERVER) { - dtls_peer_address_set(tls_ctx->active_session, &addr, addrlen); - - err = mbedtls_ssl_set_client_transport_id( - &tls_ctx->active_session->ssl, - (const unsigned char *)&addr, addrlen); - if (err < 0) { - return err; - } - } else { - /* For clients it's incorrect to receive when - * no peer has been set up. - */ - return MBEDTLS_ERR_SSL_PEER_VERIFY_FAILED; - } - } else if (!dtls_is_peer_addr_valid(tls_ctx->active_session, &addr, addrlen)) { + /* For clients it's incorrect to receive when + * no peer has been set up. + */ + return MBEDTLS_ERR_SSL_PEER_VERIFY_FAILED; + } + + if (!dtls_is_peer_addr_valid(tls_ctx->active_session, &addr, addrlen)) { + /* Received packet from a different peer, drop and retry. */ return MBEDTLS_ERR_SSL_WANT_READ; } @@ -1390,8 +1435,9 @@ static int tls_mbedtls_session_init(struct tls_session_context *session_ctx, tls_tx, tls_rx, NULL); } else { #if defined(CONFIG_NET_SOCKETS_ENABLE_DTLS) - mbedtls_ssl_set_bio(&session_ctx->ssl, tls_ctx, - dtls_tx, dtls_rx, NULL); + mbedtls_ssl_set_bio(&session_ctx->ssl, tls_ctx, dtls_tx, + is_server ? dtls_server_rx : dtls_client_rx, + NULL); /* DTLS requires timer callbacks to operate */ mbedtls_ssl_set_timer_cb(&session_ctx->ssl, From cc6248d87c00b0d4e238f7b33d3c45df51cea056 Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Tue, 9 Dec 2025 16:31:12 +0100 Subject: [PATCH 0247/6328] net: sockets: tls: Refactor RX part for DTLS server Refactor RX side for DTLS server to allow session switching when a datagram from a peer that does not match current session. The server needs to loop over established sessions, and in case no session is found allocate a new one. Signed-off-by: Robert Lubos --- subsys/net/lib/sockets/sockets_tls.c | 404 ++++++++++++++++++++++----- 1 file changed, 336 insertions(+), 68 deletions(-) diff --git a/subsys/net/lib/sockets/sockets_tls.c b/subsys/net/lib/sockets/sockets_tls.c index f3aa1d0e75cf..372ebdec5b10 100644 --- a/subsys/net/lib/sockets/sockets_tls.c +++ b/subsys/net/lib/sockets/sockets_tls.c @@ -56,6 +56,14 @@ LOG_MODULE_REGISTER(net_sock_tls, CONFIG_NET_SOCKETS_LOG_LEVEL); #include #endif +#define LOG_ADDR_PORT_HELPER(addr) \ + (addr)->sa_family == NET_AF_INET ? \ + net_sprint_ipv4_addr(&net_sin(addr)->sin_addr) : \ + net_sprint_ipv6_addr(&net_sin6(addr)->sin6_addr), \ + (addr)->sa_family == NET_AF_INET ? \ + net_ntohs(net_sin(addr)->sin_port) : \ + net_ntohs(net_sin6(addr)->sin6_port) + #if defined(CONFIG_NET_SOCKETS_TLS_MAX_APP_PROTOCOLS) #define ALPN_MAX_PROTOCOLS (CONFIG_NET_SOCKETS_TLS_MAX_APP_PROTOCOLS + 1) #else @@ -1026,6 +1034,118 @@ static int dtls_client_rx(void *ctx, unsigned char *buf, size_t len) return received; } + +static int tls_mbedtls_session_init(struct tls_session_context *session_ctx, + struct tls_context *tls_ctx, bool is_server); + +/* Returns + * - 0 when session was switched, + * - 1 if session was already valid, + * - negative error code otherwise + */ +static int dtls_server_switch_active_session(struct tls_context *tls_ctx, + const struct net_sockaddr *addr, + net_socklen_t addrlen) +{ + struct tls_session_context *session_ctx = NULL; + + if (tls_ctx->active_session->dtls_peer_addrlen == 0 || + dtls_is_peer_addr_valid(tls_ctx->active_session, addr, addrlen)) { + return 1; + } + + NET_DBG("Need to swap session for [%s]:%d (current [%s]:%d)", + LOG_ADDR_PORT_HELPER(addr), + LOG_ADDR_PORT_HELPER(&tls_ctx->active_session->dtls_peer_addr)); + + SYS_SLIST_FOR_EACH_CONTAINER(&tls_ctx->sessions, session_ctx, node) { + if (dtls_is_peer_addr_valid(session_ctx, addr, addrlen)) { + NET_DBG("Found matching session (address)"); + tls_ctx->active_session = session_ctx; + return 0; + } + } + + return -ENOENT; +} + +static int dtls_server_new_active_session(struct tls_context *tls_ctx, + const struct net_sockaddr *addr, + net_socklen_t addrlen) +{ + struct tls_session_context *session_ctx = NULL; + int ret; + + session_ctx = tls_session_alloc(); + if (session_ctx == NULL) { + return -ENOMEM; + } + + ret = tls_mbedtls_session_init(session_ctx, tls_ctx, true); + if (ret < 0) { + tls_session_free(session_ctx); + return ret; + } + + dtls_peer_address_set(session_ctx, addr, addrlen); + + ret = mbedtls_ssl_set_client_transport_id(&session_ctx->ssl, + (const unsigned char *)addr, + addrlen); + if (ret < 0) { + tls_session_free(session_ctx); + return -ENOMEM; + } + +#if defined(MBEDTLS_X509_CRT_PARSE_C) + if (tls_ctx->options.is_hostname_set) { + mbedtls_ssl_set_hostname(&session_ctx->ssl, + tls_ctx->active_session->ssl.hostname); + } +#endif + + sys_slist_append(&tls_ctx->sessions, &session_ctx->node); + tls_ctx->active_session = session_ctx; + + return 0; +} + +static int dtls_server_switch_session_on_rx(struct tls_context *tls_ctx) +{ + net_socklen_t addrlen = sizeof(struct net_sockaddr); + struct net_sockaddr addr; + uint8_t tmp_buf; + int ret; + + /* Peek the datagram first to see if the session needs to be updated. */ + ret = zsock_recvfrom(tls_ctx->sock, &tmp_buf, sizeof(tmp_buf), + ZSOCK_MSG_DONTWAIT | ZSOCK_MSG_PEEK, + &addr, &addrlen); + if (ret < 0) { + return -errno; + } + + /* Try to match existing session by peer address. */ + ret = dtls_server_switch_active_session(tls_ctx, &addr, addrlen); + if (ret == 0 || ret == 1) { + return ret; + } + + /* No session found, try to allocate one. */ + + NET_DBG("No session found (RX), allocating new"); + + ret = dtls_server_new_active_session(tls_ctx, &addr, addrlen); + if (ret < 0) { + NET_ERR("Failed to allocate new session for DTLS server, " + "dropping packet (err: %d)", ret); + + (void)zsock_recv(tls_ctx->sock, &tmp_buf, sizeof(tmp_buf), + ZSOCK_MSG_DONTWAIT); + } + + return ret; +} #endif /* CONFIG_NET_SOCKETS_ENABLE_DTLS */ static int tls_tx(void *ctx, const unsigned char *buf, size_t len) @@ -1333,6 +1453,18 @@ static int tls_mbedtls_handshake(struct tls_context *context, #if defined(CONFIG_NET_SOCKETS_ENABLE_DTLS) if (context->type == NET_SOCK_DGRAM) { + if (context->options.role == MBEDTLS_SSL_IS_SERVER) { + /* DTLS server may need to switch session. */ + int err = dtls_server_switch_session_on_rx(context); + + if (err == 0) { + /* Switched the session, repeat the loop. */ + context->active_session->handshake_in_progress = + true; + continue; + } + } + int timeout_dtls = dtls_get_remaining_timeout(context->active_session); @@ -2478,12 +2610,15 @@ static int ztls_socket(int family, int type, int proto) int ztls_close_ctx(struct tls_context *ctx, int sock) { + struct tls_session_context *session_ctx = NULL; int ret, err = 0; /* Try to send close notification. */ ctx->flags = 0; - (void)mbedtls_ssl_close_notify(&ctx->active_session->ssl); + SYS_SLIST_FOR_EACH_CONTAINER(&ctx->sessions, session_ctx, node) { + (void)mbedtls_ssl_close_notify(&session_ctx->ssl); + } err = tls_release(ctx); ret = zsock_close(ctx->sock); @@ -3044,10 +3179,11 @@ static ssize_t recvfrom_dtls_common(struct tls_context *ctx, void *buf, struct net_sockaddr *src_addr, net_socklen_t *addrlen) { - int ret; + bool is_server = ctx->options.role == MBEDTLS_SSL_IS_SERVER; bool is_block = is_blocking(ctx->sock, flags); k_timeout_t timeout; k_timepoint_t end; + int ret; if (ctx->error != 0) { errno = ctx->error; @@ -3073,6 +3209,21 @@ static ssize_t recvfrom_dtls_common(struct tls_context *ctx, void *buf, ret == MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS) { int timeout_dtls, timeout_sock, timeout_ms; + if (is_server) { + int err = dtls_server_switch_session_on_rx(ctx); + + /* If session swapping is successful, return early so that + * recvfrom_dtls_server() can proceed with another + * handshake. Otherwise, there either really was no packet, + * or we've failed to allocate a new session, so the packet + * was dropped. In either case, just proceed as if there + * were no packet. + */ + if (err == 0) { + return ret; + } + } + if (!is_block) { return ret; } @@ -3238,13 +3389,25 @@ static ssize_t recvfrom_dtls_server(struct tls_context *ctx, void *buf, * a socket. */ do { + net_socklen_t peer_addrlen = sizeof(struct net_sockaddr); + struct net_sockaddr peer_addr; + repeat = false; if (!is_handshake_complete(ctx->active_session)) { ret = tls_mbedtls_handshake(ctx, timeout); if (ret < 0) { - /* In case of EAGAIN, just exit. */ + /* In case of EAGAIN, check if it's needed to swap sessions, + * otherwise just exit. + */ if (ret == -EAGAIN) { + int err = dtls_server_switch_session_on_rx(ctx); + + if (err == 0) { + /* Switched the session, repeat the loop. */ + continue; + } + break; } @@ -3262,6 +3425,9 @@ static ssize_t recvfrom_dtls_server(struct tls_context *ctx, void *buf, ctx->error = 0; } + /* Backup peer address (to verify later if it changed). */ + dtls_peer_address_get(ctx->active_session, &peer_addr, &peer_addrlen); + ret = recvfrom_dtls_common(ctx, buf, max_len, flags, src_addr, addrlen); if (ret >= 0) { @@ -3289,7 +3455,16 @@ static ssize_t recvfrom_dtls_server(struct tls_context *ctx, void *buf, case MBEDTLS_ERR_SSL_WANT_WRITE: case MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS: case MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS: - ret = -EAGAIN; + if (peer_addrlen > 0 && + !dtls_is_peer_addr_valid(ctx->active_session, &peer_addr, + peer_addrlen)) { + /* Current peer changed, repeat the loop. */ + repeat = true; + } else { + /* Otherwise, just return the error. */ + ret = -EAGAIN; + } + break; default: @@ -3422,48 +3597,137 @@ static int ztls_poll_prepare_ctx(struct tls_context *ctx, #include -static int ztls_socket_data_check(struct tls_context *ctx) +static int tls_data_check(struct tls_context *ctx) { int ret; - if (ctx->type == NET_SOCK_STREAM) { - if (!ctx->is_initialized) { + if (!ctx->is_initialized) { + return -ENOTCONN; + } + + ctx->flags = ZSOCK_MSG_DONTWAIT; + + ret = mbedtls_ssl_read(&ctx->active_session->ssl, NULL, 0); + if (ret < 0) { + if (ret == MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY) { + /* Don't reset the context for STREAM socket - the + * application needs to reopen the socket anyway, and + * resetting the context would result in an error instead + * of 0 in a consecutive recv() call. + */ + ctx->active_session->session_closed = true; + return -ENOTCONN; } + + if (ret == MBEDTLS_ERR_SSL_WANT_READ || + ret == MBEDTLS_ERR_SSL_WANT_WRITE) { + return 0; + } + + NET_ERR("%s data check error: -%x", "TLS", -ret); + + /* MbedTLS API documentation requires session to + * be reset in other error cases + */ + if (tls_mbedtls_reset_session(ctx) != 0) { + return -ENOMEM; + } + + return -ECONNABORTED; } -#if defined(CONFIG_NET_SOCKETS_ENABLE_DTLS) - else { - if (!ctx->is_initialized) { - bool is_server = ctx->options.role == MBEDTLS_SSL_IS_SERVER; - ret = tls_mbedtls_init(ctx, is_server); - if (ret < 0) { - return -ENOMEM; - } + return mbedtls_ssl_get_bytes_avail(&ctx->active_session->ssl); +} + +static int tls_update_pollin(int fd, struct tls_context *ctx, + struct zsock_pollfd *pfd) +{ + int ret; + + if (!ctx->is_listening) { + /* Already had TLS data to read on socket. */ + if (mbedtls_ssl_get_bytes_avail(&ctx->active_session->ssl) > 0) { + pfd->revents |= ZSOCK_POLLIN; + goto next; } + } - if (!is_handshake_complete(ctx->active_session)) { - ret = tls_mbedtls_handshake(ctx, K_NO_WAIT); - if (ret < 0) { - if (ret == -EAGAIN) { - return 0; - } + if ((pfd->revents & ZSOCK_POLLIN) == 0) { + /* No new data on a socket. */ + goto next; + } - ret = tls_mbedtls_reset_session(ctx); - if (ret != 0) { - return -ENOMEM; + if (ctx->is_listening) { + goto next; + } + + ret = tls_data_check(ctx); + if (ret == -ENOTCONN || (pfd->revents & ZSOCK_POLLHUP)) { + pfd->revents |= ZSOCK_POLLHUP; + goto next; + } else if (ret < 0) { + ctx->error = -ret; + pfd->revents |= ZSOCK_POLLERR; + goto next; + } else if (ret == 0) { + goto again; + } + +next: + return 0; + +again: + /* Received encrypted data, but still not enough + * to decrypt it and return data through socket, + * ask for retry if no other events are set. + */ + pfd->revents &= ~ZSOCK_POLLIN; + + return -EAGAIN; +} + +#if defined(CONFIG_NET_SOCKETS_ENABLE_DTLS) +static int dtls_data_check(struct tls_context *ctx) +{ + bool is_server = ctx->options.role == MBEDTLS_SSL_IS_SERVER; + int ret; + + if (!ctx->is_initialized) { + ret = tls_mbedtls_init(ctx, is_server); + if (ret < 0) { + return -ENOMEM; + } + } + +again: + if (!is_handshake_complete(ctx->active_session)) { + ret = tls_mbedtls_handshake(ctx, K_NO_WAIT); + if (ret < 0) { + if (ret == -EAGAIN) { + if (is_server) { + ret = dtls_server_switch_session_on_rx(ctx); + if (ret == 0) { + goto again; + } } return 0; } - /* Socket ready to use again. */ - ctx->error = 0; + ret = tls_mbedtls_reset_session(ctx); + if (ret != 0) { + return -ENOMEM; + } return 0; } + + /* Socket ready to use again. */ + ctx->error = 0; + + return 0; } -#endif /* CONFIG_NET_SOCKETS_ENABLE_DTLS */ ctx->flags = ZSOCK_MSG_DONTWAIT; @@ -3475,13 +3739,9 @@ static int ztls_socket_data_check(struct tls_context *ctx) * resetting the context would result in an error instead * of 0 in a consecutive recv() call. */ - if (ctx->type == NET_SOCK_DGRAM) { - ret = tls_mbedtls_reset_session(ctx); - if (ret != 0) { - return -ENOMEM; - } - } else { - ctx->active_session->session_closed = true; + ret = tls_mbedtls_reset_session(ctx); + if (ret != 0) { + return -ENOMEM; } return -ENOTCONN; @@ -3489,11 +3749,23 @@ static int ztls_socket_data_check(struct tls_context *ctx) if (ret == MBEDTLS_ERR_SSL_WANT_READ || ret == MBEDTLS_ERR_SSL_WANT_WRITE) { + if (is_server) { + ret = dtls_server_switch_session_on_rx(ctx); + if (ret == 0) { + goto again; + } + } + return 0; } NET_ERR("TLS data check error: -%x", -ret); + if (ret == MBEDTLS_ERR_SSL_TIMEOUT) { + /* Send close notification before session is released. */ + (void)mbedtls_ssl_close_notify(&ctx->active_session->ssl); + } + /* MbedTLS API documentation requires session to * be reset in other error cases */ @@ -3501,63 +3773,46 @@ static int ztls_socket_data_check(struct tls_context *ctx) return -ENOMEM; } -#if defined(CONFIG_NET_SOCKETS_ENABLE_DTLS) - if (ret == MBEDTLS_ERR_SSL_TIMEOUT && ctx->type == NET_SOCK_DGRAM) { + if (ret == MBEDTLS_ERR_SSL_TIMEOUT) { /* DTLS timeout interpreted as closing of connection. */ return -ENOTCONN; } -#endif + return -ECONNABORTED; } return mbedtls_ssl_get_bytes_avail(&ctx->active_session->ssl); } -static int ztls_poll_update_pollin(int fd, struct tls_context *ctx, - struct zsock_pollfd *pfd) +static int dtls_update_pollin(int fd, struct tls_context *ctx, + struct zsock_pollfd *pfd) { int ret; - if (!ctx->is_listening) { - /* Already had TLS data to read on socket. */ - if (mbedtls_ssl_get_bytes_avail(&ctx->active_session->ssl) > 0) { - pfd->revents |= ZSOCK_POLLIN; - goto next; - } + /* Already had DTLS data to read on socket. */ + if (mbedtls_ssl_get_bytes_avail(&ctx->active_session->ssl) > 0) { + pfd->revents |= ZSOCK_POLLIN; + goto next; } - if (ctx->type == NET_SOCK_STREAM) { - if (!(pfd->revents & ZSOCK_POLLIN)) { - /* No new data on a socket. */ - goto next; - } - - if (ctx->is_listening) { - goto next; - } - } -#if defined(CONFIG_NET_SOCKETS_ENABLE_DTLS) - else { - /* Perform data check without incoming data for completed DTLS connections. - * This allows the connections to timeout with CONFIG_NET_SOCKETS_DTLS_TIMEOUT. - */ - if (!is_handshake_complete(ctx->active_session) && !(pfd->revents & ZSOCK_POLLIN)) { - goto next; - } + /* Perform data check without incoming data for completed DTLS connections. + * This allows the connections to timeout with CONFIG_NET_SOCKETS_DTLS_TIMEOUT. + */ + if (!is_handshake_complete(ctx->active_session) && (pfd->revents & ZSOCK_POLLIN) == 0) { + goto next; } -#endif - ret = ztls_socket_data_check(ctx); + + ret = dtls_data_check(ctx); if (ret == -ENOTCONN || (pfd->revents & ZSOCK_POLLHUP)) { /* Datagram does not return 0 on consecutive recv, but an error * code, hence clear POLLIN. */ - if (ctx->type == NET_SOCK_DGRAM) { - pfd->revents &= ~ZSOCK_POLLIN; - } + pfd->revents &= ~ZSOCK_POLLIN; pfd->revents |= ZSOCK_POLLHUP; goto next; } else if (ret < 0) { ctx->error = -ret; + pfd->revents &= ~ZSOCK_POLLIN; pfd->revents |= ZSOCK_POLLERR; goto next; } else if (ret == 0) { @@ -3576,6 +3831,19 @@ static int ztls_poll_update_pollin(int fd, struct tls_context *ctx, return -EAGAIN; } +#endif /* CONFIG_NET_SOCKETS_ENABLE_DTLS */ + +static int ztls_poll_update_pollin(int fd, struct tls_context *ctx, + struct zsock_pollfd *pfd) +{ +#if defined(CONFIG_NET_SOCKETS_ENABLE_DTLS) + if (ctx->type == NET_SOCK_DGRAM) { + return dtls_update_pollin(fd, ctx, pfd); + } +#endif + + return tls_update_pollin(fd, ctx, pfd); +} static int ztls_poll_update_ctx(struct tls_context *ctx, struct zsock_pollfd *pfd, From 6f58b3f24f9d75537e67ddb915c2b5e7200b4daf Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Tue, 9 Dec 2025 16:31:13 +0100 Subject: [PATCH 0248/6328] net: sockets: tls: DTLS server session matching on TX For TX, the DTLS server needs to check the peer address before passing the packet to mbed TLS. In case the peer address doesn't match the active session, it needs to switch sessions. Signed-off-by: Robert Lubos --- subsys/net/lib/sockets/sockets_tls.c | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/subsys/net/lib/sockets/sockets_tls.c b/subsys/net/lib/sockets/sockets_tls.c index 372ebdec5b10..9a3c67588762 100644 --- a/subsys/net/lib/sockets/sockets_tls.c +++ b/subsys/net/lib/sockets/sockets_tls.c @@ -2926,6 +2926,19 @@ static ssize_t sendto_dtls_server(struct tls_context *ctx, const void *buf, const struct net_sockaddr *dest_addr, net_socklen_t addrlen) { + int ret; + + if (dest_addr != NULL) { + /* Verify we have a session with the client. */ + ret = dtls_server_switch_active_session(ctx, dest_addr, addrlen); + if (ret < 0) { + NET_DBG("No session found (TX) for [%s]:%d", + LOG_ADDR_PORT_HELPER(dest_addr)); + errno = ENOTCONN; + return -1; + } + } + /* For DTLS server, require to have established DTLS connection * in order to send data. */ @@ -2934,13 +2947,6 @@ static ssize_t sendto_dtls_server(struct tls_context *ctx, const void *buf, return -1; } - /* Verify we are sending to a peer that we have connection with. */ - if (dest_addr && - !dtls_is_peer_addr_valid(ctx->active_session, dest_addr, addrlen) != 0) { - errno = EISCONN; - return -1; - } - return send_tls(ctx, buf, len, flags); } #endif /* CONFIG_NET_SOCKETS_ENABLE_DTLS */ From 4197720be805fe119ebcfc1f01c693b2c20079cf Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Tue, 9 Dec 2025 16:31:13 +0100 Subject: [PATCH 0249/6328] net: sockets: tls: Free DTLS server active session on errors In case of errors on an active session (in most cases peer closing the session), the session should be freed. Note, that as mbed TLS needs some session context to work with, the last session on a socket is not freed, but only reset instead. Signed-off-by: Robert Lubos --- subsys/net/lib/sockets/sockets_tls.c | 71 +++++++++++++++++++++++----- 1 file changed, 59 insertions(+), 12 deletions(-) diff --git a/subsys/net/lib/sockets/sockets_tls.c b/subsys/net/lib/sockets/sockets_tls.c index 9a3c67588762..3db1a0f1b141 100644 --- a/subsys/net/lib/sockets/sockets_tls.c +++ b/subsys/net/lib/sockets/sockets_tls.c @@ -302,6 +302,8 @@ static struct k_mutex context_lock; */ #define TLS_WAIT_MS 100 +static int tls_mbedtls_reset_session(struct tls_context *context); + static void tls_session_cache_reset(void) { for (int i = 0; i < ARRAY_SIZE(client_cache); i++) { @@ -1146,6 +1148,30 @@ static int dtls_server_switch_session_on_rx(struct tls_context *tls_ctx) return ret; } + +static int dtls_server_free_active_session(struct tls_context *tls_ctx) +{ + int ret = 0; + + if (sys_slist_len(&tls_ctx->sessions) > 1) { + struct tls_session_context *session_ctx; + + /* Free the session and set the active session to any other. */ + sys_slist_find_and_remove(&tls_ctx->sessions, + &tls_ctx->active_session->node); + tls_session_free(tls_ctx->active_session); + tls_ctx->active_session = + SYS_SLIST_PEEK_HEAD_CONTAINER(&tls_ctx->sessions, + session_ctx, node); + } else { + /* Last session, just reset it. */ + ret = tls_mbedtls_reset_session(tls_ctx); + } + + tls_ctx->error = 0; + + return ret; +} #endif /* CONFIG_NET_SOCKETS_ENABLE_DTLS */ static int tls_tx(void *ctx, const unsigned char *buf, size_t len) @@ -2947,7 +2973,12 @@ static ssize_t sendto_dtls_server(struct tls_context *ctx, const void *buf, return -1; } - return send_tls(ctx, buf, len, flags); + ret = send_tls(ctx, buf, len, flags); + if (ret < 0 && errno != EAGAIN) { + (void)dtls_server_free_active_session(ctx); + } + + return ret; } #endif /* CONFIG_NET_SOCKETS_ENABLE_DTLS */ @@ -3417,7 +3448,7 @@ static ssize_t recvfrom_dtls_server(struct tls_context *ctx, void *buf, break; } - ret = tls_mbedtls_reset_session(ctx); + ret = dtls_server_free_active_session(ctx); if (ret == 0) { repeat = true; } else { @@ -3448,7 +3479,7 @@ static ssize_t recvfrom_dtls_server(struct tls_context *ctx, void *buf, case MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY: case MBEDTLS_ERR_SSL_CLIENT_RECONNECT: - ret = tls_mbedtls_reset_session(ctx); + ret = dtls_server_free_active_session(ctx); if (ret == 0) { repeat = true; } else { @@ -3476,13 +3507,12 @@ static ssize_t recvfrom_dtls_server(struct tls_context *ctx, void *buf, default: NET_ERR("DTLS server recv error: -%x", -ret); - ret = tls_mbedtls_reset_session(ctx); - if (ret != 0) { + ret = dtls_server_free_active_session(ctx); + if (ret == 0) { + repeat = true; + } else { ctx->error = ENOMEM; errno = ENOMEM; - } else { - ctx->error = ECONNABORTED; - ret = -ECONNABORTED; } break; @@ -3721,7 +3751,12 @@ static int dtls_data_check(struct tls_context *ctx) return 0; } - ret = tls_mbedtls_reset_session(ctx); + if (is_server) { + ret = dtls_server_free_active_session(ctx); + } else { + ret = tls_mbedtls_reset_session(ctx); + } + if (ret != 0) { return -ENOMEM; } @@ -3745,7 +3780,13 @@ static int dtls_data_check(struct tls_context *ctx) * resetting the context would result in an error instead * of 0 in a consecutive recv() call. */ - ret = tls_mbedtls_reset_session(ctx); + + if (is_server) { + ret = dtls_server_free_active_session(ctx); + } else { + ret = tls_mbedtls_reset_session(ctx); + } + if (ret != 0) { return -ENOMEM; } @@ -3775,8 +3816,14 @@ static int dtls_data_check(struct tls_context *ctx) /* MbedTLS API documentation requires session to * be reset in other error cases */ - if (tls_mbedtls_reset_session(ctx) != 0) { - return -ENOMEM; + if (is_server) { + if (dtls_server_free_active_session(ctx) != 0) { + return -ENOMEM; + } + } else { + if (tls_mbedtls_reset_session(ctx) != 0) { + return -ENOMEM; + } } if (ret == MBEDTLS_ERR_SSL_TIMEOUT) { From 53be38d3f065293187c58878a1c89c511016e40b Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Tue, 9 Dec 2025 16:31:14 +0100 Subject: [PATCH 0250/6328] net: sockets: tls: Implement DTLS server session matching by CID In case a client address changes, but a session uses Connection ID extension, the server should verify if the packet belongs to any of the established sessions based on the CID value. Therefore, before attempting to allocate a new session in such case, loop over sessions and try to match the packet to one of the existing sessions based on CID. In case of success, update the corresponding peer address. If no session is found based on CID, only then try to allocate a new one. Signed-off-by: Robert Lubos --- subsys/net/lib/sockets/sockets_tls.c | 87 +++++++++++++++++++++++++++- 1 file changed, 86 insertions(+), 1 deletion(-) diff --git a/subsys/net/lib/sockets/sockets_tls.c b/subsys/net/lib/sockets/sockets_tls.c index 3db1a0f1b141..d69fd01cb8c6 100644 --- a/subsys/net/lib/sockets/sockets_tls.c +++ b/subsys/net/lib/sockets/sockets_tls.c @@ -1112,6 +1112,85 @@ static int dtls_server_new_active_session(struct tls_context *tls_ctx, return 0; } +#if defined(CONFIG_MBEDTLS_SSL_DTLS_CONNECTION_ID) +static K_MUTEX_DEFINE(dtls_server_cid_check_lock); + +static int dtls_server_switch_active_session_by_cid(struct tls_context *tls_ctx) +{ + static uint8_t tmp_buf[MBEDTLS_SSL_IN_CONTENT_LEN]; + struct tls_session_context *session_ctx = NULL; + int result = -ENOENT; + + if (!tls_ctx->options.dtls_cid.enabled) { + return -ENOTSUP; + } + + k_mutex_lock(&dtls_server_cid_check_lock, K_FOREVER); + + SYS_SLIST_FOR_EACH_CONTAINER(&tls_ctx->sessions, session_ctx, node) { + struct net_sockaddr addr; + net_socklen_t addrlen; + int cid_enabled; + ssize_t len; + int ret; + + ret = mbedtls_ssl_get_peer_cid(&session_ctx->ssl, &cid_enabled, + NULL, NULL); + if (ret != 0 || cid_enabled != MBEDTLS_SSL_CID_ENABLED) { + continue; + } + + /* This deserves some additional context. The only way I found to + * check if the datagram matches current session based on DTLS CID + * is mbedtls_ssl_check_record() function (which according to the + * API documentation serves exactly the purpose). Because of this, + * we need to: + * - peek the full datagram from the socket this time, not just + * a dummy byte, + * - and as the function may modify the provided datagram, we + * need to repeat this for each checked client session. + * + * As the DTLS records can take up to 16kB in size depending on + * the configuration, it's been decided to dedicate a single + * static buffer for the purpose, and protect it with a mutex to + * avoid races in case multiple DTLS server sockets run in parallel. + */ + addrlen = sizeof(struct net_sockaddr); + len = zsock_recvfrom(tls_ctx->sock, &tmp_buf, sizeof(tmp_buf), + ZSOCK_MSG_DONTWAIT | ZSOCK_MSG_PEEK, + &addr, &addrlen); + if (len < 0) { + result = -errno; + break; + } + + ret = mbedtls_ssl_check_record(&session_ctx->ssl, tmp_buf, len); + if (ret == 0) { + NET_DBG("Found matching session (CID) for [%s]:%d (was [%s]:%d)", + LOG_ADDR_PORT_HELPER(&addr), + LOG_ADDR_PORT_HELPER(&session_ctx->dtls_peer_addr)); + + /* Need to update peer address as CID matched */ + dtls_peer_address_set(session_ctx, &addr, addrlen); + tls_ctx->active_session = session_ctx; + result = 0; + break; + } + } + + k_mutex_unlock(&dtls_server_cid_check_lock); + + return result; +} +#else +#define dtls_server_switch_active_session_by_cid(...) (-ENOTSUP) +#endif /* defined(CONFIG_MBEDTLS_SSL_DTLS_CONNECTION_ID) */ + +/* Returns + * - 0 when session was switched or updated, + * - 1 if session was already valid, + * - negative error code otherwise + */ static int dtls_server_switch_session_on_rx(struct tls_context *tls_ctx) { net_socklen_t addrlen = sizeof(struct net_sockaddr); @@ -1119,7 +1198,7 @@ static int dtls_server_switch_session_on_rx(struct tls_context *tls_ctx) uint8_t tmp_buf; int ret; - /* Peek the datagram first to see if the session needs to be updated. */ + /* Peek a dummy byte first to get peer address. */ ret = zsock_recvfrom(tls_ctx->sock, &tmp_buf, sizeof(tmp_buf), ZSOCK_MSG_DONTWAIT | ZSOCK_MSG_PEEK, &addr, &addrlen); @@ -1133,6 +1212,12 @@ static int dtls_server_switch_session_on_rx(struct tls_context *tls_ctx) return ret; } + /* Not found, try to match existing session by CID */ + ret = dtls_server_switch_active_session_by_cid(tls_ctx); + if (ret == 0) { + return 0; + } + /* No session found, try to allocate one. */ NET_DBG("No session found (RX), allocating new"); From ab07f691285d7d28504c0d65d92ad3e1007f256c Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Tue, 9 Dec 2025 16:31:15 +0100 Subject: [PATCH 0251/6328] net: sockets: tls: DTLS server session timeout rework With support for multiple client sessions for DTLS server socket, the session timeout can no longer rely on built-in mbed TLS timing out mechanism, as this only works for the session that is currently active. Background sessions would never time out if the client just went silent. Therefore, allocate a per-session timestamp, that keeps track of the last activity on the session. Then, whenever poll() or recv() is called loop over all sessions to identify those that timed and should be released. Signed-off-by: Robert Lubos --- subsys/net/lib/sockets/sockets_tls.c | 55 ++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) diff --git a/subsys/net/lib/sockets/sockets_tls.c b/subsys/net/lib/sockets/sockets_tls.c index d69fd01cb8c6..e114a6f88524 100644 --- a/subsys/net/lib/sockets/sockets_tls.c +++ b/subsys/net/lib/sockets/sockets_tls.c @@ -160,6 +160,9 @@ struct tls_session_context { /* DTLS peer address length. */ net_socklen_t dtls_peer_addrlen; + + /* DTLS session expiry time (server only). */ + k_timepoint_t session_expiry; #endif /* CONFIG_NET_SOCKETS_ENABLE_DTLS */ }; @@ -395,6 +398,17 @@ static int dtls_get_remaining_timeout(struct tls_session_context *session_ctx) return timing->fin_ms - elapsed_ms; } + +static void dtls_server_init_session_timeout(struct tls_session_context *session_ctx) +{ + session_ctx->session_expiry = sys_timepoint_calc(K_FOREVER); +} + +static void dtls_server_refresh_session_timeout(struct tls_session_context *session_ctx) +{ + session_ctx->session_expiry = + sys_timepoint_calc(K_MSEC(CONFIG_NET_SOCKETS_DTLS_TIMEOUT)); +} #endif /* CONFIG_NET_SOCKETS_ENABLE_DTLS */ /* Initialize TLS internals. */ @@ -937,6 +951,10 @@ static int dtls_tx(void *ctx, const unsigned char *buf, size_t len) struct tls_context *tls_ctx = ctx; ssize_t sent; + if (tls_ctx->options.role == MBEDTLS_SSL_IS_SERVER) { + dtls_server_refresh_session_timeout(tls_ctx->active_session); + } + sent = zsock_sendto(tls_ctx->sock, buf, len, ZSOCK_MSG_DONTWAIT, &tls_ctx->active_session->dtls_peer_addr, tls_ctx->active_session->dtls_peer_addrlen); @@ -990,6 +1008,8 @@ static int dtls_server_rx(void *ctx, unsigned char *buf, size_t len) return MBEDTLS_ERR_NET_RECV_FAILED; } + dtls_server_refresh_session_timeout(tls_ctx->active_session); + /* Only allow to store peer address for DTLS servers. */ if (tls_ctx->active_session->dtls_peer_addrlen == 0) { dtls_peer_address_set(tls_ctx->active_session, &addr, addrlen); @@ -1109,6 +1129,8 @@ static int dtls_server_new_active_session(struct tls_context *tls_ctx, sys_slist_append(&tls_ctx->sessions, &session_ctx->node); tls_ctx->active_session = session_ctx; + dtls_server_refresh_session_timeout(session_ctx); + return 0; } @@ -1238,6 +1260,8 @@ static int dtls_server_free_active_session(struct tls_context *tls_ctx) { int ret = 0; + dtls_server_init_session_timeout(tls_ctx->active_session); + if (sys_slist_len(&tls_ctx->sessions) > 1) { struct tls_session_context *session_ctx; @@ -1257,6 +1281,23 @@ static int dtls_server_free_active_session(struct tls_context *tls_ctx) return ret; } + +static bool dtls_server_check_expired_sessions(struct tls_context *tls_ctx) +{ + struct tls_session_context *session_ctx, *next; + bool expired = false; + + SYS_SLIST_FOR_EACH_CONTAINER_SAFE(&tls_ctx->sessions, session_ctx, next, node) { + if (sys_timepoint_expired(session_ctx->session_expiry)) { + tls_ctx->active_session = session_ctx; + (void)mbedtls_ssl_close_notify(&tls_ctx->active_session->ssl); + (void)dtls_server_free_active_session(tls_ctx); + expired = true; + } + } + + return expired; +} #endif /* CONFIG_NET_SOCKETS_ENABLE_DTLS */ static int tls_tx(void *ctx, const unsigned char *buf, size_t len) @@ -1687,6 +1728,9 @@ static int tls_mbedtls_session_init(struct tls_session_context *session_ctx, &session_ctx->dtls_timing, dtls_timing_set_delay, dtls_timing_get_delay); + + dtls_server_init_session_timeout(session_ctx); + #if defined(CONFIG_MBEDTLS_SSL_DTLS_CONNECTION_ID) if (tls_ctx->options.dtls_cid.enabled) { ret = mbedtls_ssl_set_cid(&session_ctx->ssl, MBEDTLS_SSL_CID_ENABLED, @@ -3516,6 +3560,8 @@ static ssize_t recvfrom_dtls_server(struct tls_context *ctx, void *buf, repeat = false; + (void)dtls_server_check_expired_sessions(ctx); + if (!is_handshake_complete(ctx->active_session)) { ret = tls_mbedtls_handshake(ctx, timeout); if (ret < 0) { @@ -3583,6 +3629,7 @@ static ssize_t recvfrom_dtls_server(struct tls_context *ctx, void *buf, /* Current peer changed, repeat the loop. */ repeat = true; } else { + (void)dtls_server_check_expired_sessions(ctx); /* Otherwise, just return the error. */ ret = -EAGAIN; } @@ -3822,6 +3869,10 @@ static int dtls_data_check(struct tls_context *ctx) } again: + if (is_server && dtls_server_check_expired_sessions(ctx)) { + return -ENOTCONN; + } + if (!is_handshake_complete(ctx->active_session)) { ret = tls_mbedtls_handshake(ctx, K_NO_WAIT); if (ret < 0) { @@ -3886,6 +3937,10 @@ static int dtls_data_check(struct tls_context *ctx) if (ret == 0) { goto again; } + + if (dtls_server_check_expired_sessions(ctx)) { + return -ENOTCONN; + } } return 0; From 8afc2af3c2213364c3e1c13528b15d12fa3c0bf9 Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Mon, 15 Dec 2025 16:24:49 +0100 Subject: [PATCH 0252/6328] net: sockets: tls: Make socket options work with multi-client server For options that return the handshake status, make sure they work in multi-client DTLS server case, by returning the status for the session that completed handshake most recently. For TLS and DTLS client cases that should make no difference, as there should only be one session per context. Signed-off-by: Robert Lubos --- subsys/net/lib/sockets/sockets_tls.c | 52 ++++++++++++++++++++++++---- 1 file changed, 45 insertions(+), 7 deletions(-) diff --git a/subsys/net/lib/sockets/sockets_tls.c b/subsys/net/lib/sockets/sockets_tls.c index e114a6f88524..1725c4046878 100644 --- a/subsys/net/lib/sockets/sockets_tls.c +++ b/subsys/net/lib/sockets/sockets_tls.c @@ -2189,17 +2189,38 @@ static int tls_opt_ciphersuite_list_get(struct tls_context *context, return 0; } +static struct tls_session_context *get_latest_session(struct tls_context *context) +{ + struct tls_session_context *session_ctx = NULL; + struct tls_session_context *latest_session_ctx = NULL; + + SYS_SLIST_FOR_EACH_CONTAINER(&context->sessions, session_ctx, node) { + if ((latest_session_ctx == NULL) || + (session_ctx->handshake_timestamp > + latest_session_ctx->handshake_timestamp)) { + latest_session_ctx = session_ctx; + } + } + + return latest_session_ctx; +} + static int tls_opt_ciphersuite_used_get(struct tls_context *context, void *optval, net_socklen_t *optlen) { + struct tls_session_context *session_ctx; const char *ciph; if (*optlen != sizeof(int)) { return -EINVAL; } + session_ctx = get_latest_session(context); + if (session_ctx == NULL) { + return -ENOTCONN; + } - ciph = mbedtls_ssl_get_ciphersuite(&context->active_session->ssl); + ciph = mbedtls_ssl_get_ciphersuite(&session_ctx->ssl); if (ciph == NULL) { return -ENOTCONN; } @@ -2385,6 +2406,7 @@ static int tls_opt_dtls_peer_connection_id_value_get(struct tls_context *context net_socklen_t *optlen) { #if defined(CONFIG_MBEDTLS_SSL_DTLS_CONNECTION_ID) + struct tls_session_context *session_ctx; int enabled = false; int ret; size_t optlen_local; @@ -2393,8 +2415,12 @@ static int tls_opt_dtls_peer_connection_id_value_get(struct tls_context *context return -ENOTCONN; } - ret = mbedtls_ssl_get_peer_cid(&context->active_session->ssl, &enabled, - optval, &optlen_local); + session_ctx = get_latest_session(context); + if (session_ctx == NULL) { + return -ENOTCONN; + } + + ret = mbedtls_ssl_get_peer_cid(&session_ctx->ssl, &enabled, optval, &optlen_local); if (enabled) { *optlen = optlen_local; } else { @@ -2410,6 +2436,7 @@ static int tls_opt_dtls_connection_id_status_get(struct tls_context *context, void *optval, net_socklen_t *optlen) { #if defined(CONFIG_MBEDTLS_SSL_DTLS_CONNECTION_ID) + struct tls_session_context *session_ctx; struct tls_dtls_cid cid; int ret; int val; @@ -2425,9 +2452,13 @@ static int tls_opt_dtls_connection_id_status_get(struct tls_context *context, return -ENOTCONN; } - ret = mbedtls_ssl_get_peer_cid(&context->active_session->ssl, &enabled, - cid.cid, - &cid.cid_len); + session_ctx = get_latest_session(context); + if (session_ctx == NULL) { + return -ENOTCONN; + } + + ret = mbedtls_ssl_get_peer_cid(&session_ctx->ssl, &enabled, + cid.cid, &cid.cid_len); if (ret) { /* Handshake is not complete */ return -EAGAIN; @@ -2555,11 +2586,18 @@ static int tls_opt_session_cache_get(struct tls_context *context, static int tls_opt_cert_verify_result_get(struct tls_context *context, void *optval, net_socklen_t *optlen) { + struct tls_session_context *session_ctx; + if (*optlen != sizeof(uint32_t)) { return -EINVAL; } - *(uint32_t *)optval = mbedtls_ssl_get_verify_result(&context->active_session->ssl); + session_ctx = get_latest_session(context); + if (session_ctx == NULL) { + return -ENOTCONN; + } + + *(uint32_t *)optval = mbedtls_ssl_get_verify_result(&session_ctx->ssl); return 0; } From 3cc194ee35f6390dde4ca7f402a34c5b2a287ca3 Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Tue, 9 Dec 2025 16:31:16 +0100 Subject: [PATCH 0253/6328] tests: net: sockets: tls: Add test cases for DTLS server multi-client Add test cases verifying that DTLS server socket can handle multiple clients. Signed-off-by: Robert Lubos --- tests/net/socket/tls/prj.conf | 4 +- tests/net/socket/tls/src/main.c | 805 ++++++++++++++++++++++++++++- tests/net/socket/tls/testcase.yaml | 3 + 3 files changed, 808 insertions(+), 4 deletions(-) diff --git a/tests/net/socket/tls/prj.conf b/tests/net/socket/tls/prj.conf index 77646a01bdf2..63a0067e753f 100644 --- a/tests/net/socket/tls/prj.conf +++ b/tests/net/socket/tls/prj.conf @@ -26,6 +26,7 @@ CONFIG_ZVFS_OPEN_ADD_SIZE_NET=10 CONFIG_NET_TCP_TIME_WAIT_DELAY=10 CONFIG_NET_SOCKETS_CONNECT_TIMEOUT=200 CONFIG_NET_SOCKETS_TLS_CONNECT_TIMEOUT=200 +CONFIG_NET_SOCKETS_DTLS_TIMEOUT=1000 # Network driver config CONFIG_NET_DRIVERS=y @@ -47,7 +48,8 @@ CONFIG_ZTEST=y CONFIG_ZTEST_STACK_SIZE=4096 CONFIG_MBEDTLS_ENABLE_HEAP=y -CONFIG_MBEDTLS_HEAP_SIZE=18000 +CONFIG_MBEDTLS_HEAP_SIZE=30000 CONFIG_MBEDTLS_KEY_EXCHANGE_PSK_ENABLED=y CONFIG_MBEDTLS_HASH_ALL_ENABLED=y CONFIG_MBEDTLS_CMAC=y +CONFIG_MBEDTLS_SSL_DTLS_CONNECTION_ID=y diff --git a/tests/net/socket/tls/src/main.c b/tests/net/socket/tls/src/main.c index 1e5b34911f34..e3325407259e 100644 --- a/tests/net/socket/tls/src/main.c +++ b/tests/net/socket/tls/src/main.c @@ -15,6 +15,9 @@ LOG_MODULE_REGISTER(net_test, CONFIG_NET_SOCKETS_LOG_LEVEL); #include "../../socket_helpers.h" +struct mbedtls_ssl_context *ztls_get_mbedtls_ssl_context(int fd); +uint32_t ztls_get_session_count(void); + #define TEST_STR_SMALL "test" #define MY_IPV4_ADDR "127.0.0.1" @@ -22,6 +25,9 @@ LOG_MODULE_REGISTER(net_test, CONFIG_NET_SOCKETS_LOG_LEVEL); #define ANY_PORT 0 #define SERVER_PORT 4242 +#define CLIENT_1_PORT 4243 +#define CLIENT_2_PORT 4244 +#define CLIENT_3_PORT 4245 #define PSK_TAG 1 @@ -34,7 +40,7 @@ LOG_MODULE_REGISTER(net_test, CONFIG_NET_SOCKETS_LOG_LEVEL); K_THREAD_STACK_DEFINE(tls_test_work_queue_stack, TLS_TEST_WORK_QUEUE_STACK_SIZE); static struct k_work_q tls_test_work_queue; -int c_sock = -1, s_sock = -1, new_sock = -1; +int c_sock = -1, c_sock_2 = -1, s_sock = -1, new_sock = -1; static void test_work_reschedule(struct k_work_delayable *dwork, k_timeout_t delay) @@ -122,6 +128,14 @@ static void test_send(int sock, const void *buf, size_t len, int flags) "send failed"); } +static void test_sendto(int sock, const void *buf, size_t len, int flags, + struct net_sockaddr *addr, net_socklen_t addrlen) +{ + zassert_equal(zsock_sendto(sock, buf, len, flags, addr, addrlen), + len, + "sendto failed"); +} + static void test_sendmsg(int sock, const struct net_msghdr *msg, int flags) { size_t total_len = 0; @@ -165,6 +179,11 @@ static void test_sockets_close(void) c_sock = -1; } + if (c_sock_2 >= 0) { + test_close(c_sock_2); + c_sock_2 = -1; + } + if (s_sock >= 0) { test_close(s_sock); s_sock = -1; @@ -1721,8 +1740,6 @@ ZTEST(net_socket_tls, test_poll_dtls_pollhup) k_msleep(10); } -mbedtls_ssl_context *ztls_get_mbedtls_ssl_context(int fd); - ZTEST(net_socket_tls, test_poll_tls_pollerr) { uint8_t rx_buf; @@ -1880,6 +1897,788 @@ ZTEST(net_socket_tls, test_dtls_bad_cred) test_bad_cred_common(true); } +static void dtls_client_connect_send_no_assert_work_handler(struct k_work *work) +{ + struct k_work_delayable *dwork = k_work_delayable_from_work(work); + struct connect_data *data = + CONTAINER_OF(dwork, struct connect_data, work); + uint8_t tx_buf = 0; + int ret; + + ret = zsock_connect(data->sock, data->addr, data->addr->sa_family == NET_AF_INET ? + sizeof(struct net_sockaddr_in) : sizeof(struct net_sockaddr_in6)); + if (ret < 0) { + return; + } + + zsock_send(data->sock, &tx_buf, sizeof(tx_buf), 0); +} + +static void dtls_verify_address(struct net_sockaddr *addr, net_socklen_t addrlen, + struct net_sockaddr *expected) +{ + if (expected->sa_family == NET_AF_INET) { + zassert_equal(addrlen, sizeof(struct net_sockaddr_in), "Address length mismatch"); + zassert_equal(net_sin(addr)->sin_family, NET_AF_INET, "Address family mismatch"); + zassert_equal(net_sin(addr)->sin_port, net_sin(expected)->sin_port, + "Address port mismatch"); + zassert_equal(net_sin(addr)->sin_addr.s_addr, net_sin(expected)->sin_addr.s_addr, + "Address mismatch"); + } else { + zassert_equal(addrlen, sizeof(struct net_sockaddr_in6), "Address length mismatch"); + zassert_equal(net_sin6(addr)->sin6_family, NET_AF_INET6, "Address family mismatch"); + zassert_equal(net_sin6(addr)->sin6_port, net_sin6(expected)->sin6_port, + "Address port mismatch"); + zassert_mem_equal(net_sin6(addr)->sin6_addr.s6_addr, + net_sin6(expected)->sin6_addr.s6_addr, + NET_IPV6_ADDR_SIZE, "Address mismatch"); + } +} + +static void test_dtls_server_multi_client_prepare_socks(net_sa_family_t family, + struct net_sockaddr *s_saddr, + struct net_sockaddr *c_saddr_1, + struct net_sockaddr *c_saddr_2) +{ + net_socklen_t exp_addrlen = family == NET_AF_INET6 ? + sizeof(struct net_sockaddr_in6) : + sizeof(struct net_sockaddr_in); + struct timeval timeo_optval = { + .tv_sec = 1, + .tv_usec = 0, + }; + int role = ZSOCK_TLS_DTLS_ROLE_SERVER; + + if (family == NET_AF_INET6) { + prepare_sock_dtls_v6(MY_IPV6_ADDR, CLIENT_1_PORT, &c_sock, + (struct net_sockaddr_in6 *)c_saddr_1, + NET_IPPROTO_DTLS_1_2); + prepare_sock_dtls_v6(MY_IPV6_ADDR, CLIENT_2_PORT, &c_sock_2, + (struct net_sockaddr_in6 *)c_saddr_2, + NET_IPPROTO_DTLS_1_2); + prepare_sock_dtls_v6(MY_IPV6_ADDR, SERVER_PORT, &s_sock, + (struct net_sockaddr_in6 *)s_saddr, + NET_IPPROTO_DTLS_1_2); + } else { + prepare_sock_dtls_v4(MY_IPV4_ADDR, CLIENT_1_PORT, &c_sock, + (struct net_sockaddr_in *)c_saddr_1, + NET_IPPROTO_DTLS_1_2); + prepare_sock_dtls_v4(MY_IPV4_ADDR, CLIENT_2_PORT, &c_sock_2, + (struct net_sockaddr_in *)c_saddr_2, + NET_IPPROTO_DTLS_1_2); + prepare_sock_dtls_v4(MY_IPV4_ADDR, SERVER_PORT, &s_sock, + (struct net_sockaddr_in *)s_saddr, + NET_IPPROTO_DTLS_1_2); + } + + test_config_psk(s_sock, c_sock); + test_config_psk(s_sock, c_sock_2); + + zassert_ok(zsock_setsockopt(s_sock, ZSOCK_SOL_TLS, ZSOCK_TLS_DTLS_ROLE, + &role, sizeof(role)), + "setsockopt failed (%d)", errno); + zassert_ok(zsock_setsockopt(s_sock, ZSOCK_SOL_SOCKET, ZSOCK_SO_RCVTIMEO, + &timeo_optval, sizeof(timeo_optval)), + "setsockopt failed (%d)", errno); + zassert_ok(zsock_setsockopt(c_sock, ZSOCK_SOL_SOCKET, ZSOCK_SO_RCVTIMEO, + &timeo_optval, sizeof(timeo_optval)), + "setsockopt failed (%d)", errno); + zassert_ok(zsock_setsockopt(c_sock_2, ZSOCK_SOL_SOCKET, ZSOCK_SO_RCVTIMEO, + &timeo_optval, sizeof(timeo_optval)), + "setsockopt failed (%d)", errno); + + test_bind(c_sock, c_saddr_1, exp_addrlen); + test_bind(c_sock_2, c_saddr_2, exp_addrlen); + test_bind(s_sock, s_saddr, exp_addrlen); +} + +static void test_dtls_server_multi_client_hs_in_poll(net_sa_family_t family) +{ + struct net_sockaddr c_saddr_1; + struct net_sockaddr c_saddr_2; + struct net_sockaddr s_saddr; + struct net_sockaddr recv_addr; + net_socklen_t recv_addrlen; + struct connect_data test_data; + struct zsock_pollfd fds[1]; + uint8_t tx_buf = 0; + uint8_t rx_buf; + int ret; + + test_dtls_server_multi_client_prepare_socks(family, &s_saddr, &c_saddr_1, + &c_saddr_2); + zassert_equal(ztls_get_session_count(), 3, "Expected session count mismatch"); + + /* Client 1 handshake */ + test_data.sock = c_sock; + test_data.addr = &s_saddr; + k_work_init_delayable(&test_data.work, dtls_client_connect_send_work_handler); + test_work_reschedule(&test_data.work, K_NO_WAIT); + + /* DTLS has no separate call like accept() to know when the handshake + * is complete, therefore send a dummy byte once handshake is done to + * unblock poll(). + */ + fds[0].fd = s_sock; + fds[0].events = ZSOCK_POLLIN; + ret = zsock_poll(fds, 1, 1000); + zassert_equal(ret, 1, "poll() did not report data ready"); + zassert_equal(ztls_get_session_count(), 3, + "Server shouldn't have allocated extra session yet"); + + /* Flush the dummy byte. */ + recv_addrlen = sizeof(recv_addr); + ret = zsock_recvfrom(s_sock, &rx_buf, sizeof(rx_buf), 0, + &recv_addr, &recv_addrlen); + zassert_equal(ret, sizeof(rx_buf), "recv() failed"); + dtls_verify_address(&recv_addr, recv_addrlen, &c_saddr_1); + + /* Client 2 handshake */ + test_data.sock = c_sock_2; + test_data.addr = &s_saddr; + k_work_init_delayable(&test_data.work, dtls_client_connect_send_no_assert_work_handler); + test_work_reschedule(&test_data.work, K_NO_WAIT); + + /* DTLS has no separate call like accept() to know when the handshake + * is complete, therefore send a dummy byte once handshake is done to + * unblock poll(). + */ + fds[0].fd = s_sock; + fds[0].events = ZSOCK_POLLIN; + ret = zsock_poll(fds, 1, 1000); + zassert_equal(ret, 1, "poll() did not report data ready"); + zassert_equal(ztls_get_session_count(), 4, "Server should've allocated extra session"); + + /* Flush the dummy byte. */ + recv_addrlen = sizeof(recv_addr); + ret = zsock_recvfrom(s_sock, &rx_buf, sizeof(rx_buf), 0, + &recv_addr, &recv_addrlen); + zassert_equal(ret, sizeof(rx_buf), "recv() failed"); + dtls_verify_address(&recv_addr, recv_addrlen, &c_saddr_2); + + /* Now as two sessions are established, send data from client 1 again. */ + test_send(c_sock, &tx_buf, sizeof(tx_buf), 0); + + /* And verify the server receives the data with correct address */ + fds[0].fd = s_sock; + fds[0].events = ZSOCK_POLLIN; + ret = zsock_poll(fds, 1, 1000); + zassert_equal(ret, 1, "poll() did not report data ready"); + + recv_addrlen = sizeof(recv_addr); + ret = zsock_recvfrom(s_sock, &rx_buf, sizeof(rx_buf), 0, + &recv_addr, &recv_addrlen); + zassert_equal(ret, sizeof(rx_buf), "recv() failed"); + dtls_verify_address(&recv_addr, recv_addrlen, &c_saddr_1); + + /* Repeat for client 2 again */ + test_send(c_sock_2, &tx_buf, sizeof(tx_buf), 0); + + /* And verify the server receives the data with correct address */ + fds[0].fd = s_sock; + fds[0].events = ZSOCK_POLLIN; + ret = zsock_poll(fds, 1, 1000); + zassert_equal(ret, 1, "poll() did not report data ready"); + + recv_addrlen = sizeof(recv_addr); + ret = zsock_recvfrom(s_sock, &rx_buf, sizeof(rx_buf), 0, + &recv_addr, &recv_addrlen); + zassert_equal(ret, sizeof(rx_buf), "recv() failed"); + dtls_verify_address(&recv_addr, recv_addrlen, &c_saddr_2); + + /* Close the first client session */ + test_close(c_sock); + c_sock = -1; + + /* Let the server update sessions, poll should report POLLHUP. */ + fds[0].fd = s_sock; + fds[0].events = ZSOCK_POLLIN; + ret = zsock_poll(fds, 1, 10); + zassert_equal(ret, 1, "poll() should report event"); + zassert_equal(fds[0].revents, ZSOCK_POLLHUP, "No POLLHUP event"); + + /* Two sessions should've been released (one for client, one for server) + * and the server should still be able to receive data from the second client. + */ + zassert_equal(ztls_get_session_count(), 2, "Expected session count mismatch"); + + test_send(c_sock_2, &tx_buf, sizeof(tx_buf), 0); + + fds[0].fd = s_sock; + fds[0].events = ZSOCK_POLLIN; + ret = zsock_poll(fds, 1, 1000); + zassert_equal(ret, 1, "poll() did not report data ready"); + + recv_addrlen = sizeof(recv_addr); + ret = zsock_recvfrom(s_sock, &rx_buf, sizeof(rx_buf), 0, + &recv_addr, &recv_addrlen); + zassert_equal(ret, sizeof(rx_buf), "recv() failed"); + dtls_verify_address(&recv_addr, recv_addrlen, &c_saddr_2); + + /* Close the second client session. */ + test_close(c_sock_2); + c_sock_2 = -1; + + /* Let the server update sessions. */ + fds[0].fd = s_sock; + fds[0].events = ZSOCK_POLLIN; + ret = zsock_poll(fds, 1, 10); + zassert_equal(ret, 1, "poll() should report event"); + zassert_equal(fds[0].revents, ZSOCK_POLLHUP, "No POLLHUP event"); + + /* One session should be released (client), server socket needs at least + * one DTLS session to work with (even disconnected one). + */ + zassert_equal(ztls_get_session_count(), 1, "Expected session count mismatch"); + + test_work_wait(&test_data.work); +} + +ZTEST(net_socket_tls, test_v4_dtls_server_multi_client_hs_in_poll) +{ + test_dtls_server_multi_client_hs_in_poll(NET_AF_INET); +} + +ZTEST(net_socket_tls, test_v6_dtls_server_multi_client_hs_in_poll) +{ + test_dtls_server_multi_client_hs_in_poll(NET_AF_INET6); +} + +static void test_dtls_server_multi_client_hs_in_recvfrom(net_sa_family_t family) +{ + struct net_sockaddr c_saddr_1; + struct net_sockaddr c_saddr_2; + struct net_sockaddr s_saddr; + struct net_sockaddr recv_addr; + net_socklen_t recv_addrlen; + struct connect_data test_data; + uint8_t tx_buf = 0; + uint8_t rx_buf; + int ret; + + test_dtls_server_multi_client_prepare_socks(family, &s_saddr, &c_saddr_1, + &c_saddr_2); + zassert_equal(ztls_get_session_count(), 3, "Expected session count mismatch"); + + /* Client 1 handshake */ + test_data.sock = c_sock; + test_data.addr = &s_saddr; + k_work_init_delayable(&test_data.work, dtls_client_connect_send_work_handler); + test_work_reschedule(&test_data.work, K_NO_WAIT); + + /* Block in recv for the handshake to complete. */ + recv_addrlen = sizeof(recv_addr); + ret = zsock_recvfrom(s_sock, &rx_buf, sizeof(rx_buf), 0, + &recv_addr, &recv_addrlen); + zassert_equal(ret, sizeof(rx_buf), "recv() failed"); + dtls_verify_address(&recv_addr, recv_addrlen, &c_saddr_1); + zassert_equal(ztls_get_session_count(), 3, + "Server shouldn't have allocated extra session yet"); + + /* Client 2 handshake */ + test_data.sock = c_sock_2; + test_data.addr = &s_saddr; + k_work_init_delayable(&test_data.work, dtls_client_connect_send_no_assert_work_handler); + test_work_reschedule(&test_data.work, K_NO_WAIT); + + /* Block in recv for the second handshake to complete. */ + recv_addrlen = sizeof(recv_addr); + ret = zsock_recvfrom(s_sock, &rx_buf, sizeof(rx_buf), 0, + &recv_addr, &recv_addrlen); + zassert_equal(ret, sizeof(rx_buf), "recv() failed"); + dtls_verify_address(&recv_addr, recv_addrlen, &c_saddr_2); + zassert_equal(ztls_get_session_count(), 4, "Server should've allocated extra session"); + + /* Now as two sessions are established, send data from client 1 again. */ + test_send(c_sock, &tx_buf, sizeof(tx_buf), 0); + + /* And verify the server receives the data with correct address */ + recv_addrlen = sizeof(recv_addr); + ret = zsock_recvfrom(s_sock, &rx_buf, sizeof(rx_buf), 0, + &recv_addr, &recv_addrlen); + zassert_equal(ret, sizeof(rx_buf), "recv() failed"); + dtls_verify_address(&recv_addr, recv_addrlen, &c_saddr_1); + + /* Repeat for client 2 again */ + test_send(c_sock_2, &tx_buf, sizeof(tx_buf), 0); + + /* And verify the server receives the data with correct address */ + recv_addrlen = sizeof(recv_addr); + ret = zsock_recvfrom(s_sock, &rx_buf, sizeof(rx_buf), 0, + &recv_addr, &recv_addrlen); + zassert_equal(ret, sizeof(rx_buf), "recv() failed"); + dtls_verify_address(&recv_addr, recv_addrlen, &c_saddr_2); + + /* Close the second client session */ + test_close(c_sock_2); + c_sock_2 = -1; + + /* Small delay for the alerts exchange */ + k_msleep(10); + + /* Let the server update sessions. */ + ret = zsock_recv(s_sock, &rx_buf, sizeof(rx_buf), ZSOCK_MSG_DONTWAIT); + zassert_equal(ret, -1, "recv() should've reported EAGAIN"); + zassert_equal(errno, EAGAIN, "wrong errno value"); + + /* Two sessions should've been released (one for client, one for server) + * and the server should still be able to receive data from the second client. + */ + zassert_equal(ztls_get_session_count(), 2, "Expected session count mismatch"); + + test_send(c_sock, &tx_buf, sizeof(tx_buf), 0); + + recv_addrlen = sizeof(recv_addr); + ret = zsock_recvfrom(s_sock, &rx_buf, sizeof(rx_buf), 0, + &recv_addr, &recv_addrlen); + zassert_equal(ret, sizeof(rx_buf), "recv() failed"); + dtls_verify_address(&recv_addr, recv_addrlen, &c_saddr_1); + + /* Close the first client session. */ + test_close(c_sock); + c_sock = -1; + + /* Small delay for the alerts exchange */ + k_msleep(10); + + /* Let the server update sessions. */ + ret = zsock_recv(s_sock, &rx_buf, sizeof(rx_buf), ZSOCK_MSG_DONTWAIT); + zassert_equal(ret, -1, "recv() should've reported EAGAIN"); + zassert_equal(errno, EAGAIN, "wrong errno value"); + + /* One session should be released (client), server socket needs at least + * one DTLS session to work with (even disconnected one). + */ + zassert_equal(ztls_get_session_count(), 1, "Expected session count mismatch"); + + test_work_wait(&test_data.work); +} + +ZTEST(net_socket_tls, test_v4_dtls_server_multi_client_hs_in_recvfrom) +{ + test_dtls_server_multi_client_hs_in_recvfrom(NET_AF_INET); +} + +ZTEST(net_socket_tls, test_v6_dtls_server_multi_client_hs_in_recvfrom) +{ + test_dtls_server_multi_client_hs_in_recvfrom(NET_AF_INET6); +} + +static void test_dtls_server_multi_client_prepare_two_connections( + net_sa_family_t family, struct net_sockaddr *s_saddr, + struct net_sockaddr *c_saddr_1, struct net_sockaddr *c_saddr_2, + int32_t delay) +{ + struct connect_data test_data; + uint8_t rx_buf; + int ret; + + test_dtls_server_multi_client_prepare_socks(family, s_saddr, c_saddr_1, + c_saddr_2); + /* Client 1 handshake */ + test_data.sock = c_sock; + test_data.addr = s_saddr; + k_work_init_delayable(&test_data.work, dtls_client_connect_send_work_handler); + test_work_reschedule(&test_data.work, K_NO_WAIT); + + /* Block in recv for the handshake to complete. */ + ret = zsock_recvfrom(s_sock, &rx_buf, sizeof(rx_buf), 0, NULL, NULL); + zassert_equal(ret, sizeof(rx_buf), "recv() failed"); + + if (delay > 0) { + k_msleep(delay); + } + + /* Client 2 handshake */ + test_data.sock = c_sock_2; + test_data.addr = s_saddr; + k_work_init_delayable(&test_data.work, dtls_client_connect_send_no_assert_work_handler); + test_work_reschedule(&test_data.work, K_NO_WAIT); + + /* Block in recv for the second handshake to complete. */ + ret = zsock_recvfrom(s_sock, &rx_buf, sizeof(rx_buf), 0, NULL, NULL); + zassert_equal(ret, sizeof(rx_buf), "recv() failed"); + + test_work_wait(&test_data.work); +} + +static void test_dtls_server_multi_client_sendto(net_sa_family_t family) +{ + struct net_sockaddr c_saddr_1; + struct net_sockaddr c_saddr_2; + struct net_sockaddr s_saddr; + net_socklen_t addrlen = family == NET_AF_INET6 ? + sizeof(struct net_sockaddr_in6) : + sizeof(struct net_sockaddr_in); + uint8_t tx_buf = 0; + uint8_t rx_buf; + int ret; + + test_dtls_server_multi_client_prepare_two_connections(family, &s_saddr, + &c_saddr_1, &c_saddr_2, 0); + zassert_equal(ztls_get_session_count(), 4, "Expected session count mismatch"); + + /* As two sessions are established, send data from server to client 1. */ + test_sendto(s_sock, &tx_buf, sizeof(tx_buf), 0, &c_saddr_1, addrlen); + ret = zsock_recv(c_sock, &rx_buf, sizeof(rx_buf), 0); + zassert_equal(ret, sizeof(rx_buf), "recv() failed"); + + /* Now to client 2. */ + test_sendto(s_sock, &tx_buf, sizeof(tx_buf), 0, &c_saddr_2, addrlen); + ret = zsock_recv(c_sock_2, &rx_buf, sizeof(rx_buf), 0); + zassert_equal(ret, sizeof(rx_buf), "recv() failed"); + + /* And back to client 1 again. */ + test_sendto(s_sock, &tx_buf, sizeof(tx_buf), 0, &c_saddr_1, addrlen); + ret = zsock_recv(c_sock, &rx_buf, sizeof(rx_buf), 0); + zassert_equal(ret, sizeof(rx_buf), "recv() failed"); + + /* Close the first client session */ + test_close(c_sock); + c_sock = -1; + + /* Small delay for the alerts exchange */ + k_msleep(10); + + /* Let the server update sessions. */ + ret = zsock_recv(s_sock, &rx_buf, sizeof(rx_buf), ZSOCK_MSG_DONTWAIT); + zassert_equal(ret, -1, "recv() should've reported EAGAIN"); + zassert_equal(errno, EAGAIN, "wrong errno value"); + + /* Two sessions should've been released (one for client, one for server) + * and the server should still be able to receive data from the second client. + */ + zassert_equal(ztls_get_session_count(), 2, "Expected session count mismatch"); + + /* Sending to second client should still work */ + test_sendto(s_sock, &tx_buf, sizeof(tx_buf), 0, &c_saddr_2, addrlen); + ret = zsock_recv(c_sock_2, &rx_buf, sizeof(rx_buf), 0); + zassert_equal(ret, sizeof(rx_buf), "recv() failed"); + + /* Sending to the first client should fail though. */ + ret = zsock_sendto(s_sock, &tx_buf, sizeof(tx_buf), 0, &c_saddr_1, addrlen); + zassert_equal(ret, -1, "zsock_sendto() should've failed"); + zassert_equal(errno, ENOTCONN, "wrong errno"); + + /* Close the second client session. */ + test_close(c_sock_2); + c_sock_2 = -1; + + /* Small delay for the alerts exchange */ + k_msleep(10); + + /* Let the server update sessions. */ + ret = zsock_recv(s_sock, &rx_buf, sizeof(rx_buf), ZSOCK_MSG_DONTWAIT); + zassert_equal(ret, -1, "recv() should've reported EAGAIN"); + zassert_equal(errno, EAGAIN, "wrong errno value"); + + /* One session should be released (client), server socket needs at least + * one DTLS session to work with (even disconnected one). + */ + zassert_equal(ztls_get_session_count(), 1, "Expected session count mismatch"); + + /* But sending to the second client should fail now. */ + ret = zsock_sendto(s_sock, &tx_buf, sizeof(tx_buf), 0, &c_saddr_2, addrlen); + zassert_equal(ret, -1, "zsock_sendto() should've failed"); + zassert_equal(errno, ENOTCONN, "wrong errno"); +} + +ZTEST(net_socket_tls, test_v4_dtls_server_multi_client_sendto) +{ + test_dtls_server_multi_client_sendto(NET_AF_INET); +} + +ZTEST(net_socket_tls, test_v6_dtls_server_multi_client_sendto) +{ + test_dtls_server_multi_client_sendto(NET_AF_INET6); +} + +static void test_dtls_server_cid_matching_on_addr_change(net_sa_family_t family) +{ + struct net_sockaddr c_saddr_1; + struct net_sockaddr c_saddr_2; + struct net_sockaddr c_saddr_1_backup; + struct net_sockaddr s_saddr; + struct net_sockaddr recv_addr; + net_socklen_t recv_addrlen; + net_socklen_t addrlen = family == NET_AF_INET6 ? + sizeof(struct net_sockaddr_in6) : + sizeof(struct net_sockaddr_in); + struct connect_data test_data; + uint8_t tx_buf = 0; + uint8_t rx_buf; + int cid, ret; + + if (!IS_ENABLED(CONFIG_MBEDTLS_SSL_DTLS_CONNECTION_ID)) { + ztest_test_skip(); + } + + test_dtls_server_multi_client_prepare_socks(family, &s_saddr, &c_saddr_1, + &c_saddr_2); + zassert_equal(ztls_get_session_count(), 3, "Expected session count mismatch"); + + /* Enable DTLS CID for clients */ + cid = ZSOCK_TLS_DTLS_CID_ENABLED; + zassert_ok(zsock_setsockopt(c_sock, ZSOCK_SOL_TLS, ZSOCK_TLS_DTLS_CID, + &cid, sizeof(cid)), "setsockopt failed (%d)", errno); + zassert_ok(zsock_setsockopt(c_sock_2, ZSOCK_SOL_TLS, ZSOCK_TLS_DTLS_CID, + &cid, sizeof(cid)), "setsockopt failed (%d)", errno); + + /* And enable CID processing for server */ + cid = ZSOCK_TLS_DTLS_CID_SUPPORTED; + zassert_ok(zsock_setsockopt(s_sock, ZSOCK_SOL_TLS, ZSOCK_TLS_DTLS_CID, + &cid, sizeof(cid)), "setsockopt failed (%d)", errno); + + /* Client 1 handshake */ + test_data.sock = c_sock; + test_data.addr = &s_saddr; + k_work_init_delayable(&test_data.work, dtls_client_connect_send_work_handler); + test_work_reschedule(&test_data.work, K_NO_WAIT); + + /* Block in recv for the handshake to complete. */ + recv_addrlen = sizeof(recv_addr); + ret = zsock_recvfrom(s_sock, &rx_buf, sizeof(rx_buf), 0, + &recv_addr, &recv_addrlen); + zassert_equal(ret, sizeof(rx_buf), "recv() failed"); + dtls_verify_address(&recv_addr, recv_addrlen, &c_saddr_1); + zassert_equal(ztls_get_session_count(), 3, + "Server shouldn't have allocated extra session"); + + /* Rebind the client socket to a different port */ + c_saddr_1_backup = c_saddr_1; + if (family == NET_AF_INET) { + net_sin(&c_saddr_1)->sin_port = net_htons(CLIENT_3_PORT); + } else { + net_sin6(&c_saddr_1)->sin6_port = net_htons(CLIENT_3_PORT); + } + + test_bind(c_sock, &c_saddr_1, addrlen); + + /* After rebinding, try to send some data to the server. */ + test_send(c_sock, &tx_buf, sizeof(tx_buf), 0); + + /* And verify the server receives the data with correct address */ + recv_addrlen = sizeof(recv_addr); + ret = zsock_recvfrom(s_sock, &rx_buf, sizeof(rx_buf), 0, + &recv_addr, &recv_addrlen); + zassert_equal(ret, sizeof(rx_buf), "recv() failed"); + dtls_verify_address(&recv_addr, recv_addrlen, &c_saddr_1); + + /* No new session should've been spawned */ + zassert_equal(ztls_get_session_count(), 3, + "Server shouldn't have allocated extra session"); + + /* Sending back with the old address should fail */ + ret = zsock_sendto(s_sock, &tx_buf, sizeof(tx_buf), 0, &c_saddr_1_backup, + addrlen); + zassert_equal(ret, -1, "zsock_sendto() should've failed"); + zassert_equal(errno, ENOTCONN, "wrong errno"); + + /* Sending back with the new address should succeed */ + test_sendto(s_sock, &tx_buf, sizeof(tx_buf), 0, &c_saddr_1, addrlen); + ret = zsock_recv(c_sock, &rx_buf, sizeof(rx_buf), 0); + zassert_equal(ret, sizeof(tx_buf), "recv() failed"); + + /* New client connecting with the "old" address but different CID */ + c_saddr_2 = c_saddr_1_backup; + test_bind(c_sock_2, &c_saddr_2, addrlen); + + /* Client 2 handshake */ + test_data.sock = c_sock_2; + test_data.addr = &s_saddr; + k_work_init_delayable(&test_data.work, dtls_client_connect_send_work_handler); + test_work_reschedule(&test_data.work, K_NO_WAIT); + + /* Block in recv for the handshake to complete. */ + recv_addrlen = sizeof(recv_addr); + ret = zsock_recvfrom(s_sock, &rx_buf, sizeof(rx_buf), 0, + &recv_addr, &recv_addrlen); + zassert_equal(ret, sizeof(rx_buf), "recv() failed"); + dtls_verify_address(&recv_addr, recv_addrlen, &c_saddr_2); + /* New session should be spawned */ + zassert_equal(ztls_get_session_count(), 4, + "Server should have allocated new session"); + + /* Rebind the second client socket to a different port */ + if (family == NET_AF_INET) { + net_sin(&c_saddr_2)->sin_port = net_htons(CLIENT_2_PORT); + } else { + net_sin6(&c_saddr_2)->sin6_port = net_htons(CLIENT_2_PORT); + } + + test_bind(c_sock_2, &c_saddr_2, addrlen); + + /* After rebinding, try to send some data to the server. */ + test_send(c_sock_2, &tx_buf, sizeof(tx_buf), 0); + + /* And verify the server receives the data with correct address */ + recv_addrlen = sizeof(recv_addr); + ret = zsock_recvfrom(s_sock, &rx_buf, sizeof(rx_buf), 0, + &recv_addr, &recv_addrlen); + zassert_equal(ret, sizeof(rx_buf), "recv() failed"); + dtls_verify_address(&recv_addr, recv_addrlen, &c_saddr_2); + + /* No new session should've been spawned */ + zassert_equal(ztls_get_session_count(), 4, + "Server shouldn't have allocated extra session"); + + /* Close both clients and verify session count dropped. */ + test_close(c_sock); + test_close(c_sock_2); + c_sock = -1; + c_sock_2 = -1; + + /* Small delay for the alerts exchange */ + k_msleep(10); + + /* Let the server update sessions. */ + ret = zsock_recv(s_sock, &rx_buf, sizeof(rx_buf), ZSOCK_MSG_DONTWAIT); + zassert_equal(ret, -1, "recv() should've reported EAGAIN"); + zassert_equal(errno, EAGAIN, "wrong errno value"); + + zassert_equal(ztls_get_session_count(), 1, "Leftover sessions!"); + + test_work_wait(&test_data.work); +} + +ZTEST(net_socket_tls, test_v4_dtls_server_cid_matching_on_addr_change) +{ + test_dtls_server_cid_matching_on_addr_change(NET_AF_INET); +} + +ZTEST(net_socket_tls, test_v6_dtls_server_cid_matching_on_addr_change) +{ + test_dtls_server_cid_matching_on_addr_change(NET_AF_INET6); +} + +static void test_dtls_server_session_timeout_poll(net_sa_family_t family) +{ + struct net_sockaddr c_saddr_1; + struct net_sockaddr c_saddr_2; + struct net_sockaddr s_saddr; + int32_t delay = CONFIG_NET_SOCKETS_DTLS_TIMEOUT / 2 + 100; + struct zsock_pollfd fds[1]; + uint8_t rx_buf; + int ret; + + test_dtls_server_multi_client_prepare_two_connections( + family, &s_saddr, &c_saddr_1, &c_saddr_2, delay); + zassert_equal(ztls_get_session_count(), 4, "Expected session count mismatch"); + + /* First client session should time out */ + fds[0].fd = s_sock; + fds[0].events = ZSOCK_POLLIN; + ret = zsock_poll(fds, 1, delay); + zassert_equal(ret, 1, "poll() did not report data ready"); + zassert_equal(fds[0].revents, ZSOCK_POLLHUP, "expected ZSOCK_POLLHUP"); + zassert_equal(ztls_get_session_count(), 3, "Expected session count mismatch"); + + /* Small delay for the alerts exchange */ + k_msleep(10); + + /* Verify client socket reports error (server closed the session) */ + ret = zsock_recv(c_sock, &rx_buf, sizeof(rx_buf), ZSOCK_MSG_DONTWAIT); + zassert_equal(ret, -1, "recv() should've failed"); + zassert_equal(errno, ENOTCONN, "Wrong errno, expected ENOTCONN"); + + /* Second client should still be operational */ + ret = zsock_recv(c_sock_2, &rx_buf, sizeof(rx_buf), ZSOCK_MSG_DONTWAIT); + /* Not really an error (EAGAIN) */ + zassert_equal(ret, -1, "recv() should've failed"); + zassert_equal(errno, EAGAIN, "Wrong errno, expected EAGAIN"); + + /* Second client session should time out */ + fds[0].fd = s_sock; + fds[0].events = ZSOCK_POLLIN; + ret = zsock_poll(fds, 1, delay); + zassert_equal(ret, 1, "poll() did not report data ready"); + zassert_equal(fds[0].revents, ZSOCK_POLLHUP, "expected ZSOCK_POLLHUP"); + zassert_equal(ztls_get_session_count(), 3, "Expected session count mismatch"); + + /* Small delay for the alerts exchange */ + k_msleep(10); + + /* Verify second client socket reports error (server closed the session) */ + ret = zsock_recv(c_sock_2, &rx_buf, sizeof(rx_buf), ZSOCK_MSG_DONTWAIT); + zassert_equal(ret, -1, "recv() should've failed"); + zassert_equal(errno, ENOTCONN, "Wrong errno, expected ENOTCONN"); +} + +ZTEST(net_socket_tls, test_v4_dtls_server_session_timeout_poll) +{ + test_dtls_server_session_timeout_poll(NET_AF_INET); +} + +ZTEST(net_socket_tls, test_v6_dtls_server_session_timeout_poll) +{ + test_dtls_server_session_timeout_poll(NET_AF_INET6); +} + +static void test_dtls_server_session_timeout_recvfrom(net_sa_family_t family) +{ + struct net_sockaddr c_saddr_1; + struct net_sockaddr c_saddr_2; + struct net_sockaddr s_saddr; + int32_t delay = CONFIG_NET_SOCKETS_DTLS_TIMEOUT / 2 + 100; + struct timeval timeo_optval; + uint8_t rx_buf; + int ret; + + timeo_optval.tv_sec = 0; + timeo_optval.tv_usec = delay * USEC_PER_MSEC; + + test_dtls_server_multi_client_prepare_two_connections( + family, &s_saddr, &c_saddr_1, &c_saddr_2, delay); + zassert_equal(ztls_get_session_count(), 4, "Expected session count mismatch"); + + zassert_ok(zsock_setsockopt(s_sock, ZSOCK_SOL_SOCKET, ZSOCK_SO_RCVTIMEO, + &timeo_optval, sizeof(timeo_optval)), + "setsockopt failed (%d)", errno); + + /* Block in recv, it should timeout, and the first client should've timed + * out at this point. + */ + ret = zsock_recvfrom(s_sock, &rx_buf, sizeof(rx_buf), 0, NULL, NULL); + zassert_equal(ret, -1, "recv() should've timed out"); + zassert_equal(errno, EAGAIN, "Wrong errno, expected EAGAIN"); + zassert_equal(ztls_get_session_count(), 3, "Expected session count mismatch"); + + /* Small delay for the alerts exchange */ + k_msleep(10); + + /* Verify client socket reports error (server closed the session) */ + ret = zsock_recv(c_sock, &rx_buf, sizeof(rx_buf), ZSOCK_MSG_DONTWAIT); + zassert_equal(ret, -1, "recv() should've failed"); + zassert_equal(errno, ENOTCONN, "Wrong errno, expected ENOTCONN"); + + /* Second client should still be operational */ + ret = zsock_recv(c_sock_2, &rx_buf, sizeof(rx_buf), ZSOCK_MSG_DONTWAIT); + /* Not really an error (EAGAIN) */ + zassert_equal(ret, -1, "recv() should've failed"); + zassert_equal(errno, EAGAIN, "Wrong errno, expected EAGAIN"); + + /* Second client session should time out */ + ret = zsock_recvfrom(s_sock, &rx_buf, sizeof(rx_buf), 0, NULL, NULL); + zassert_equal(ret, -1, "recv() should've timed out"); + zassert_equal(errno, EAGAIN, "Wrong errno, expected EAGAIN"); + zassert_equal(ztls_get_session_count(), 3, "Expected session count mismatch"); + + /* Verify second client socket reports error (server closed the session) */ + ret = zsock_recv(c_sock_2, &rx_buf, sizeof(rx_buf), ZSOCK_MSG_DONTWAIT); + zassert_equal(ret, -1, "recv() should've failed"); + zassert_equal(errno, ENOTCONN, "Wrong errno, expected ENOTCONN"); +} + +ZTEST(net_socket_tls, test_v4_dtls_server_session_timeout_recvfrom) +{ + test_dtls_server_session_timeout_recvfrom(NET_AF_INET); +} + +ZTEST(net_socket_tls, test_v6_dtls_server_session_timeout_recvfrom) +{ + test_dtls_server_session_timeout_recvfrom(NET_AF_INET6); +} + static void *tls_tests_setup(void) { k_work_queue_init(&tls_test_work_queue); diff --git a/tests/net/socket/tls/testcase.yaml b/tests/net/socket/tls/testcase.yaml index f652305f20bc..b4acc1c18060 100644 --- a/tests/net/socket/tls/testcase.yaml +++ b/tests/net/socket/tls/testcase.yaml @@ -21,3 +21,6 @@ tests: net.socket.tls.sendmsg_no_buf: extra_configs: - CONFIG_NET_SOCKETS_DTLS_SENDMSG_BUF_SIZE=0 + net.socket.tls.no_dtls_cid: + extra_configs: + - CONFIG_MBEDTLS_SSL_DTLS_CONNECTION_ID=n From ba047342201ea1373534b77154b8ff47d5bb5779 Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Fri, 19 Dec 2025 11:40:46 +0100 Subject: [PATCH 0254/6328] net: sockets: tls: Optimze helper buffer for sendmsg and CID check Both cases use a large static buffer, we can optimize here and use a single mutex-protected buffer for both. sendmsg() test case needed adjustments, as it was also testing a buffer overflow scenario. This can only be properly tested however if CID feature is disabled, as otherwise the common helper buffer size is increased for the CID use case, preventing the overflow from taking place. Signed-off-by: Robert Lubos --- subsys/net/lib/sockets/sockets_tls.c | 42 ++++++++++++++-------- tests/net/socket/tls/src/main.c | 53 +++++++++++++++++++++++++++- 2 files changed, 79 insertions(+), 16 deletions(-) diff --git a/subsys/net/lib/sockets/sockets_tls.c b/subsys/net/lib/sockets/sockets_tls.c index 1725c4046878..1ad37bb7da9e 100644 --- a/subsys/net/lib/sockets/sockets_tls.c +++ b/subsys/net/lib/sockets/sockets_tls.c @@ -72,8 +72,16 @@ LOG_MODULE_REGISTER(net_sock_tls, CONFIG_NET_SOCKETS_LOG_LEVEL); #if defined(CONFIG_NET_SOCKETS_ENABLE_DTLS) #define DTLS_SENDMSG_BUF_SIZE (CONFIG_NET_SOCKETS_DTLS_SENDMSG_BUF_SIZE) + +#if defined(CONFIG_MBEDTLS_SSL_DTLS_CONNECTION_ID) +#define DTLS_CID_CHECK_BUF_SIZE (MBEDTLS_SSL_IN_CONTENT_LEN) +#else +#define DTLS_CID_CHECK_BUF_SIZE 0 +#endif /* CONFIG_MBEDTLS_SSL_DTLS_CONNECTION_ID */ + #else #define DTLS_SENDMSG_BUF_SIZE 0 +#define DTLS_CID_CHECK_BUF_SIZE 0 #endif /* CONFIG_NET_SOCKETS_ENABLE_DTLS */ static const struct socket_op_vtable tls_sock_fd_op_vtable; @@ -280,6 +288,11 @@ __net_socket struct tls_context { #endif /* CONFIG_MBEDTLS */ }; +#if defined(CONFIG_NET_SOCKETS_ENABLE_DTLS) +#define DTLS_HELPER_BUF_SIZE MAX(DTLS_SENDMSG_BUF_SIZE, DTLS_CID_CHECK_BUF_SIZE) +static uint8_t dtls_helper_buf[DTLS_HELPER_BUF_SIZE]; +static K_MUTEX_DEFINE(dtls_helper_buf_lock); +#endif /* A global pool of TLS contexts. */ static struct tls_context tls_contexts[CONFIG_NET_SOCKETS_TLS_MAX_CONTEXTS]; @@ -1135,11 +1148,8 @@ static int dtls_server_new_active_session(struct tls_context *tls_ctx, } #if defined(CONFIG_MBEDTLS_SSL_DTLS_CONNECTION_ID) -static K_MUTEX_DEFINE(dtls_server_cid_check_lock); - static int dtls_server_switch_active_session_by_cid(struct tls_context *tls_ctx) { - static uint8_t tmp_buf[MBEDTLS_SSL_IN_CONTENT_LEN]; struct tls_session_context *session_ctx = NULL; int result = -ENOENT; @@ -1147,7 +1157,7 @@ static int dtls_server_switch_active_session_by_cid(struct tls_context *tls_ctx) return -ENOTSUP; } - k_mutex_lock(&dtls_server_cid_check_lock, K_FOREVER); + k_mutex_lock(&dtls_helper_buf_lock, K_FOREVER); SYS_SLIST_FOR_EACH_CONTAINER(&tls_ctx->sessions, session_ctx, node) { struct net_sockaddr addr; @@ -1178,7 +1188,7 @@ static int dtls_server_switch_active_session_by_cid(struct tls_context *tls_ctx) * avoid races in case multiple DTLS server sockets run in parallel. */ addrlen = sizeof(struct net_sockaddr); - len = zsock_recvfrom(tls_ctx->sock, &tmp_buf, sizeof(tmp_buf), + len = zsock_recvfrom(tls_ctx->sock, &dtls_helper_buf, sizeof(dtls_helper_buf), ZSOCK_MSG_DONTWAIT | ZSOCK_MSG_PEEK, &addr, &addrlen); if (len < 0) { @@ -1186,7 +1196,7 @@ static int dtls_server_switch_active_session_by_cid(struct tls_context *tls_ctx) break; } - ret = mbedtls_ssl_check_record(&session_ctx->ssl, tmp_buf, len); + ret = mbedtls_ssl_check_record(&session_ctx->ssl, dtls_helper_buf, len); if (ret == 0) { NET_DBG("Found matching session (CID) for [%s]:%d (was [%s]:%d)", LOG_ADDR_PORT_HELPER(&addr), @@ -1200,7 +1210,7 @@ static int dtls_server_switch_active_session_by_cid(struct tls_context *tls_ctx) } } - k_mutex_unlock(&dtls_server_cid_check_lock); + k_mutex_unlock(&dtls_helper_buf_lock); return result; } @@ -3174,40 +3184,42 @@ ssize_t ztls_sendto_ctx(struct tls_context *ctx, const void *buf, size_t len, #endif /* CONFIG_NET_SOCKETS_ENABLE_DTLS */ } +#if defined(CONFIG_NET_SOCKETS_ENABLE_DTLS) static ssize_t dtls_sendmsg_merge_and_send(struct tls_context *ctx, const struct net_msghdr *msg, int flags) { - static K_MUTEX_DEFINE(sendmsg_lock); - static uint8_t sendmsg_buf[DTLS_SENDMSG_BUF_SIZE]; ssize_t len = 0; - k_mutex_lock(&sendmsg_lock, K_FOREVER); + k_mutex_lock(&dtls_helper_buf_lock, K_FOREVER); for (int i = 0; i < msg->msg_iovlen; i++) { struct net_iovec *vec = msg->msg_iov + i; if (vec->iov_len > 0) { - if (len + vec->iov_len > sizeof(sendmsg_buf)) { - k_mutex_unlock(&sendmsg_lock); + if (len + vec->iov_len > sizeof(dtls_helper_buf)) { + k_mutex_unlock(&dtls_helper_buf_lock); errno = EMSGSIZE; return -1; } - memcpy(sendmsg_buf + len, vec->iov_base, vec->iov_len); + memcpy(dtls_helper_buf + len, vec->iov_base, vec->iov_len); len += vec->iov_len; } } if (len > 0) { - len = ztls_sendto_ctx(ctx, sendmsg_buf, len, flags, + len = ztls_sendto_ctx(ctx, dtls_helper_buf, len, flags, msg->msg_name, msg->msg_namelen); } - k_mutex_unlock(&sendmsg_lock); + k_mutex_unlock(&dtls_helper_buf_lock); return len; } +#else +#define dtls_sendmsg_merge_and_send(...) (-1) +#endif static ssize_t tls_sendmsg_loop_and_send(struct tls_context *ctx, const struct net_msghdr *msg, diff --git a/tests/net/socket/tls/src/main.c b/tests/net/socket/tls/src/main.c index e3325407259e..5db92a18ff36 100644 --- a/tests/net/socket/tls/src/main.c +++ b/tests/net/socket/tls/src/main.c @@ -697,7 +697,6 @@ static void test_dtls_sendmsg(net_sa_family_t family) { int rv; uint8_t buf[128 + 1] = { 0 }; - uint8_t dummy_byte = 0; static const char expected_str[] = "testtest"; struct net_iovec iov[3] = { { @@ -752,6 +751,38 @@ static void test_dtls_sendmsg(net_sa_family_t family) test_work_wait(&test_data.tx_work); + test_sockets_close(); + + /* Small delay for the final alert exchange */ + k_msleep(10); +} + +static void test_dtls_sendmsg_overflow(net_sa_family_t family) +{ + int rv; + uint8_t buf[128 + 1] = { 0 }; + uint8_t dummy_byte = 0; + struct net_iovec iov[3] = { + { + .iov_base = TEST_STR_SMALL, + .iov_len = sizeof(TEST_STR_SMALL) - 1, + }, + { + .iov_base = TEST_STR_SMALL, + .iov_len = sizeof(TEST_STR_SMALL) - 1, + }, + {}, + }; + struct net_msghdr msg = {}; + struct test_sendmsg_data test_data = { + .msg = &msg, + }; + + test_prepare_dtls_connection(family); + + test_data.sock = c_sock; + k_work_init_delayable(&test_data.tx_work, test_sendmsg_tx_work_handler); + /* sendmsg() with single fragment should still work even if larger than * intermediate buffer size */ @@ -813,6 +844,26 @@ ZTEST(net_socket_tls, test_v6_dtls_sendmsg) test_dtls_sendmsg(NET_AF_INET6); } +ZTEST(net_socket_tls, test_v4_dtls_sendmsg_overflow) +{ + if ((CONFIG_NET_SOCKETS_DTLS_SENDMSG_BUF_SIZE == 0) || + IS_ENABLED(CONFIG_MBEDTLS_SSL_DTLS_CONNECTION_ID)) { + ztest_test_skip(); + } + + test_dtls_sendmsg_overflow(NET_AF_INET); +} + +ZTEST(net_socket_tls, test_v6_dtls_sendmsg_overflow) +{ + if ((CONFIG_NET_SOCKETS_DTLS_SENDMSG_BUF_SIZE == 0) || + IS_ENABLED(CONFIG_MBEDTLS_SSL_DTLS_CONNECTION_ID)) { + ztest_test_skip(); + } + + test_dtls_sendmsg_overflow(NET_AF_INET6); +} + struct close_data { struct k_work_delayable work; int *fd; From 506a59396fdfa6cbd932d2bcaedee8d8c0b72cbd Mon Sep 17 00:00:00 2001 From: Johann Fischer Date: Fri, 18 Jul 2025 00:28:40 +0200 Subject: [PATCH 0255/6328] usb: device_next: fix compilation if the user disables HWINFO Make USBD_HWINFO_DEVID_LENGTH prompt optional so that the code compiles even if HWINFO is disabled. Signed-off-by: Johann Fischer --- subsys/usb/device_next/Kconfig | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/subsys/usb/device_next/Kconfig b/subsys/usb/device_next/Kconfig index 5e7b02e5ee71..dd7748f51b43 100644 --- a/subsys/usb/device_next/Kconfig +++ b/subsys/usb/device_next/Kconfig @@ -96,8 +96,7 @@ config USBD_MSG_WORK_DELAY yet ready to publish the message. The delay unit is milliseconds. config USBD_HWINFO_DEVID_LENGTH - int "The length of the device ID requested from HWINFO in bytes" - depends on HWINFO + int "The length of the device ID requested from HWINFO in bytes" if HWINFO range 8 128 default 16 help From e73e2f148cdd573b9050985382ba1c4b6c50ecf4 Mon Sep 17 00:00:00 2001 From: Marcelo Roberto Jimenez Date: Tue, 18 Nov 2025 10:57:52 -0300 Subject: [PATCH 0256/6328] drivers: ethernet: xmc4xxx: BUG Fix: RX code dropping packets The ethernet DMA driver code was causing the silent dropping of packets with length 125, 126 and 127. The root cause of the problem is that the DMA engine performs an extra four bytes transfer corresponding to the Receive Status Word. For those particular packet lengths, the previous code incorrectly calculated the last fragment size. The new code avoids that pitfall by decrementing the total frame size as the fragments are being collected, while avoiding the creation of an extra fragment on the extracted network packet. Signed-off-by: Marcelo Roberto Jimenez --- drivers/ethernet/eth_xmc4xxx.c | 125 +++++++++++++++++++++++++-------- 1 file changed, 95 insertions(+), 30 deletions(-) diff --git a/drivers/ethernet/eth_xmc4xxx.c b/drivers/ethernet/eth_xmc4xxx.c index 1eb16f7f76c2..394cb38be76c 100644 --- a/drivers/ethernet/eth_xmc4xxx.c +++ b/drivers/ethernet/eth_xmc4xxx.c @@ -61,7 +61,7 @@ LOG_MODULE_REGISTER(eth_xmc4xxx); #define IS_TIMESTAMP_AVAILABLE_RX(desc) (((desc)->status & ETH_MAC_DMA_RDES0_TSA) != 0) #define IS_TIMESTAMP_AVAILABLE_TX(desc) (((desc)->status & ETH_MAC_DMA_TDES0_TTSS) != 0) -#define TOTAL_FRAME_LENGTH(desc) (FIELD_GET(ETH_MAC_DMA_RDES0_FL, (desc)->status) - 4) +#define TOTAL_FRAME_LENGTH(desc) (FIELD_GET(ETH_MAC_DMA_RDES0_FL, (desc)->status)) #define ETH_STATUS_ERROR_TRANSMIT_EVENTS \ (XMC_ETH_MAC_EVENT_BUS_ERROR | XMC_ETH_MAC_EVENT_TRANSMIT_JABBER_TIMEOUT | \ @@ -366,10 +366,11 @@ static struct net_pkt *eth_xmc4xxx_rx_pkt(const struct device *dev) bool eof_found = false; uint16_t tail; XMC_ETH_MAC_DMA_DESC_t *dma_desc; - int num_frags = 0; uint16_t frame_end_index; - struct net_buf *frag, *last_frag = NULL; + struct net_buf *frag, *prev_frag = NULL; + uint16_t remaining_length = 0; + /* tail is the index in the circular buffer of DMA descriptors */ tail = dev_data->dma_desc_rx_tail; dma_desc = &rx_dma_desc[tail]; @@ -383,50 +384,88 @@ static struct net_pkt *eth_xmc4xxx_rx_pkt(const struct device *dev) return NULL; } + /* Search for the end of frame descriptor and get the total + * frame length. + */ while (!IS_OWNED_BY_DMA_RX(dma_desc)) { eof_found = IS_END_OF_FRAME_RX(dma_desc); - num_frags++; if (eof_found) { + remaining_length = TOTAL_FRAME_LENGTH(dma_desc); break; } - MODULO_INC_RX(tail); - if (tail == dev_data->dma_desc_rx_tail) { - /* wrapped */ + /* We wrapped around the circular buffer, came back to + * the starting point, and still did not find the EOF. + * We could return here, but it is safer to do so after + * the loop. + */ break; } - dma_desc = &rx_dma_desc[tail]; } - if (!eof_found) { return NULL; } + /* Save the index of the last frame */ frame_end_index = tail; + /* The DMA engine performs an extra 4 bytes transfer + * corresponding to the Receive Status Word, which is sent + * along the data after the end of the frame (Ref: XMC4500 + * Reference Manual, 15.2.2.2 Receive Path, page 15-25). For + * this reason, it is necessary to subtract four from the + * total frame length. The incorrect handling of this + * difference was the cause of a subtle bug, in which packets + * with length 125, 126 and 127 were silently dropped upon + * reception. + */ + remaining_length -= 4; + + /* Allocate the new fresh packet to receive the data. */ pkt = net_pkt_rx_alloc(K_NO_WAIT); - if (pkt == NULL) { + if (!pkt) { #ifdef CONFIG_NET_STATISTICS_ETHERNET dev_data->stats.errors.rx++; dev_data->stats.error_details.rx_no_buffer_count++; #endif LOG_DBG("Net packet allocation error"); - /* continue because we still need to read out the packet */ + /* continue because we still need to read out the packet. */ } + /* In this loop, the following actions are taken: + * + * 1 - If a packet has been successfully allocated, retrieve the fresh + * fragment from the DMA descriptor and substitute it with a new one + * allocated from the pool. + * + * 2 - Link each retrieved fragment in a list in the newly allocated + * packet. + * + * 3 - Prepare the DMA descriptor for a new DMA round. + * + * It is imperative that this loop is not interrupted until all DMA + * descriptors have been sent back to DMA ownership. + */ + /* Restart the DMA descriptor pointer */ tail = dev_data->dma_desc_rx_tail; dma_desc = &rx_dma_desc[tail]; for (;;) { - if (pkt != NULL) { - uint16_t frag_len = CONFIG_NET_BUF_DATA_SIZE; - - frag = dev_data->rx_frag_list[tail]; + if (pkt) { + uint16_t fragment_length; + + /* Calculate this fragment's length and update the + * remaining length. + */ + if (remaining_length > CONFIG_NET_BUF_DATA_SIZE) { + fragment_length = CONFIG_NET_BUF_DATA_SIZE; + remaining_length -= CONFIG_NET_BUF_DATA_SIZE; + } else { + fragment_length = remaining_length; + remaining_length = 0; + } if (tail == frame_end_index) { - frag_len = TOTAL_FRAME_LENGTH(dma_desc) - - CONFIG_NET_BUF_DATA_SIZE * (num_frags - 1); - if (IS_TIMESTAMP_AVAILABLE_RX(dma_desc)) { struct net_ptp_time timestamp = { .second = dma_desc->time_stamp_seconds, @@ -436,46 +475,72 @@ static struct net_pkt *eth_xmc4xxx_rx_pkt(const struct device *dev) net_pkt_set_priority(pkt, NET_PRIORITY_CA); } } - + /* This fragment has the fresh DMA data */ + frag = dev_data->rx_frag_list[tail]; + /* Due to the minus four above, the fragment length can + * become zero before the last fragment is processed. + */ + if (!fragment_length) { + /* No need to worry about fragment substitution + * for this fragment, just reset it and prepare + * the DMA descriptor. + */ + net_buf_reset(frag); + goto prepare_dma_descriptor; + } + /* Allocate a new net fragment to substitute the current + * one on the current DMA descriptor. + */ new_frag = net_pkt_get_frag(pkt, CONFIG_NET_BUF_DATA_SIZE, K_NO_WAIT); - if (new_frag == NULL) { + if (!new_frag) { #ifdef CONFIG_NET_STATISTICS_ETHERNET dev_data->stats.errors.rx++; dev_data->stats.error_details.rx_buf_alloc_failed++; #endif - LOG_DBG("Frag allocation error. Increase CONFIG_NET_BUF_RX_COUNT."); net_pkt_unref(pkt); pkt = NULL; + LOG_DBG("Frag allocation error. Increase CONFIG_NET_BUF_RX_COUNT."); } else { - net_buf_add(frag, frag_len); - if (!last_frag) { + /* Sets the received fragment length */ + net_buf_add(frag, fragment_length); + if (!prev_frag) { + /* The first fragment goes to the + * packet. + */ net_pkt_frag_insert(pkt, frag); } else { - net_buf_frag_insert(last_frag, frag); + /* Other fragments get added to the + * previous fragment. + */ + net_buf_frag_insert(prev_frag, frag); } - - last_frag = frag; - frag = new_frag; - dev_data->rx_frag_list[tail] = frag; + prev_frag = frag; + dev_data->rx_frag_list[tail] = new_frag; } } +prepare_dma_descriptor: + /* Prepare the current DMA descriptor for the next reception. */ dma_desc->buffer1 = (uint32_t)dev_data->rx_frag_list[tail]->data; dma_desc->length = dev_data->rx_frag_list[tail]->size | ETH_RX_DMA_DESC_SECOND_ADDR_CHAINED_MASK; dma_desc->status = ETH_MAC_DMA_RDES0_OWN; if (tail == frame_end_index) { + /* Time to leave the loop. */ break; } - MODULO_INC_RX(tail); dma_desc = &rx_dma_desc[tail]; } - MODULO_INC_RX(tail); + + /* Leave the device tail index pointing to the next DMA descriptor the + * DMA engine will use. + */ dev_data->dma_desc_rx_tail = tail; + /* Finally, enable a new DMA reception. */ eth_xmc4xxx_trigger_dma_rx(dev_cfg->regs); return pkt; From 261dfbc765c7f88d12106230022cb0d4967788f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20K=C4=99dziora?= Date: Wed, 29 Oct 2025 11:00:28 +0100 Subject: [PATCH 0257/6328] drivers: spi_dw: Add clock control MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This adds optional clock control support to the spi_dw driver. The support currently assumes that the clock control binding uses clkid for the clock cell name. Signed-off-by: Łukasz Kędziora Signed-off-by: Piotr Zierhoffer Signed-off-by: Andreas Weissel --- drivers/spi/spi_dw.c | 20 ++++++++++++++++++++ drivers/spi/spi_dw.h | 8 ++++++++ 2 files changed, 28 insertions(+) diff --git a/drivers/spi/spi_dw.c b/drivers/spi/spi_dw.c index 9f00905a3f02..587342931aea 100644 --- a/drivers/spi/spi_dw.c +++ b/drivers/spi/spi_dw.c @@ -558,6 +558,16 @@ int spi_dw_init(const struct device *dev) pinctrl_apply_state(info->pcfg, PINCTRL_STATE_DEFAULT); #endif +#if defined(CONFIG_CLOCK_CONTROL) + if (info->clk_dev) { + err = clock_control_on(info->clk_dev, info->clk_id); + if (err < 0) { + LOG_ERR("Failed to enable the clock"); + return err; + } + } +#endif + DEVICE_MMIO_MAP(dev, K_MEM_CACHE_NONE); info->config_func(); @@ -649,6 +659,15 @@ COND_CODE_1(IS_EQ(DT_NUM_IRQS(DT_DRV_INST(inst)), 1), \ (SPI_CFG_IRQS_MULTIPLE_ERR_LINES(inst))))) \ } +#if defined(CONFIG_CLOCK_CONTROL) +#define CLOCK_DW_CONFIG(n) \ + IF_ENABLED(DT_INST_NODE_HAS_PROP(0, clocks), \ + (.clk_dev = DEVICE_DT_GET(DT_INST_CLOCKS_CTLR(n)), \ + .clk_id = (clock_control_subsys_t)DT_INST_CLOCKS_CELL(n, clkid),)) +#else +#define CLOCK_DW_CONFIG(n) +#endif + #define SPI_DW_INIT(inst) \ IF_ENABLED(CONFIG_PINCTRL, (PINCTRL_DT_INST_DEFINE(inst);)) \ SPI_DW_IRQ_HANDLER(inst); \ @@ -679,6 +698,7 @@ COND_CODE_1(IS_EQ(DT_NUM_IRQS(DT_DRV_INST(inst)), 1), \ .set_bit_func = reg_set_bit, \ .clear_bit_func = reg_clear_bit, \ .test_bit_func = reg_test_bit,)) \ + CLOCK_DW_CONFIG(inst) \ }; \ SPI_DEVICE_DT_INST_DEFINE(inst, \ spi_dw_init, \ diff --git a/drivers/spi/spi_dw.h b/drivers/spi/spi_dw.h index c91ddbf7996c..0868cd50ddee 100644 --- a/drivers/spi/spi_dw.h +++ b/drivers/spi/spi_dw.h @@ -14,6 +14,10 @@ #include #include +#if defined(CONFIG_CLOCK_CONTROL) +#include +#endif + #include "spi_context.h" #ifdef __cplusplus @@ -46,6 +50,10 @@ struct spi_dw_config { uint8_t max_xfer_size; #ifdef CONFIG_PINCTRL const struct pinctrl_dev_config *pcfg; +#endif +#if defined(CONFIG_CLOCK_CONTROL) + const struct device *clk_dev; + const clock_control_subsys_t clk_id; #endif spi_dw_read_t read_func; spi_dw_write_t write_func; From d807e39a2cbfa28d5a5b60a663c43ea9b3b95fd2 Mon Sep 17 00:00:00 2001 From: Andy Lin Date: Wed, 7 Jan 2026 01:42:17 +0800 Subject: [PATCH 0258/6328] arch: riscv: Add the support for Zbkb ISA extension Introduce the missing flag to compile code with Zbkb extension, which has already been supported by the GCC 12 in current SDK. Signed-off-by: Andy Lin --- arch/riscv/Kconfig.isa | 8 ++++++++ cmake/compiler/gcc/target_riscv.cmake | 4 ++++ 2 files changed, 12 insertions(+) diff --git a/arch/riscv/Kconfig.isa b/arch/riscv/Kconfig.isa index c5ee324464d8..f5df9b85eef1 100644 --- a/arch/riscv/Kconfig.isa +++ b/arch/riscv/Kconfig.isa @@ -237,6 +237,14 @@ config RISCV_ISA_EXT_ZBC The Zbc instructions can be used for carry-less multiplication that is the multiplication in the polynomial ring over GF(2). +config RISCV_ISA_EXT_ZBKB + bool + help + (Zbkb) - Zbkb BitManip Extension (Bit-manipulation for Cryptography) + + The Zbkb instructions can be used for accelerating cryptography workloads + and contain rotation, reversion, packing and some advanced bit-manipulation. + config RISCV_ISA_EXT_ZBS bool help diff --git a/cmake/compiler/gcc/target_riscv.cmake b/cmake/compiler/gcc/target_riscv.cmake index e440d4e2b158..656b597a393e 100644 --- a/cmake/compiler/gcc/target_riscv.cmake +++ b/cmake/compiler/gcc/target_riscv.cmake @@ -118,6 +118,10 @@ if(CONFIG_RISCV_ISA_EXT_ZBC) string(CONCAT riscv_march ${riscv_march} "_zbc") endif() +if(CONFIG_RISCV_ISA_EXT_ZBKB) + string(CONCAT riscv_march ${riscv_march} "_zbkb") +endif() + if(CONFIG_RISCV_ISA_EXT_ZBS) string(CONCAT riscv_march ${riscv_march} "_zbs") endif() From a616f7b107b0ceefd937acb3a5e64d09c8bf764b Mon Sep 17 00:00:00 2001 From: Hugues Fruchet Date: Thu, 8 Jan 2026 17:08:11 +0100 Subject: [PATCH 0259/6328] drivers: video: stm32_venc: fix release sequence Fix missing H264 library release and total memory count reset. Signed-off-by: Hugues Fruchet --- drivers/video/video_stm32_venc.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/video/video_stm32_venc.c b/drivers/video/video_stm32_venc.c index 4bbfa847b5aa..e7e4ed045def 100644 --- a/drivers/video/video_stm32_venc.c +++ b/drivers/video/video_stm32_venc.c @@ -601,12 +601,15 @@ static int encoder_start(struct stm32_venc_data *data, struct video_buffer *outp static int encoder_end(struct stm32_venc_data *data) { + struct stm32_venc_ewl *inst = &ewl_instance; H264EncIn enc_in = {0}; H264EncOut enc_out = {0}; if (data->encoder != NULL) { H264EncStrmEnd(data->encoder, &enc_in, &enc_out); + H264EncRelease(data->encoder); data->encoder = NULL; + inst->mem_cnt = 0; } return 0; From e84f19578095893967760e28dff6dfc5d0d7a60e Mon Sep 17 00:00:00 2001 From: Hugues Fruchet Date: Tue, 21 Oct 2025 17:55:00 +0200 Subject: [PATCH 0260/6328] drivers: video: stm32_venc: fix delta frames generation Only key frames were generated because of resync flag always true, fix this. Signed-off-by: Hugues Fruchet --- drivers/video/video_stm32_venc.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/video/video_stm32_venc.c b/drivers/video/video_stm32_venc.c index e7e4ed045def..6994dca8b41a 100644 --- a/drivers/video/video_stm32_venc.c +++ b/drivers/video/video_stm32_venc.c @@ -647,10 +647,11 @@ static int encode_frame(struct stm32_venc_data *data) goto out; } - /* one key frame every seconds */ + /* one key frame every VENC_DEFAULT_FRAMERATE frames */ if ((data->frame_nb % VENC_DEFAULT_FRAMERATE) == 0 || data->resync) { /* if frame is the first or resync needed: set as intra coded */ enc_in.codingType = H264ENC_INTRA_FRAME; + data->resync = false; } else { /* if there was a frame previously, set as predicted */ enc_in.timeIncrement = 1; From f396ac9efcce3388a5052aa67f2ebaaa146f24aa Mon Sep 17 00:00:00 2001 From: Hugues Fruchet Date: Wed, 5 Nov 2025 17:13:04 +0100 Subject: [PATCH 0261/6328] drivers: video: stm32_venc: fix completion on interrupt Fix wait of hardware encoding completion by using interrupt signaling instead of polling on irq status. Signed-off-by: Hugues Fruchet --- drivers/video/video_stm32_venc.c | 65 +++++--------------------------- 1 file changed, 10 insertions(+), 55 deletions(-) diff --git a/drivers/video/video_stm32_venc.c b/drivers/video/video_stm32_venc.c index 6994dca8b41a..f7a7a83bb81d 100644 --- a/drivers/video/video_stm32_venc.c +++ b/drivers/video/video_stm32_venc.c @@ -349,69 +349,24 @@ i32 EWLWaitHwRdy(const void *instance, uint32_t *slices_ready) { struct stm32_venc_ewl *inst = (struct stm32_venc_ewl *)instance; const struct stm32_venc_config *config = inst->config; - int32_t ret = EWL_HW_WAIT_TIMEOUT; - volatile uint32_t irq_stats; - uint32_t prev_slices_ready = 0; - k_timepoint_t timeout = sys_timepoint_calc(K_MSEC(EWL_TIMEOUT)); uint32_t start = sys_clock_tick_get_32(); __ASSERT_NO_MSG(inst != NULL); - /* check how to clear IRQ flags for VENC */ - uint32_t clr_by_write_1 = EWLReadReg(inst, BASE_HWFuse2) & HWCFGIrqClearSupport; + if (k_sem_take(&inst->complete, K_MSEC(EWL_TIMEOUT))) { + uint32_t irq_status = sys_read32(config->reg + BASE_HEncIRQ); - do { - irq_stats = sys_read32(config->reg + BASE_HEncIRQ); - /* get the number of completed slices from ASIC registers. */ - if (slices_ready != NULL && *slices_ready > prev_slices_ready) { - *slices_ready = FIELD_GET(NUM_SLICES_READY_MASK, - sys_read32(config->reg + BASE_HEncControl7)); - } - - LOG_DBG("IRQ stat = %08x", irq_stats); - - uint32_t hw_handshake_status = IS_BIT_SET( - sys_read32(config->reg + BASE_HEncInstantInput), LOW_LATENCY_HW_ITF_EN); - - /* ignore the irq status of input line buffer in hw handshake mode */ - if ((irq_stats == ASIC_STATUS_LINE_BUFFER_DONE) && (hw_handshake_status != 0UL)) { - sys_write32(ASIC_STATUS_FUSE, config->reg + BASE_HEncIRQ); - continue; - } - - if ((irq_stats & ASIC_STATUS_ALL) != 0UL) { - /* clear IRQ and slice ready status */ - uint32_t clr_stats; - - irq_stats &= ~(ASIC_STATUS_SLICE_READY | ASIC_IRQ_LINE); - - if (clr_by_write_1 != 0UL) { - clr_stats = ASIC_STATUS_SLICE_READY | ASIC_IRQ_LINE; - } else { - clr_stats = irq_stats; - } - - sys_write32(clr_stats, config->reg + BASE_HEncIRQ); - ret = EWL_OK; - break; - } - - if (slices_ready != NULL && *slices_ready > prev_slices_ready) { - ret = EWL_OK; - break; - } - - } while (!sys_timepoint_expired(timeout)); - - if (ret != EWL_OK) { - LOG_ERR("Timeout"); - return ret; + LOG_ERR("timeout, status=0x%x", irq_status); + return EWL_HW_WAIT_TIMEOUT; } LOG_DBG("encoding = %d ms", k_ticks_to_ms_ceil32(sys_clock_tick_get_32() - start)); + /* get the number of completed slices from ASIC registers. */ if (slices_ready != NULL) { - LOG_DBG("slices_ready = %d", *slices_ready); + *slices_ready = FIELD_GET(NUM_SLICES_READY_MASK, + sys_read32(config->reg + BASE_HEncControl7)); + LOG_DBG("slices=%d", *slices_ready); } return EWL_OK; @@ -801,9 +756,9 @@ ISR_DIRECT_DECLARE(stm32_venc_isr) * and signal to EWLWaitHwRdy */ sys_write32(ASIC_STATUS_SLICE_READY | ASIC_IRQ_LINE, config->reg + BASE_HEncIRQ); - } - k_sem_give(&inst->complete); + k_sem_give(&inst->complete); + } return 0; } From 8c8a021a5f801c1569e1bd85615605ef8eb985f5 Mon Sep 17 00:00:00 2001 From: Hugues Fruchet Date: Wed, 5 Nov 2025 17:16:29 +0100 Subject: [PATCH 0262/6328] drivers: video: stm32_venc: log interrupts Log number of interrupts, including fuse interrupts at each key frame and at the end of encoding. Signed-off-by: Hugues Fruchet --- drivers/video/video_stm32_venc.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/drivers/video/video_stm32_venc.c b/drivers/video/video_stm32_venc.c index f7a7a83bb81d..7f9d3f5e1ffa 100644 --- a/drivers/video/video_stm32_venc.c +++ b/drivers/video/video_stm32_venc.c @@ -86,7 +86,10 @@ struct stm32_venc_ewl { const struct stm32_venc_config *config; struct k_sem complete; uint32_t irq_status; + + /* Stats counters (for debugging) */ uint32_t irq_cnt; + uint32_t irq_fuse_cnt; uint32_t mem_cnt; }; @@ -168,6 +171,7 @@ const void *EWLInit(EWLInitParam_t *param) /* set client type */ ewl_instance.client_type = param->clientType; ewl_instance.irq_cnt = 0; + ewl_instance.irq_fuse_cnt = 0; return (void *)&ewl_instance; } @@ -453,8 +457,11 @@ static int encoder_prepare(struct stm32_venc_data *data) H264EncPreProcessingCfg preproc_cfg = {0}; H264EncRateCtrl ratectrl_cfg = {0}; H264EncCodingCtrl codingctrl_cfg = {0}; + struct stm32_venc_ewl *inst = &ewl_instance; data->frame_nb = 0; + inst->irq_cnt = 0; + inst->irq_fuse_cnt = 0; /* set config to 1 reference frame */ cfg.refFrameAmount = 1; @@ -578,6 +585,7 @@ static int encode_frame(struct stm32_venc_data *data) struct video_buffer *output; H264EncIn enc_in = {0}; H264EncOut enc_out = {0}; + struct stm32_venc_ewl *inst = &ewl_instance; if (k_fifo_is_empty(&data->in_fifo_in) || k_fifo_is_empty(&data->out_fifo_in)) { /* Encoding deferred to next buffer queueing */ @@ -607,6 +615,9 @@ static int encode_frame(struct stm32_venc_data *data) /* if frame is the first or resync needed: set as intra coded */ enc_in.codingType = H264ENC_INTRA_FRAME; data->resync = false; + + LOG_DBG("frames=%d irq=%d fuse=%d", data->frame_nb, inst->irq_cnt, + inst->irq_fuse_cnt); } else { /* if there was a frame previously, set as predicted */ enc_in.timeIncrement = 1; @@ -679,12 +690,15 @@ static int encode_frame(struct stm32_venc_data *data) static int stm32_venc_set_stream(const struct device *dev, bool enable, enum video_buf_type type) { struct stm32_venc_data *data = dev->data; + struct stm32_venc_ewl *inst = &ewl_instance; ARG_UNUSED(type); if (!enable) { /* Stop VENC */ encoder_end(data); + LOG_DBG("frames=%d irq=%d fuse=%d", data->frame_nb, inst->irq_cnt, + inst->irq_fuse_cnt); } return 0; @@ -748,6 +762,7 @@ ISR_DIRECT_DECLARE(stm32_venc_isr) sys_write32(ASIC_STATUS_FUSE | ASIC_IRQ_LINE, config->reg + BASE_HEncIRQ); /* read back the IRQ status to update its value */ irq_status = sys_read32(config->reg + BASE_HEncIRQ); + inst->irq_fuse_cnt++; } if (irq_status != 0U) { From cc8475dd52713dd8194960e9045efb09a93a7a0c Mon Sep 17 00:00:00 2001 From: Hugues Fruchet Date: Wed, 5 Nov 2025 17:27:30 +0100 Subject: [PATCH 0263/6328] drivers: video: stm32_dcmipp: set multilines to 128 to limit interrupts Set multiline on pixel pipes to 128 lines to limit slave IP hardware handshakes and so reduce the number of interrupts received by slave IP. Signed-off-by: Hugues Fruchet --- drivers/video/video_stm32_dcmipp.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/drivers/video/video_stm32_dcmipp.c b/drivers/video/video_stm32_dcmipp.c index ef305458f8d3..50a5c9dd0131 100644 --- a/drivers/video/video_stm32_dcmipp.c +++ b/drivers/video/video_stm32_dcmipp.c @@ -1168,6 +1168,17 @@ static int stm32_dcmipp_stream_enable(const struct device *dev) if (ret < 0) { goto out; } + + /* Limit the amount of hardware handshake interrupts received by slave IP */ + if (pipe->id == DCMIPP_PIPE1) { + stm32_reg_modify_bits(&dcmipp->hdcmipp.Instance->P1PPCR, + DCMIPP_P1PPCR_LINEMULT_Msk, + DCMIPP_MULTILINE_128_LINES); + } else { + stm32_reg_modify_bits(&dcmipp->hdcmipp.Instance->P2PPCR, + DCMIPP_P1PPCR_LINEMULT_Msk, + DCMIPP_MULTILINE_128_LINES); + } } #endif From 70f57d119ac197194c5db1d93d386a6b36be5a26 Mon Sep 17 00:00:00 2001 From: Hugues Fruchet Date: Thu, 13 Nov 2025 18:20:26 +0100 Subject: [PATCH 0264/6328] drivers: video: stm32_dcmipp: give back buffers at stream disable Give back buffers at stream disable. Signed-off-by: Hugues Fruchet --- drivers/video/video_stm32_dcmipp.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/video/video_stm32_dcmipp.c b/drivers/video/video_stm32_dcmipp.c index 50a5c9dd0131..c72750a2720c 100644 --- a/drivers/video/video_stm32_dcmipp.c +++ b/drivers/video/video_stm32_dcmipp.c @@ -1240,6 +1240,7 @@ static int stm32_dcmipp_stream_disable(const struct device *dev) struct stm32_dcmipp_pipe_data *pipe = dev->data; struct stm32_dcmipp_data *dcmipp = pipe->dcmipp; const struct stm32_dcmipp_config *config = dev->config; + struct video_buffer *vbuf; int ret; k_mutex_lock(&pipe->lock, K_FOREVER); @@ -1300,6 +1301,12 @@ static int stm32_dcmipp_stream_disable(const struct device *dev) k_fifo_put(&pipe->fifo_in, pipe->active); } + /* Forward all buffers in fifo_in to fifo_out */ + while ((vbuf = k_fifo_get(&pipe->fifo_in, K_NO_WAIT)) != NULL) { + vbuf->bytesused = 0; + k_fifo_put(&pipe->fifo_out, vbuf); + } + pipe->state = STM32_DCMIPP_STOPPED; pipe->is_streaming = false; dcmipp->enabled_pipe--; From 0c0bb202c79f670c241cdc3078c02724cfaf895c Mon Sep 17 00:00:00 2001 From: Hugues Fruchet Date: Thu, 22 Jan 2026 13:48:52 +0100 Subject: [PATCH 0265/6328] samples: video: tcpserversink: fix missing input buffer encoder dequeue Fix missing input buffer encoder dequeue, this was corrupting camera device fifo because of same buffer queued into two different fifo. Signed-off-by: Hugues Fruchet --- samples/drivers/video/tcpserversink/src/main.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/samples/drivers/video/tcpserversink/src/main.c b/samples/drivers/video/tcpserversink/src/main.c index 051a30a1edce..bf99295ef798 100644 --- a/samples/drivers/video/tcpserversink/src/main.c +++ b/samples/drivers/video/tcpserversink/src/main.c @@ -187,6 +187,12 @@ int encode_frame(struct video_buffer *in, struct video_buffer **out) return ret; } + ret = video_dequeue(encoder_dev, &in, K_FOREVER); + if (ret) { + LOG_ERR("Unable to dequeue encoder input buf"); + return ret; + } + return 0; } From 9ebfb206af8eeb88ea486c0a84fb8b4382d59131 Mon Sep 17 00:00:00 2001 From: Hugues Fruchet Date: Thu, 6 Nov 2025 11:00:07 +0100 Subject: [PATCH 0266/6328] samples: video: tcpserversink: fix multiple connect/disconnect Fix multiple connect/disconnect regression introduced in 6a7aefaa samples: video: tcpserversink: check video_enqueue/dequeue return values. Signed-off-by: Hugues Fruchet --- samples/drivers/video/tcpserversink/src/main.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/samples/drivers/video/tcpserversink/src/main.c b/samples/drivers/video/tcpserversink/src/main.c index bf99295ef798..8e1c95363b33 100644 --- a/samples/drivers/video/tcpserversink/src/main.c +++ b/samples/drivers/video/tcpserversink/src/main.c @@ -422,6 +422,8 @@ int main(void) /* Connection loop */ do { + bool disconnected = false; + LOG_INF("TCP: Waiting for client..."); client = accept(sock, (struct sockaddr *)&client_addr, &client_addr_len); @@ -473,6 +475,7 @@ int main(void) vbuf_out->bytesused); /* Send compressed video buffer to TCP client */ ret = sendall(client, vbuf_out->buffer, vbuf_out->bytesused); + disconnected = ret && ret != -EAGAIN; vbuf_out->type = VIDEO_BUF_TYPE_OUTPUT; ret = video_enqueue(encoder_dev, vbuf_out); @@ -485,8 +488,9 @@ int main(void) LOG_INF("Sending frame %d", i++); /* Send video buffer to TCP client */ ret = sendall(client, vbuf->buffer, vbuf->bytesused); + disconnected = ret && ret != -EAGAIN; #endif - if (ret && ret != -EAGAIN) { + if (disconnected) { /* client disconnected */ LOG_ERR("TCP: Client disconnected %d", ret); close(client); @@ -498,7 +502,7 @@ int main(void) LOG_ERR("Unable to enqueue video buf"); return 0; } - } while (!ret); + } while (!ret && !disconnected); /* stop capture */ if (video_stream_stop(video_dev, type)) { From b0fd7d96653d78fcff305868adcf60bc35c9399c Mon Sep 17 00:00:00 2001 From: Hugues Fruchet Date: Mon, 17 Nov 2025 10:50:02 +0100 Subject: [PATCH 0267/6328] samples: video: tcpserversink: release camera frame as soon as possible Release camera frame immediately after video encoding. Doing so, the frame could be reused by camera for next capture without waiting for the end of network transmission. Signed-off-by: Hugues Fruchet --- .../drivers/video/tcpserversink/src/main.c | 20 +++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/samples/drivers/video/tcpserversink/src/main.c b/samples/drivers/video/tcpserversink/src/main.c index 8e1c95363b33..d19b93b2d1ec 100644 --- a/samples/drivers/video/tcpserversink/src/main.c +++ b/samples/drivers/video/tcpserversink/src/main.c @@ -471,6 +471,13 @@ int main(void) #if DT_HAS_CHOSEN(zephyr_videoenc) encode_frame(vbuf, &vbuf_out); + vbuf->type = VIDEO_BUF_TYPE_INPUT; + ret = video_enqueue(video_dev, vbuf); + if (ret) { + LOG_ERR("Unable to enqueue video buf"); + return 0; + } + LOG_INF("Sending compressed frame %d (size=%d bytes)", i++, vbuf_out->bytesused); /* Send compressed video buffer to TCP client */ @@ -489,12 +496,6 @@ int main(void) /* Send video buffer to TCP client */ ret = sendall(client, vbuf->buffer, vbuf->bytesused); disconnected = ret && ret != -EAGAIN; -#endif - if (disconnected) { - /* client disconnected */ - LOG_ERR("TCP: Client disconnected %d", ret); - close(client); - } vbuf->type = VIDEO_BUF_TYPE_INPUT; ret = video_enqueue(video_dev, vbuf); @@ -502,6 +503,13 @@ int main(void) LOG_ERR("Unable to enqueue video buf"); return 0; } +#endif + if (disconnected) { + /* client disconnected */ + LOG_ERR("TCP: Client disconnected %d", ret); + close(client); + } + } while (!ret && !disconnected); /* stop capture */ From 59b653bb4f6d0ebe7b67e6fdb876090424b92621 Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Tue, 13 Jan 2026 13:30:11 +0100 Subject: [PATCH 0268/6328] tests: net: lib: http_server: Add test case for overlapping resources Add a test case verifying that if there's a static resource defined which overlaps a FS resource pointing to a directory, it takes preference on exact URI match. Signed-off-by: Robert Lubos --- tests/net/lib/http_server/core/prj.conf | 1 + tests/net/lib/http_server/core/src/main.c | 94 +++++++++++++++++++++++ 2 files changed, 95 insertions(+) diff --git a/tests/net/lib/http_server/core/prj.conf b/tests/net/lib/http_server/core/prj.conf index 9d032dc34889..6937eda0cbc9 100644 --- a/tests/net/lib/http_server/core/prj.conf +++ b/tests/net/lib/http_server/core/prj.conf @@ -44,6 +44,7 @@ CONFIG_HTTP_SERVER_CAPTURE_HEADERS=y CONFIG_HTTP_SERVER_CAPTURE_HEADER_BUFFER_SIZE=64 CONFIG_HTTP_SERVER_CAPTURE_HEADER_COUNT=2 CONFIG_HTTP_SERVER_REPORT_FAILURE_REASON=y +CONFIG_HTTP_SERVER_RESOURCE_WILDCARD=y CONFIG_HTTP_SERVER_MAX_CLIENTS=5 CONFIG_HTTP_SERVER_MAX_STREAMS=5 diff --git a/tests/net/lib/http_server/core/src/main.c b/tests/net/lib/http_server/core/src/main.c index c372f6c8b702..03b86d26bcc6 100644 --- a/tests/net/lib/http_server/core/src/main.c +++ b/tests/net/lib/http_server/core/src/main.c @@ -2805,6 +2805,100 @@ ZTEST(server_function_tests, test_http1_static_fs_compression) zassert_mem_equal(buf, expected_response, expected_response_size, "Received data doesn't match expected response"); } + +#define TEST_DIR_OVERLAP LFS_MNTP "/testfs" +#define TEST_FILE_OVERLAP "test_file" + +static struct http_resource_detail_static_fs static_file_resource_detail_dir = { + .common = { + .type = HTTP_RESOURCE_TYPE_STATIC_FS, + .bitmask_of_supported_http_methods = BIT(HTTP_GET), + .content_type = "text/html", + }, + .fs_path = LFS_MNTP, +}; + +HTTP_RESOURCE_DEFINE(static_fs_resource_dir, test_http_service, "/testfs", + &static_file_resource_detail_dir); + +static const char static_overlap_resource_payload[] = TEST_STATIC_PAYLOAD; +struct http_resource_detail_static static_overlap_resource_detail = { + .common = { + .type = HTTP_RESOURCE_TYPE_STATIC, + .bitmask_of_supported_http_methods = BIT(HTTP_GET), + }, + .static_data = static_overlap_resource_payload, + .static_data_len = sizeof(static_overlap_resource_payload) - 1, +}; + +HTTP_RESOURCE_DEFINE(static_overlap_resource, test_http_service, "/testfs/static", + &static_overlap_resource_detail); + +static void setup_fs_with_subdir(void) +{ + test_clear_flash(); + + zassert_equal(test_unmount(), TC_PASS, "Failed to unmount fs"); + zassert_equal(test_mount(), TC_PASS, "Failed to mount fs"); + + zassert_equal(test_mkdir(TEST_DIR_OVERLAP, TEST_FILE_OVERLAP), TC_PASS, + "Failed to create dir"); +} + +/* Verify that if the filesystem resource overlaps with a statically defined one, + * the latter takes preference. + */ +ZTEST(server_function_tests, test_http1_static_fs_overlap) +{ + static const char http1_request_file[] = + "GET /testfs/test_file HTTP/1.1\r\n" + "Host: 127.0.0.1:8080\r\n" + "User-Agent: curl/7.68.0\r\n" + "Accept: */*\r\n" + "\r\n"; + static const char expected_response_file[] = + "HTTP/1.1 200 OK\r\n" + "Content-Length: 30\r\n" + "Content-Type: text/html\r\n" + "\r\n" + TEST_STATIC_FS_PAYLOAD; + static const char http1_request_static[] = + "GET /testfs/static HTTP/1.1\r\n" + "Host: 127.0.0.1:8080\r\n" + "User-Agent: curl/7.68.0\r\n" + "Accept: */*\r\n" + "\r\n"; + static const char expected_response_static[] = + "HTTP/1.1 200 OK\r\n" + "Content-Type: text/html\r\n" + "Content-Length: 13\r\n" + "\r\n" + TEST_STATIC_PAYLOAD; + size_t offset = 0; + int ret; + + setup_fs_with_subdir(); + + ret = zsock_send(client_fd, http1_request_static, strlen(http1_request_static), 0); + zassert_not_equal(ret, -1, "send() failed (%d)", errno); + + memset(buf, 0, sizeof(buf)); + + test_read_data(&offset, sizeof(expected_response_static) - 1); + zassert_mem_equal(buf, expected_response_static, sizeof(expected_response_static) - 1, + "Received data doesn't match expected response"); + + ret = zsock_send(client_fd, http1_request_file, strlen(http1_request_file), 0); + zassert_not_equal(ret, -1, "send() failed (%d)", errno); + + memset(buf, 0, sizeof(buf)); + offset = 0; + + test_read_data(&offset, sizeof(expected_response_file) - 1); + zassert_mem_equal(buf, expected_response_file, sizeof(expected_response_file) - 1, + "Received data doesn't match expected response"); +} + #endif /* DT_HAS_COMPAT_STATUS_OKAY(zephyr_ram_disk) */ static void http_server_tests_before(void *fixture) From 10b9520cacf450998150d725274a7d6b88c48e24 Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Tue, 13 Jan 2026 15:25:49 +0100 Subject: [PATCH 0269/6328] net: lib: http_server: Prefer explicitly defined resources over FS ones Do direct resource path comparison on all registered resources before falling back to fnmatch() so that exact path matches get always preference. Signed-off-by: Robert Lubos --- subsys/net/lib/http/http_server_core.c | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/subsys/net/lib/http/http_server_core.c b/subsys/net/lib/http/http_server_core.c index 2c96c2643c85..3605e98da21c 100644 --- a/subsys/net/lib/http/http_server_core.c +++ b/subsys/net/lib/http/http_server_core.c @@ -780,22 +780,28 @@ struct http_resource_detail *get_resource_detail(const struct http_service_desc continue; } - if (IS_ENABLED(CONFIG_HTTP_SERVER_RESOURCE_WILDCARD)) { + if (compare_strings(path, resource->resource) == 0) { + NET_DBG("Got match for %s", resource->resource); + + *path_len = strlen(resource->resource); + return resource->detail; + } + } + + if (IS_ENABLED(CONFIG_HTTP_SERVER_RESOURCE_WILDCARD)) { + HTTP_SERVICE_FOREACH_RESOURCE(service, resource) { int ret; + if (skip_this(resource, is_websocket)) { + continue; + } + ret = fnmatch(resource->resource, path, (FNM_PATHNAME | FNM_LEADING_DIR)); if (ret == 0) { *path_len = path_len_without_query(path); return resource->detail; } } - - if (compare_strings(path, resource->resource) == 0) { - NET_DBG("Got match for %s", resource->resource); - - *path_len = strlen(resource->resource); - return resource->detail; - } } if (service->res_fallback != NULL) { From 2719679c2639fae1015f70d3482d5fbdd70225a0 Mon Sep 17 00:00:00 2001 From: Gaetan Perrot Date: Sat, 17 Jan 2026 02:18:33 +0900 Subject: [PATCH 0270/6328] drivers: ethernet: lan9250: fix error handling Several LAN9250 helper functions ignored return values from register access and wait routines, potentially hiding SPI or timeout failures. Propagate error codes from read/write/wait helpers throughout the driver so failures are detected and handled by callers. This improves robustness and makes error conditions visible during initialization, PHY access, RX/TX paths, and MAC configuration. Signed-off-by: Gaetan Perrot --- drivers/ethernet/eth_lan9250.c | 366 +++++++++++++++++++++++---------- 1 file changed, 262 insertions(+), 104 deletions(-) diff --git a/drivers/ethernet/eth_lan9250.c b/drivers/ethernet/eth_lan9250.c index 050e5d56f065..7557df3cdede 100644 --- a/drivers/ethernet/eth_lan9250.c +++ b/drivers/ethernet/eth_lan9250.c @@ -94,35 +94,61 @@ static int lan9250_wait_ready(const struct device *dev, uint16_t address, uint32 static int lan9250_read_mac_reg(const struct device *dev, uint8_t address, uint32_t *value) { uint32_t tmp; + int ret; /* Wait for MAC to be ready and send writing register command and data */ - lan9250_wait_ready(dev, LAN9250_MAC_CSR_CMD, LAN9250_MAC_CSR_CMD_BUSY, 0, - LAN9250_MAC_TIMEOUT); - lan9250_write_sys_reg(dev, LAN9250_MAC_CSR_CMD, - address | LAN9250_MAC_CSR_CMD_BUSY | LAN9250_MAC_CSR_CMD_READ); + ret = lan9250_wait_ready(dev, LAN9250_MAC_CSR_CMD, LAN9250_MAC_CSR_CMD_BUSY, 0, + LAN9250_MAC_TIMEOUT); + if (ret < 0) { + return ret; + } + + ret = lan9250_write_sys_reg(dev, LAN9250_MAC_CSR_CMD, + address | LAN9250_MAC_CSR_CMD_BUSY | LAN9250_MAC_CSR_CMD_READ); + if (ret < 0) { + return ret; + } /* Wait for MAC to be ready and send writing register command and data */ - lan9250_wait_ready(dev, LAN9250_MAC_CSR_CMD, LAN9250_MAC_CSR_CMD_BUSY, 0, - LAN9250_MAC_TIMEOUT); - lan9250_read_sys_reg(dev, LAN9250_MAC_CSR_DATA, &tmp); + ret = lan9250_wait_ready(dev, LAN9250_MAC_CSR_CMD, LAN9250_MAC_CSR_CMD_BUSY, 0, + LAN9250_MAC_TIMEOUT); + if (ret < 0) { + return ret; + } + + ret = lan9250_read_sys_reg(dev, LAN9250_MAC_CSR_DATA, &tmp); + if (ret < 0) { + return ret; + } *value = tmp; + return 0; } static int lan9250_write_mac_reg(const struct device *dev, uint8_t address, uint32_t data) { + int ret; /* Wait for MAC to be ready and send writing register command and data */ - lan9250_wait_ready(dev, LAN9250_MAC_CSR_CMD, LAN9250_MAC_CSR_CMD_BUSY, 0, - LAN9250_MAC_TIMEOUT); - lan9250_write_sys_reg(dev, LAN9250_MAC_CSR_DATA, data); - lan9250_write_sys_reg(dev, LAN9250_MAC_CSR_CMD, address | LAN9250_MAC_CSR_CMD_BUSY); + ret = lan9250_wait_ready(dev, LAN9250_MAC_CSR_CMD, LAN9250_MAC_CSR_CMD_BUSY, 0, + LAN9250_MAC_TIMEOUT); + if (ret < 0) { + return ret; + } - /* Wait until writing MAC is done */ - lan9250_wait_ready(dev, LAN9250_MAC_CSR_CMD, LAN9250_MAC_CSR_CMD_BUSY, 0, - LAN9250_MAC_TIMEOUT); + ret = lan9250_write_sys_reg(dev, LAN9250_MAC_CSR_DATA, data); + if (ret < 0) { + return ret; + } - return 0; + ret = lan9250_write_sys_reg(dev, LAN9250_MAC_CSR_CMD, address | LAN9250_MAC_CSR_CMD_BUSY); + if (ret < 0) { + return ret; + } + + /* Wait until writing MAC is done */ + return lan9250_wait_ready(dev, LAN9250_MAC_CSR_CMD, LAN9250_MAC_CSR_CMD_BUSY, 0, + LAN9250_MAC_TIMEOUT); } static int lan9250_wait_mac_ready(const struct device *dev, uint8_t address, uint32_t mask, @@ -147,10 +173,14 @@ static int lan9250_wait_mac_ready(const struct device *dev, uint8_t address, uin static int lan9250_read_phy_reg(const struct device *dev, uint8_t address, uint16_t *value) { uint32_t tmp; + int ret; /* Wait PHY to be ready and send reading register command */ - lan9250_wait_mac_ready(dev, LAN9250_HMAC_MII_ACC, LAN9250_HMAC_MII_ACC_MIIBZY, 0, - LAN9250_PHY_TIMEOUT); + ret = lan9250_wait_mac_ready(dev, LAN9250_HMAC_MII_ACC, LAN9250_HMAC_MII_ACC_MIIBZY, 0, + LAN9250_PHY_TIMEOUT); + if (ret < 0) { + return ret; + } /* Reference: Microchip Ethernet LAN9250 * https://github.com/microchip-pic-avr-solutions/ethernet-lan9250/ @@ -166,14 +196,24 @@ static int lan9250_read_phy_reg(const struct device *dev, uint8_t address, uint1 * Where phy_add = 0b00001 & index = address * Data = ((phy_add & 0x1F) << 11) | ((index & 0x1F) << 6) */ - lan9250_write_mac_reg(dev, LAN9250_HMAC_MII_ACC, (1 << 11) | ((address & 0x1F) << 6)); + ret = lan9250_write_mac_reg(dev, LAN9250_HMAC_MII_ACC, (1 << 11) | ((address & 0x1F) << 6)); + if (ret < 0) { + return ret; + } /* Wait PHY to be ready and send reading register command */ - lan9250_wait_mac_ready(dev, LAN9250_HMAC_MII_ACC, LAN9250_HMAC_MII_ACC_MIIBZY, 0, - LAN9250_PHY_TIMEOUT); + ret = lan9250_wait_mac_ready(dev, LAN9250_HMAC_MII_ACC, LAN9250_HMAC_MII_ACC_MIIBZY, 0, + LAN9250_PHY_TIMEOUT); + if (ret < 0) { + return ret; + } /* Read 32bit value from the indirect MAC registers */ - lan9250_read_mac_reg(dev, LAN9250_HMAC_MII_DATA, &tmp); + ret = lan9250_read_mac_reg(dev, LAN9250_HMAC_MII_DATA, &tmp); + if (ret < 0) { + return ret; + } + *value = tmp; return 0; @@ -181,10 +221,18 @@ static int lan9250_read_phy_reg(const struct device *dev, uint8_t address, uint1 static int lan9250_write_phy_reg(const struct device *dev, uint8_t address, uint16_t data) { + int ret; /* Wait PHY to be ready and send reading register command */ - lan9250_wait_mac_ready(dev, LAN9250_HMAC_MII_ACC, LAN9250_HMAC_MII_ACC_MIIBZY, 0, - LAN9250_PHY_TIMEOUT); - lan9250_write_mac_reg(dev, LAN9250_HMAC_MII_DATA, data); + ret = lan9250_wait_mac_ready(dev, LAN9250_HMAC_MII_ACC, LAN9250_HMAC_MII_ACC_MIIBZY, 0, + LAN9250_PHY_TIMEOUT); + if (ret < 0) { + return ret; + } + + ret = lan9250_write_mac_reg(dev, LAN9250_HMAC_MII_DATA, data); + if (ret < 0) { + return ret; + } /* Reference: Microchip Ethernet LAN9250 * https://github.com/microchip-pic-avr-solutions/ethernet-lan9250/ @@ -200,35 +248,45 @@ static int lan9250_write_phy_reg(const struct device *dev, uint8_t address, uint * Where phy_add = 0b00001 & index = address * Data = ((phy_add & 0x1F) << 11) | ((index & 0x1F)<< 6) | MIIWnR */ - lan9250_write_mac_reg(dev, LAN9250_HMAC_MII_ACC, - (1 << 11) | ((address & 0x1F) << 6) | LAN9250_HMAC_MII_ACC_MIIW_R); + ret = lan9250_write_mac_reg(dev, LAN9250_HMAC_MII_ACC, + (1 << 11) | ((address & 0x1F) << 6) | + LAN9250_HMAC_MII_ACC_MIIW_R); + if (ret < 0) { + return ret; + } /* Wait PHY to be ready and send reading register command */ - lan9250_wait_mac_ready(dev, LAN9250_HMAC_MII_ACC, LAN9250_HMAC_MII_ACC_MIIBZY, 0, - LAN9250_PHY_TIMEOUT); - - return 0; + return lan9250_wait_mac_ready(dev, LAN9250_HMAC_MII_ACC, LAN9250_HMAC_MII_ACC_MIIBZY, 0, + LAN9250_PHY_TIMEOUT); } static int lan9250_set_macaddr(const struct device *dev) { struct lan9250_runtime *ctx = dev->data; + int ret; - lan9250_write_mac_reg(dev, LAN9250_HMAC_ADDRL, - ctx->mac_address[0] | (ctx->mac_address[1] << 8) | - (ctx->mac_address[2] << 16) | (ctx->mac_address[3] << 24)); - lan9250_write_mac_reg(dev, LAN9250_HMAC_ADDRH, - ctx->mac_address[4] | (ctx->mac_address[5] << 8)); + ret = lan9250_write_mac_reg(dev, LAN9250_HMAC_ADDRL, + ctx->mac_address[0] | (ctx->mac_address[1] << 8) | + (ctx->mac_address[2] << 16) | + (ctx->mac_address[3] << 24)); + if (ret < 0) { + return ret; + } - return 0; + return lan9250_write_mac_reg(dev, LAN9250_HMAC_ADDRH, + ctx->mac_address[4] | (ctx->mac_address[5] << 8)); } static int lan9250_hw_cfg_check(const struct device *dev) { uint32_t tmp; + int ret; do { - lan9250_read_sys_reg(dev, LAN9250_HW_CFG, &tmp); + ret = lan9250_read_sys_reg(dev, LAN9250_HW_CFG, &tmp); + if (ret < 0) { + return ret; + } k_busy_wait(USEC_PER_MSEC * 1U); } while ((tmp & LAN9250_HW_CFG_DEVICE_READY) == 0); @@ -240,26 +298,33 @@ static int lan9250_sw_reset(const struct device *dev) int ret; ret = lan9250_write_sys_reg(dev, LAN9250_RESET_CTL, - LAN9250_RESET_CTL_HMAC_RST | - LAN9250_RESET_CTL_PHY_RST | - LAN9250_RESET_CTL_DIGITAL_RST); + LAN9250_RESET_CTL_HMAC_RST | LAN9250_RESET_CTL_PHY_RST | + LAN9250_RESET_CTL_DIGITAL_RST); if (ret < 0) { return ret; } /* Wait until LAN9250 SPI bus is ready */ - return lan9250_wait_ready(dev, LAN9250_BYTE_TEST, BOTR_MASK, - LAN9250_BYTE_TEST_DEFAULT, LAN9250_RESET_TIMEOUT); + return lan9250_wait_ready(dev, LAN9250_BYTE_TEST, BOTR_MASK, LAN9250_BYTE_TEST_DEFAULT, + LAN9250_RESET_TIMEOUT); } static int lan9250_configure(const struct device *dev) { uint32_t tmp; + int ret; - lan9250_hw_cfg_check(dev); + ret = lan9250_hw_cfg_check(dev); + if (ret < 0) { + return ret; + } /* Read LAN9250 hardware ID */ - lan9250_read_sys_reg(dev, LAN9250_ID_REV, &tmp); + ret = lan9250_read_sys_reg(dev, LAN9250_ID_REV, &tmp); + if (ret < 0) { + return ret; + } + if ((tmp & LAN9250_ID_REV_CHIP_ID) != LAN9250_ID_REV_CHIP_ID_DEFAULT) { LOG_ERR("ERROR: Bad Rev ID: %08x\n", tmp); return -ENODEV; @@ -272,8 +337,11 @@ static int lan9250_configure(const struct device *dev) * - TX status FIFO size: 512 * - RX status FIFO size: 512 */ - lan9250_write_sys_reg(dev, LAN9250_HW_CFG, - LAN9250_HW_CFG_MBO | LAN9250_HW_CFG_TX_FIF_SZ_8KB); + ret = lan9250_write_sys_reg(dev, LAN9250_HW_CFG, + LAN9250_HW_CFG_MBO | LAN9250_HW_CFG_TX_FIF_SZ_8KB); + if (ret < 0) { + return ret; + } /* Configure MAC automatic flow control: * @@ -282,7 +350,10 @@ static int lan9250_configure(const struct device *dev) * LAN_Regwrite32(AFC_CFG, 0x006E3741); * */ - lan9250_write_sys_reg(dev, LAN9250_AFC_CFG, 0x006e3741); + ret = lan9250_write_sys_reg(dev, LAN9250_AFC_CFG, 0x006e3741); + if (ret < 0) { + return ret; + } /* Configure interrupt: * @@ -291,27 +362,39 @@ static int lan9250_configure(const struct device *dev) * - Interrupt pin active output low * - Interrupt pin push-pull driver */ - lan9250_write_sys_reg(dev, LAN9250_IRQ_CFG, - LAN9250_IRQ_CFG_INT_DEAS_100US | LAN9250_IRQ_CFG_IRQ_EN | - LAN9250_IRQ_CFG_IRQ_TYPE_PP); + ret = lan9250_write_sys_reg(dev, LAN9250_IRQ_CFG, + LAN9250_IRQ_CFG_INT_DEAS_100US | LAN9250_IRQ_CFG_IRQ_EN | + LAN9250_IRQ_CFG_IRQ_TYPE_PP); + if (ret < 0) { + return ret; + } /* Configure interrupt trigger source, please refer to macro * LAN9250_INT_SOURCE. */ - lan9250_write_sys_reg(dev, LAN9250_INT_EN, - LAN9250_INT_EN_PHY_INT_EN | LAN9250_INT_EN_RSFL_EN); + ret = lan9250_write_sys_reg(dev, LAN9250_INT_EN, + LAN9250_INT_EN_PHY_INT_EN | LAN9250_INT_EN_RSFL_EN); + if (ret < 0) { + return ret; + } /* Disable TX data FIFO available interrupt */ - lan9250_write_sys_reg(dev, LAN9250_FIFO_INT, - LAN9250_FIFO_INT_TX_DATA_AVAILABLE_LEVEL | - LAN9250_FIFO_INT_TX_STATUS_LEVEL); + ret = lan9250_write_sys_reg(dev, LAN9250_FIFO_INT, + LAN9250_FIFO_INT_TX_DATA_AVAILABLE_LEVEL | + LAN9250_FIFO_INT_TX_STATUS_LEVEL); + if (ret < 0) { + return ret; + } /* Configure RX: * * - RX DMA counter: Ethernet maximum packet size * - RX data offset: 4, so that need read dummy before reading data */ - lan9250_write_sys_reg(dev, LAN9250_RX_CFG, 0x06000000 | 0x00000400); + ret = lan9250_write_sys_reg(dev, LAN9250_RX_CFG, 0x06000000 | 0x00000400); + if (ret < 0) { + return ret; + } /* Configure remote power management: * @@ -322,19 +405,25 @@ static int lan9250_configure(const struct device *dev) * - Wake on * - Clear wakeon */ - lan9250_write_sys_reg(dev, LAN9250_PMT_CTRL, - LAN9250_PMT_CTRL_PM_WAKE | LAN9250_PMT_CTRL_1588_DIS | - LAN9250_PMT_CTRL_1588_TSU_DIS | LAN9250_PMT_CTRL_WOL_EN | - LAN9250_PMT_CTRL_WOL_STS); + ret = lan9250_write_sys_reg(dev, LAN9250_PMT_CTRL, + LAN9250_PMT_CTRL_PM_WAKE | LAN9250_PMT_CTRL_1588_DIS | + LAN9250_PMT_CTRL_1588_TSU_DIS | + LAN9250_PMT_CTRL_WOL_EN | LAN9250_PMT_CTRL_WOL_STS); + if (ret < 0) { + return ret; + } /* Configure PHY basic control: * * - Auto-Negotiation for 10/100 Mbits and Half/Full Duplex */ - lan9250_write_phy_reg(dev, LAN9250_PHY_BASIC_CONTROL, - LAN9250_PHY_BASIC_CONTROL_PHY_AN | - LAN9250_PHY_BASIC_CONTROL_PHY_SPEED_SEL_LSB | - LAN9250_PHY_BASIC_CONTROL_PHY_DUPLEX); + ret = lan9250_write_phy_reg(dev, LAN9250_PHY_BASIC_CONTROL, + LAN9250_PHY_BASIC_CONTROL_PHY_AN | + LAN9250_PHY_BASIC_CONTROL_PHY_SPEED_SEL_LSB | + LAN9250_PHY_BASIC_CONTROL_PHY_DUPLEX); + if (ret < 0) { + return ret; + } /* Configure PHY auto-negotiation advertisement capability: * @@ -344,18 +433,25 @@ static int lan9250_configure(const struct device *dev) * - 10Base-X half/full duplex * - Select IEEE802.3 */ - lan9250_write_phy_reg(dev, LAN9250_PHY_AN_ADV, - LAN9250_PHY_AN_ADV_ASYM_PAUSE | LAN9250_PHY_AN_ADV_SYM_PAUSE | - LAN9250_PHY_AN_ADV_100BTX_HD | LAN9250_PHY_AN_ADV_100BTX_FD | - LAN9250_PHY_AN_ADV_10BT_HD | LAN9250_PHY_AN_ADV_10BT_FD | - LAN9250_PHY_AN_ADV_SELECTOR_DEFAULT); + ret = lan9250_write_phy_reg( + dev, LAN9250_PHY_AN_ADV, + LAN9250_PHY_AN_ADV_ASYM_PAUSE | LAN9250_PHY_AN_ADV_SYM_PAUSE | + LAN9250_PHY_AN_ADV_100BTX_HD | LAN9250_PHY_AN_ADV_100BTX_FD | + LAN9250_PHY_AN_ADV_10BT_HD | LAN9250_PHY_AN_ADV_10BT_FD | + LAN9250_PHY_AN_ADV_SELECTOR_DEFAULT); + if (ret < 0) { + return ret; + } /* Configure PHY special mode: * * - PHY mode = 111b, enable all capable and auto-nagotiation * - PHY address = 1, default value is fixed to 1 by manufacturer */ - lan9250_write_phy_reg(dev, LAN9250_PHY_SPECIAL_MODES, 0x00E0 | 1); + ret = lan9250_write_phy_reg(dev, LAN9250_PHY_SPECIAL_MODES, 0x00E0 | 1); + if (ret < 0) { + return ret; + } /* Configure PHY special control or status indication: * @@ -363,29 +459,41 @@ static int lan9250_configure(const struct device *dev) * - Auto-MDIX * - Disable SQE tests */ - lan9250_write_phy_reg(dev, LAN9250_PHY_SPECIAL_CONTROL_STAT_IND, - LAN9250_PHY_SPECIAL_CONTROL_STAT_IND_AMDIXCTRL | - LAN9250_PHY_SPECIAL_CONTROL_STAT_IND_AMDIXEN | - LAN9250_PHY_SPECIAL_CONTROL_STAT_IND_SQEOFF); + ret = lan9250_write_phy_reg(dev, LAN9250_PHY_SPECIAL_CONTROL_STAT_IND, + LAN9250_PHY_SPECIAL_CONTROL_STAT_IND_AMDIXCTRL | + LAN9250_PHY_SPECIAL_CONTROL_STAT_IND_AMDIXEN | + LAN9250_PHY_SPECIAL_CONTROL_STAT_IND_SQEOFF); + if (ret < 0) { + return ret; + } /* Configure PHY interrupt source: * * - Link up * - Link down */ - lan9250_write_phy_reg(dev, LAN9250_PHY_INTERRUPT_MASK, - LAN9250_PHY_INTERRUPT_SOURCE_LINK_UP | - LAN9250_PHY_INTERRUPT_SOURCE_LINK_DOWN); + ret = lan9250_write_phy_reg(dev, LAN9250_PHY_INTERRUPT_MASK, + LAN9250_PHY_INTERRUPT_SOURCE_LINK_UP | + LAN9250_PHY_INTERRUPT_SOURCE_LINK_DOWN); + if (ret < 0) { + return ret; + } /* Configure special control or status: * * - Fixed to write 0000010b to reserved filed */ - lan9250_write_phy_reg(dev, LAN9250_PHY_SPECIAL_CONTROL_STATUS, - LAN9250_PHY_MODE_CONTROL_STATUS_ALTINT); + ret = lan9250_write_phy_reg(dev, LAN9250_PHY_SPECIAL_CONTROL_STATUS, + LAN9250_PHY_MODE_CONTROL_STATUS_ALTINT); + if (ret < 0) { + return ret; + } /* Clear interrupt status */ - lan9250_write_sys_reg(dev, LAN9250_INT_STS, 0xFFFFFFFF); + ret = lan9250_write_sys_reg(dev, LAN9250_INT_STS, 0xFFFFFFFF); + if (ret < 0) { + return ret; + } /* Configure HMAC control: * @@ -397,18 +505,18 @@ static int lan9250_configure(const struct device *dev) * - Hash filtering disabled * - Promiscuous disabled */ - lan9250_write_mac_reg(dev, LAN9250_HMAC_CR, - LAN9250_HMAC_CR_PADSTR | LAN9250_HMAC_CR_FDPX | - LAN9250_HMAC_CR_TXEN | LAN9250_HMAC_CR_RXEN | - LAN9250_HMAC_CR_MCPAS); + ret = lan9250_write_mac_reg(dev, LAN9250_HMAC_CR, + LAN9250_HMAC_CR_PADSTR | LAN9250_HMAC_CR_TXEN | + LAN9250_HMAC_CR_RXEN | LAN9250_HMAC_CR_FDPX); + if (ret < 0) { + return ret; + } /* Configure TX: * * - TX enable */ - lan9250_write_sys_reg(dev, LAN9250_TX_CFG, LAN9250_TX_CFG_TX_ON); - - return 0; + return lan9250_write_sys_reg(dev, LAN9250_TX_CFG, LAN9250_TX_CFG_TX_ON); } static int lan9250_write_buf(const struct device *dev, uint8_t *data_buffer, uint16_t buf_len) @@ -465,13 +573,20 @@ static int lan9250_rx(const struct device *dev) uint16_t pkt_len; uint8_t pktcnt; uint32_t tmp; + int ret; /* Check valid packet count */ - lan9250_read_sys_reg(dev, LAN9250_RX_FIFO_INF, &tmp); + ret = lan9250_read_sys_reg(dev, LAN9250_RX_FIFO_INF, &tmp); + if (ret < 0) { + return ret; + } pktcnt = (tmp & 0x00ff0000) >> 16; /* Check packet length */ - lan9250_read_sys_reg(dev, LAN9250_RX_STATUS_FIFO, &tmp); + ret = lan9250_read_sys_reg(dev, LAN9250_RX_STATUS_FIFO, &tmp); + if (ret < 0) { + return ret; + } pkt_len = (tmp & LAN9250_RX_STS_PACKET_LEN) >> 16; if (pktcnt == 0 || pkt_len == 0) { @@ -479,7 +594,10 @@ static int lan9250_rx(const struct device *dev) } /* Read dummy data */ - lan9250_read_sys_reg(dev, LAN9250_RX_DATA_FIFO, &tmp); + ret = lan9250_read_sys_reg(dev, LAN9250_RX_DATA_FIFO, &tmp); + if (ret < 0) { + return ret; + } pkt_len -= 4; if (pkt_len > NET_ETH_MAX_FRAME_SIZE) { @@ -509,12 +627,18 @@ static int lan9250_rx(const struct device *dev) } pkt_len -= data_len; - lan9250_read_buf(dev, data_ptr, data_len); + ret = lan9250_read_buf(dev, data_ptr, data_len); + if (ret < 0) { + return ret; + } net_buf_add(pkt_buf, data_len); pkt_buf = pkt_buf->frags; } while (pkt_len > 0); - lan9250_read_sys_reg(dev, LAN9250_RX_DATA_FIFO, &tmp); + ret = lan9250_read_sys_reg(dev, LAN9250_RX_DATA_FIFO, &tmp); + if (ret < 0) { + return ret; + } net_pkt_set_iface(pkt, ctx->iface); /* Feed buffer frame to IP stack */ @@ -535,30 +659,48 @@ static int lan9250_tx(const struct device *dev, struct net_pkt *pkt) uint16_t free_size; uint8_t status_size; uint32_t tmp; + int ret; + + ret = lan9250_read_sys_reg(dev, LAN9250_TX_FIFO_INF, ®val); + if (ret < 0) { + return ret; + } - lan9250_read_sys_reg(dev, LAN9250_TX_FIFO_INF, ®val); status_size = (regval & LAN9250_TX_FIFO_INF_TXSUSED) >> 16; free_size = regval & LAN9250_TX_FIFO_INF_TXFREE; k_sem_take(&ctx->tx_rx_sem, K_FOREVER); /* TX command 'A' */ - lan9250_write_sys_reg(dev, LAN9250_TX_DATA_FIFO, - LAN9250_TX_CMD_A_INT_ON_COMP | LAN9250_TX_CMD_A_BUFFER_ALIGN_4B | - LAN9250_TX_CMD_A_START_OFFSET_0B | - LAN9250_TX_CMD_A_FIRST_SEG | LAN9250_TX_CMD_A_LAST_SEG | len); + ret = lan9250_write_sys_reg( + dev, LAN9250_TX_DATA_FIFO, + LAN9250_TX_CMD_A_INT_ON_COMP | LAN9250_TX_CMD_A_BUFFER_ALIGN_4B | + LAN9250_TX_CMD_A_START_OFFSET_0B | LAN9250_TX_CMD_A_FIRST_SEG | + LAN9250_TX_CMD_A_LAST_SEG | len); + if (ret < 0) { + return ret; + } /* TX command 'B' */ - lan9250_write_sys_reg(dev, LAN9250_TX_DATA_FIFO, LAN9250_TX_CMD_B_PACKET_TAG | len); + ret = lan9250_write_sys_reg(dev, LAN9250_TX_DATA_FIFO, LAN9250_TX_CMD_B_PACKET_TAG | len); + if (ret < 0) { + return ret; + } if (net_pkt_read(pkt, ctx->buf, len)) { return -EIO; } - lan9250_write_buf(dev, ctx->buf, LAN9250_ALIGN(len)); + ret = lan9250_write_buf(dev, ctx->buf, LAN9250_ALIGN(len)); + if (ret < 0) { + return ret; + } for (int i = 0; i < status_size; i++) { - lan9250_read_sys_reg(dev, LAN9250_TX_STATUS_FIFO, &tmp); + ret = lan9250_read_sys_reg(dev, LAN9250_TX_STATUS_FIFO, &tmp); + if (ret < 0) { + return ret; + } } k_sem_give(&ctx->tx_rx_sem); @@ -647,12 +789,17 @@ static int lan9250_set_config(const struct device *dev, enum ethernet_config_typ const struct ethernet_config *config) { struct lan9250_runtime *ctx = dev->data; + int ret; switch (type) { case ETHERNET_CONFIG_TYPE_MAC_ADDRESS: memcpy(ctx->mac_address, config->mac_address.addr, sizeof(ctx->mac_address)); - lan9250_set_macaddr(dev); + ret = lan9250_set_macaddr(dev); + if (ret < 0) { + LOG_ERR("Set mac address failed"); + return ret; + } LOG_INF("%s MAC set to %02x:%02x:%02x:%02x:%02x:%02x", dev->name, @@ -668,7 +815,10 @@ static int lan9250_set_config(const struct device *dev, enum ethernet_config_typ if (IS_ENABLED(CONFIG_NET_PROMISCUOUS_MODE)) { uint32_t reg; - lan9250_read_mac_reg(dev, LAN9250_HMAC_CR, ®); + ret = lan9250_read_mac_reg(dev, LAN9250_HMAC_CR, ®); + if (ret < 0) { + return ret; + } /* See Table 11-1 from the LAN9250 data sheet */ if (config->promisc_mode) { @@ -775,10 +925,18 @@ static int lan9250_init(const struct device *dev) LOG_ERR("Reset failed"); return ret; } - lan9250_configure(dev); + ret = lan9250_configure(dev); + if (ret < 0) { + LOG_ERR("Configuration failed"); + return ret; + } (void)net_eth_mac_load(&config->mac_cfg, context->mac_address); - lan9250_set_macaddr(dev); + ret = lan9250_set_macaddr(dev); + if (ret < 0) { + LOG_ERR("Set mac address failed"); + return ret; + } k_thread_create(&context->thread, context->thread_stack, CONFIG_ETH_LAN9250_RX_THREAD_STACK_SIZE, From f18da88e3f2484199318e81aeb25dadb35e31450 Mon Sep 17 00:00:00 2001 From: Gaetan Perrot Date: Tue, 20 Jan 2026 02:02:51 +0900 Subject: [PATCH 0271/6328] drivers: ethernet: lan9250: fix uninitialized variable warning The lan9250_thread() function declares a local variable that may be used without being initialized, triggering a -Wmaybe-uninitialized warning when building with -Werror. Initialize the variable at declaration to ensure deterministic behavior and avoid build failures. No functional change intended. Signed-off-by: Gaetan Perrot --- drivers/ethernet/eth_lan9250.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/ethernet/eth_lan9250.c b/drivers/ethernet/eth_lan9250.c index 7557df3cdede..c722e61beab3 100644 --- a/drivers/ethernet/eth_lan9250.c +++ b/drivers/ethernet/eth_lan9250.c @@ -723,7 +723,7 @@ static void lan9250_thread(void *p1, void *p2, void *p3) const struct device *dev = p1; struct lan9250_runtime *context = dev->data; uint32_t int_sts; - uint16_t tmp; + uint16_t tmp = 0; uint32_t ier; while (true) { From ed545d230275648be0630fcc4439647d9cd226d5 Mon Sep 17 00:00:00 2001 From: Gaetan Perrot Date: Thu, 22 Jan 2026 01:20:17 +0900 Subject: [PATCH 0272/6328] drivers: ethernet: lan9250: Make interrupt mask constant unsigned Add a 'U' suffix to the interrupt status mask passed to lan9250_write_sys_reg() to make the constant explicitly unsigned. This avoids signed/unsigned ambiguity and addresses a SonarQube static analysis warning. Signed-off-by: Gaetan Perrot --- drivers/ethernet/eth_lan9250.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/ethernet/eth_lan9250.c b/drivers/ethernet/eth_lan9250.c index c722e61beab3..c6699898fbb5 100644 --- a/drivers/ethernet/eth_lan9250.c +++ b/drivers/ethernet/eth_lan9250.c @@ -490,7 +490,7 @@ static int lan9250_configure(const struct device *dev) } /* Clear interrupt status */ - ret = lan9250_write_sys_reg(dev, LAN9250_INT_STS, 0xFFFFFFFF); + ret = lan9250_write_sys_reg(dev, LAN9250_INT_STS, 0xFFFFFFFFU); if (ret < 0) { return ret; } From 7af0a2fcdf5ebf8ce56017c15827b8871e657f9a Mon Sep 17 00:00:00 2001 From: Gaetan Perrot Date: Wed, 21 Jan 2026 18:55:15 +0900 Subject: [PATCH 0273/6328] sensor: adi: adxl372: stream: check return value of adxl372_set_op_mode Check the return value of adxl372_set_op_mode() in adxl372_submit_stream() and abort on error. Fix CID: 516239 Signed-off-by: Gaetan Perrot --- drivers/sensor/adi/adxl372/adxl372_stream.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/sensor/adi/adxl372/adxl372_stream.c b/drivers/sensor/adi/adxl372/adxl372_stream.c index 0555109b8023..f2b59f68b622 100644 --- a/drivers/sensor/adi/adxl372/adxl372_stream.c +++ b/drivers/sensor/adi/adxl372/adxl372_stream.c @@ -114,7 +114,10 @@ void adxl372_submit_stream(const struct device *dev, struct rtio_iodev_sqe *iode adxl372_configure_fifo(dev, current_fifo_mode, data->fifo_config.fifo_format, data->fifo_config.fifo_samples); - adxl372_set_op_mode(dev, cfg_372->op_mode); + rc = adxl372_set_op_mode(dev, cfg_372->op_mode); + if (rc < 0) { + return; + } } rc = gpio_pin_interrupt_configure_dt(&cfg_372->interrupt, GPIO_INT_EDGE_TO_ACTIVE); From 8402a4f8e5b49c09f65bbfb7d93164375eceaf4b Mon Sep 17 00:00:00 2001 From: Pieter De Gendt Date: Wed, 21 Jan 2026 11:17:47 +0100 Subject: [PATCH 0274/6328] drivers: gpio: mcux: Fix updating ICR registers without IRQ lock During configuration the base->ICR1 or base->ICR2 register is written without an IRQ lock. This can result in unwanted side-effects if the status bit isn't cleared, or the edge select still needs to be updated. Signed-off-by: Pieter De Gendt --- drivers/gpio/gpio_mcux_igpio.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/drivers/gpio/gpio_mcux_igpio.c b/drivers/gpio/gpio_mcux_igpio.c index f55df0746ae8..6e0240d9d5d1 100644 --- a/drivers/gpio/gpio_mcux_igpio.c +++ b/drivers/gpio/gpio_mcux_igpio.c @@ -292,6 +292,10 @@ static int mcux_igpio_pin_interrupt_configure(const struct device *dev, return -ENOTSUP; } + if (pin >= 32) { + return -EINVAL; + } + if (mode == GPIO_INT_MODE_DISABLED) { key = irq_lock(); @@ -314,18 +318,16 @@ static int mcux_igpio_pin_interrupt_configure(const struct device *dev, icr = 0; } + key = irq_lock(); + if (pin < 16) { shift = 2 * pin; base->ICR1 = (base->ICR1 & ~(3 << shift)) | (icr << shift); - } else if (pin < 32) { + } else { shift = 2 * (pin - 16); base->ICR2 = (base->ICR2 & ~(3 << shift)) | (icr << shift); - } else { - return -EINVAL; } - key = irq_lock(); - WRITE_BIT(base->EDGE_SEL, pin, trig == GPIO_INT_TRIG_BOTH); WRITE_BIT(base->ISR, pin, 1); WRITE_BIT(base->IMR, pin, 1); From f64a999147e74e95739bf61fec5562c0d2ca0955 Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Wed, 21 Jan 2026 12:24:22 +0200 Subject: [PATCH 0275/6328] drivers: bluetooth: silabs_efr32: Fix default for max PAwR advertisers This option already depends on BT_PER_ADV_RSP being enabled, so we should have a more reasonable default for it. This way e.g. the existing PAwR sample app should work without additional changes. Signed-off-by: Johan Hedberg --- drivers/bluetooth/hci/Kconfig.silabs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/bluetooth/hci/Kconfig.silabs b/drivers/bluetooth/hci/Kconfig.silabs index 74188c1f1387..a5a4014a53ca 100644 --- a/drivers/bluetooth/hci/Kconfig.silabs +++ b/drivers/bluetooth/hci/Kconfig.silabs @@ -164,7 +164,7 @@ if BT_PER_ADV_RSP config BT_SILABS_EFR32_MAX_PAWR_ADVERTISERS int "Maximum numbers of Periodic Advertising With Response advertisers" - default 0 + default 1 range 0 BT_SILABS_EFR32_MAX_PERIODIC_ADVERTISERS config BT_SILABS_EFR32_MAX_PAWR_ADVERTISED_DATA_LENGTH_HINT From de04861e294c9db18f6f948c19de45fd0d150ed7 Mon Sep 17 00:00:00 2001 From: Fabrice DJIATSA Date: Wed, 21 Jan 2026 11:48:36 +0100 Subject: [PATCH 0276/6328] samples: sensor: stream_drdy: fix invalid dt enums in overlays Fix Devicetree compilation errors caused by incorrect enum macro names used in DTS overlay files. Replace LSM6DSV16X_DT_ODR_AT_120Hz with the correct Devicetree enum LSM6DSVXXX_DT_ODR_AT_120Hz in the stream_drdy sample boards overlay. Signed-off-by: Fabrice DJIATSA --- samples/sensor/stream_drdy/boards/nucleo_f401re.overlay | 2 +- samples/sensor/stream_drdy/boards/nucleo_h503rb.overlay | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/samples/sensor/stream_drdy/boards/nucleo_f401re.overlay b/samples/sensor/stream_drdy/boards/nucleo_f401re.overlay index 012cf89d9a8c..79be674ebe2d 100644 --- a/samples/sensor/stream_drdy/boards/nucleo_f401re.overlay +++ b/samples/sensor/stream_drdy/boards/nucleo_f401re.overlay @@ -22,7 +22,7 @@ lsm6dsv16x_6b_x_nucleo_iks4a1: lsm6dsv16x@6b { compatible = "st,lsm6dsv16x"; reg = <0x6b>; - accel-odr = ; + accel-odr = ; accel-range = ; int2-gpios = <&arduino_header 10 GPIO_ACTIVE_HIGH>; /* D4 (PB5) */ drdy-pin = <2>; diff --git a/samples/sensor/stream_drdy/boards/nucleo_h503rb.overlay b/samples/sensor/stream_drdy/boards/nucleo_h503rb.overlay index 012cf89d9a8c..79be674ebe2d 100644 --- a/samples/sensor/stream_drdy/boards/nucleo_h503rb.overlay +++ b/samples/sensor/stream_drdy/boards/nucleo_h503rb.overlay @@ -22,7 +22,7 @@ lsm6dsv16x_6b_x_nucleo_iks4a1: lsm6dsv16x@6b { compatible = "st,lsm6dsv16x"; reg = <0x6b>; - accel-odr = ; + accel-odr = ; accel-range = ; int2-gpios = <&arduino_header 10 GPIO_ACTIVE_HIGH>; /* D4 (PB5) */ drdy-pin = <2>; From d1e8918332c1420f40b2f857c3372c4f30c1db22 Mon Sep 17 00:00:00 2001 From: Fabrice DJIATSA Date: Wed, 21 Jan 2026 11:51:08 +0100 Subject: [PATCH 0277/6328] boards: shields: x_nucleo_dfx01m2: fix invalid dt enums in overlays Fix the panel pixel format enum in the X-NUCLEO-GFX01M2 shield overlay by using PANEL_PIXEL_FORMAT_RGB_565 as defined in panel dt-bindings. Signed-off-by: Fabrice DJIATSA --- boards/shields/x_nucleo_gfx01m2/x_nucleo_gfx01m2.overlay | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/boards/shields/x_nucleo_gfx01m2/x_nucleo_gfx01m2.overlay b/boards/shields/x_nucleo_gfx01m2/x_nucleo_gfx01m2.overlay index 812fa68422d9..641a5e294029 100644 --- a/boards/shields/x_nucleo_gfx01m2/x_nucleo_gfx01m2.overlay +++ b/boards/shields/x_nucleo_gfx01m2/x_nucleo_gfx01m2.overlay @@ -74,7 +74,7 @@ width = <240>; height = <320>; rotation = <180>; - pixel-format = ; + pixel-format = ; frmctr1 = [00 1f]; /* 60Hz frame rate */ }; }; From c64c13e5256da78311eb970becc99c6be121b203 Mon Sep 17 00:00:00 2001 From: Mathieu Choplain Date: Wed, 21 Jan 2026 11:40:36 +0100 Subject: [PATCH 0278/6328] soc: st: stm32: cleanup linker scripts of STM32MP1 series STM32MP1 series used a custom SOC_LINKER_SCRIPT, but all it did was include the main Cortex-M script, unnecessarily re-include headers already included by the main script(!) and add a custom section. Get rid of the custom SOC_LINKER_SCRIPT but keep the custom section by moving it to a linker script snippet file, added to the build system using CMake directives. Signed-off-by: Mathieu Choplain --- soc/st/stm32/stm32mp1x/CMakeLists.txt | 4 +++- soc/st/stm32/stm32mp1x/linker.ld | 25 ------------------------- soc/st/stm32/stm32mp1x/rsc_table.ld | 9 +++++++++ 3 files changed, 12 insertions(+), 26 deletions(-) delete mode 100644 soc/st/stm32/stm32mp1x/linker.ld create mode 100644 soc/st/stm32/stm32mp1x/rsc_table.ld diff --git a/soc/st/stm32/stm32mp1x/CMakeLists.txt b/soc/st/stm32/stm32mp1x/CMakeLists.txt index 65004cceca8c..99cf221d1d7c 100644 --- a/soc/st/stm32/stm32mp1x/CMakeLists.txt +++ b/soc/st/stm32/stm32mp1x/CMakeLists.txt @@ -9,4 +9,6 @@ zephyr_sources( zephyr_include_directories(.) -set(SOC_LINKER_SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/linker.ld CACHE INTERNAL "") +zephyr_linker_sources_ifdef(CONFIG_OPENAMP_RSC_TABLE ROM_SECTIONS rsc_table.ld) + +set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "") diff --git a/soc/st/stm32/stm32mp1x/linker.ld b/soc/st/stm32/stm32mp1x/linker.ld deleted file mode 100644 index 65c4a77d34fc..000000000000 --- a/soc/st/stm32/stm32mp1x/linker.ld +++ /dev/null @@ -1,25 +0,0 @@ -/* linker.ld - Linker command/script file */ - -/* - * Copyright (c) 2019 STMicroelectronics - * - * SPDX-License-Identifier: Apache-2.0 - */ - - -#include - -SECTIONS - { - -#include -#include - -#ifdef CONFIG_OPENAMP_RSC_TABLE - - SECTION_PROLOGUE(.resource_table,, SUBALIGN(4)) - { - KEEP(*(.resource_table*)) - } GROUP_LINK_IN(ROMABLE_REGION) -#endif -} diff --git a/soc/st/stm32/stm32mp1x/rsc_table.ld b/soc/st/stm32/stm32mp1x/rsc_table.ld new file mode 100644 index 000000000000..56bcf64f6648 --- /dev/null +++ b/soc/st/stm32/stm32mp1x/rsc_table.ld @@ -0,0 +1,9 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2019-2026 STMicroelectronics + * SPDX-License-Identifier: Apache-2.0 + */ + +SECTION_PROLOGUE(.resource_table,, SUBALIGN(4)) +{ + KEEP(*(.resource_table*)) +} GROUP_LINK_IN(ROMABLE_REGION) From 7a8bc1cdced63b00a09e23a8b0bf2ec4ea82d946 Mon Sep 17 00:00:00 2001 From: Mathieu Choplain Date: Wed, 21 Jan 2026 11:43:51 +0100 Subject: [PATCH 0279/6328] soc: st: stm32: cleanup linker script of STM32MP2 series Remove inclusion of files already included by the arch linker script from the SoC-specific linker script. Signed-off-by: Mathieu Choplain --- soc/st/stm32/stm32mp2x/m33/linker.ld | 7 ------- 1 file changed, 7 deletions(-) diff --git a/soc/st/stm32/stm32mp2x/m33/linker.ld b/soc/st/stm32/stm32mp2x/m33/linker.ld index a26493a726a9..5437c57b9410 100644 --- a/soc/st/stm32/stm32mp2x/m33/linker.ld +++ b/soc/st/stm32/stm32mp2x/m33/linker.ld @@ -9,10 +9,3 @@ #define rom_start .isr_vectors #include - -SECTIONS -{ - /* Standard Zephyr relocation section */ -#include -#include -} From 08f8223d5564a79e9ae15528633249a53922431e Mon Sep 17 00:00:00 2001 From: Gaetan Perrot Date: Thu, 22 Jan 2026 16:56:37 +0900 Subject: [PATCH 0280/6328] boards: phytec: phyboard_atlas: xip: fix typos in comments Fix spelling and wording issues in comments for phytec phyboard_atlas xip FlexSPI NOR configuration headers. No functional change. Signed-off-by: Gaetan Perrot --- .../phyboard_atlas/xip/phycore_rt1170_flexspi_nor_config.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/boards/phytec/phyboard_atlas/xip/phycore_rt1170_flexspi_nor_config.h b/boards/phytec/phyboard_atlas/xip/phycore_rt1170_flexspi_nor_config.h index c3eca7df6b7e..a43425e7d0bc 100644 --- a/boards/phytec/phyboard_atlas/xip/phycore_rt1170_flexspi_nor_config.h +++ b/boards/phytec/phyboard_atlas/xip/phycore_rt1170_flexspi_nor_config.h @@ -113,7 +113,7 @@ enum { FLEXSPI_MISC_OFFSET_SAFE_CONFIG_FREQ_ENABLE = 4, /* Bit for Pad setting override enable */ FLEXSPI_MISC_OFFSET_PAD_SETTING_OVERRIDE_ENABLE = 5, - /* Bit for DDR clock confiuration indication. */ + /* Bit for DDR clock configuration indication. */ FLEXSPI_MISC_OFFSET_DDR_MODE_ENABLE = 6, }; @@ -239,7 +239,7 @@ typedef struct flexspi_config { * 8 - Octal */ uint8_t sflash_pad_type; - /* [0x046-0x046] Serial Flash Frequencey, device specific + /* [0x046-0x046] Serial Flash Frequency, device specific * definitions, See System Boot Chapter for more details */ uint8_t serial_clk_freq; @@ -355,7 +355,7 @@ typedef struct _flexspi_nor_config { uint8_t need_exit_nocmd_mode; /* Half the Serial Clock for non-read command: true/false */ uint8_t half_clk_for_non_read_cmd; - /* Need to Restore NoCmd mode after IP commmand execution */ + /* Need to Restore NoCmd mode after IP command execution */ uint8_t need_restore_nocmd_mode; /* Block size */ uint32_t block_size; From 9535aebafefcb5cc98f39268d300cd2e7d710c1c Mon Sep 17 00:00:00 2001 From: Marcelo Roberto Jimenez Date: Sun, 14 Dec 2025 19:38:08 -0300 Subject: [PATCH 0281/6328] drivers: flash: flash_shell.c: Run clang-format before patch This patch runs clang-format on the flash_shell.c file before the real patch gets applied, otherwise the changes would be hard to read. Signed-off-by: Marcelo Roberto Jimenez --- drivers/flash/flash_shell.c | 102 +++++++++++++++--------------------- 1 file changed, 42 insertions(+), 60 deletions(-) diff --git a/drivers/flash/flash_shell.c b/drivers/flash/flash_shell.c index 77fb7af3a785..718c5946eefe 100644 --- a/drivers/flash/flash_shell.c +++ b/drivers/flash/flash_shell.c @@ -50,9 +50,8 @@ static const struct device *const zephyr_flash_controller = static uint8_t __aligned(4) test_arr[CONFIG_FLASH_SHELL_BUFFER_SIZE]; -static int parse_helper(const struct shell *sh, size_t *argc, - char **argv[], const struct device * *flash_dev, - uint32_t *addr) +static int parse_helper(const struct shell *sh, size_t *argc, char **argv[], + const struct device **flash_dev, uint32_t *addr) { char *endptr; @@ -109,12 +108,13 @@ static int cmd_erase(const struct shell *sh, size_t argc, char *argv[]) } else { struct flash_pages_info info; - result = flash_get_page_info_by_offs(flash_dev, page_addr, - &info); + result = flash_get_page_info_by_offs(flash_dev, page_addr, &info); if (result != 0) { - shell_error(sh, "Could not determine page size, " - "code %d.", result); + shell_error(sh, + "Could not determine page size, " + "code %d.", + result); return -EINVAL; } @@ -275,8 +275,7 @@ static int cmd_test(const struct shell *sh, size_t argc, char *argv[]) size = strtoul(argv[2], NULL, 16); repeat = strtoul(argv[3], NULL, 16); if (size > CONFIG_FLASH_SHELL_BUFFER_SIZE) { - shell_error(sh, " must be at most 0x%x.", - CONFIG_FLASH_SHELL_BUFFER_SIZE); + shell_error(sh, " must be at most 0x%x.", CONFIG_FLASH_SHELL_BUFFER_SIZE); return -EINVAL; } @@ -332,7 +331,7 @@ static int cmd_test(const struct shell *sh, size_t argc, char *argv[]) } #ifdef CONFIG_FLASH_SHELL_TEST_COMMANDS -const static uint8_t speed_types[][4] = { "B", "KiB", "MiB", "GiB" }; +const static uint8_t speed_types[][4] = {"B", "KiB", "MiB", "GiB"}; const static uint32_t speed_divisor = 1024; static int read_write_erase_validate(const struct shell *sh, size_t argc, char *argv[], @@ -645,11 +644,11 @@ static void bypass_cb(const struct shell *sh, uint8_t *recv, size_t len, void *u if (flash_load_boff == flash_load_buf_size) { uint32_t addr = flash_load_addr + flash_load_written; int rc = flash_write(flash_load_dev, addr, flash_load_buf, - flash_load_buf_size); + flash_load_buf_size); if (rc != 0) { - shell_error(sh, "Write to addr %x on dev %p ERROR!", - addr, flash_load_dev); + shell_error(sh, "Write to addr %x on dev %p ERROR!", addr, + flash_load_dev); } shell_print(sh, "Written chunk %d", flash_load_chunk); @@ -664,15 +663,14 @@ static void bypass_cb(const struct shell *sh, uint8_t *recv, size_t len, void *u * at the end. */ if (flash_load_written < flash_load_total && - flash_load_written + flash_load_boff >= flash_load_total) { + flash_load_written + flash_load_boff >= flash_load_total) { uint32_t addr = flash_load_addr + flash_load_written; int rc = flash_write(flash_load_dev, addr, flash_load_buf, flash_load_boff); if (rc != 0) { set_bypass(sh, NULL); - shell_error(sh, "Write to addr %x on dev %p ERROR!", - addr, flash_load_dev); + shell_error(sh, "Write to addr %x on dev %p ERROR!", addr, flash_load_dev); return; } @@ -715,7 +713,7 @@ static int cmd_load(const struct shell *sh, size_t argc, char *argv[]) if (flash_load_buf_size < write_block_size) { shell_error(sh, "Size of buffer is too small to be aligned to %zu.", - write_block_size); + write_block_size); return -ENOSPC; } @@ -725,7 +723,7 @@ static int cmd_load(const struct shell *sh, size_t argc, char *argv[]) shell_warn(sh, "Load buffer was not aligned to %zu.", write_block_size); shell_warn(sh, "Effective load buffer size was set from %d to %d", - FLASH_LOAD_BUF_MAX, flash_load_buf_size); + FLASH_LOAD_BUF_MAX, flash_load_buf_size); } /* Prepare data for callback. */ @@ -761,8 +759,8 @@ static int cmd_page_info(const struct shell *sh, size_t argc, char *argv[]) return -EINVAL; } - shell_print(sh, "Page for address 0x%x:\nstart offset: 0x%lx\nsize: %zu\nindex: %d", - addr, info.start_offset, info.size, info.index); + shell_print(sh, "Page for address 0x%x:\nstart offset: 0x%lx\nsize: %zu\nindex: %d", addr, + info.start_offset, info.size, info.index); return 0; } @@ -794,56 +792,41 @@ static void device_name_get(size_t idx, struct shell_static_entry *entry) entry->syntax = (dev != NULL) ? dev->name : NULL; entry->handler = NULL; - entry->help = NULL; + entry->help = NULL; entry->subcmd = &dsub_device_name; } -SHELL_STATIC_SUBCMD_SET_CREATE(flash_cmds, +SHELL_STATIC_SUBCMD_SET_CREATE( + flash_cmds, SHELL_CMD_ARG(copy, &dsub_device_name, - " ", - cmd_copy, 5, 5), - SHELL_CMD_ARG(erase, &dsub_device_name, - "[] []", - cmd_erase, 2, 2), - SHELL_CMD_ARG(read, &dsub_device_name, - "[]
[]", - cmd_read, 2, 2), - SHELL_CMD_ARG(test, &dsub_device_name, - "[]
", - cmd_test, 4, 1), - SHELL_CMD_ARG(write, &dsub_device_name, - "[]
[...]", - cmd_write, 3, BUF_ARRAY_CNT), - SHELL_CMD_ARG(load, &dsub_device_name, - "[]
", - cmd_load, 3, 1), - SHELL_CMD_ARG(page_info, &dsub_device_name, - "[]
", - cmd_page_info, 2, 1), + " ", cmd_copy, 5, 5), + SHELL_CMD_ARG(erase, &dsub_device_name, "[] []", cmd_erase, 2, + 2), + SHELL_CMD_ARG(read, &dsub_device_name, "[]
[]", cmd_read, 2, + 2), + SHELL_CMD_ARG(test, &dsub_device_name, "[]
", + cmd_test, 4, 1), + SHELL_CMD_ARG(write, &dsub_device_name, "[]
[...]", + cmd_write, 3, BUF_ARRAY_CNT), + SHELL_CMD_ARG(load, &dsub_device_name, "[]
", cmd_load, 3, 1), + SHELL_CMD_ARG(page_info, &dsub_device_name, "[]
", cmd_page_info, 2, 1), #if DT_HAS_COMPAT_STATUS_OKAY(fixed_partitions) - SHELL_CMD_ARG(partitions, &dsub_device_name, - "", - cmd_partitions, 0, 0), + SHELL_CMD_ARG(partitions, &dsub_device_name, "", cmd_partitions, 0, 0), #endif #ifdef CONFIG_FLASH_SHELL_TEST_COMMANDS - SHELL_CMD_ARG(read_test, &dsub_device_name, - "[]
", - cmd_read_test, 4, 1), - SHELL_CMD_ARG(write_test, &dsub_device_name, - "[]
", - cmd_write_test, 4, 1), - SHELL_CMD_ARG(erase_test, &dsub_device_name, - "[]
", - cmd_erase_test, 4, 1), + SHELL_CMD_ARG(read_test, &dsub_device_name, "[]
", + cmd_read_test, 4, 1), + SHELL_CMD_ARG(write_test, &dsub_device_name, "[]
", + cmd_write_test, 4, 1), + SHELL_CMD_ARG(erase_test, &dsub_device_name, "[]
", + cmd_erase_test, 4, 1), SHELL_CMD_ARG(erase_write_test, &dsub_device_name, - "[]
", - cmd_erase_write_test, 4, 1), + "[]
", cmd_erase_write_test, 4, 1), #endif - SHELL_SUBCMD_SET_END -); + SHELL_SUBCMD_SET_END); static int cmd_flash(const struct shell *sh, size_t argc, char **argv) { @@ -851,5 +834,4 @@ static int cmd_flash(const struct shell *sh, size_t argc, char **argv) return -EINVAL; } -SHELL_CMD_ARG_REGISTER(flash, &flash_cmds, "Flash shell commands", - cmd_flash, 2, 0); +SHELL_CMD_ARG_REGISTER(flash, &flash_cmds, "Flash shell commands", cmd_flash, 2, 0); From ec8472c36298a3070ffcef055a43770ca9dec5ad Mon Sep 17 00:00:00 2001 From: Marcelo Roberto Jimenez Date: Mon, 15 Dec 2025 20:13:24 -0300 Subject: [PATCH 0282/6328] tests: subsys: shell: Clang-format on shell_flash_test.c This patch runs clang-format on the shell_flash_test.c file before the real patch gets applied, otherwise the changes would be hard to read. Signed-off-by: Marcelo Roberto Jimenez --- tests/subsys/shell/shell_flash/src/shell_flash_test.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/tests/subsys/shell/shell_flash/src/shell_flash_test.c b/tests/subsys/shell/shell_flash/src/shell_flash_test.c index f4c51f595146..065d41dcf082 100644 --- a/tests/subsys/shell/shell_flash/src/shell_flash_test.c +++ b/tests/subsys/shell/shell_flash/src/shell_flash_test.c @@ -38,7 +38,7 @@ ZTEST(shell_flash, test_flash_read) const struct device *const flash_dev = DEVICE_DT_GET(DT_CHOSEN(zephyr_flash_controller)); const char *buf; const int test_base = FLASH_SIMULATOR_BASE_OFFSET; - const int test_size = 0x24; /* 32-alignment required */ + const int test_size = 0x24; /* 32-alignment required */ uint8_t data[test_size]; size_t size; int ret; @@ -48,8 +48,7 @@ ZTEST(shell_flash, test_flash_read) data[i] = 'A' + i; } - zassert_true(device_is_ready(flash_dev), - "Simulated flash driver not ready"); + zassert_true(device_is_ready(flash_dev), "Simulated flash driver not ready"); ret = flash_write(flash_dev, test_base, data, test_size); zassert_equal(0, ret, "flash_write() failed: %d", ret); From 391ca7c7de35a9419e83c8a118b36ebfc66d887a Mon Sep 17 00:00:00 2001 From: Marcelo Roberto Jimenez Date: Sun, 14 Dec 2025 19:46:29 -0300 Subject: [PATCH 0283/6328] drivers: flash: flash_shell.c: Fix parsing of "flash read" The parsing of the number of bytes to read in the read command was being done in hexadecimal, causing unexpected behavior. Now the number can be interpreted in decimal or hexadecimal if prefixed with 0x. Signed-off-by: Marcelo Roberto Jimenez --- drivers/flash/flash_shell.c | 2 +- tests/subsys/shell/shell_flash/src/shell_flash_test.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/flash/flash_shell.c b/drivers/flash/flash_shell.c index 718c5946eefe..e0ffd51dc39a 100644 --- a/drivers/flash/flash_shell.c +++ b/drivers/flash/flash_shell.c @@ -234,7 +234,7 @@ static int cmd_read(const struct shell *sh, size_t argc, char *argv[]) } if (argc > 2) { - cnt = strtoul(argv[2], NULL, 16); + cnt = strtoul(argv[2], NULL, 0); } else { cnt = 1; } diff --git a/tests/subsys/shell/shell_flash/src/shell_flash_test.c b/tests/subsys/shell/shell_flash/src/shell_flash_test.c index 065d41dcf082..345d6c0c33cb 100644 --- a/tests/subsys/shell/shell_flash/src/shell_flash_test.c +++ b/tests/subsys/shell/shell_flash/src/shell_flash_test.c @@ -53,7 +53,7 @@ ZTEST(shell_flash, test_flash_read) ret = flash_write(flash_dev, test_base, data, test_size); zassert_equal(0, ret, "flash_write() failed: %d", ret); - ret = shell_execute_cmd(NULL, "flash read 0 23"); + ret = shell_execute_cmd(NULL, "flash read 0 0x23"); zassert_equal(0, ret, "flash read failed: %d", ret); buf = shell_backend_dummy_get_output(sh, &size); From 1ab8978e66624400ff341b8c17f37d6729051c09 Mon Sep 17 00:00:00 2001 From: Marcelo Roberto Jimenez Date: Sun, 14 Dec 2025 19:54:06 -0300 Subject: [PATCH 0284/6328] drivers: flash: flash_shell.c: Fix flash read help text Actually, the parameter is the number of bytes to read, not the number of double words. Signed-off-by: Marcelo Roberto Jimenez --- drivers/flash/flash_shell.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/flash/flash_shell.c b/drivers/flash/flash_shell.c index e0ffd51dc39a..b750227c7b19 100644 --- a/drivers/flash/flash_shell.c +++ b/drivers/flash/flash_shell.c @@ -802,7 +802,7 @@ SHELL_STATIC_SUBCMD_SET_CREATE( " ", cmd_copy, 5, 5), SHELL_CMD_ARG(erase, &dsub_device_name, "[] []", cmd_erase, 2, 2), - SHELL_CMD_ARG(read, &dsub_device_name, "[]
[]", cmd_read, 2, + SHELL_CMD_ARG(read, &dsub_device_name, "[]
[]", cmd_read, 2, 2), SHELL_CMD_ARG(test, &dsub_device_name, "[]
", cmd_test, 4, 1), From 92df06bf1d48363f42a8e5af45861c6a7d81ffd1 Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Mon, 5 Jan 2026 16:10:11 +0100 Subject: [PATCH 0285/6328] boards: native: nrf_bsim: Add simple model of LDREX/STREX/CLREX Add a model of LDREX/STREX/CLREX, that although simple may be correct enough to cover the needs of SW using these instructions. Signed-off-by: Alberto Escolar Piedras --- boards/native/nrf_bsim/common/cmsis/cmsis.c | 153 ++++++++++++++++++ boards/native/nrf_bsim/common/cmsis/cmsis.h | 2 + .../nrf_bsim/common/cmsis/cmsis_instr.h | 117 +------------- boards/native/nrf_bsim/irq_handler.c | 1 + 4 files changed, 163 insertions(+), 110 deletions(-) diff --git a/boards/native/nrf_bsim/common/cmsis/cmsis.c b/boards/native/nrf_bsim/common/cmsis/cmsis.c index dac5f82e699e..c241e3a7b3d6 100644 --- a/boards/native/nrf_bsim/common/cmsis/cmsis.c +++ b/boards/native/nrf_bsim/common/cmsis/cmsis.c @@ -97,3 +97,156 @@ void __SEV(void) { nrfbsim_SEV_model(); } + +/* + * Implement the following ARM instructions + * + * - STR Exclusive(8,16 & 32bit) (__STREX{B,H,W}) + * - LDR Exclusive(8,16 & 32bit) (__LDREX{B,H,W}) + * - CLREX : Exclusive lock removal (__CLREX) + * + * Description: + * From ARMs description it is relatively unclear how the LDREX/STREX/CLREX + * are really implemented in M4/M33 devices. + * + * The current model simply sets a local monitor (local to the processor) + * exclusive lock for the current MCU when a LDREX is executed. + * STREX check this lock, and succeeds if set, fails otherwise. + * The lock is cleared whenever STREX or CLREX are run, or when we return + * from an interrupt handler. + * See Arm v8-M Architecture Reference Manual: "B9.2 The local monitors" and + * "B9.4 Exclusive access instructions and the monitors". + * + * The address is ignored, and we do not model a "system/global" monitor. + * The access width is ignored from the locking point of view. + * In principle this model would seem to fulfill the functionality described + * by ARM. + * + * Note that as the POSIX arch will not make an embedded + * thread lose context while just executing its own code, and it does not + * allow parallel embedded SW threads to execute at the same exact time, + * there is no real need to protect atomicity. + * But, some embedded code may use this instructions in between busy waits, + * and expect that an interrupt in the meanwhile will indeed cause a + * following STREX to fail. + * + * As this ARM exclusive access monitor mechanism can in principle be + * used for other, unexpected, purposes, this simple replacement may not be + * enough. + */ + +static bool ex_lock; /* LDREX/STREX/CLREX lock state */ + +bool nrfbsim_STREXlock_model(void) +{ + if (ex_lock == false) { + return true; + } + + ex_lock = false; + return false; +} + +void nrfbsim_clear_excl_access(void) +{ + ex_lock = false; +} + +/** + * \brief Pretend to execute a STR Exclusive (8 bit) + * \details Executes an exclusive STR instruction for 8 bit values. + * \param [in] value Value to store + * \param [in] ptr Pointer to location + * \return 0 Function succeeded + * \return 1 Function did not succeeded (value not changed) + */ +uint32_t __STREXB(uint8_t value, volatile uint8_t *ptr) +{ + if (nrfbsim_STREXlock_model()) { + return 1; + } + *ptr = value; + return 0; +} + +/** + * \brief Pretend to execute a STR Exclusive (16 bit) + * \details Executes a exclusive STR instruction for 16 bit values. + * \param [in] value Value to store + * \param [in] ptr Pointer to location + * \return 0 Function succeeded + * \return 1 Function did not succeeded (value not changed) + */ +uint32_t __STREXH(uint16_t value, volatile uint16_t *ptr) +{ + if (nrfbsim_STREXlock_model()) { + return 1; + } + *ptr = value; + return 0; +} + +/** + * \brief Pretend to execute a STR Exclusive (32 bit) + * \details Executes a exclusive~ STR instruction for 32 bit values. + * \param [in] value Value to store + * \param [in] ptr Pointer to location + * \return 0 Function succeeded + * \return 1 Function did not succeeded (value not changed) + */ +uint32_t __STREXW(uint32_t value, volatile uint32_t *ptr) +{ + if (nrfbsim_STREXlock_model()) { + return 1; + } + *ptr = value; + return 0; +} + +/** + * \brief Pretend to execute a LDR Exclusive (8 bit) + * \details Executes an exclusive LDR instruction for 8 bit value. + * Meaning, set an exclusive lock, and load the stored value + * \param [in] ptr Pointer to data + * \return value of type uint8_t at (*ptr) + */ +uint8_t __LDREXB(volatile uint8_t *ptr) +{ + ex_lock = true; + return *ptr; +} + +/** + * \brief Pretend to execute a LDR Exclusive (16 bit) + * \details Executes an ~exclusive~ LDR instruction for 16 bit value. + * Meaning, set an exclusive lock, and load the stored value + * \param [in] ptr Pointer to data + * \return value of type uint8_t at (*ptr) + */ +uint16_t __LDREXH(volatile uint16_t *ptr) +{ + ex_lock = true; + return *ptr; +} + +/** + * \brief Execute a LDR Exclusive (32 bit) + * \details Executes an exclusive LDR instruction for 32 bit value. + * Meaning, set an exclusive lock, and load the stored value + * \param [in] ptr Pointer to data + * \return value of type uint8_t at (*ptr) + */ +uint32_t __LDREXW(volatile uint32_t *ptr) +{ + ex_lock = true; + return *ptr; +} + +/** + * \brief Remove the exclusive lock + * \details Removes the exclusive lock which is created by LDREX + */ +void __CLREX(void) +{ + ex_lock = false; +} diff --git a/boards/native/nrf_bsim/common/cmsis/cmsis.h b/boards/native/nrf_bsim/common/cmsis/cmsis.h index 25a9fe4d6578..490e9af8025c 100644 --- a/boards/native/nrf_bsim/common/cmsis/cmsis.h +++ b/boards/native/nrf_bsim/common/cmsis/cmsis.h @@ -36,6 +36,8 @@ void NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority); uint32_t NVIC_GetPriority(IRQn_Type IRQn); void NVIC_SystemReset(void); +void nrfbsim_clear_excl_access(void); + #ifdef __cplusplus } #endif diff --git a/boards/native/nrf_bsim/common/cmsis/cmsis_instr.h b/boards/native/nrf_bsim/common/cmsis/cmsis_instr.h index e3dfd2aad232..619c68d75490 100644 --- a/boards/native/nrf_bsim/common/cmsis/cmsis_instr.h +++ b/boards/native/nrf_bsim/common/cmsis/cmsis_instr.h @@ -40,116 +40,13 @@ void __WFE(void); void __WFI(void); void __SEV(void); -/* - * Implement the following ARM intrinsics as non-exclusive accesses - * - * - STR Exclusive(8,16 & 32bit) (__STREX{B,H,W}) - * - LDR Exclusive(8,16 & 32bit) (__LDREX{B,H,W}) - * - CLREX : Exclusive lock removal (__CLREX) - no-op - * - * Description: - * These accesses always succeed, and do NOT set any kind of internal - * exclusive access flag; - * There is no local/global memory monitors, MPU control of what are - * shareable regions, exclusive reservations granules, automatic clearing - * on context switch, or so. - * - * This should be enough for the expected uses of LDR/STREXB - * (locking mutexes or guarding other atomic operations, inside a few lines - * of code in the same function): As the POSIX arch will not make an embedded - * thread lose context while just executing its own code, and it does not - * allow parallel embedded SW threads to execute at the same exact time, - * there is no actual need to protect atomicity. - * - * But as this ARM exclusive access monitor mechanism can in principle be - * used for other, unexpected, purposes, this simple replacement may not be - * enough. - */ - -/** - * \brief Pretend to execute a STR Exclusive (8 bit) - * \details Executes a ~exclusive~ STR instruction for 8 bit values. - * \param [in] value Value to store - * \param [in] ptr Pointer to location - * \return 0 Function succeeded (always) - */ -static inline uint32_t __STREXB(uint8_t value, volatile uint8_t *ptr) -{ - *ptr = value; - return 0; -} - -/** - * \brief Pretend to execute a STR Exclusive (16 bit) - * \details Executes a ~exclusive~ STR instruction for 16 bit values. - * \param [in] value Value to store - * \param [in] ptr Pointer to location - * \return 0 Function succeeded (always) - */ -static inline uint32_t __STREXH(uint16_t value, volatile uint16_t *ptr) -{ - *ptr = value; - return 0; -} - -/** - * \brief Pretend to execute a STR Exclusive (32 bit) - * \details Executes a ~exclusive~ STR instruction for 32 bit values. - * \param [in] value Value to store - * \param [in] ptr Pointer to location - * \return 0 Function succeeded (always) - */ -static inline uint32_t __STREXW(uint32_t value, volatile uint32_t *ptr) -{ - *ptr = value; - return 0; -} - -/** - * \brief Pretend to execute a LDR Exclusive (8 bit) - * \details Executes an ~exclusive~ LDR instruction for 8 bit value. - * Meaning, it does not set a exclusive lock, - * instead just loads the stored value - * \param [in] ptr Pointer to data - * \return value of type uint8_t at (*ptr) - */ -static inline uint8_t __LDREXB(volatile uint8_t *ptr) -{ - return *ptr; -} - -/** - * \brief Pretend to execute a LDR Exclusive (16 bit) - * \details Executes an ~exclusive~ LDR instruction for 16 bit value. - * Meaning, it does not set a exclusive lock, - * instead just loads the stored value - * \param [in] ptr Pointer to data - * \return value of type uint8_t at (*ptr) - */ -static inline uint16_t __LDREXH(volatile uint16_t *ptr) -{ - return *ptr; -} - -/** - * \brief Pretend to execute a LDR Exclusive (32 bit) - * \details Executes an ~exclusive~ LDR instruction for 32 bit value. - * Meaning, it does not set a exclusive lock, - * instead just loads the stored value - * \param [in] ptr Pointer to data - * \return value of type uint8_t at (*ptr) - */ -static inline uint32_t __LDREXW(volatile uint32_t *ptr) -{ - return *ptr; -} - -/** - * \brief Pretend to remove the exclusive lock - * \details The real function would removes the exclusive lock which is created - * by LDREX, this one does nothing - */ -static inline void __CLREX(void) { /* Nothing to be done */ } +uint32_t __STREXB(uint8_t value, volatile uint8_t *ptr); +uint32_t __STREXH(uint16_t value, volatile uint16_t *ptr); +uint32_t __STREXW(uint32_t value, volatile uint32_t *ptr); +uint8_t __LDREXB(volatile uint8_t *ptr); +uint16_t __LDREXH(volatile uint16_t *ptr); +uint32_t __LDREXW(volatile uint32_t *ptr); +void __CLREX(void); /** * \brief Model of an ARM CLZ instruction diff --git a/boards/native/nrf_bsim/irq_handler.c b/boards/native/nrf_bsim/irq_handler.c index 74d0dc5889ee..502be495def7 100644 --- a/boards/native/nrf_bsim/irq_handler.c +++ b/boards/native/nrf_bsim/irq_handler.c @@ -117,6 +117,7 @@ void posix_irq_handler(void) currently_running_irq = irq_nbr; vector_to_irq(irq_nbr, &may_swap); + nrfbsim_clear_excl_access(); currently_running_irq = last_running_irq; hw_irq_ctrl_reeval_level_irq(cpu_n, irq_nbr); From b84bdbcee34ecb8bb7ea1d5792086cf70ddce3f2 Mon Sep 17 00:00:00 2001 From: Wolfgang Betz Date: Tue, 13 Jan 2026 10:22:51 +0100 Subject: [PATCH 0286/6328] dts: arm: st: n6: Use dedicated dts node for NPU cache (aka CACHEAXI) The new node is called "npu_cache". This way a possibility is offered to choose - thru an overlay - if to enable the NPU cache or not. This new node has a dependency with node "npu", so the NPU cache's status is taken into account only in case node "npu" has status "okay". Default status value of "npu_cache" is "okay" (i.e. enable the NPU cache). Signed-off-by: Wolfgang Betz --- dts/arm/st/n6/stm32n6.dtsi | 15 +++-- dts/bindings/misc/st,stm32-npu-cache.yaml | 18 ++++++ soc/st/stm32/stm32n6x/CMakeLists.txt | 1 + soc/st/stm32/stm32n6x/Kconfig | 8 +-- soc/st/stm32/stm32n6x/npu/Kconfig | 30 +++++++++ soc/st/stm32/stm32n6x/npu/npu_cache_stm32n6.c | 63 +++++++++++++++++++ soc/st/stm32/stm32n6x/npu/npu_stm32n6.c | 22 ++++--- 7 files changed, 136 insertions(+), 21 deletions(-) create mode 100644 dts/bindings/misc/st,stm32-npu-cache.yaml create mode 100644 soc/st/stm32/stm32n6x/npu/Kconfig create mode 100644 soc/st/stm32/stm32n6x/npu/npu_cache_stm32n6.c diff --git a/dts/arm/st/n6/stm32n6.dtsi b/dts/arm/st/n6/stm32n6.dtsi index 2facbb234784..4ceb43cd1994 100644 --- a/dts/arm/st/n6/stm32n6.dtsi +++ b/dts/arm/st/n6/stm32n6.dtsi @@ -1362,14 +1362,19 @@ npu: npu@580e0000 { compatible = "st,stm32-npu"; reg = <0x580e0000 DT_SIZE_K(128)>; - clocks = <&rcc STM32_CLOCK(AHB5, 31)>, - <&rcc STM32_CLOCK(AHB5, 30)>; - clock-names = "npu", "cacheaxi"; - resets = <&rctl STM32_RESET(AHB5, 31)>, - <&rctl STM32_RESET(AHB5, 30)>; + clocks = <&rcc STM32_CLOCK(AHB5, 31)>; + resets = <&rctl STM32_RESET(AHB5, 31)>; status = "disabled"; }; + npu_cache: cache-controller@580dfc00 { + compatible = "st,stm32-npu-cache"; + reg = <0x580dfc00 DT_SIZE_K(1)>; + clocks = <&rcc STM32_CLOCK(AHB5, 30)>; + resets = <&rctl STM32_RESET(AHB5, 30)>; + status = "okay"; + }; + venc: venc@58005000 { compatible = "st,stm32-venc"; reg = <0x58005000 0x1000>; diff --git a/dts/bindings/misc/st,stm32-npu-cache.yaml b/dts/bindings/misc/st,stm32-npu-cache.yaml new file mode 100644 index 000000000000..fc80627059d8 --- /dev/null +++ b/dts/bindings/misc/st,stm32-npu-cache.yaml @@ -0,0 +1,18 @@ +# Copyright (c) 2026 STMicroelectronics +# SPDX-License-Identifier: Apache-2.0 + +description: STM32N6 NPU cache (aka CACHEAXI) block + +compatible: "st,stm32-npu-cache" + +include: [reset-device.yaml, base.yaml] + +properties: + reg: + required: true + + clocks: + required: true + + resets: + required: true diff --git a/soc/st/stm32/stm32n6x/CMakeLists.txt b/soc/st/stm32/stm32n6x/CMakeLists.txt index eb2d26e6a1c9..b177fa3f95fa 100644 --- a/soc/st/stm32/stm32n6x/CMakeLists.txt +++ b/soc/st/stm32/stm32n6x/CMakeLists.txt @@ -7,6 +7,7 @@ zephyr_sources( zephyr_sources_ifdef(CONFIG_STM32N6_NPU npu/npu_stm32n6.c + npu/npu_cache_stm32n6.c ) zephyr_include_directories(.) diff --git a/soc/st/stm32/stm32n6x/Kconfig b/soc/st/stm32/stm32n6x/Kconfig index e3aba615e544..96a5e683f81f 100644 --- a/soc/st/stm32/stm32n6x/Kconfig +++ b/soc/st/stm32/stm32n6x/Kconfig @@ -30,12 +30,6 @@ if SOC_SERIES_STM32N6X config STM32N6_BOOT_SERIAL bool "Serial boot target (USB)" -config STM32N6_NPU - bool "Neural-ART accelerator (NPU)" - select RESET - default y - depends on DT_HAS_ST_STM32_NPU_ENABLED - config STM32N6_RIF_OPEN bool "Configure the RIF with all OPEN access" default y @@ -45,4 +39,6 @@ config STM32N6_RIF_OPEN configured during SoC initialization. Zephyr running with Secure privileges has full access to all SoC resources. +source "soc/st/stm32/stm32n6x/npu/Kconfig" + endif # SOC_SERIES_STM32N6X diff --git a/soc/st/stm32/stm32n6x/npu/Kconfig b/soc/st/stm32/stm32n6x/npu/Kconfig new file mode 100644 index 000000000000..9cfec5a6746d --- /dev/null +++ b/soc/st/stm32/stm32n6x/npu/Kconfig @@ -0,0 +1,30 @@ +# STMicroelectronics STM32N6 MCU series + +# Copyright (c) 2026 STMicroelectronics +# SPDX-License-Identifier: Apache-2.0 + +config STM32N6_NPU + bool "Neural-ART accelerator (NPU)" + select RESET + default y + depends on DT_HAS_ST_STM32_NPU_ENABLED + +config STM32N6_NPU_INIT_PRIORITY + int "STM32N6 NPU init priority" + default KERNEL_INIT_PRIORITY_DEFAULT + depends on STM32N6_NPU + help + STM32N6 NPU initialization priority. + + Note: This value must have a higher priority (i.e., lower numerical value) + than `STM32N6_NPU_CACHE_INIT_PRIORITY`! + +config STM32N6_NPU_CACHE_INIT_PRIORITY + int "STM32N6 NPU cache (aka CACHEAXI) init priority" + default APPLICATION_INIT_PRIORITY + depends on STM32N6_NPU + help + STM32N6 NPU cache (aka CACHEAXI) initialization priority. + + Note: This value must have a lower priority (i.e., higher numerical value) + than `STM32N6_NPU_INIT_PRIORITY`! diff --git a/soc/st/stm32/stm32n6x/npu/npu_cache_stm32n6.c b/soc/st/stm32/stm32n6x/npu/npu_cache_stm32n6.c new file mode 100644 index 000000000000..a69aa096ee9e --- /dev/null +++ b/soc/st/stm32/stm32n6x/npu/npu_cache_stm32n6.c @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2026 STMicroelectronics + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT st_stm32_npu_cache + +#include +#include +#include +#include + +#define NPU_CACHE_NODE DT_DRV_INST(0) +#define NPU_CACHE_BASE DT_REG_ADDR(NPU_CACHE_NODE) + +#define NPU_CACHE_CTRL_REG_OFFSET 0x0 +#define NPU_CACHE_ERR_IRQ_OFFSET 0x8 +#define NPU_CACHE_DISABLE 0x0 +#define NPU_CACHE_ENABLE 0x1 +#define NPU_CACHE_CNT_ENABLE 0x33330000 +#define NPU_CACHE_CNT_RESET 0xCCCC0000 +#define NPU_CACHE_ERR_IRQ_ENABLE BIT(2) + +/* + * Define npu_cache_stm32_enable and instantiate the device only if both + * the NPU and NPU cache nodes are enabled in the device tree. + * This avoids unused function warnings when the cache is disabled. + */ +#if DT_NODE_HAS_STATUS_OKAY(DT_INST(0, st_stm32_npu)) && \ + DT_NODE_HAS_STATUS_OKAY(DT_INST(0, st_stm32_npu_cache)) +static int npu_cache_stm32_enable(const struct device *dev) +{ + /* Disable cache */ + sys_write32(NPU_CACHE_DISABLE, NPU_CACHE_BASE + NPU_CACHE_CTRL_REG_OFFSET); + + k_busy_wait(5 * USEC_PER_MSEC); /* 5ms delay */ + + /* Enable cache */ + sys_write32(NPU_CACHE_ENABLE, NPU_CACHE_BASE + NPU_CACHE_CTRL_REG_OFFSET); + + /* Enable cache counters */ + sys_set_bits(NPU_CACHE_BASE + NPU_CACHE_CTRL_REG_OFFSET, NPU_CACHE_CNT_ENABLE); + + /* Reset cache counters */ + sys_set_bits(NPU_CACHE_BASE + NPU_CACHE_CTRL_REG_OFFSET, NPU_CACHE_CNT_RESET); + + /* Enable cache error interrupt */ + sys_write32(NPU_CACHE_ERR_IRQ_ENABLE, NPU_CACHE_BASE + NPU_CACHE_ERR_IRQ_OFFSET); + + return 0; +} + +DEVICE_DT_INST_DEFINE(0, npu_cache_stm32_enable, NULL, NULL, NULL, POST_KERNEL, + CONFIG_STM32N6_NPU_CACHE_INIT_PRIORITY, NULL); + +/* + * Guarantee that initialization priority for the NPU is higher than the one of the NPU cache (aka + * CACHEAXI) + */ +BUILD_ASSERT(CONFIG_STM32N6_NPU_CACHE_INIT_PRIORITY > CONFIG_STM32N6_NPU_INIT_PRIORITY, + "NPU cache initialization must run after NPU driver initialization"); +#endif /* st_stm32_npu && st_stm32_npu_cache */ diff --git a/soc/st/stm32/stm32n6x/npu/npu_stm32n6.c b/soc/st/stm32/stm32n6x/npu/npu_stm32n6.c index 4c437281aedc..1bfa8ef24fbf 100644 --- a/soc/st/stm32/stm32n6x/npu/npu_stm32n6.c +++ b/soc/st/stm32/stm32n6x/npu/npu_stm32n6.c @@ -34,11 +34,11 @@ static int npu_stm32_init(const struct device *dev) return -ENODEV; } - if (clock_control_on(clk, (clock_control_subsys_t) &cfg->pclken_npu) != 0) { + if (clock_control_on(clk, (clock_control_subsys_t)&cfg->pclken_npu) != 0) { return -EIO; } - if (clock_control_on(clk, (clock_control_subsys_t) &cfg->pclken_cacheaxi) != 0) { + if (clock_control_on(clk, (clock_control_subsys_t)&cfg->pclken_cacheaxi) != 0) { return -EIO; } @@ -53,14 +53,16 @@ static int npu_stm32_init(const struct device *dev) return 0; } - static const struct npu_stm32_cfg npu_stm32_cfg = { - .pclken_npu = STM32_CLOCK_INFO_BY_NAME(DT_NODELABEL(npu), npu), - .pclken_cacheaxi = STM32_CLOCK_INFO_BY_NAME(DT_NODELABEL(npu), cacheaxi), - .reset_npu = RESET_DT_SPEC_GET_BY_IDX(DT_NODELABEL(npu), 0), - .reset_cacheaxi = RESET_DT_SPEC_GET_BY_IDX(DT_NODELABEL(npu), 1), + .pclken_npu = STM32_DT_INST_CLOCK_INFO(0), + .reset_npu = RESET_DT_SPEC_INST_GET(0), + /* + * Even if npu_cache node is disabled, its clocks must be enabled for NPU operation. + * This is why we need to get clock and reset line from the npu_cache node. + */ + .pclken_cacheaxi = STM32_CLOCK_INFO(0, DT_NODELABEL(npu_cache)), + .reset_cacheaxi = RESET_DT_SPEC_GET(DT_NODELABEL(npu_cache)), }; -DEVICE_DT_DEFINE(DT_NODELABEL(npu), npu_stm32_init, NULL, - NULL, &npu_stm32_cfg, POST_KERNEL, - CONFIG_APPLICATION_INIT_PRIORITY, NULL); +DEVICE_DT_INST_DEFINE(0, npu_stm32_init, NULL, NULL, &npu_stm32_cfg, POST_KERNEL, + CONFIG_STM32N6_NPU_INIT_PRIORITY, NULL); From ec5c3420b353c7d3e462006c70a70d8c35e23664 Mon Sep 17 00:00:00 2001 From: Cesar Santos Date: Fri, 16 Jan 2026 10:21:08 +0000 Subject: [PATCH 0287/6328] samples: net: secure_mqtt_sensor_actuator: add missing POSIX libraries In order to compile the demo application for a secure MQTT connection, several networking API functions are used, which is properly defined by some of the POSIX libraries already integrated onto Zephyr project. By adding the missing libraries, compilation to the reference board adi_eval_adin1110ebz passes. As a minor change, reordered the sequence of included libraries to be in alphabetical order. Fixes #102372. Signed-off-by: Cesar Santos --- samples/net/secure_mqtt_sensor_actuator/src/mqtt_client.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/samples/net/secure_mqtt_sensor_actuator/src/mqtt_client.c b/samples/net/secure_mqtt_sensor_actuator/src/mqtt_client.c index 5095da7c2c3e..0ce2e6586e5f 100644 --- a/samples/net/secure_mqtt_sensor_actuator/src/mqtt_client.c +++ b/samples/net/secure_mqtt_sensor_actuator/src/mqtt_client.c @@ -7,10 +7,13 @@ #include LOG_MODULE_REGISTER(app_mqtt, LOG_LEVEL_DBG); +#include #include -#include #include -#include +#include +#include +#include +#include #include #include "mqtt_client.h" From b4bbba70b1bf46aef114ad87479001fab48acb3c Mon Sep 17 00:00:00 2001 From: Svitlana Drozd Date: Tue, 20 Jan 2026 15:02:55 +0200 Subject: [PATCH 0288/6328] boards: raspberrypi: rpi_5: remove unnecessary arm_64bit option The ARM cores in BCM2712 are incapable of running the kernel in 32-bit mode. The option `arm_64bit=1` is unnecessary and can be confusing, as Raspberry Pi 5 runs in 64-bit mode by default. Removed the `arm_64bit=1` configuration from documentation for Raspberry Pi 5 (BCM2712). Signed-off-by: Svitlana Drozd --- boards/raspberrypi/rpi_5/doc/index.rst | 2 -- 1 file changed, 2 deletions(-) diff --git a/boards/raspberrypi/rpi_5/doc/index.rst b/boards/raspberrypi/rpi_5/doc/index.rst index d8b94b7a87ed..63a8bdfb574f 100644 --- a/boards/raspberrypi/rpi_5/doc/index.rst +++ b/boards/raspberrypi/rpi_5/doc/index.rst @@ -57,7 +57,6 @@ config.txt .. code-block:: text kernel=zephyr.bin - arm_64bit=1 zephyr.bin @@ -98,7 +97,6 @@ config.txt .. code-block:: text kernel=zephyr.bin - arm_64bit=1 enable_uart=1 uart_2ndstage=1 From cdfd692b76e7a4f575de99b568cdb471cef9f678 Mon Sep 17 00:00:00 2001 From: Svitlana Drozd Date: Tue, 20 Jan 2026 15:14:20 +0200 Subject: [PATCH 0289/6328] boards: raspberrypi: rpi_5: correct DTB file name in doc The DTB file was previously listed as bcm2712-rpi-5.dtb, which was inaccurate, as the hyperlink referenced the `bcm2712-rpi-5-b.dtb` file. To ensure documentation precision and avoid potential confusion, update the file name to the correct `bcm2712-rpi-5-b.dtb`. Signed-off-by: Svitlana Drozd --- boards/raspberrypi/rpi_5/doc/index.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/boards/raspberrypi/rpi_5/doc/index.rst b/boards/raspberrypi/rpi_5/doc/index.rst index 63a8bdfb574f..104e521555d8 100644 --- a/boards/raspberrypi/rpi_5/doc/index.rst +++ b/boards/raspberrypi/rpi_5/doc/index.rst @@ -46,7 +46,7 @@ In brief, 2. Save three files below in the root directory. * config.txt * zephyr.bin - * `bcm2712-rpi-5.dtb`_ + * `bcm2712-rpi-5-b.dtb`_ 3. Insert the Micro SD card and power on the Raspberry Pi 5. then, You will see the Raspberry Pi 5 running the :file:`zephyr.bin`. @@ -133,7 +133,7 @@ When you power on the Raspberry Pi 5, you will see the following output in the s .. _Raspberry Pi hardware: https://www.raspberrypi.com/documentation/computers/raspberry-pi.html -.. _bcm2712-rpi-5.dtb: +.. _bcm2712-rpi-5-b.dtb: https://github.com/raspberrypi/firmware/raw/master/boot/bcm2712-rpi-5-b.dtb .. _Raspberry Pi Debug Probe: From 1feabd2552a4789126be4fe3d46f19af26c4da93 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Wed, 21 Jan 2026 11:51:40 +0100 Subject: [PATCH 0290/6328] shell: fix potential buffer overflow in shell_help_is_structured() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The function was casting a char* help pointer to struct shell_cmd_help* and reading its 4-byte magic field. When the help string was shorter than 4 bytes, this caused a read past the end of the buffer. The fix replaces the struct cast with a byte-by-byte comparison of the magic number. Fixes zephyrproject-rtos/zephyr#102598 Co-authored-by: Alberto Escolar Piedras Signed-off-by: Benjamin Cabé --- include/zephyr/shell/shell.h | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/include/zephyr/shell/shell.h b/include/zephyr/shell/shell.h index 7274b650180c..a451bda9df25 100644 --- a/include/zephyr/shell/shell.h +++ b/include/zephyr/shell/shell.h @@ -326,10 +326,16 @@ struct shell_cmd_help { */ static inline bool shell_help_is_structured(const char *help) { - const struct shell_cmd_help *structured = (const struct shell_cmd_help *)help; + const uint32_t magic32 = SHELL_STRUCTURED_HELP_MAGIC; + const char *magic = (const char *)&magic32; - return structured != NULL && IS_PTR_ALIGNED(structured, struct shell_cmd_help) && - structured->magic == SHELL_STRUCTURED_HELP_MAGIC; + /** + * Check if what help points to starts with the structured help magic word, + * but without assuming help is 32 bit aligned, or that if it is a string, + * that it is at least 4 bytes long. + */ + return help != NULL && (magic[0] == help[0]) && (magic[1] == help[1]) + && (magic[2] == help[2]) && (magic[3] == help[3]); } #if defined(CONFIG_SHELL_HELP) || defined(__DOXYGEN__) From 6404f3781448f40e2b2fdef8050cce493cb87f89 Mon Sep 17 00:00:00 2001 From: Andrej Butok Date: Wed, 21 Jan 2026 13:39:59 +0100 Subject: [PATCH 0291/6328] boards: nxp: Fix NXP MCU board names in yaml - Fixes an inconsistency in the board list of the MCUx-VSCode extension. No functional change. - Adjusts names in yaml files to follow the currently used approach "NXP [(cpu)] [(type)]". Signed-off-by: Andrej Butok --- boards/nxp/frdm_mcxn947/frdm_mcxn947_mcxn947_cpu0_qspi.yaml | 2 +- boards/nxp/lpcxpresso11u68/lpcxpresso11u68.yaml | 2 +- boards/nxp/lpcxpresso54114/lpcxpresso54114_lpc54114_m0.yaml | 2 +- boards/nxp/lpcxpresso54114/lpcxpresso54114_lpc54114_m4.yaml | 2 +- .../nxp/lpcxpresso55s69/lpcxpresso55s69_lpc55s69_cpu0_ns.yaml | 2 +- boards/nxp/mcx_nx4x_evk/mcx_n9xx_evk_mcxn947_cpu0_qspi.yaml | 2 +- boards/nxp/mcxw72_evk/mcxw72_evk_mcxw727c_cpu0.yaml | 2 +- boards/nxp/mimxrt1050_evk/mimxrt1050_evk_mimxrt1052_qspi.yaml | 2 +- .../mimxrt1060_evk/mimxrt1060_evk_mimxrt1062_hyperflash.yaml | 2 +- boards/nxp/mimxrt1062_fmurt6/board.yml | 2 +- boards/nxp/mimxrt1160_evk/mimxrt1160_evk_mimxrt1166_cm4.yaml | 2 +- boards/nxp/mimxrt1160_evk/mimxrt1160_evk_mimxrt1166_cm7.yaml | 2 +- boards/nxp/mimxrt1170_evk/mimxrt1170_evk_mimxrt1176_cm4.yaml | 2 +- boards/nxp/mimxrt1170_evk/mimxrt1170_evk_mimxrt1176_cm4_B.yaml | 2 +- boards/nxp/mimxrt1170_evk/mimxrt1170_evk_mimxrt1176_cm7.yaml | 2 +- boards/nxp/mimxrt1170_evk/mimxrt1170_evk_mimxrt1176_cm7_B.yaml | 2 +- boards/nxp/mimxrt1180_evk/mimxrt1180_evk_mimxrt1189_cm33.yaml | 2 +- boards/nxp/mimxrt1180_evk/mimxrt1180_evk_mimxrt1189_cm7.yaml | 2 +- boards/nxp/mimxrt595_evk/mimxrt595_evk_mimxrt595s_f1.yaml | 2 +- boards/nxp/mimxrt685_evk/mimxrt685_evk_mimxrt685s_hifi4.yaml | 2 +- .../nxp/mimxrt700_evk/mimxrt700_evk_mimxrt798s_cm33_cpu0.yaml | 2 +- .../nxp/mimxrt700_evk/mimxrt700_evk_mimxrt798s_cm33_cpu1.yaml | 2 +- boards/nxp/mimxrt700_evk/mimxrt700_evk_mimxrt798s_hifi1.yaml | 2 +- boards/nxp/mimxrt700_evk/mimxrt700_evk_mimxrt798s_hifi4.yaml | 2 +- boards/nxp/rd_rw612_bga/rd_rw612_bga.yaml | 2 +- boards/nxp/rd_rw612_bga/rd_rw612_bga_rw612_ethernet.yaml | 2 +- 26 files changed, 26 insertions(+), 26 deletions(-) diff --git a/boards/nxp/frdm_mcxn947/frdm_mcxn947_mcxn947_cpu0_qspi.yaml b/boards/nxp/frdm_mcxn947/frdm_mcxn947_mcxn947_cpu0_qspi.yaml index 50fdca7748b5..8a1f10e06caf 100644 --- a/boards/nxp/frdm_mcxn947/frdm_mcxn947_mcxn947_cpu0_qspi.yaml +++ b/boards/nxp/frdm_mcxn947/frdm_mcxn947_mcxn947_cpu0_qspi.yaml @@ -5,7 +5,7 @@ # identifier: frdm_mcxn947/mcxn947/cpu0/qspi -name: NXP FRDM-MCXN947 QSPI (CPU0) +name: NXP FRDM-MCXN947 (CPU0) (QSPI) type: mcu arch: arm ram: 320 diff --git a/boards/nxp/lpcxpresso11u68/lpcxpresso11u68.yaml b/boards/nxp/lpcxpresso11u68/lpcxpresso11u68.yaml index 192ca797f629..395d7ef378b1 100644 --- a/boards/nxp/lpcxpresso11u68/lpcxpresso11u68.yaml +++ b/boards/nxp/lpcxpresso11u68/lpcxpresso11u68.yaml @@ -1,5 +1,5 @@ identifier: lpcxpresso11u68 -name: NXP LPCxpresso 11U68 +name: NXP LPCxpresso11U68 type: mcu arch: arm ram: 32 diff --git a/boards/nxp/lpcxpresso54114/lpcxpresso54114_lpc54114_m0.yaml b/boards/nxp/lpcxpresso54114/lpcxpresso54114_lpc54114_m0.yaml index 8294367fcbd0..17cc1eb2d2d8 100644 --- a/boards/nxp/lpcxpresso54114/lpcxpresso54114_lpc54114_m0.yaml +++ b/boards/nxp/lpcxpresso54114/lpcxpresso54114_lpc54114_m0.yaml @@ -5,7 +5,7 @@ # identifier: lpcxpresso54114/lpc54114/m0 -name: NXP LPCXpresso54114 M0 +name: NXP LPCXpresso54114 (M0) type: mcu arch: arm ram: 32 diff --git a/boards/nxp/lpcxpresso54114/lpcxpresso54114_lpc54114_m4.yaml b/boards/nxp/lpcxpresso54114/lpcxpresso54114_lpc54114_m4.yaml index f1f13fb5cdae..8e0db4faf46f 100644 --- a/boards/nxp/lpcxpresso54114/lpcxpresso54114_lpc54114_m4.yaml +++ b/boards/nxp/lpcxpresso54114/lpcxpresso54114_lpc54114_m4.yaml @@ -5,7 +5,7 @@ # identifier: lpcxpresso54114/lpc54114/m4 -name: NXP LPCXpresso54114 M4 +name: NXP LPCXpresso54114 (M4) type: mcu arch: arm ram: 64 diff --git a/boards/nxp/lpcxpresso55s69/lpcxpresso55s69_lpc55s69_cpu0_ns.yaml b/boards/nxp/lpcxpresso55s69/lpcxpresso55s69_lpc55s69_cpu0_ns.yaml index ee3a4348eb02..ab0331e7bf61 100644 --- a/boards/nxp/lpcxpresso55s69/lpcxpresso55s69_lpc55s69_cpu0_ns.yaml +++ b/boards/nxp/lpcxpresso55s69/lpcxpresso55s69_lpc55s69_cpu0_ns.yaml @@ -5,7 +5,7 @@ # identifier: lpcxpresso55s69/lpc55s69/cpu0/ns -name: NXP LPCXpresso55S69 (Non-Secure) +name: NXP LPCXpresso55S69 (CPU0) (Non-Secure) type: mcu arch: arm ram: 136 diff --git a/boards/nxp/mcx_nx4x_evk/mcx_n9xx_evk_mcxn947_cpu0_qspi.yaml b/boards/nxp/mcx_nx4x_evk/mcx_n9xx_evk_mcxn947_cpu0_qspi.yaml index c2b1422dfe4c..9a47d0dc8f68 100644 --- a/boards/nxp/mcx_nx4x_evk/mcx_n9xx_evk_mcxn947_cpu0_qspi.yaml +++ b/boards/nxp/mcx_nx4x_evk/mcx_n9xx_evk_mcxn947_cpu0_qspi.yaml @@ -5,7 +5,7 @@ # identifier: mcx_n9xx_evk/mcxn947/cpu0/qspi -name: NXP MCX-N9XX-EVK QSPI (CPU0) +name: NXP MCX-N9XX-EVK (CPU0) (QSPI) type: mcu arch: arm ram: 320 diff --git a/boards/nxp/mcxw72_evk/mcxw72_evk_mcxw727c_cpu0.yaml b/boards/nxp/mcxw72_evk/mcxw72_evk_mcxw727c_cpu0.yaml index f3f9a54cf1da..518afbadeaa3 100644 --- a/boards/nxp/mcxw72_evk/mcxw72_evk_mcxw727c_cpu0.yaml +++ b/boards/nxp/mcxw72_evk/mcxw72_evk_mcxw727c_cpu0.yaml @@ -1,5 +1,5 @@ identifier: mcxw72_evk/mcxw727c/cpu0 -name: NXP MCXW72_EVK +name: NXP MCXW72-EVK type: mcu arch: arm ram: 264 diff --git a/boards/nxp/mimxrt1050_evk/mimxrt1050_evk_mimxrt1052_qspi.yaml b/boards/nxp/mimxrt1050_evk/mimxrt1050_evk_mimxrt1052_qspi.yaml index e05c61c13acc..752e98b34d60 100644 --- a/boards/nxp/mimxrt1050_evk/mimxrt1050_evk_mimxrt1052_qspi.yaml +++ b/boards/nxp/mimxrt1050_evk/mimxrt1050_evk_mimxrt1052_qspi.yaml @@ -5,7 +5,7 @@ # identifier: mimxrt1050_evk/mimxrt1052/qspi -name: NXP MIMXRT1050-EVK-QSPI +name: NXP MIMXRT1050-EVK (QSPI) type: mcu arch: arm toolchain: diff --git a/boards/nxp/mimxrt1060_evk/mimxrt1060_evk_mimxrt1062_hyperflash.yaml b/boards/nxp/mimxrt1060_evk/mimxrt1060_evk_mimxrt1062_hyperflash.yaml index acf3d6016ff3..e87daa765bda 100644 --- a/boards/nxp/mimxrt1060_evk/mimxrt1060_evk_mimxrt1062_hyperflash.yaml +++ b/boards/nxp/mimxrt1060_evk/mimxrt1060_evk_mimxrt1062_hyperflash.yaml @@ -5,7 +5,7 @@ # identifier: mimxrt1060_evk/mimxrt1062/hyperflash -name: NXP MIMXRT1060-EVK-HYPERFLASH +name: NXP MIMXRT1060-EVK (HyperFlash) type: mcu arch: arm toolchain: diff --git a/boards/nxp/mimxrt1062_fmurt6/board.yml b/boards/nxp/mimxrt1062_fmurt6/board.yml index 60541a7f3614..bf397cc5dd35 100644 --- a/boards/nxp/mimxrt1062_fmurt6/board.yml +++ b/boards/nxp/mimxrt1062_fmurt6/board.yml @@ -1,6 +1,6 @@ board: name: mimxrt1062_fmurt6 - full_name: FMURT6 + full_name: MIMXRT1062-FMURT6 vendor: nxp socs: - name: mimxrt1062 diff --git a/boards/nxp/mimxrt1160_evk/mimxrt1160_evk_mimxrt1166_cm4.yaml b/boards/nxp/mimxrt1160_evk/mimxrt1160_evk_mimxrt1166_cm4.yaml index 445f170f5730..a1a3f487a3f9 100644 --- a/boards/nxp/mimxrt1160_evk/mimxrt1160_evk_mimxrt1166_cm4.yaml +++ b/boards/nxp/mimxrt1160_evk/mimxrt1160_evk_mimxrt1166_cm4.yaml @@ -5,7 +5,7 @@ # identifier: mimxrt1160_evk/mimxrt1166/cm4 -name: NXP MIMXRT1160-EVK CM4 +name: NXP MIMXRT1160-EVK (CM4) type: mcu arch: arm toolchain: diff --git a/boards/nxp/mimxrt1160_evk/mimxrt1160_evk_mimxrt1166_cm7.yaml b/boards/nxp/mimxrt1160_evk/mimxrt1160_evk_mimxrt1166_cm7.yaml index d803d9332e38..e5929321e915 100644 --- a/boards/nxp/mimxrt1160_evk/mimxrt1160_evk_mimxrt1166_cm7.yaml +++ b/boards/nxp/mimxrt1160_evk/mimxrt1160_evk_mimxrt1166_cm7.yaml @@ -5,7 +5,7 @@ # identifier: mimxrt1160_evk/mimxrt1166/cm7 -name: NXP MIMXRT1160-EVK CM7 +name: NXP MIMXRT1160-EVK (CM7) type: mcu arch: arm toolchain: diff --git a/boards/nxp/mimxrt1170_evk/mimxrt1170_evk_mimxrt1176_cm4.yaml b/boards/nxp/mimxrt1170_evk/mimxrt1170_evk_mimxrt1176_cm4.yaml index 4056069d8aa9..a66b47c46781 100644 --- a/boards/nxp/mimxrt1170_evk/mimxrt1170_evk_mimxrt1176_cm4.yaml +++ b/boards/nxp/mimxrt1170_evk/mimxrt1170_evk_mimxrt1176_cm4.yaml @@ -5,7 +5,7 @@ # identifier: mimxrt1170_evk@A/mimxrt1176/cm4 -name: NXP MIMXRT1170-EVK CM4 +name: NXP MIMXRT1170-EVK (CM4) type: mcu arch: arm toolchain: diff --git a/boards/nxp/mimxrt1170_evk/mimxrt1170_evk_mimxrt1176_cm4_B.yaml b/boards/nxp/mimxrt1170_evk/mimxrt1170_evk_mimxrt1176_cm4_B.yaml index af866754ca76..083c299b2c92 100644 --- a/boards/nxp/mimxrt1170_evk/mimxrt1170_evk_mimxrt1176_cm4_B.yaml +++ b/boards/nxp/mimxrt1170_evk/mimxrt1170_evk_mimxrt1176_cm4_B.yaml @@ -5,7 +5,7 @@ # identifier: mimxrt1170_evk@B/mimxrt1176/cm4 -name: NXP MIMXRT1170-EVKB CM4 +name: NXP MIMXRT1170-EVKB (CM4) type: mcu arch: arm toolchain: diff --git a/boards/nxp/mimxrt1170_evk/mimxrt1170_evk_mimxrt1176_cm7.yaml b/boards/nxp/mimxrt1170_evk/mimxrt1170_evk_mimxrt1176_cm7.yaml index 46587fb95477..452968e2b344 100644 --- a/boards/nxp/mimxrt1170_evk/mimxrt1170_evk_mimxrt1176_cm7.yaml +++ b/boards/nxp/mimxrt1170_evk/mimxrt1170_evk_mimxrt1176_cm7.yaml @@ -5,7 +5,7 @@ # identifier: mimxrt1170_evk@A/mimxrt1176/cm7 -name: NXP MIMXRT1170-EVK CM7 +name: NXP MIMXRT1170-EVK (CM7) type: mcu arch: arm toolchain: diff --git a/boards/nxp/mimxrt1170_evk/mimxrt1170_evk_mimxrt1176_cm7_B.yaml b/boards/nxp/mimxrt1170_evk/mimxrt1170_evk_mimxrt1176_cm7_B.yaml index 009aebd98e20..e71986bc2ae5 100644 --- a/boards/nxp/mimxrt1170_evk/mimxrt1170_evk_mimxrt1176_cm7_B.yaml +++ b/boards/nxp/mimxrt1170_evk/mimxrt1170_evk_mimxrt1176_cm7_B.yaml @@ -5,7 +5,7 @@ # identifier: mimxrt1170_evk@B/mimxrt1176/cm7 -name: NXP MIMXRT1170-EVKB CM7 +name: NXP MIMXRT1170-EVKB (CM7) type: mcu arch: arm toolchain: diff --git a/boards/nxp/mimxrt1180_evk/mimxrt1180_evk_mimxrt1189_cm33.yaml b/boards/nxp/mimxrt1180_evk/mimxrt1180_evk_mimxrt1189_cm33.yaml index ae2a0c86bcc4..4d3e8da3aef2 100644 --- a/boards/nxp/mimxrt1180_evk/mimxrt1180_evk_mimxrt1189_cm33.yaml +++ b/boards/nxp/mimxrt1180_evk/mimxrt1180_evk_mimxrt1189_cm33.yaml @@ -5,7 +5,7 @@ # identifier: mimxrt1180_evk/mimxrt1189/cm33 -name: NXP MIMXRT1180-EVK CM33 +name: NXP MIMXRT1180-EVK (CM33) type: mcu arch: arm toolchain: diff --git a/boards/nxp/mimxrt1180_evk/mimxrt1180_evk_mimxrt1189_cm7.yaml b/boards/nxp/mimxrt1180_evk/mimxrt1180_evk_mimxrt1189_cm7.yaml index 6d23f30f31c3..a44dbf609b77 100644 --- a/boards/nxp/mimxrt1180_evk/mimxrt1180_evk_mimxrt1189_cm7.yaml +++ b/boards/nxp/mimxrt1180_evk/mimxrt1180_evk_mimxrt1189_cm7.yaml @@ -5,7 +5,7 @@ # identifier: mimxrt1180_evk/mimxrt1189/cm7 -name: NXP MIMXRT1180-EVK CM7 +name: NXP MIMXRT1180-EVK (CM7) type: mcu arch: arm toolchain: diff --git a/boards/nxp/mimxrt595_evk/mimxrt595_evk_mimxrt595s_f1.yaml b/boards/nxp/mimxrt595_evk/mimxrt595_evk_mimxrt595s_f1.yaml index 48245feebc68..a51f88ed0268 100644 --- a/boards/nxp/mimxrt595_evk/mimxrt595_evk_mimxrt595s_f1.yaml +++ b/boards/nxp/mimxrt595_evk/mimxrt595_evk_mimxrt595s_f1.yaml @@ -1,5 +1,5 @@ identifier: mimxrt595_evk/mimxrt595s/f1 -name: i.MXRT595 Fusion F1 DSP +name: NXP MIMXRT595-EVK (Fusion F1 DSP) type: mcu arch: xtensa toolchain: diff --git a/boards/nxp/mimxrt685_evk/mimxrt685_evk_mimxrt685s_hifi4.yaml b/boards/nxp/mimxrt685_evk/mimxrt685_evk_mimxrt685s_hifi4.yaml index 86cd87801adb..f0684da96fdc 100644 --- a/boards/nxp/mimxrt685_evk/mimxrt685_evk_mimxrt685s_hifi4.yaml +++ b/boards/nxp/mimxrt685_evk/mimxrt685_evk_mimxrt685s_hifi4.yaml @@ -5,7 +5,7 @@ # identifier: mimxrt685_evk/mimxrt685s/hifi4 -name: NXP MIMXRT685-EVK (HiFi 4) +name: NXP MIMXRT685-EVK (HiFi4) type: mcu arch: xtensa ram: 64 diff --git a/boards/nxp/mimxrt700_evk/mimxrt700_evk_mimxrt798s_cm33_cpu0.yaml b/boards/nxp/mimxrt700_evk/mimxrt700_evk_mimxrt798s_cm33_cpu0.yaml index eeade2809eaa..0c208f2fd854 100644 --- a/boards/nxp/mimxrt700_evk/mimxrt700_evk_mimxrt798s_cm33_cpu0.yaml +++ b/boards/nxp/mimxrt700_evk/mimxrt700_evk_mimxrt798s_cm33_cpu0.yaml @@ -5,7 +5,7 @@ # identifier: mimxrt700_evk/mimxrt798s/cm33_cpu0 -name: NXP MIMXRT700-EVK (CM33_CPU0) +name: NXP MIMXRT700-EVK (CPU0) type: mcu arch: arm ram: 512 diff --git a/boards/nxp/mimxrt700_evk/mimxrt700_evk_mimxrt798s_cm33_cpu1.yaml b/boards/nxp/mimxrt700_evk/mimxrt700_evk_mimxrt798s_cm33_cpu1.yaml index 13f0b3b76602..8867a4488bf1 100644 --- a/boards/nxp/mimxrt700_evk/mimxrt700_evk_mimxrt798s_cm33_cpu1.yaml +++ b/boards/nxp/mimxrt700_evk/mimxrt700_evk_mimxrt798s_cm33_cpu1.yaml @@ -5,7 +5,7 @@ # identifier: mimxrt700_evk/mimxrt798s/cm33_cpu1 -name: NXP MIMXRT700-EVK (CM33_CPU1) +name: NXP MIMXRT700-EVK (CPU1) type: mcu arch: arm ram: 256 diff --git a/boards/nxp/mimxrt700_evk/mimxrt700_evk_mimxrt798s_hifi1.yaml b/boards/nxp/mimxrt700_evk/mimxrt700_evk_mimxrt798s_hifi1.yaml index 7c3bee257ef9..8617853f99b7 100644 --- a/boards/nxp/mimxrt700_evk/mimxrt700_evk_mimxrt798s_hifi1.yaml +++ b/boards/nxp/mimxrt700_evk/mimxrt700_evk_mimxrt798s_hifi1.yaml @@ -5,7 +5,7 @@ # identifier: mimxrt700_evk/mimxrt798s/hifi1 -name: NXP MIMXRT700-EVK HiFi1 +name: NXP MIMXRT700-EVK (HiFi1) type: mcu arch: xtensa toolchain: diff --git a/boards/nxp/mimxrt700_evk/mimxrt700_evk_mimxrt798s_hifi4.yaml b/boards/nxp/mimxrt700_evk/mimxrt700_evk_mimxrt798s_hifi4.yaml index 925a17ac4664..da3dd26e465f 100644 --- a/boards/nxp/mimxrt700_evk/mimxrt700_evk_mimxrt798s_hifi4.yaml +++ b/boards/nxp/mimxrt700_evk/mimxrt700_evk_mimxrt798s_hifi4.yaml @@ -5,7 +5,7 @@ # identifier: mimxrt700_evk/mimxrt798s/hifi4 -name: NXP MIMXRT700-EVK HiFi4 +name: NXP MIMXRT700-EVK (HiFi4) type: mcu arch: xtensa toolchain: diff --git a/boards/nxp/rd_rw612_bga/rd_rw612_bga.yaml b/boards/nxp/rd_rw612_bga/rd_rw612_bga.yaml index de886b57e84a..dc71244aa10f 100644 --- a/boards/nxp/rd_rw612_bga/rd_rw612_bga.yaml +++ b/boards/nxp/rd_rw612_bga/rd_rw612_bga.yaml @@ -5,7 +5,7 @@ # identifier: rd_rw612_bga -name: NXP RD_RW612_BGA +name: NXP RD-RW612-BGA type: mcu arch: arm toolchain: diff --git a/boards/nxp/rd_rw612_bga/rd_rw612_bga_rw612_ethernet.yaml b/boards/nxp/rd_rw612_bga/rd_rw612_bga_rw612_ethernet.yaml index dbdff161607e..ec8e5acec716 100644 --- a/boards/nxp/rd_rw612_bga/rd_rw612_bga_rw612_ethernet.yaml +++ b/boards/nxp/rd_rw612_bga/rd_rw612_bga_rw612_ethernet.yaml @@ -5,7 +5,7 @@ # identifier: rd_rw612_bga/rw612/ethernet -name: NXP RD_RW612_BGA ETHERNET +name: NXP RD-RW612-BGA (Ethernet) type: mcu arch: arm toolchain: From 089bb1f0001684d74017faa186ecc3285ed8cfa7 Mon Sep 17 00:00:00 2001 From: Cristian Bulacu Date: Wed, 21 Jan 2026 15:36:07 +0200 Subject: [PATCH 0292/6328] samples: net: openthread: Remove OT reference device flag for NXP RW612 This commit removes the OPENTHREAD_REFERENCE_DEVICE flag for NXP RW612 samples, as these are not meant to be included in a test setup. Signed-off-by: Cristian Bulacu --- samples/net/openthread/border_router/prj.conf | 1 - samples/net/openthread/shell/prj-ot-host.conf | 1 - 2 files changed, 2 deletions(-) diff --git a/samples/net/openthread/border_router/prj.conf b/samples/net/openthread/border_router/prj.conf index 6e2bb959b3ef..0c71d6214e1b 100644 --- a/samples/net/openthread/border_router/prj.conf +++ b/samples/net/openthread/border_router/prj.conf @@ -124,7 +124,6 @@ CONFIG_OPENTHREAD_SRP_SERVER=y CONFIG_OPENTHREAD_SRP_ADV_PROXY=y CONFIG_OPENTHREAD_DNSSD_DISCOVERY_PROXY=y CONFIG_OPENTHREAD_PING_SENDER=y -CONFIG_OPENTHREAD_REFERENCE_DEVICE=y CONFIG_OPENTHREAD_LINK_METRICS_INITIATOR=y CONFIG_OPENTHREAD_DUA=y CONFIG_OPENTHREAD_MLR=y diff --git a/samples/net/openthread/shell/prj-ot-host.conf b/samples/net/openthread/shell/prj-ot-host.conf index 1565846414bd..63d7aa5291a9 100644 --- a/samples/net/openthread/shell/prj-ot-host.conf +++ b/samples/net/openthread/shell/prj-ot-host.conf @@ -38,7 +38,6 @@ CONFIG_OPENTHREAD_SETTINGS_RAM=y CONFIG_OPENTHREAD_NUM_MESSAGE_BUFFERS=256 CONFIG_OPENTHREAD_COAP=y CONFIG_OPENTHREAD_JOINER=y -CONFIG_OPENTHREAD_REFERENCE_DEVICE=y CONFIG_OPENTHREAD_DHCP6_CLIENT=y CONFIG_OPENTHREAD_LINK_METRICS_INITIATOR=y CONFIG_OPENTHREAD_LINK_METRICS_SUBJECT=y From f87fff19a77c659e80db0f67008b7d9f8516bf94 Mon Sep 17 00:00:00 2001 From: Cristian Bulacu Date: Wed, 21 Jan 2026 15:48:22 +0200 Subject: [PATCH 0293/6328] tests: net: remove OT reference device flag for OT tests This commit removes OPENTHREAD_REFERENCE_DEVICE flag for OpenThread tests. Signed-off-by: Cristian Bulacu --- tests/net/all/testcase.yaml | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/net/all/testcase.yaml b/tests/net/all/testcase.yaml index 36e9cdc456f4..888ae892e4a6 100644 --- a/tests/net/all/testcase.yaml +++ b/tests/net/all/testcase.yaml @@ -103,7 +103,6 @@ tests: - CONFIG_OPENTHREAD_SRP_ADV_PROXY=y - CONFIG_OPENTHREAD_DNSSD_DISCOVERY_PROXY=y - CONFIG_OPENTHREAD_PING_SENDER=y - - CONFIG_OPENTHREAD_REFERENCE_DEVICE=y - CONFIG_OPENTHREAD_LINK_METRICS_INITIATOR=y - CONFIG_OPENTHREAD_DUA=y - CONFIG_OPENTHREAD_MLR=y From a04d8957c2120abb1187a0d4fa4b97f10307a8b0 Mon Sep 17 00:00:00 2001 From: Jakub Rzeszutko Date: Wed, 21 Jan 2026 15:28:31 +0100 Subject: [PATCH 0294/6328] shell: fix race condition between prompt print and RX buffer flush Move z_shell_backend_rx_buffer_flush() before state_set() in shell_start() to prevent a race condition where incoming shell commands could be lost. Previously, the sequence was: 1. state_set() - prints the prompt 2. z_shell_backend_rx_buffer_flush() - flushes RX buffer If the shell thread was preempted after printing the prompt, the host could see the prompt and send commands. When the thread resumed, z_shell_backend_rx_buffer_flush() would discard those commands. By flushing the RX buffer before printing the prompt, any commands received after the prompt is visible will not be affected by the flush operation. Fixes #99674 Signed-off-by: Jakub Rzeszutko --- subsys/shell/shell.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/subsys/shell/shell.c b/subsys/shell/shell.c index a331464ba09d..9596ae1b2ffe 100644 --- a/subsys/shell/shell.c +++ b/subsys/shell/shell.c @@ -1449,12 +1449,6 @@ int shell_start(const struct shell *sh) z_shell_vt100_color_set(sh, SHELL_NORMAL); } - /* print new line before printing the prompt to clear the line - * vt100 are not used here for compatibility reasons - */ - z_cursor_next_line_move(sh); - state_set(sh, SHELL_STATE_ACTIVE); - /* * If the shell is stopped with the shell_stop function, its backend remains active * and continues to buffer incoming data. As a result, when the shell is resumed, @@ -1463,6 +1457,12 @@ int shell_start(const struct shell *sh) */ z_shell_backend_rx_buffer_flush(sh); + /* print new line before printing the prompt to clear the line + * vt100 are not used here for compatibility reasons + */ + z_cursor_next_line_move(sh); + state_set(sh, SHELL_STATE_ACTIVE); + z_shell_unlock(sh); return 0; From daf90f79eeb782235f81906841c2aa3696545910 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fin=20Maa=C3=9F?= Date: Tue, 28 Oct 2025 13:49:22 +0100 Subject: [PATCH 0295/6328] arch: riscv: add dependencies to FLOAT_HARD MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1. it reguires that there are floating point registers, so the extention f is required. (zfinx uses the int regs instead) 2. RV32E doesn't supports hardware floating-point calling convention. Signed-off-by: Fin Maaß --- arch/riscv/Kconfig | 3 +++ 1 file changed, 3 insertions(+) diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig index b720faa35a2d..df5574609e5b 100644 --- a/arch/riscv/Kconfig +++ b/arch/riscv/Kconfig @@ -13,8 +13,11 @@ config FLOAT_HARD bool "Hard-float calling convention" default y depends on FPU + depends on !RISCV_ISA_RV32E + depends on RISCV_ISA_EXT_F help This option enables the hard-float calling convention. + Adds eight floating-point argument registers. choice RISCV_GP_PURPOSE prompt "Purpose of the global pointer (GP) register" From 03418c538ebb904d5641195913b34ce060d69b4b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fin=20Maa=C3=9F?= Date: Tue, 28 Oct 2025 13:54:11 +0100 Subject: [PATCH 0296/6328] riscv: gcc: seperate fpu mabi and march part MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit seperate fpu mabi and march part, also use the extention for the march part to make it easier to add Zfinx and Zdinx later. Signed-off-by: Fin Maaß --- cmake/compiler/gcc/target_riscv.cmake | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/cmake/compiler/gcc/target_riscv.cmake b/cmake/compiler/gcc/target_riscv.cmake index 656b597a393e..6764aa5ff42c 100644 --- a/cmake/compiler/gcc/target_riscv.cmake +++ b/cmake/compiler/gcc/target_riscv.cmake @@ -34,17 +34,20 @@ if(CONFIG_RISCV_ISA_EXT_A) string(CONCAT riscv_march ${riscv_march} "a") endif() -if(CONFIG_FPU) +if(CONFIG_FLOAT_HARD) if(CONFIG_CPU_HAS_FPU_DOUBLE_PRECISION) - if(CONFIG_FLOAT_HARD) - string(CONCAT riscv_mabi ${riscv_mabi} "d") - endif() - string(CONCAT riscv_march ${riscv_march} "fd") + string(APPEND riscv_mabi "d") else() - if(CONFIG_FLOAT_HARD) - string(CONCAT riscv_mabi ${riscv_mabi} "f") - endif() - string(CONCAT riscv_march ${riscv_march} "f") + string(APPEND riscv_mabi "f") + endif() +endif() + +if(CONFIG_FPU) + if(CONFIG_RISCV_ISA_EXT_F) + string(APPEND riscv_march "f") + endif() + if(CONFIG_RISCV_ISA_EXT_D) + string(APPEND riscv_march "d") endif() endif() From c4945315e76aa29a9fcea6c269dc0f6a91bfa652 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fin=20Maa=C3=9F?= Date: Tue, 28 Oct 2025 13:56:44 +0100 Subject: [PATCH 0297/6328] riscv: gcc: use string(APPEND MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit use string(APPEND instead of string(CONCAT where possible. Makes it shorter. Signed-off-by: Fin Maaß --- cmake/compiler/gcc/target_riscv.cmake | 50 +++++++++++++-------------- 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/cmake/compiler/gcc/target_riscv.cmake b/cmake/compiler/gcc/target_riscv.cmake index 6764aa5ff42c..420d56aedf1e 100644 --- a/cmake/compiler/gcc/target_riscv.cmake +++ b/cmake/compiler/gcc/target_riscv.cmake @@ -12,26 +12,26 @@ elseif(CONFIG_RISCV_CMODEL_LARGE) endif() if(CONFIG_64BIT) - string(CONCAT riscv_mabi ${riscv_mabi} "64") - string(CONCAT riscv_march ${riscv_march} "64") + string(APPEND riscv_mabi "64") + string(APPEND riscv_march "64") else() string(CONCAT riscv_mabi "i" ${riscv_mabi} "32") - string(CONCAT riscv_march ${riscv_march} "32") + string(APPEND riscv_march "32") endif() if(CONFIG_RISCV_ISA_RV32E) - string(CONCAT riscv_mabi ${riscv_mabi} "e") - string(CONCAT riscv_march ${riscv_march} "e") + string(APPEND riscv_mabi "e") + string(APPEND riscv_march "e") else() - string(CONCAT riscv_march ${riscv_march} "i") + string(APPEND riscv_march "i") endif() if(CONFIG_RISCV_ISA_EXT_M) - string(CONCAT riscv_march ${riscv_march} "m") + string(APPEND riscv_march "m") endif() if(CONFIG_RISCV_ISA_EXT_A) - string(CONCAT riscv_march ${riscv_march} "a") + string(APPEND riscv_march "a") endif() if(CONFIG_FLOAT_HARD) @@ -52,73 +52,73 @@ if(CONFIG_FPU) endif() if(CONFIG_RISCV_ISA_EXT_C) - string(CONCAT riscv_march ${riscv_march} "c") + string(APPEND riscv_march "c") endif() if(CONFIG_RISCV_ISA_EXT_ZICNTR) - string(CONCAT riscv_march ${riscv_march} "_zicntr") + string(APPEND riscv_march "_zicntr") endif() if(CONFIG_RISCV_ISA_EXT_ZICSR) - string(CONCAT riscv_march ${riscv_march} "_zicsr") + string(APPEND riscv_march "_zicsr") endif() if(CONFIG_RISCV_ISA_EXT_ZIFENCEI) - string(CONCAT riscv_march ${riscv_march} "_zifencei") + string(APPEND riscv_march "_zifencei") endif() # Check whether we already imply Zaamo/Zalrsc by selecting the A extension; if not - check them # individually and enable them as needed if(NOT CONFIG_RISCV_ISA_EXT_A) if(CONFIG_RISCV_ISA_EXT_ZAAMO) - string(CONCAT riscv_march ${riscv_march} "_zaamo") + string(APPEND riscv_march "_zaamo") endif() if(CONFIG_RISCV_ISA_EXT_ZALRSC) - string(CONCAT riscv_march ${riscv_march} "_zalrsc") + string(APPEND riscv_march "_zalrsc") endif() endif() # Zca is implied by C if(CONFIG_RISCV_ISA_EXT_ZCA AND NOT CONFIG_RISCV_ISA_EXT_C) - string(CONCAT riscv_march ${riscv_march} "_zca") + string(APPEND riscv_march "_zca") endif() if(CONFIG_RISCV_ISA_EXT_ZCB) - string(CONCAT riscv_march ${riscv_march} "_zcb") + string(APPEND riscv_march "_zcb") endif() # Zcd is implied by C+D if(CONFIG_RISCV_ISA_EXT_ZCD AND NOT (CONFIG_RISCV_ISA_EXT_C AND CONFIG_RISCV_ISA_EXT_D)) - string(CONCAT riscv_march ${riscv_march} "_zcd") + string(APPEND riscv_march "_zcd") endif() # Zcf is implied by C+F if(CONFIG_RISCV_ISA_EXT_ZCF AND NOT (CONFIG_RISCV_ISA_EXT_C AND CONFIG_RISCV_ISA_EXT_F)) - string(CONCAT riscv_march ${riscv_march} "_zcf") + string(APPEND riscv_march "_zcf") endif() if(CONFIG_RISCV_ISA_EXT_ZCMP) - string(CONCAT riscv_march ${riscv_march} "_zcmp") + string(APPEND riscv_march "_zcmp") endif() if(CONFIG_RISCV_ISA_EXT_ZCMT) - string(CONCAT riscv_march ${riscv_march} "_zcmt") + string(APPEND riscv_march "_zcmt") endif() if(CONFIG_RISCV_ISA_EXT_ZBA) - string(CONCAT riscv_march ${riscv_march} "_zba") + string(APPEND riscv_march "_zba") endif() if(CONFIG_RISCV_ISA_EXT_ZBB) - string(CONCAT riscv_march ${riscv_march} "_zbb") + string(APPEND riscv_march "_zbb") endif() if(CONFIG_RISCV_ISA_EXT_ZBC) - string(CONCAT riscv_march ${riscv_march} "_zbc") + string(APPEND riscv_march "_zbc") endif() if(CONFIG_RISCV_ISA_EXT_ZBKB) @@ -126,14 +126,14 @@ if(CONFIG_RISCV_ISA_EXT_ZBKB) endif() if(CONFIG_RISCV_ISA_EXT_ZBS) - string(CONCAT riscv_march ${riscv_march} "_zbs") + string(APPEND riscv_march "_zbs") endif() # Check whether we already imply Zmmul by selecting the M extension; if not - enable it if(NOT CONFIG_RISCV_ISA_EXT_M AND CONFIG_RISCV_ISA_EXT_ZMMUL AND "${GCC_COMPILER_VERSION}" VERSION_GREATER_EQUAL 13.0.0) - string(CONCAT riscv_march ${riscv_march} "_zmmul") + string(APPEND riscv_march "_zmmul") endif() list(APPEND RISCV_C_FLAGS From 6d2471af4138e8a92272a8b73fde41692a6c3a6e Mon Sep 17 00:00:00 2001 From: Andreas Schmidt Date: Fri, 21 Nov 2025 10:13:01 +0000 Subject: [PATCH 0298/6328] drivers: spi: spi_shell: enumerate only direct SPI controller children RUN_FN_ON_SPI_DEVICE to run a given fn only if the node_id is a direct child of the SPI controller (i.e. DT_PARENT(node_id) == DT_BUS(node_id)), and the node itself has status okay. This prevents enumerating sub-nodes of SPI devices (for example GPIO sub-devices) which are not direct children of the SPI controller. Fixes #99785 Signed-off-by: Andreas Schmidt --- drivers/spi/spi_shell.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/drivers/spi/spi_shell.c b/drivers/spi/spi_shell.c index a45dafcbcee7..d9c812380fec 100644 --- a/drivers/spi/spi_shell.c +++ b/drivers/spi/spi_shell.c @@ -29,11 +29,16 @@ /* Maximum bytes we can write and read at once */ #define MAX_SPI_BYTES MIN((CONFIG_SHELL_ARGC_MAX - TXRX_ARGV_BYTES), 32) -/* Runs the given fn only if the node_id belongs to a spi device, which is on an okay spi bus. */ -#define RUN_FN_ON_SPI_DEVICE(node_id, fn) \ - COND_CODE_1(DT_ON_BUS(node_id, spi), \ - (COND_CODE_1(DT_NODE_HAS_STATUS_OKAY(DT_BUS(node_id)), \ - (fn), ())), ()) +/* Runs the given fn only if the node_id is a direct child of the SPI + * controller (i.e. DT_PARENT(node_id) == DT_BUS(node_id)), and the node + * itself has status okay. This prevents enumerating sub-nodes of SPI + * devices (for example GPIO sub-devices) which are on the same SPI bus + * but are not direct children of the controller. + */ +#define RUN_FN_ON_SPI_DEVICE(node_id, fn) \ + COND_CODE_1(DT_ON_BUS(node_id, spi), \ + (COND_CODE_1(DT_SAME_NODE(DT_PARENT(node_id), DT_BUS(node_id)), \ + (COND_CODE_1(DT_NODE_HAS_STATUS_OKAY(node_id), (fn), ())), ())), ()) /* Create specified number of empty structs, separated by ',' */ #define _EMPTY_STRUCT_INST(idx, list) {0} From 92e6d6de31f5969abbd7fc5f482afd14d328f8db Mon Sep 17 00:00:00 2001 From: Terry Geng Date: Sun, 28 Dec 2025 13:16:00 -0500 Subject: [PATCH 0299/6328] west.yml: Update hal_rpi_pico revision for flash write fix Update hal_rpi_pico to include the fix to the flash write code from zephyrproject-rtos/hal_rpi_pico#15. Fixes #95729 Fixes #96224 Signed-off-by: Terry Geng --- west.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/west.yml b/west.yml index de9a40ee46ea..53726d5ea1c2 100644 --- a/west.yml +++ b/west.yml @@ -236,7 +236,7 @@ manifest: - hal - name: hal_rpi_pico path: modules/hal/rpi_pico - revision: 09e957522da60581cf7958b31f8e625d969c69a5 + revision: 562b41e10a1d8b1a761b253b107c5c6a84cf4535 groups: - hal - name: hal_sifli From 744a7f4daf17395e29d020adeb010ec76ac8e8f0 Mon Sep 17 00:00:00 2001 From: Daniel Leung Date: Mon, 5 Jan 2026 12:15:06 -0800 Subject: [PATCH 0300/6328] xtensa: mmu: do doxygen for functions This changes the existing comments for functions into doxygen style documentation for functions. Also adds missing doxygen doc for functions. Signed-off-by: Daniel Leung --- arch/xtensa/core/mmu.c | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/arch/xtensa/core/mmu.c b/arch/xtensa/core/mmu.c index dd20136427a0..fd961f4df2f7 100644 --- a/arch/xtensa/core/mmu.c +++ b/arch/xtensa/core/mmu.c @@ -18,6 +18,15 @@ BUILD_ASSERT((CONFIG_PRIVILEGED_STACK_SIZE > 0) && extern uint32_t *xtensa_kernel_ptables; +/** + * @brief Precompute register values needed during page table switching. + * + * This precomputes the necessary values for registers that must be + * programmed when switching page tables. This is on a per-domain basis as + * each domain has a corresponding set of page tables. + * + * @param domain Pointer to the memory domain. + */ void xtensa_mmu_compute_domain_regs(struct arch_mem_domain *domain) { uint32_t vecbase = XTENSA_RSR("VECBASE"); @@ -60,7 +69,10 @@ void xtensa_mmu_compute_domain_regs(struct arch_mem_domain *domain) | XTENSA_MMU_VECBASE_WAY; } -/* Switch to a new page table. There are four items we have to set in +/** + * @brief Switch to new page tables of a memory domain. + * + * Switch to a new page table. There are four items that must be set in * the hardware: the PTE virtual address, the ring/ASID mapping * register, and two pinned entries in the data TLB handling refills * for the page tables and the vector handlers. @@ -74,6 +86,9 @@ void xtensa_mmu_compute_domain_regs(struct arch_mem_domain *domain) * holds our five instructions is sufficient to guarantee that: I * couldn't think of a way to do the alignment statically that also * interoperated well with inline assembly). + * + * @param domain Pointer to the memory domain containing the page tables + * to be used after switching. */ void xtensa_mmu_set_paging(struct arch_mem_domain *domain) { @@ -90,7 +105,12 @@ void xtensa_mmu_set_paging(struct arch_mem_domain *domain) "r"(domain->reg_vecpin_at), "r"(domain->reg_vecpin_as)); } -/* This is effectively the same algorithm from xtensa_mmu_set_paging(), +/** + * @brief Initialize paging to enable MMU. + * + * This routine initializes paging which enables MMU. + * + * This is effectively the same algorithm from xtensa_mmu_set_paging(), * but it also disables the hardware-initialized 512M TLB entries in * way 6 (because the hardware disallows duplicate TLB mappings). For * instruction fetches this produces a critical ordering constraint: From ed4cec2d220ba292860495100d1db3744c2fea8b Mon Sep 17 00:00:00 2001 From: Daniel Leung Date: Mon, 5 Jan 2026 13:38:12 -0800 Subject: [PATCH 0301/6328] xtensa: ptables: doxygen doc This adds doxygen doc to the page table source file as we are missing quite a bit of documentation there. Signed-off-by: Daniel Leung --- arch/xtensa/core/ptables.c | 297 ++++++++++++++++++++++++++++++++----- 1 file changed, 258 insertions(+), 39 deletions(-) diff --git a/arch/xtensa/core/ptables.c b/arch/xtensa/core/ptables.c index 3ec0bb672720..7047d2ebc90c 100644 --- a/arch/xtensa/core/ptables.c +++ b/arch/xtensa/core/ptables.c @@ -126,36 +126,49 @@ #define PAGE_TABLE_IS_CACHED 1 #endif -/* Skip TLB IPI when updating page tables. +/** + * @brief Option to skip TLB IPI when updating page tables. + * + * Skip TLB IPI when updating page tables. + * * This allows us to send IPI only after the last * changes of a series. */ #define OPTION_NO_TLB_IPI BIT(0) -/* Restore the PTE attributes if they have been +/** + * @brief Option to restore PTE attributes. + * + * Restore the PTE attributes if they have been * stored in the SW bits part in the PTE. */ #define OPTION_RESTORE_ATTRS BIT(1) -/* Save the PTE attributes and ring in the SW bits part in the PTE. */ +/** + * @brief Option to save PTE attributes. + * + * Save the PTE attributes and ring in the SW bits part in the PTE. + */ #define OPTION_SAVE_ATTRS BIT(2) -/* Level 1 contains page table entries - * necessary to map the page table itself. +/** + * @brief Number of page table entries (PTE) in level 1 page tables. + * + * Level 1 contains page table entries necessary to map the page table itself. */ #define L1_PAGE_TABLE_NUM_ENTRIES 1024U -/* Size of level 1 page table. - */ +/** Size of one level 1 page table in bytes. */ #define L1_PAGE_TABLE_SIZE (L1_PAGE_TABLE_NUM_ENTRIES * sizeof(uint32_t)) -/* Level 2 contains page table entries - * necessary to map the page table itself. +/** + * @brief Number of page table entries (PTE) in level 2 page tables. + * + * Level 2 contains page table entries necessary to map memory pages. */ #define L2_PAGE_TABLE_NUM_ENTRIES 1024U -/* Size of level 2 page table. - */ +/** Size of one level 2 page table in bytes. */ #define L2_PAGE_TABLE_SIZE (L2_PAGE_TABLE_NUM_ENTRIES * sizeof(uint32_t)) LOG_MODULE_DECLARE(os, CONFIG_KERNEL_LOG_LEVEL); @@ -163,7 +176,9 @@ LOG_MODULE_DECLARE(os, CONFIG_KERNEL_LOG_LEVEL); BUILD_ASSERT(CONFIG_MMU_PAGE_SIZE == 0x1000, "MMU_PAGE_SIZE value is invalid, only 4 kB pages are supported\n"); -/* +/** + * @brief Array of level 1 page tables. + * * Level 1 page table has to be 4Kb to fit into one of the wired entries. * All entries are initialized as INVALID, so an attempt to read an unmapped * area will cause a double exception. @@ -174,19 +189,25 @@ BUILD_ASSERT(CONFIG_MMU_PAGE_SIZE == 0x1000, static uint32_t l1_page_tables[CONFIG_XTENSA_MMU_NUM_L1_TABLES][L1_PAGE_TABLE_NUM_ENTRIES] __aligned(KB(4)); -/* - * That is an alias for the page tables set used by the kernel. +/** + * @brief Alias for the page tables set used by the kernel. */ uint32_t *xtensa_kernel_ptables = (uint32_t *)l1_page_tables[0]; -/* +/** + * @brief Array of level 2 page tables. + * * Each table in the level 2 maps a 4Mb memory range. It consists of 1024 entries each one * covering a 4Kb page. */ static uint32_t l2_page_tables[CONFIG_XTENSA_MMU_NUM_L2_TABLES][L2_PAGE_TABLE_NUM_ENTRIES] __aligned(KB(4)); -/* +/** + * @brief Usage tracking for level 1 page tables. + * + * This is a bit mask of which L1 tables are being used. + * * This additional variable tracks which l1 tables are in use. This is kept separated from * the tables to keep alignment easier. * @@ -194,7 +215,12 @@ static uint32_t l2_page_tables[CONFIG_XTENSA_MMU_NUM_L2_TABLES][L2_PAGE_TABLE_NU */ static ATOMIC_DEFINE(l1_page_tables_track, CONFIG_XTENSA_MMU_NUM_L1_TABLES); -/* +/** + * @brief Usage tracking for level 2 page tables. + * + * This is an array of integer counter indicating how many times one L2 tables is + * referenced by L1 tables. + * * This additional variable tracks which l2 tables are in use. This is kept separated from * the tables to keep alignment easier. */ @@ -208,9 +234,7 @@ static uint32_t l1_page_tables_max_usage; static uint32_t l2_page_tables_max_usage; #endif /* CONFIG_XTENSA_MMU_PAGE_TABLE_STATS */ -/* - * Protects xtensa_domain_list and serializes access to page tables. - */ +/** Spin lock to protect xtensa_domain_list and serializes access to page tables. */ static struct k_spinlock xtensa_mmu_lock; /** Spin lock to guard update to page table counters. */ @@ -218,19 +242,22 @@ static struct k_spinlock xtensa_counter_lock; #ifdef CONFIG_USERSPACE -/* +/** + * @brief Number of ASIDs has been allocated. + * * Each domain has its own ASID. ASID can go through 1 (kernel) to 255. * When a TLB entry matches, the hw will check the ASID in the entry and finds * the correspondent position in the RASID register. This position will then be * compared with the current ring (CRING) to check the permission. + * + * This keeps track of how many ASIDs have been allocated for memory domains. */ static uint8_t asid_count = 3; -/* - * List with all active and initialized memory domains. - */ +/** Linked list with all active and initialized memory domains. */ static sys_slist_t xtensa_domain_list; +/** Actions when duplicating page tables. */ enum dup_action { /* Restore all entries when duplicating. */ RESTORE, @@ -246,7 +273,9 @@ static void dup_l2_table_if_needed(uint32_t *l1_table, uint32_t l1_pos, enum dup extern char _heap_end[]; extern char _heap_start[]; -/* +/** + * @brief Memory regions to initialize page tables at boot. + * * Static definition of all code & data memory regions of the * current Zephyr image. This information must be available & * processed upon MMU initialization. @@ -361,6 +390,14 @@ static inline int l2_table_to_counter_pos(uint32_t *l2_table) return (l2_table - (uint32_t *)l2_page_tables) / (L2_PAGE_TABLE_NUM_ENTRIES); } +/** + * @brief Allocate a level 2 page table from the L2 table array. + * + * This allocates a new level 2 page table from the L2 table array. + * + * @return Pointer to the newly allocated L2 table. NULL if no free table + * in the array. + */ static inline uint32_t *alloc_l2_table(void) { uint16_t idx; @@ -384,6 +421,16 @@ static inline uint32_t *alloc_l2_table(void) return ret; } +/** + * @brief Map memory in the kernel page tables. + * + * This is used during boot, and is to map a region of memory in the kernel page tables. + * + * @param[in] start Start address of the memory region. + * @param[in] end End address of the memory region. + * @param[in] attrs Page table attributes for the memory region. + * @param[in] options Options for the memory region. + */ static void map_memory_range(const uint32_t start, const uint32_t end, const uint32_t attrs, const uint32_t options) { @@ -511,14 +558,15 @@ void xtensa_mmu_reinit(void) } #ifdef CONFIG_ARCH_HAS_RESERVED_PAGE_FRAMES -/* Zephyr's linker scripts for Xtensa usually puts - * something before z_mapped_start (aka .text), - * i.e. vecbase, so that we need to reserve those - * space or else k_mem_map() would be mapping those, - * resulting in faults. - */ __weak void arch_reserved_pages_update(void) { + /* Zephyr's linker scripts for Xtensa usually puts + * something before z_mapped_start (aka .text), + * i.e. vecbase, so that we need to reserve those + * space or else k_mem_map() would be mapping those, + * resulting in faults. + */ + uintptr_t page; int idx; @@ -530,6 +578,22 @@ __weak void arch_reserved_pages_update(void) } #endif /* CONFIG_ARCH_HAS_RESERVED_PAGE_FRAMES */ +/** + * @brief Map one memory page in the L2 table. + * + * This maps exactly one memory page in the L2 table. + * + * A new L2 table will be allocated if necessary. + * + * @param[in] l1_table Pointer to the level 1 page table. + * @param[in] vaddr Virtual address to be mapped. + * @param[in] phys Physical address to map to. + * @param[in] attrs Page table attributes (actual hardware attributes). + * @param[in] is_user True if this mapping can be used in user mode, false if kernel mode only. + * + * @retval true Mapping is successful. + * @retval false Mapping failed. Usually means there are no free L2 tables to be allocated. + */ static bool l2_page_table_map(uint32_t *l1_table, void *vaddr, uintptr_t phys, uint32_t attrs, bool is_user) { @@ -574,6 +638,18 @@ static bool l2_page_table_map(uint32_t *l1_table, void *vaddr, uintptr_t phys, return true; } +/** + * @brief Called by @ref arch_mem_map to map one memory page. + * + * @see arch_mem_map + * + * This should only be called by @ref arch_mem_map to perform the mapping in the L2 tables. + * + * @param[in] vaddr Virtual address to be mapped. + * @param[in] paddr Physical address to map to. + * @param[in] attrs Page table attributes (actual hardware attributes). + * @param[in] is_user True if mapping for user mode, false if kernel mode only. + */ static inline void __arch_mem_map(void *vaddr, uintptr_t paddr, uint32_t attrs, bool is_user) { bool ret; @@ -745,6 +821,15 @@ static void l2_page_table_unmap(uint32_t *l1_table, void *vaddr) } } +/** + * @brief Called by @ref arch_mem_unmap to unmap one memory page. + * + * @see arch_mem_unmap + * + * This should only be called by @ref arch_mem_unmap to remove the mapping in the L2 tables. + * + * @param[in] vaddr Virtual address to be unmapped. + */ static inline void __arch_mem_unmap(void *vaddr) { l2_page_table_unmap(xtensa_kernel_ptables, vaddr); @@ -916,6 +1001,11 @@ static bool is_l2_table_inside_array(uint32_t *l2_table) return (addr >= l2_table_begin) && (addr < l2_table_end); } +/** + * @brief Increment the tracking counter for one L2 table. + * + * @param[in] l2_table Pointer to the level 2 page table. + */ static ALWAYS_INLINE void l2_page_tables_counter_inc(uint32_t *l2_table) { if (is_l2_table_inside_array(l2_table)) { @@ -923,6 +1013,11 @@ static ALWAYS_INLINE void l2_page_tables_counter_inc(uint32_t *l2_table) } } +/** + * @brief Decrement the tracking counter for one L2 table. + * + * @param[in] l2_table Pointer to the level 2 page table. + */ static ALWAYS_INLINE void l2_page_tables_counter_dec(uint32_t *l2_table) { if (is_l2_table_inside_array(l2_table)) { @@ -932,6 +1027,13 @@ static ALWAYS_INLINE void l2_page_tables_counter_dec(uint32_t *l2_table) #ifdef CONFIG_USERSPACE +/** + * @brief Get the page table for the thread. + * + * @param[in] thread Pointer to the thread object. + * + * @return Pointer to the L1 table corresponding to the thread. + */ static inline uint32_t *thread_page_tables_get(const struct k_thread *thread) { if ((thread->base.user_options & K_USER) != 0U) { @@ -941,6 +1043,14 @@ static inline uint32_t *thread_page_tables_get(const struct k_thread *thread) return xtensa_kernel_ptables; } +/** + * @brief Allocate a level 1 page table from the L1 table array. + * + * This allocates a new level 1 page table from the L1 table array. + * + * @return Pointer to the newly allocated L2 table. NULL if no free table + * in the array. + */ static inline uint32_t *alloc_l1_table(void) { uint16_t idx; @@ -974,10 +1084,10 @@ static inline uint32_t *alloc_l1_table(void) } /** - * Given page table position, calculate the corresponding virtual address. + * @brief Given page table position, calculate the corresponding virtual address. * - * @param l1_pos Position in L1 page table. - * @param l2_pos Position in L2 page table. + * @param[in] l1_pos Position in L1 page table. + * @param[in] l2_pos Position in L2 page table. * @return Virtual address. */ static ALWAYS_INLINE uint32_t vaddr_from_pt_pos(uint32_t l1_pos, uint32_t l2_pos) @@ -985,6 +1095,19 @@ static ALWAYS_INLINE uint32_t vaddr_from_pt_pos(uint32_t l1_pos, uint32_t l2_pos return (l1_pos << 22U) | (l2_pos << 12U); } +/** + * @brief Duplicate an existing level 2 page table. + * + * This allocates a new level 2 page table and duplicates the PTEs from an existing + * L2 table. + * + * @param[in] src_l2_table Pointer to the source L2 table to be duplicated. + * @param[in] action Action during duplication. + * RESTORE to restore PTEs to the attributes stored in the backup bits. + * COPY to copy PTEs from source without modifications. + * + * @return Pointer to the newly duplicated L2 table. NULL if table allocation fails. + */ static uint32_t *dup_l2_table(uint32_t *src_l2_table, enum dup_action action) { uint32_t *l2_table; @@ -1020,6 +1143,14 @@ static uint32_t *dup_l2_table(uint32_t *src_l2_table, enum dup_action action) return l2_table; } +/** + * @brief Duplicate the kernel page table into a new level 1 page table. + * + * This allocates a new level 1 page table and copy the PTEs from the kernel + * page table. + * + * @return Pointer to the newly duplicated L1 table. NULL if table allocation fails. + */ static uint32_t *dup_l1_table(void) { uint32_t *l1_table = alloc_l1_table(); @@ -1090,6 +1221,26 @@ static uint32_t *dup_l1_table(void) return l1_table; } +/** + * @brief Duplicate an existing level 2 page table if needed. + * + * If a L2 table is referenced by multiple L1 tables, we need to make a copy of + * the existing L2 table and modify the new table, basically a copy-on-write + * operation. + * + * If a new L2 table needs to be allocated, the corresponding PTE in the L1 table + * will be modified to point to the new table. + * + * If the L2 table is only referenced by exactly one L1 table, no duplication + * will be performed. + * + * @param[in] l1_table Pointer to the level 1 page table. + * @param[in] l1_pos Index of the PTE within the L1 table pointing to the L2 table + * to be examined. + * @param[in] action Action during duplication. + * RESTORE to restore PTEs to the attributes stored in the backup bits. + * COPY to copy PTEs from source without modifications. + */ static void dup_l2_table_if_needed(uint32_t *l1_table, uint32_t l1_pos, enum dup_action action) { uint32_t *l2_table, *src_l2_table; @@ -1165,8 +1316,22 @@ int arch_mem_domain_init(struct k_mem_domain *domain) return ret; } +/** + * @brief Update the mappings of a memory region. + * + * @note This does not lock the necessary spin locks to prevent simultaneous updates + * to the page tables. Use @ref update_region instead if locking is desired. + * + * @param[in] l1_table Pointer to the L1 table. + * @param[in] start Starting virtual address of the memory region to be updated. + * @param[in] size Size of the memory region to be updated. + * @param[in] ring Ring value to set to. + * @param[in] attrs Page table attributes to set to (not used if option is RESTORE). + * @param[in] option Option for the memory region. + * OPTION_RESTORE_ATTRS will restore the attributes from the backup bits. + */ static void region_map_update(uint32_t *l1_table, uintptr_t start, - size_t size, uint32_t ring, uint32_t flags, uint32_t option) + size_t size, uint32_t ring, uint32_t attrs, uint32_t option) { for (size_t offset = 0; offset < size; offset += CONFIG_MMU_PAGE_SIZE) { uint32_t *l2_table, pte; @@ -1197,7 +1362,7 @@ static void region_map_update(uint32_t *l1_table, uintptr_t start, new_attrs = PTE_BCKUP_ATTR_GET(pte); new_ring = PTE_BCKUP_RING_GET(pte); } else { - new_attrs = flags; + new_attrs = attrs; new_ring = ring; } @@ -1214,14 +1379,28 @@ static void region_map_update(uint32_t *l1_table, uintptr_t start, } } +/** + * @brief Update the attributes of the memory region. + * + * @note This locks the necessary spin locks to prevent simultaneous updates + * to the page tables. + * + * @param[in] ptables Pointer to the L1 table. + * @param[in] start Starting virtual address of the memory region to be updated. + * @param[in] size Size of the memory region to be updated. + * @param[in] ring Ring value to set to. + * @param[in] attrs Page table attributes to set to (not used if option is RESTORE). + * @param[in] option Option for the memory region. + * OPTION_RESTORE_ATTRS will restore the attributes from the backup bits. + */ static void update_region(uint32_t *ptables, uintptr_t start, size_t size, - uint32_t ring, uint32_t flags, uint32_t option) + uint32_t ring, uint32_t attrs, uint32_t option) { k_spinlock_key_t key; key = k_spin_lock(&xtensa_mmu_lock); - region_map_update(ptables, start, size, ring, flags, option); + region_map_update(ptables, start, size, ring, attrs, option); #if CONFIG_MP_MAX_NUM_CPUS > 1 if ((option & OPTION_NO_TLB_IPI) != OPTION_NO_TLB_IPI) { @@ -1235,6 +1414,22 @@ static void update_region(uint32_t *ptables, uintptr_t start, size_t size, k_spin_unlock(&xtensa_mmu_lock, key); } +/** + * @brief Reset the attributes of the memory region. + * + * This restores the ring and PTE attributes to the backup bits. + * Usually this restores the PTEs corresponding to the memory region to + * the ring and attributes at boot time just before MMU is enabled. + * + * @note This calls @ref update_region which locks the necessary spin locks to + * prevent simultaneous updates to the page tables. + * + * @param[in] ptables Pointer to the L1 table. + * @param[in] start Starting virtual address of the memory region to be updated. + * @param[in] size Size of the memory region to be updated. + * @param[in] option Option for the memory region. + * OPTION_RESTORE_ATTRS will restore the attributes from the backup bits. + */ static inline void reset_region(uint32_t *ptables, uintptr_t start, size_t size, uint32_t option) { update_region(ptables, start, size, RING_KERNEL, XTENSA_MMU_PERM_W, @@ -1286,7 +1481,6 @@ int arch_mem_domain_partition_add(struct k_mem_domain *domain, return 0; } -/* These APIs don't need to do anything */ int arch_mem_domain_thread_add(struct k_thread *thread) { bool is_user, is_migration; @@ -1371,6 +1565,17 @@ int arch_mem_domain_thread_remove(struct k_thread *thread) return 0; } +/** + * @brief Check if a page can be legally accessed. + * + * @param[in] ptables Pointer to the level 1 page table. + * @param[in] page Virtual address of the page to be checked. + * @param[in] ring Ring value for the access. + * @param[in] write True if the access needs to write to this page, false if read only. + * + * @retval true Access is legal. + * @retval false Access is not legal and will probably generate page fault. + */ static bool page_validate(uint32_t *ptables, uint32_t page, uint8_t ring, bool write) { uint8_t asid_ring; @@ -1409,6 +1614,20 @@ static bool page_validate(uint32_t *ptables, uint32_t page, uint8_t ring, bool w return true; } +/** + * @brief Check if a memory region can be legally accessed. + * + * @param[in] ptables Pointer to the level 1 page table. + * @param[in] addr Start virtual address of the memory region to be checked. + * @param[in] size Size of the memory region to be checked. + * @param[in] write True if the access needs to write to this page, false if read only. + * @param[in] ring Ring value for the access. + * + * @retval 0 Access is legal. + * @retval -1 Access is not legal and will probably generate page fault. + * + * @see arch_buffer_validate + */ static int mem_buffer_validate(const void *addr, size_t size, int write, int ring) { int ret = 0; From 8c02dde4377e53761bf2789dc3eaa1ba34edc2d4 Mon Sep 17 00:00:00 2001 From: Daniel Leung Date: Mon, 5 Jan 2026 12:21:08 -0800 Subject: [PATCH 0302/6328] xtensa: move MMU init functions to mmu.c Since we have split source files for page table related stuff and MMU related stuff, move the MMU initialization functions from the page table source file into MMU source file. Signed-off-by: Daniel Leung --- arch/xtensa/core/mmu.c | 38 +++++++++++++++++++++++++ arch/xtensa/core/ptables.c | 41 +-------------------------- arch/xtensa/include/xtensa_mmu_priv.h | 5 ++++ 3 files changed, 44 insertions(+), 40 deletions(-) diff --git a/arch/xtensa/core/mmu.c b/arch/xtensa/core/mmu.c index fd961f4df2f7..8aba541f843e 100644 --- a/arch/xtensa/core/mmu.c +++ b/arch/xtensa/core/mmu.c @@ -208,3 +208,41 @@ void xtensa_mmu_init_paging(void) } __asm__ volatile("isync"); } + +__weak void arch_xtensa_mmu_post_init(bool is_core0) +{ + ARG_UNUSED(is_core0); +} + +void xtensa_mmu_init(void) +{ + xtensa_init_page_tables(); + + xtensa_mmu_init_paging(); + + /* + * This is used to determine whether we are faulting inside double + * exception if this is not zero. Sometimes SoC starts with this not + * being set to zero. So clear it during boot. + */ + XTENSA_WSR(ZSR_DEPC_SAVE_STR, 0); + + arch_xtensa_mmu_post_init(_current_cpu->id == 0); +} + +void xtensa_mmu_reinit(void) +{ + /* First initialize the hardware */ + xtensa_mmu_init_paging(); + +#ifdef CONFIG_USERSPACE + struct k_thread *thread = _current_cpu->current; + struct arch_mem_domain *domain = &(thread->mem_domain_info.mem_domain->arch); + + + /* Set the page table for current context */ + xtensa_mmu_set_paging(domain); +#endif /* CONFIG_USERSPACE */ + + arch_xtensa_mmu_post_init(_current_cpu->id == 0); +} diff --git a/arch/xtensa/core/ptables.c b/arch/xtensa/core/ptables.c index 7047d2ebc90c..b8bc6fa5675b 100644 --- a/arch/xtensa/core/ptables.c +++ b/arch/xtensa/core/ptables.c @@ -474,7 +474,7 @@ static void map_memory_range(const uint32_t start, const uint32_t end, } } -static void xtensa_init_page_tables(void) +void xtensa_init_page_tables(void) { volatile uint8_t entry; static bool already_inited; @@ -518,45 +518,6 @@ static void xtensa_init_page_tables(void) } } -__weak void arch_xtensa_mmu_post_init(bool is_core0) -{ - ARG_UNUSED(is_core0); -} - -void xtensa_mmu_init(void) -{ - xtensa_init_page_tables(); - - xtensa_mmu_init_paging(); - - /* - * This is used to determine whether we are faulting inside double - * exception if this is not zero. Sometimes SoC starts with this not - * being set to zero. So clear it during boot. - */ - XTENSA_WSR(ZSR_DEPC_SAVE_STR, 0); - - arch_xtensa_mmu_post_init(_current_cpu->id == 0); -} - -void xtensa_mmu_reinit(void) -{ - /* First initialize the hardware */ - xtensa_mmu_init_paging(); - -#ifdef CONFIG_USERSPACE - struct k_thread *thread = _current_cpu->current; - struct arch_mem_domain *domain = - &(thread->mem_domain_info.mem_domain->arch); - - - /* Set the page table for current context */ - xtensa_mmu_set_paging(domain); -#endif /* CONFIG_USERSPACE */ - - arch_xtensa_mmu_post_init(_current_cpu->id == 0); -} - #ifdef CONFIG_ARCH_HAS_RESERVED_PAGE_FRAMES __weak void arch_reserved_pages_update(void) { diff --git a/arch/xtensa/include/xtensa_mmu_priv.h b/arch/xtensa/include/xtensa_mmu_priv.h index 1f899a1c1242..48df860dd772 100644 --- a/arch/xtensa/include/xtensa_mmu_priv.h +++ b/arch/xtensa/include/xtensa_mmu_priv.h @@ -485,6 +485,11 @@ void xtensa_mmu_set_paging(struct arch_mem_domain *domain); */ void xtensa_mmu_compute_domain_regs(struct arch_mem_domain *domain); +/** + * @brief Initialize page tables needed for boot. + */ +void xtensa_init_page_tables(void); + /** * @} */ From cb5b83b9bc335560cc78f39a4b1a2b2d180e9574 Mon Sep 17 00:00:00 2001 From: Gaetan Perrot Date: Wed, 21 Jan 2026 04:12:26 +0900 Subject: [PATCH 0303/6328] drivers: comparator: mcux_acmp: remove dead error handling The MCUX ACMP configuration helpers always return 0, making their error checks in mcux_acmp_init() unreachable. Remove the redundant return value checks to simplify the initialization flow. No functional change. Signed-off-by: Gaetan Perrot --- drivers/comparator/comparator_mcux_acmp.c | 24 ++++------------------- 1 file changed, 4 insertions(+), 20 deletions(-) diff --git a/drivers/comparator/comparator_mcux_acmp.c b/drivers/comparator/comparator_mcux_acmp.c index c8eab2e09b6c..d11ccd9f602b 100644 --- a/drivers/comparator/comparator_mcux_acmp.c +++ b/drivers/comparator/comparator_mcux_acmp.c @@ -561,11 +561,7 @@ static int mcux_acmp_init(const struct device *dev) comp_mcux_acmp_init_mode_config(dev, &config->mode_config); - ret = comp_mcux_acmp_set_input_config(dev, &config->input_config); - if (ret) { - LOG_ERR("failed to set %s", "input config"); - return ret; - } + comp_mcux_acmp_set_input_config(dev, &config->input_config); ret = comp_mcux_acmp_set_filter_config(dev, &config->filter_config); if (ret) { @@ -573,26 +569,14 @@ static int mcux_acmp_init(const struct device *dev) return ret; } - ret = comp_mcux_acmp_set_dac_config(dev, &config->dac_config); - if (ret) { - LOG_ERR("failed to set %s", "dac config"); - return ret; - } + comp_mcux_acmp_set_dac_config(dev, &config->dac_config); #if COMP_MCUX_ACMP_HAS_DISCRETE_MODE - ret = comp_mcux_acmp_set_dm_config(dev, &config->dm_config); - if (ret) { - LOG_ERR("failed to set %s", "discrete mode config"); - return ret; - } + comp_mcux_acmp_set_dm_config(dev, &config->dm_config); #endif #if COMP_MCUX_ACMP_HAS_WINDOW_MODE - ret = comp_mcux_acmp_set_window_mode(dev, config->enable_window_mode); - if (ret) { - LOG_ERR("failed to set %s", "window mode"); - return ret; - } + comp_mcux_acmp_set_window_mode(dev, config->enable_window_mode); #endif ACMP_DisableInterrupts(config->base, UINT32_MAX); From 5ee5dafdd137ae34e647d9e8c4f6cd69f7b3e59e Mon Sep 17 00:00:00 2001 From: Maochen Wang Date: Thu, 22 Jan 2026 14:10:36 +0800 Subject: [PATCH 0304/6328] hostap: fix incorrect link mode selection for SAP When SAP runs on hostapd, the HE (11ax) capability should be determined based on hw_mode->he_capab, which reflects the Wi-Fi FW capability. Using conf->ieee80211ax is incorrect because it only represents the default value derived from build-time configuration macros, and does not accurately represent real hardware capabilities. Same change is also needed for VHT and HT check. Signed-off-by: Maochen Wang --- modules/hostap/src/hapd_api.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/modules/hostap/src/hapd_api.c b/modules/hostap/src/hapd_api.c index 3a12826afc3c..fbee5210350b 100644 --- a/modules/hostap/src/hapd_api.c +++ b/modules/hostap/src/hapd_api.c @@ -771,13 +771,14 @@ int hostapd_ap_status(const struct device *dev, struct wifi_iface_status *status hw_mode = iface->current_mode; - status->link_mode = conf->ieee80211ax ? WIFI_6 - : conf->ieee80211ac ? WIFI_5 - : conf->ieee80211n ? WIFI_4 - : hw_mode->mode == HOSTAPD_MODE_IEEE80211G ? WIFI_3 - : hw_mode->mode == HOSTAPD_MODE_IEEE80211A ? WIFI_2 - : hw_mode->mode == HOSTAPD_MODE_IEEE80211B ? WIFI_1 - : WIFI_0; + status->link_mode = (hw_mode->he_capab[IEEE80211_MODE_AP].he_supported + && conf->ieee80211ax) ? WIFI_6 + : (hw_mode->vht_capab && conf->ieee80211ac) ? WIFI_5 + : (hw_mode->ht_capab && conf->ieee80211n) ? WIFI_4 + : hw_mode->mode == HOSTAPD_MODE_IEEE80211G ? WIFI_3 + : hw_mode->mode == HOSTAPD_MODE_IEEE80211A ? WIFI_2 + : hw_mode->mode == HOSTAPD_MODE_IEEE80211B ? WIFI_1 + : WIFI_0; status->twt_capable = (hw_mode->he_capab[IEEE80211_MODE_AP].mac_cap[0] & 0x04); out: From 7a26b751c13b5589f3a8bcabec4e9467f78ce627 Mon Sep 17 00:00:00 2001 From: Markus Lassila Date: Wed, 21 Jan 2026 14:20:24 +0200 Subject: [PATCH 0305/6328] net: ppp: Fixes to peer LCP_OPTION_MRU handling - Use the minimum of our and peer MRU as the MTU of the link. Allows for cases where our MRU is < 1500. - Move all of the MRU handling under CONFIG_NET_L2_PPP_OPTION_MRU. So that we handle both sending the LCP_OPTION_MRU in Configure-Request and receiving it in Configure-Request. - Remove CONFIG_NET_L2_PPP_OPTION_MAX_MRU. From RFC 1661, 6.1 Implementation note: ... The peer need not Configure-Nak to indicate that it will only send smaller packets, since the implementation will always require support for at least 1500 octets. - Set ppp_my_options_parse_conf_ack so that ack's are parsed. Signed-off-by: Markus Lassila --- subsys/net/l2/ppp/Kconfig | 7 ------- subsys/net/l2/ppp/lcp.c | 44 +++++++++++++++++++++++++-------------- 2 files changed, 28 insertions(+), 23 deletions(-) diff --git a/subsys/net/l2/ppp/Kconfig b/subsys/net/l2/ppp/Kconfig index d5dae67f99c8..1dc6baf601aa 100644 --- a/subsys/net/l2/ppp/Kconfig +++ b/subsys/net/l2/ppp/Kconfig @@ -60,13 +60,6 @@ config NET_L2_PPP_OPTION_MRU help Enable support for LCP MRU option. -config NET_L2_PPP_OPTION_MAX_MRU - int "LCP MRU maximum size" - default 1500 - help - Set the maximal MRU size which is allowed while negotiation with peer over LCP. - The default value is defined by RFC 1661. - config NET_L2_PPP_OPTION_SERVE_IP bool "Serve IP address to peer" help diff --git a/subsys/net/l2/ppp/lcp.c b/subsys/net/l2/ppp/lcp.c index 9c664d006021..7a25e47b923b 100644 --- a/subsys/net/l2/ppp/lcp.c +++ b/subsys/net/l2/ppp/lcp.c @@ -122,8 +122,9 @@ static int lcp_async_ctrl_char_map_parse(struct ppp_fsm *fsm, struct net_pkt *pk return 0; } +#if defined(CONFIG_NET_L2_PPP_OPTION_MRU) static int lcp_peer_mru_parse(struct ppp_fsm *fsm, struct net_pkt *pkt, - void *user_data) + void *user_data) { struct lcp_option_data *data = user_data; uint16_t peer_mru; @@ -137,19 +138,13 @@ static int lcp_peer_mru_parse(struct ppp_fsm *fsm, struct net_pkt *pkt, NET_DBG("[LCP] Received peer MRU %u", peer_mru); - if (peer_mru > CONFIG_NET_L2_PPP_OPTION_MAX_MRU) { - LOG_WRN("[LCP] Received peer MRU is too big. %u > %u.", - peer_mru, CONFIG_NET_L2_PPP_OPTION_MAX_MRU); - return -EINVAL; - } - data->mru = peer_mru; return 0; } static int lcp_peer_mru_nack(struct ppp_fsm *fsm, struct net_pkt *ret_pkt, - void *user_data) + void *user_data) { struct ppp_context *ctx = ppp_fsm_ctx(fsm); @@ -157,14 +152,16 @@ static int lcp_peer_mru_nack(struct ppp_fsm *fsm, struct net_pkt *ret_pkt, (void)net_pkt_write_u8(ret_pkt, 4); return net_pkt_write_be16(ret_pkt, ctx->lcp.my_options.mru); } +#endif static const struct ppp_peer_option_info lcp_peer_options[] = { PPP_PEER_OPTION(LCP_OPTION_AUTH_PROTO, lcp_auth_proto_parse, lcp_auth_proto_nack), PPP_PEER_OPTION(LCP_OPTION_ASYNC_CTRL_CHAR_MAP, lcp_async_ctrl_char_map_parse, NULL), - PPP_PEER_OPTION(LCP_OPTION_MRU, lcp_peer_mru_parse, - lcp_peer_mru_nack), +#if defined(CONFIG_NET_L2_PPP_OPTION_MRU) + PPP_PEER_OPTION(LCP_OPTION_MRU, lcp_peer_mru_parse, lcp_peer_mru_nack), +#endif }; static int lcp_config_info_req(struct ppp_fsm *fsm, @@ -191,6 +188,9 @@ static int lcp_config_info_req(struct ppp_fsm *fsm, ctx->lcp.peer_options.auth_proto = data.auth_proto; ctx->lcp.peer_options.async_map = data.async_ctrl_char_map; +#if defined(CONFIG_NET_L2_PPP_OPTION_MRU) + ctx->lcp.peer_options.mru = data.mru; +#endif NET_DBG("Asynchronous Control Character Map: %08X", data.async_ctrl_char_map); if (data.auth_proto_present) { @@ -259,12 +259,23 @@ static void lcp_up(struct ppp_fsm *fsm) struct ppp_context *ctx = CONTAINER_OF(fsm, struct ppp_context, lcp.fsm); - if (ctx->lcp.peer_options.mru > 0) { - NET_DBG("Set MTU size from peer options: %u -> %u", - net_if_get_mtu(ctx->iface), ctx->lcp.peer_options.mru); - net_if_set_mtu(ctx->iface, ctx->lcp.peer_options.mru); +#if defined(CONFIG_NET_L2_PPP_OPTION_MRU) + /* Set MTU based on negotiated MRU values. + * Use the minimum of our MRU and peer's MRU to ensure both sides + * can handle the packet size. + */ + uint16_t mtu = ctx->lcp.my_options.mru; + + if (ctx->lcp.peer_options.mru > 0 && + ctx->lcp.peer_options.mru < mtu) { + mtu = ctx->lcp.peer_options.mru; } + NET_DBG("PPP MTU set to %d (mru=%d, peer_mru=%d)", + mtu, ctx->lcp.my_options.mru, ctx->lcp.peer_options.mru); + net_if_set_mtu(ctx->iface, mtu); +#endif + ppp_link_established(ctx, fsm); } @@ -305,7 +316,7 @@ static int lcp_ack_mru(struct ppp_context *ctx, struct net_pkt *pkt, return -EINVAL; } - ret = net_pkt_read(pkt, &mru, sizeof(mru)); + ret = net_pkt_read_be16(pkt, &mru); if (ret) { return ret; } @@ -328,7 +339,7 @@ static int lcp_nak_mru(struct ppp_context *ctx, struct net_pkt *pkt, return -EINVAL; } - ret = net_pkt_read(pkt, &mru, sizeof(mru)); + ret = net_pkt_read_be16(pkt, &mru); if (ret) { return ret; } @@ -456,6 +467,7 @@ static void lcp_init(struct ppp_context *ctx) ctx->lcp.fsm.cb.config_info_add = lcp_config_info_add; ctx->lcp.fsm.cb.config_info_req = lcp_config_info_req; + ctx->lcp.fsm.cb.config_info_ack = ppp_my_options_parse_conf_ack; ctx->lcp.fsm.cb.config_info_nack = lcp_config_info_nack; ctx->lcp.fsm.cb.config_info_rej = ppp_my_options_parse_conf_rej; From bf04578e5617568851309cdf5858c6618287868b Mon Sep 17 00:00:00 2001 From: Scott Worley Date: Tue, 20 Jan 2026 13:58:14 -0500 Subject: [PATCH 0306/6328] boards: microchip: mec_assy6941: mec165xb: Add flash image generator rules We updated Microchip mec_assy6941 board cmake rules to invoke a tool for generating a SPI flash image for MEC165xB. We also added a MEC165xB specific configuration file for the tool. Revision B MEC175x/165x parts require 'DeviceSel' field set to 'B'. Signed-off-by: Scott Worley --- boards/microchip/mec_assy6941/CMakeLists.txt | 2 + .../mec_assy6941/support/mec165xb_spi_cfg.txt | 93 +++++++++++++++++++ 2 files changed, 95 insertions(+) create mode 100644 boards/microchip/mec_assy6941/support/mec165xb_spi_cfg.txt diff --git a/boards/microchip/mec_assy6941/CMakeLists.txt b/boards/microchip/mec_assy6941/CMakeLists.txt index 84b859f1f176..6b7afa2916b8 100644 --- a/boards/microchip/mec_assy6941/CMakeLists.txt +++ b/boards/microchip/mec_assy6941/CMakeLists.txt @@ -8,6 +8,8 @@ if(CONFIG_SOC_SERIES_MEC174X) set(PART_PREFIX mec174x) elseif(CONFIG_SOC_SERIES_MEC175X) set(PART_PREFIX mec175x) +elseif(CONFIG_SOC_SERIES_MEC165XB) + set(PART_PREFIX mec165xb) else() message(NOTICE "Unknown SoC series! No SPI image will be generated") endif() diff --git a/boards/microchip/mec_assy6941/support/mec165xb_spi_cfg.txt b/boards/microchip/mec_assy6941/support/mec165xb_spi_cfg.txt new file mode 100644 index 000000000000..3aa5732f9765 --- /dev/null +++ b/boards/microchip/mec_assy6941/support/mec165xb_spi_cfg.txt @@ -0,0 +1,93 @@ +; Copyright (c) 2026, Microchip Technology Inc. +; SPDX-License-Identifier: Apache-2.0 +; MEC165xB SPI Image Generator configuration file +[SPI] +SPISizeMegabits = 128 + +[DEVICE] +DeviceSel = B +TagAddr0 = 0 +TagAddr1 = 0 +; BoardID is used by a Boot-ROM feature named PlatformID. By default PlatformID +; is disabled. If PlatformID is enabled in OTP Boot-ROM will check the image +; BoardID value with an OTP PlatformID value. Load is aborted if the ID's do +; not match. +BoardID = 0x316 + +[IMAGE "0"] +ImageLocation = 0x2000 +SpiFreqMHz = 24 +SpiReadCommand = slow +SpiDriveStrength = 4 +SpiSlewFast = false +SpiSignalControl = 0x00 +IMG1BinFile = zephyr.bin +ImageRevision = 0 +FwOffset = 0 +IMG1LoadAddress = 0xC0000 +IMG1EntryAddress = 0 +UseECDSA = false +AuthenticateKeySelt = 5 +AutoKeyRevEn = true +KeyRevPermission = 0xff +AutoRollBackProtEn = false +RollbackProtPerm031000 = 0 +RollbackProtPerm063032 = 0 +RollbackProtPerm095063 = 0 +RollbackProtPerm127096 = 0 +ECDSAPrivKeyFile = ECC384r.pem +ECDSAPrivKeyPassword = MCHPECC384r +FwEncrypt = false +AesGenECPubKeyFile = ECC384r_crt.pem +TagBuildNumber= 0 +Comp0ProgDrvStrenEN = false +Comp0WritCmdTotByts = 0 +Comp0ReadCmdByte = 0 +Comp0WritCmdByte = 0 +Comp0DrvValue = 0 +Comp0DrvMask = 0 +Comp1ProgDrvStrenEN = false +Comp1WritCmdTotByts = 0 +Comp1ReadCmdByte = 0 +Comp1WritCmdByte = 0 +Comp1DrvValue = 0 +Comp1DrvMask = 0 + +[IMAGE "1"] +ImageLocation = 0x4000 +SpiFreqMHz = 12 +SpiReadCommand = slow +SpiDriveStrength = 4 +SpiSlewFast = false +SpiSignalControl = 0x00 +IMG1BinFile = zephyr.bin +ImageRevision = 0 +FwOffset = 0 +IMG1LoadAddress = 0xC0000 +IMG1EntryAddress = 0 +UseECDSA = false +AuthenticateKeySelt = 5 +AutoKeyRevEn = true +KeyRevPermission = 0 +AutoRollBackProtEn = false +RollbackProtPerm031000 = 0 +RollbackProtPerm063032 = 0 +RollbackProtPerm095063 = 0 +RollbackProtPerm127096 = 0 +ECDSAPrivKeyFile = ECC384r.pem +ECDSAPrivKeyPassword = MCHPECC384r +FwEncrypt = false +AesGenECPubKeyFile = ECC384r_crt.pem +TagBuildNumber= 0 +Comp0ProgDrvStrenEN = false +Comp0WritCmdTotByts = 0 +Comp0ReadCmdByte = 0 +Comp0WritCmdByte = 0 +Comp0DrvValue = 0 +Comp0DrvMask = 0 +Comp1ProgDrvStrenEN = false +Comp1WritCmdTotByts = 0 +Comp1ReadCmdByte = 0 +Comp1WritCmdByte = 0 +Comp1DrvValue = 0 +Comp1DrvMask = 0 From 4a30049073a6704f378d028b630842e11b6a4f39 Mon Sep 17 00:00:00 2001 From: Riadh Ghaddab Date: Wed, 21 Jan 2026 16:29:23 +0100 Subject: [PATCH 0307/6328] tests: nrf: add integration platform for rram_throttling Add the target nrf54l15dk/nrf54l15/cpuapp as the integration platform in the testcase yaml file. Signed-off-by: Riadh Ghaddab --- tests/boards/nrf/rram_throttling/testcase.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/boards/nrf/rram_throttling/testcase.yaml b/tests/boards/nrf/rram_throttling/testcase.yaml index 4ed53aac8c7b..4aee70d034b4 100644 --- a/tests/boards/nrf/rram_throttling/testcase.yaml +++ b/tests/boards/nrf/rram_throttling/testcase.yaml @@ -13,3 +13,5 @@ tests: platform_allow: - nrf54l15dk/nrf54l15/cpuapp - nrf54l15dk/nrf54l10/cpuapp + integration_platforms: + - nrf54l15dk/nrf54l15/cpuapp From 0228579f6f37736343515a545fd01a717d5884ab Mon Sep 17 00:00:00 2001 From: Scott Worley Date: Wed, 21 Jan 2026 08:34:10 -0500 Subject: [PATCH 0308/6328] dts: arm: microchip: mec: Fix compatible on last GPIO bank The compatible for the last GPIO banks in Microchip MEC5 chip DTSI was not changed when the GPIO driver was updated. We changed the compatible to the correct name. Signed-off-by: Scott Worley --- dts/arm/microchip/mec/mec5.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dts/arm/microchip/mec/mec5.dtsi b/dts/arm/microchip/mec/mec5.dtsi index 60de7b7afa6e..f644ec36c42d 100644 --- a/dts/arm/microchip/mec/mec5.dtsi +++ b/dts/arm/microchip/mec/mec5.dtsi @@ -220,7 +220,7 @@ }; gpio_240_276: gpio@40081280 { - compatible = "microchip,mec5-gpio"; + compatible = "microchip,xec-gpio"; reg = <0x40081280 0x80 0x40081314 0x04 0x40081394 0x04 0x400813e8 0x04>; gpio-controller; From f7d444bf26ef5e9c4a9caf56399577f04403153c Mon Sep 17 00:00:00 2001 From: Victor Luque Date: Wed, 21 Jan 2026 17:21:28 +0100 Subject: [PATCH 0309/6328] manifest: update hal_nordic to fix TWIM instance in samples Manifest update to pull fix for TWIM instance in TX-RX and TX-TX samples. Signed-off-by: Victor Luque --- west.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/west.yml b/west.yml index 53726d5ea1c2..d14802d07072 100644 --- a/west.yml +++ b/west.yml @@ -200,7 +200,7 @@ manifest: groups: - hal - name: hal_nordic - revision: a83db66acbeca0bfef157a0c3482c07ddbb82555 + revision: daad38f2e9f6c641849010d74fe02ea736d4d921 path: modules/hal/nordic groups: - hal From ce8e3c0a7e14a1f81da3cb34ee63598dad2b403b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Wed, 21 Jan 2026 22:11:15 +0100 Subject: [PATCH 0310/6328] drivers: spi: adopt SHELL_HELP in spi shell module MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Use SHELL_HELP macro for help strings to ensure consistency across various shell modules and to save on code size. Signed-off-by: Benjamin Cabé --- drivers/spi/spi_shell.c | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/drivers/spi/spi_shell.c b/drivers/spi/spi_shell.c index d9c812380fec..436a5a2d2552 100644 --- a/drivers/spi/spi_shell.c +++ b/drivers/spi/spi_shell.c @@ -421,24 +421,24 @@ static int cmd_spi_conf_cs(const struct shell *ctx, size_t argc, char **argv) SHELL_STATIC_SUBCMD_SET_CREATE( sub_spi_cmds, SHELL_CMD_ARG(conf, &dsub_get_spi_shell_device_name, - "Configure SPI\n" - "Usage: spi conf []\n" - " - any sequence of letters:\n" - "o - SPI_MODE_CPOL\n" - "h - SPI_MODE_CPHA\n" - "l - SPI_TRANSFER_LSB\n" - "T - SPI_FRAME_FORMAT_TI\n" - "example: spi conf spi1 1000000 ol", + SHELL_HELP("Configure SPI bus", + " []\n" + " any sequence of letters:\n" + "o - SPI_MODE_CPOL\n" + "h - SPI_MODE_CPHA\n" + "l - SPI_TRANSFER_LSB\n" + "T - SPI_FRAME_FORMAT_TI\n" + "Example: spi conf spi1 1000000 ol"), cmd_spi_conf, 3, 1), SHELL_CMD_ARG(cs, &dsub_get_spi_shell_device_name_and_set_gpio_dsub, - "Assign CS GPIO to SPI device\n" - "Usage: spi cs []\n" - "example: spi cs spi1 gpio1 3 0x01", + SHELL_HELP("Assign CS GPIO to SPI device", + " []\n" + "Example: spi cs spi1 gpio1 3 0x01"), cmd_spi_conf_cs, 4, 1), SHELL_CMD_ARG(transceive, &dsub_get_spi_shell_device_name, - "Transceive data to and from an SPI device\n" - "Usage: spi transceive [ ...]\n" - "example: spi transceive spi1 0x00 0x01", + SHELL_HELP("Transceive data to/from SPI device", + " [ ...]\n" + "Example: spi transceive spi1 0x00 0x01"), cmd_spi_transceive, 3, MAX_SPI_BYTES - 1), SHELL_SUBCMD_SET_END); From 2cee3420b8a7ea606ae0be685dc5cec069a8f1d6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Wed, 21 Jan 2026 22:18:38 +0100 Subject: [PATCH 0311/6328] drivers: ptp: adopt SHELL_HELP in ptp shell module MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Use SHELL_HELP macro for help strings to ensure consistency across various shell modules and to save on code size. Signed-off-by: Benjamin Cabé --- drivers/ptp_clock/ptp_clock_shell.c | 39 +++++++++++++++-------------- 1 file changed, 20 insertions(+), 19 deletions(-) diff --git a/drivers/ptp_clock/ptp_clock_shell.c b/drivers/ptp_clock/ptp_clock_shell.c index c8bc0735ce75..35a1658942b3 100644 --- a/drivers/ptp_clock/ptp_clock_shell.c +++ b/drivers/ptp_clock/ptp_clock_shell.c @@ -225,29 +225,30 @@ static int cmd_ptp_clock_selftest(const struct shell *sh, size_t argc, char **ar SHELL_STATIC_SUBCMD_SET_CREATE(sub_ptp_clock_cmds, SHELL_CMD_ARG(get, &dsub_device_name, - "Get time: get ", - cmd_ptp_clock_get, 2, 0), + SHELL_HELP("Get current time", ""), + cmd_ptp_clock_get, 2, 0), SHELL_CMD_ARG(set, &dsub_device_name, - "Set time: set ", - cmd_ptp_clock_set, 3, 0), + SHELL_HELP("Set time", " "), + cmd_ptp_clock_set, 3, 0), SHELL_CMD_ARG(adj, &dsub_device_name, - "Adjust time: adj ", - cmd_ptp_clock_adj, 3, 0), + SHELL_HELP("Adjust time", " "), + cmd_ptp_clock_adj, 3, 0), SHELL_CMD_ARG(freq, &dsub_device_name, - "Adjust frequency: freq ", - cmd_ptp_clock_freq, 3, 0), + SHELL_HELP("Adjust frequency", " "), + cmd_ptp_clock_freq, 3, 0), SHELL_CMD_ARG(selftest, &dsub_device_name, - "selftest