From 33d1792e3db5ccb01d5a64ad7a3f14f36f65dfe8 Mon Sep 17 00:00:00 2001 From: Andriy Gelman Date: Wed, 26 Oct 2022 12:00:06 -0400 Subject: [PATCH] drivers: spi: Add xmc4xxx driver Adds spi driver for xmc4xxx SoCs. Signed-off-by: Andriy Gelman --- boards/arm/xmc45_relax_kit/doc/index.rst | 2 + drivers/spi/CMakeLists.txt | 1 + drivers/spi/Kconfig | 2 + drivers/spi/Kconfig.xmc4xxx | 20 + drivers/spi/spi_xmc4xxx.c | 366 ++++++++++++++++++ .../infineon/xmc4500_F100x1024-pinctrl.dtsi | 113 ++++++ dts/bindings/spi/infineon,xmc4xxx-spi.yaml | 43 ++ modules/Kconfig.infineon | 5 + soc/arm/infineon_xmc/4xxx/Kconfig.series | 1 + 9 files changed, 553 insertions(+) create mode 100644 drivers/spi/Kconfig.xmc4xxx create mode 100644 drivers/spi/spi_xmc4xxx.c create mode 100644 dts/bindings/spi/infineon,xmc4xxx-spi.yaml diff --git a/boards/arm/xmc45_relax_kit/doc/index.rst b/boards/arm/xmc45_relax_kit/doc/index.rst index 59a37bc2b6a..ee107a66fb9 100644 --- a/boards/arm/xmc45_relax_kit/doc/index.rst +++ b/boards/arm/xmc45_relax_kit/doc/index.rst @@ -43,6 +43,8 @@ The Relax Kit development board configuration supports the following hardware fe +-----------+------------+-----------------------+ | UART | on-chip | serial port | +-----------+------------+-----------------------+ +| SPI | on-chip | spi | ++-----------+------------+-----------------------+ More details about the supported peripherals are available in `XMC4500 TRM`_ Other hardware features are not currently supported by the Zephyr kernel. diff --git a/drivers/spi/CMakeLists.txt b/drivers/spi/CMakeLists.txt index 6c2f4df1881..54a2d5f569a 100644 --- a/drivers/spi/CMakeLists.txt +++ b/drivers/spi/CMakeLists.txt @@ -34,6 +34,7 @@ zephyr_library_sources_ifdef(CONFIG_SPI_MCHP_QSPI spi_mchp_mss_qspi.c) zephyr_library_sources_ifdef(CONFIG_SPI_PL022 spi_pl022.c) zephyr_library_sources_ifdef(CONFIG_SPI_ANDES_ATCSPI200 spi_andes_atcspi200.c) zephyr_library_sources_ifdef(CONFIG_NXP_S32_SPI spi_nxp_s32.c) +zephyr_library_sources_ifdef(CONFIG_SPI_XMC4XXX spi_xmc4xxx.c) zephyr_library_sources_ifdef(CONFIG_SPI_ASYNC spi_signal.c) zephyr_library_sources_ifdef(CONFIG_USERSPACE spi_handlers.c) diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig index a1f46d02738..df2fa6a5c82 100644 --- a/drivers/spi/Kconfig +++ b/drivers/spi/Kconfig @@ -107,4 +107,6 @@ source "drivers/spi/Kconfig.andes_atcspi200" source "drivers/spi/Kconfig.nxp_s32" +source "drivers/spi/Kconfig.xmc4xxx" + endif # SPI diff --git a/drivers/spi/Kconfig.xmc4xxx b/drivers/spi/Kconfig.xmc4xxx new file mode 100644 index 00000000000..b34fc3943e6 --- /dev/null +++ b/drivers/spi/Kconfig.xmc4xxx @@ -0,0 +1,20 @@ +# Copyright (c) 2022 Schlumberger +# SPDX-License-Identifier: Apache-2.0 + +menuconfig SPI_XMC4XXX + bool "XMC4XX SPI driver" + default y + depends on DT_HAS_INFINEON_XMC4XXX_SPI_ENABLED + select GPIO + help + Enable XMC4XXX SPI driver. + + +if SPI_XMC4XXX + +config SPI_XMC4XXX_INTERRUPT + bool "XMC4XXX SPI interrupt mode" + help + Enables interrupt support for XMC4XXX SPI driver. + +endif # SPI_XMC4XXX diff --git a/drivers/spi/spi_xmc4xxx.c b/drivers/spi/spi_xmc4xxx.c new file mode 100644 index 00000000000..fe039701f15 --- /dev/null +++ b/drivers/spi/spi_xmc4xxx.c @@ -0,0 +1,366 @@ +/* + * Copyright (c) 2022 Schlumberger + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT infineon_xmc4xxx_spi + +#define LOG_LEVEL CONFIG_SPI_LOG_LEVEL +#include +LOG_MODULE_REGISTER(spi_xmc4xxx); + +#include "spi_context.h" + +#include +#include + +#include +#include + +struct spi_xmc4xxx_config { + XMC_USIC_CH_t *spi; + const struct pinctrl_dev_config *pcfg; + uint8_t miso_src; +#if defined(CONFIG_SPI_XMC4XXX_INTERRUPT) + void (*irq_config_func)(const struct device *dev); +#endif +}; + +struct spi_xmc4xxx_data { + struct spi_context ctx; +}; + +static void spi_xmc4xxx_shift_frames(const struct device *dev) +{ + struct spi_xmc4xxx_data *data = dev->data; + const struct spi_xmc4xxx_config *config = dev->config; + struct spi_context *ctx = &data->ctx; + uint8_t tx_data = 0; + uint8_t rx_data; + uint32_t status; + + if (spi_context_tx_buf_on(ctx)) { + tx_data = ctx->tx_buf[0]; + } + + XMC_SPI_CH_ClearStatusFlag(config->spi, + XMC_SPI_CH_STATUS_FLAG_TRANSMIT_SHIFT_INDICATION | + XMC_SPI_CH_STATUS_FLAG_RECEIVE_INDICATION | + XMC_SPI_CH_STATUS_FLAG_ALTERNATIVE_RECEIVE_INDICATION); + + XMC_SPI_CH_Transmit(config->spi, tx_data, XMC_SPI_CH_MODE_STANDARD); + + spi_context_update_tx(ctx, 1, 1); + +#if defined(CONFIG_SPI_XMC4XXX_INTERRUPT) + return; +#endif + + /* Wait to finish transmitting */ + while (1) { + status = XMC_SPI_CH_GetStatusFlag(config->spi); + if (status & XMC_SPI_CH_STATUS_FLAG_TRANSMIT_SHIFT_INDICATION) { + break; + } + } + + /* Wait to finish receiving */ + while (1) { + status = XMC_SPI_CH_GetStatusFlag(config->spi); + if (status & (XMC_SPI_CH_STATUS_FLAG_RECEIVE_INDICATION | + XMC_SPI_CH_STATUS_FLAG_ALTERNATIVE_RECEIVE_INDICATION)) { + break; + } + } + + rx_data = XMC_SPI_CH_GetReceivedData(config->spi); + + if (spi_context_rx_buf_on(ctx)) { + *ctx->rx_buf = rx_data; + } + spi_context_update_rx(ctx, 1, 1); +} + +#if defined(CONFIG_SPI_XMC4XXX_INTERRUPT) +static void spi_xmc4xxx_isr(const struct device *dev) +{ + struct spi_xmc4xxx_data *data = dev->data; + const struct spi_xmc4xxx_config *config = dev->config; + struct spi_context *ctx = &data->ctx; + uint8_t rx_data; + + rx_data = XMC_SPI_CH_GetReceivedData(config->spi); + + if (spi_context_rx_buf_on(ctx)) { + *ctx->rx_buf = rx_data; + } + spi_context_update_rx(ctx, 1, 1); + + if (spi_context_tx_on(ctx) || spi_context_rx_on(ctx)) { + spi_xmc4xxx_shift_frames(dev); + return; + } + + if (!(ctx->config->operation & SPI_HOLD_ON_CS)) { + spi_context_cs_control(ctx, false); + } + + spi_context_complete(ctx, dev, 0); +} +#endif + +#define LOOPBACK_SRC 6 +static int spi_xmc4xxx_configure(const struct device *dev, const struct spi_config *spi_cfg) +{ + int ret; + struct spi_xmc4xxx_data *data = dev->data; + const struct spi_xmc4xxx_config *config = dev->config; + struct spi_context *ctx = &data->ctx; + uint16_t settings = spi_cfg->operation; + bool CPOL = SPI_MODE_GET(settings) & SPI_MODE_CPOL; + bool CPHA = SPI_MODE_GET(settings) & SPI_MODE_CPHA; + XMC_SPI_CH_CONFIG_t usic_cfg = {.baudrate = spi_cfg->frequency}; + XMC_SPI_CH_BRG_SHIFT_CLOCK_PASSIVE_LEVEL_t clock_settings; + + if (spi_context_configured(ctx, spi_cfg)) { + return 0; + } + + ctx->config = spi_cfg; + + if (spi_cfg->operation & SPI_HALF_DUPLEX) { + LOG_ERR("Half-duplex not supported"); + return -ENOTSUP; + } + + if (spi_cfg->operation & SPI_OP_MODE_SLAVE) { + LOG_ERR("Slave mode not supported"); + return -ENOTSUP; + } + + if (SPI_WORD_SIZE_GET(spi_cfg->operation) != 8) { + LOG_ERR("Only 8 bit word size is supported"); + return -ENOTSUP; + } + + ret = XMC_SPI_CH_Stop(config->spi); + if (ret != XMC_SPI_CH_STATUS_OK) { + return -EBUSY; + } + XMC_SPI_CH_Init(config->spi, &usic_cfg); + XMC_SPI_CH_Start(config->spi); + + if (SPI_MODE_GET(settings) & SPI_MODE_LOOP) { + XMC_SPI_CH_SetInputSource(config->spi, XMC_SPI_CH_INPUT_DIN0, LOOPBACK_SRC); + } else { + XMC_SPI_CH_SetInputSource(config->spi, XMC_SPI_CH_INPUT_DIN0, config->miso_src); + } + + if (!CPOL && !CPHA) { + clock_settings = XMC_SPI_CH_BRG_SHIFT_CLOCK_PASSIVE_LEVEL_0_DELAY_ENABLED; + } else if (!CPOL && CPHA) { + clock_settings = XMC_SPI_CH_BRG_SHIFT_CLOCK_PASSIVE_LEVEL_0_DELAY_DISABLED; + } else if (CPOL && !CPHA) { + clock_settings = XMC_SPI_CH_BRG_SHIFT_CLOCK_PASSIVE_LEVEL_1_DELAY_ENABLED; + } else if (CPOL && CPHA) { + clock_settings = XMC_SPI_CH_BRG_SHIFT_CLOCK_PASSIVE_LEVEL_1_DELAY_DISABLED; + } + XMC_SPI_CH_ConfigureShiftClockOutput(config->spi, clock_settings, + XMC_SPI_CH_BRG_SHIFT_CLOCK_OUTPUT_SCLK); + + if (settings & SPI_TRANSFER_LSB) { + XMC_SPI_CH_SetBitOrderLsbFirst(config->spi); + } else { + XMC_SPI_CH_SetBitOrderMsbFirst(config->spi); + } + + XMC_SPI_CH_SetWordLength(config->spi, 8); + + return 0; +} + +static int spi_xmc4xxx_transceive(const struct device *dev, const struct spi_config *spi_cfg, + const struct spi_buf_set *tx_bufs, + const struct spi_buf_set *rx_bufs, + bool asynchronous, spi_callback_t cb, void *userdata) +{ + struct spi_xmc4xxx_data *data = dev->data; + const struct spi_xmc4xxx_config *config = dev->config; + struct spi_context *ctx = &data->ctx; + uint32_t recv_status; + int ret; + + if (!tx_bufs && !rx_bufs) { + return 0; + } + +#ifndef CONFIG_SPI_XMC4XXX_INTERRUPT + if (asynchronous) { + return -ENOTSUP; + } +#endif + + spi_context_lock(ctx, asynchronous, cb, userdata, spi_cfg); + + ret = spi_xmc4xxx_configure(dev, spi_cfg); + if (ret) { + LOG_DBG("SPI config on device %s failed\n", dev->name); + spi_context_release(ctx, ret); + return ret; + } + + /* flush out any received bytes */ + recv_status = XMC_USIC_CH_GetReceiveBufferStatus(config->spi); + if (recv_status & USIC_CH_RBUFSR_RDV0_Msk) { + XMC_SPI_CH_GetReceivedData(config->spi); + } + if (recv_status & USIC_CH_RBUFSR_RDV1_Msk) { + XMC_SPI_CH_GetReceivedData(config->spi); + } + + spi_context_buffers_setup(ctx, tx_bufs, rx_bufs, 1); + + spi_context_cs_control(ctx, true); + +#if defined(CONFIG_SPI_XMC4XXX_INTERRUPT) + XMC_SPI_CH_EnableEvent(config->spi, XMC_SPI_CH_EVENT_STANDARD_RECEIVE | + XMC_SPI_CH_EVENT_ALTERNATIVE_RECEIVE); + spi_xmc4xxx_shift_frames(dev); + ret = spi_context_wait_for_completion(ctx); + /* cs released in isr */ +#else + while (spi_context_tx_on(ctx) || spi_context_rx_on(ctx)) { + spi_xmc4xxx_shift_frames(dev); + } + + if (!(spi_cfg->operation & SPI_HOLD_ON_CS)) { + spi_context_cs_control(ctx, false); + } +#endif + + spi_context_release(ctx, ret); + + return ret; +} + +#if defined(CONFIG_SPI_ASYNC) +static int spi_xmc4xxx_transceive_async(const struct device *dev, const struct spi_config *spi_cfg, + const struct spi_buf_set *tx_bufs, + const struct spi_buf_set *rx_bufs, + spi_callback_t cb, + void *userdata) +{ + return spi_xmc4xxx_transceive(dev, spi_cfg, tx_bufs, rx_bufs, true, cb, userdata); +} +#endif + +static int spi_xmc4xxx_transceive_sync(const struct device *dev, const struct spi_config *spi_cfg, + const struct spi_buf_set *tx_bufs, + const struct spi_buf_set *rx_bufs) +{ + return spi_xmc4xxx_transceive(dev, spi_cfg, tx_bufs, rx_bufs, false, NULL, NULL); +} + +static int spi_xmc4xxx_release(const struct device *dev, const struct spi_config *config) +{ + struct spi_xmc4xxx_data *data = dev->data; + + if (!spi_context_configured(&data->ctx, config)) { + return -EINVAL; + } + + spi_context_unlock_unconditionally(&data->ctx); + return 0; +} + +static int spi_xmc4xxx_init(const struct device *dev) +{ + struct spi_xmc4xxx_data *data = dev->data; + const struct spi_xmc4xxx_config *config = dev->config; + int ret; + + XMC_USIC_CH_Enable(config->spi); + + spi_context_unlock_unconditionally(&data->ctx); + +#if defined(CONFIG_SPI_XMC4XXX_INTERRUPT) + config->irq_config_func(dev); +#endif + + ret = pinctrl_apply_state(config->pcfg, PINCTRL_STATE_DEFAULT); + if (ret < 0) { + return ret; + } + + XMC_SPI_CH_SetInputSource(config->spi, XMC_SPI_CH_INPUT_DIN0, config->miso_src); + spi_context_cs_configure_all(&data->ctx); + + return 0; +} + +static const struct spi_driver_api spi_xmc4xxx_driver_api = { + .transceive = spi_xmc4xxx_transceive_sync, +#if defined(CONFIG_SPI_ASYNC) + .transceive_async = spi_xmc4xxx_transceive_async, +#endif + .release = spi_xmc4xxx_release, +}; + +#if defined(CONFIG_SPI_XMC4XXX_INTERRUPT) + +#define USIC_IRQ_MIN 84 +#define IRQS_PER_USIC 6 + +#define XMC4XXX_IRQ_HANDLER_INIT(index) \ + static void spi_xmc4xxx_irq_setup_##index(const struct device *dev) \ + { \ + const struct spi_xmc4xxx_config *config = dev->config; \ + uint8_t service_request; \ + uint8_t irq_num; \ + \ + irq_num = DT_INST_IRQ_BY_NAME(index, rx, irq); \ + service_request = (irq_num - USIC_IRQ_MIN) % IRQS_PER_USIC; \ + \ + XMC_SPI_CH_SelectInterruptNodePointer( \ + config->spi, XMC_SPI_CH_INTERRUPT_NODE_POINTER_RECEIVE, service_request); \ + XMC_SPI_CH_SelectInterruptNodePointer( \ + config->spi, XMC_SPI_CH_INTERRUPT_NODE_POINTER_ALTERNATE_RECEIVE, \ + service_request); \ + \ + XMC_SPI_CH_EnableEvent(config->spi, XMC_SPI_CH_EVENT_STANDARD_RECEIVE | \ + XMC_SPI_CH_EVENT_ALTERNATIVE_RECEIVE); \ + \ + IRQ_CONNECT(DT_INST_IRQ_BY_NAME(index, rx, irq), \ + DT_INST_IRQ_BY_NAME(index, rx, priority), spi_xmc4xxx_isr, \ + DEVICE_DT_INST_GET(index), 0); \ + irq_enable(DT_INST_IRQ_BY_NAME(index, rx, irq)); \ + } + +#define XMC4XXX_IRQ_HANDLER_STRUCT_INIT(index) .irq_config_func = spi_xmc4xxx_irq_setup_##index, + +#else +#define XMC4XXX_IRQ_HANDLER_INIT(index) +#define XMC4XXX_IRQ_HANDLER_STRUCT_INIT(index) +#endif + +#define XMC4XXX_INIT(index) \ + PINCTRL_DT_INST_DEFINE(index); \ + XMC4XXX_IRQ_HANDLER_INIT(index) \ + static struct spi_xmc4xxx_data xmc4xxx_data_##index = { \ + SPI_CONTEXT_CS_GPIOS_INITIALIZE(DT_DRV_INST(index), ctx) \ + SPI_CONTEXT_INIT_LOCK(xmc4xxx_data_##index, ctx), \ + SPI_CONTEXT_INIT_SYNC(xmc4xxx_data_##index, ctx), \ + }; \ + \ + static const struct spi_xmc4xxx_config xmc4xxx_config_##index = { \ + .spi = (XMC_USIC_CH_t *)DT_INST_REG_ADDR(index), \ + .pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(index), \ + .miso_src = DT_INST_ENUM_IDX(index, miso_src), \ + XMC4XXX_IRQ_HANDLER_STRUCT_INIT(index)}; \ + \ + DEVICE_DT_INST_DEFINE(index, &spi_xmc4xxx_init, NULL, &xmc4xxx_data_##index, \ + &xmc4xxx_config_##index, POST_KERNEL, \ + CONFIG_SPI_INIT_PRIORITY, &spi_xmc4xxx_driver_api); + +DT_INST_FOREACH_STATUS_OKAY(XMC4XXX_INIT) diff --git a/dts/arm/infineon/xmc4500_F100x1024-pinctrl.dtsi b/dts/arm/infineon/xmc4500_F100x1024-pinctrl.dtsi index fc8c8bea6d7..9b9e0a96542 100644 --- a/dts/arm/infineon/xmc4500_F100x1024-pinctrl.dtsi +++ b/dts/arm/infineon/xmc4500_F100x1024-pinctrl.dtsi @@ -86,4 +86,117 @@ /omit-if-no-ref/ uart_rx_p4_0_u2c1: uart_rx_p4_0_u2c1 { pinmux = ; /* USIC input src = DX0C */ }; + + /omit-if-no-ref/ spi_mosi_p0_1_u1c1: spi_mosi_p0_1_u1c1 { + pinmux = ; + }; + /omit-if-no-ref/ spi_mosi_p0_5_u1c0: spi_mosi_p0_5_u1c0 { + pinmux = ; + }; + /omit-if-no-ref/ spi_mosi_p1_5_u0c0: spi_mosi_p1_5_u0c0 { + pinmux = ; + }; + /omit-if-no-ref/ spi_mosi_p1_7_u0c0: spi_mosi_p1_7_u0c0 { + pinmux = ; + }; + /omit-if-no-ref/ spi_mosi_p2_5_u0c1: spi_mosi_p2_5_u0c1 { + pinmux = ; + }; + /omit-if-no-ref/ spi_mosi_p2_14_u1c0: spi_mosi_p2_14_u1c0 { + pinmux = ; + }; + /omit-if-no-ref/ spi_mosi_p3_5_u2c1: spi_mosi_p3_5_u2c1 { + pinmux = ; + }; + /omit-if-no-ref/ spi_mosi_p3_5_u0c1: spi_mosi_p3_5_u0c1 { + pinmux = ; + }; + /omit-if-no-ref/ spi_mosi_p5_0_u2c0: spi_mosi_p5_0_u2c0 { + pinmux = ; + }; + /omit-if-no-ref/ spi_mosi_p5_1_u0c0: spi_mosi_p5_1_u0c0 { + pinmux = ; + }; + + /omit-if-no-ref/ spi_miso_p1_4_u0c0: spi_miso_p1_4_u0c0 { + pinmux = ; /* USIC input src = DX0B */ + }; + /omit-if-no-ref/ spi_miso_p1_5_u0c0: spi_miso_p1_5_u0c0 { + pinmux = ; /* USIC input src = DX0A */ + }; + /omit-if-no-ref/ spi_miso_p5_0_u0c0: spi_miso_p5_0_u0c0 { + pinmux = ; /* USIC input src = DX0D */ + }; + /omit-if-no-ref/ spi_miso_p2_2_u0c1: spi_miso_p2_2_u0c1 { + pinmux = ; /* USIC input src = DX0A */ + }; + /omit-if-no-ref/ spi_miso_p2_5_u0c1: spi_miso_p2_5_u0c1 { + pinmux = ; /* USIC input src = DX0B */ + }; + /omit-if-no-ref/ spi_miso_p4_0_u0c1: spi_miso_p4_0_u0c1 { + pinmux = ; /* USIC input src = DX0E */ + }; + /omit-if-no-ref/ spi_miso_p0_4_u1c0: spi_miso_p0_4_u1c0 { + pinmux = ; /* USIC input src = DX0A */ + }; + /omit-if-no-ref/ spi_miso_p0_5_u1c0: spi_miso_p0_5_u1c0 { + pinmux = ; /* USIC input src = DX0B */ + }; + /omit-if-no-ref/ spi_miso_p2_14_u1c0: spi_miso_p2_14_u1c0 { + pinmux = ; /* USIC input src = DX0D */ + }; + /omit-if-no-ref/ spi_miso_p2_15_u1c0: spi_miso_p2_15_u1c0 { + pinmux = ; /* USIC input src = DX0C */ + }; + /omit-if-no-ref/ spi_miso_p0_0_u1c1: spi_miso_p0_0_u1c1 { + pinmux = ; /* USIC input src = DX0D */ + }; + /omit-if-no-ref/ spi_miso_p5_0_u2c0: spi_miso_p5_0_u2c0 { + pinmux = ; /* USIC input src = DX0B */ + }; + /omit-if-no-ref/ spi_miso_p5_1_u2c0: spi_miso_p5_1_u2c0 { + pinmux = ; /* USIC input src = DX0A */ + }; + /omit-if-no-ref/ spi_miso_p3_4_u2c1: spi_miso_p3_4_u2c1 { + pinmux = ; /* USIC input src = DX0B */ + }; + /omit-if-no-ref/ spi_miso_p3_5_u2c1: spi_miso_p3_5_u2c1 { + pinmux = ; /* USIC input src = DX0A */ + }; + /omit-if-no-ref/ spi_miso_p4_0_u2c1: spi_miso_p4_0_u2c1 { + pinmux = ; /* USIC input src = DX0C */ + }; + /omit-if-no-ref/ spi_sclk_p0_8_u0c0: spi_sclk_p0_8_u0c0 { + pinmux = ; + }; + /omit-if-no-ref/ spi_sclk_p0_10_u1c1: spi_sclk_p0_10_u1c1 { + pinmux = ; + }; + /omit-if-no-ref/ spi_sclk_p0_11_u1c0: spi_sclk_p0_11_u1c0 { + pinmux = ; + }; + /omit-if-no-ref/ spi_sclk_p1_1_u0c0: spi_sclk_p1_1_u0c0 { + pinmux = ; + }; + /omit-if-no-ref/ spi_sclk_p1_6_u0c0: spi_sclk_p1_6_u0c0 { + pinmux = ; + }; + /omit-if-no-ref/ spi_sclk_p1_10_u0c0: spi_sclk_p1_10_u0c0 { + pinmux = ; + }; + /omit-if-no-ref/ spi_sclk_p2_4_u0c1: spi_sclk_p2_4_u0c1 { + pinmux = ; + }; + /omit-if-no-ref/ spi_sclk_p3_0_u0c1: spi_sclk_p3_0_u0c1 { + pinmux = ; + }; + /omit-if-no-ref/ spi_sclk_p3_6_u2c1: spi_sclk_p3_6_u2c1 { + pinmux = ; + }; + /omit-if-no-ref/ spi_sclk_p3_6_u0c1: spi_sclk_p3_6_u0c1 { + pinmux = ; + }; + /omit-if-no-ref/ spi_sclk_p5_2_u2c0: spi_sclk_p5_2_u2c0 { + pinmux = ; + }; }; diff --git a/dts/bindings/spi/infineon,xmc4xxx-spi.yaml b/dts/bindings/spi/infineon,xmc4xxx-spi.yaml new file mode 100644 index 00000000000..d12a7ac82b5 --- /dev/null +++ b/dts/bindings/spi/infineon,xmc4xxx-spi.yaml @@ -0,0 +1,43 @@ +# Copyright (c) 2022 Schlumberger +# SPDX-License-Identifier: Apache-2.0 + +description: INFINEON XMC4XXX SPI controller + +compatible: "infineon,xmc4xxx-spi" + +include: [spi-controller.yaml, pinctrl-device.yaml] + +properties: + reg: + required: true + + miso-src: + description: | + Connects the SPI miso line (USIC DX0 input) to a specific GPIO pin. + The USIC DX0 input is a multiplexer which connects to different GPIO pins. + Refer to the XMC4XXX reference manual for the GPIO pin/mux mappings. DX0G + is the loopback input line. + type: string + required: true + enum: + - "DX0A" + - "DX0B" + - "DX0C" + - "DX0D" + - "DX0E" + - "DX0F" + - "DX0G" + + interrupts: + description: | + IRQ number and priority to use for interrupt driven UART. + USIC0..2 have their own interrupt range as follows: + USIC0 = [84, 89] + USIC1 = [90, 95] + USIC2 = [96, 101] + + pinctrl-0: + required: true + + pinctrl-names: + required: true diff --git a/modules/Kconfig.infineon b/modules/Kconfig.infineon index 3b2f8b51c8d..0268a8db008 100644 --- a/modules/Kconfig.infineon +++ b/modules/Kconfig.infineon @@ -35,4 +35,9 @@ config HAS_XMCLIB_DMA help Enable XMCLIB DMA +config HAS_XMCLIB_SPI + bool + help + Enable XMCLIB SPI + endif # HAS_XMCLIB diff --git a/soc/arm/infineon_xmc/4xxx/Kconfig.series b/soc/arm/infineon_xmc/4xxx/Kconfig.series index 76facd3384b..4e130ba3563 100644 --- a/soc/arm/infineon_xmc/4xxx/Kconfig.series +++ b/soc/arm/infineon_xmc/4xxx/Kconfig.series @@ -17,5 +17,6 @@ config SOC_SERIES_XMC_4XXX select HAS_XMCLIB_ERU select HAS_XMCLIB_VADC select HAS_XMCLIB_DMA + select HAS_XMCLIB_SPI help Enable support for XMC 4xxx MCU series