|  | /* | 
|  | * Copyright (c) 2022 Cypress Semiconductor Corporation (an Infineon company) or | 
|  | * an affiliate of Cypress Semiconductor Corporation | 
|  | * | 
|  | * SPDX-License-Identifier: Apache-2.0 | 
|  | */ | 
|  |  | 
|  | /** | 
|  | * @brief UART driver for Infineon CAT1 MCU family. | 
|  | * | 
|  | * Note: | 
|  | * - Uart ASYNC functionality is not implemented in current | 
|  | *   version of Uart CAT1 driver. | 
|  | */ | 
|  |  | 
|  | #define DT_DRV_COMPAT infineon_cat1_uart | 
|  |  | 
|  | #include <zephyr/drivers/uart.h> | 
|  | #include <zephyr/drivers/pinctrl.h> | 
|  | #include <cyhal_uart.h> | 
|  | #include <cyhal_utils_psoc.h> | 
|  | #include <cyhal_scb_common.h> | 
|  |  | 
|  | /* Data structure */ | 
|  | struct ifx_cat1_uart_data { | 
|  | cyhal_uart_t obj;                               /* UART CYHAL object */ | 
|  | struct uart_config cfg; | 
|  | cyhal_resource_inst_t hw_resource; | 
|  | cyhal_clock_t clock; | 
|  |  | 
|  | #if CONFIG_UART_INTERRUPT_DRIVEN | 
|  | uart_irq_callback_user_data_t irq_cb;           /* Interrupt Callback */ | 
|  | void *irq_cb_data;                              /* Interrupt Callback Arg */ | 
|  | #endif /* CONFIG_UART_INTERRUPT_DRIVEN */ | 
|  | }; | 
|  |  | 
|  | /* Device config structure */ | 
|  | struct ifx_cat1_uart_config { | 
|  | const struct pinctrl_dev_config *pcfg; | 
|  | CySCB_Type *reg_addr; | 
|  | struct uart_config dt_cfg; | 
|  | uint8_t irq_priority; | 
|  | }; | 
|  |  | 
|  | /* Default Counter configuration structure */ | 
|  | static const cy_stc_scb_uart_config_t _cyhal_uart_default_config = { | 
|  | .uartMode = CY_SCB_UART_STANDARD, | 
|  | .enableMutliProcessorMode = false, | 
|  | .smartCardRetryOnNack = false, | 
|  | .irdaInvertRx = false, | 
|  | .irdaEnableLowPowerReceiver = false, | 
|  | .oversample = 12, | 
|  | .enableMsbFirst = false, | 
|  | .dataWidth = 8UL, | 
|  | .parity = CY_SCB_UART_PARITY_NONE, | 
|  | .stopBits = CY_SCB_UART_STOP_BITS_1, | 
|  | .enableInputFilter = false, | 
|  | .breakWidth = 11UL, | 
|  | .dropOnFrameError = false, | 
|  | .dropOnParityError = false, | 
|  |  | 
|  | .receiverAddress = 0x0UL, | 
|  | .receiverAddressMask = 0x0UL, | 
|  | .acceptAddrInFifo = false, | 
|  |  | 
|  | .enableCts = false, | 
|  | .ctsPolarity = CY_SCB_UART_ACTIVE_LOW, | 
|  | #if defined(COMPONENT_CAT1A) || defined(COMPONENT_CAT1B) | 
|  | .rtsRxFifoLevel = 20UL, | 
|  | #elif defined(COMPONENT_CAT2) | 
|  | .rtsRxFifoLevel = 3UL, | 
|  | #endif | 
|  | .rtsPolarity = CY_SCB_UART_ACTIVE_LOW, | 
|  |  | 
|  | /* Level triggers when at least one element is in FIFO */ | 
|  | .rxFifoTriggerLevel = 0UL, | 
|  | .rxFifoIntEnableMask = 0x0UL, | 
|  |  | 
|  | /* Level triggers when half-fifo is half empty */ | 
|  | .txFifoTriggerLevel = (CY_SCB_FIFO_SIZE / 2 - 1), | 
|  | .txFifoIntEnableMask = 0x0UL | 
|  | }; | 
|  |  | 
|  | /* Helper API */ | 
|  | static cyhal_uart_parity_t _convert_uart_parity_z_to_cyhal(enum uart_config_parity parity) | 
|  | { | 
|  | cyhal_uart_parity_t cyhal_parity; | 
|  |  | 
|  | switch (parity) { | 
|  | case UART_CFG_PARITY_NONE: | 
|  | cyhal_parity = CYHAL_UART_PARITY_NONE; | 
|  | break; | 
|  | case UART_CFG_PARITY_ODD: | 
|  | cyhal_parity = CYHAL_UART_PARITY_ODD; | 
|  | break; | 
|  | case UART_CFG_PARITY_EVEN: | 
|  | cyhal_parity = CYHAL_UART_PARITY_EVEN; | 
|  | break; | 
|  | default: | 
|  | cyhal_parity = CYHAL_UART_PARITY_NONE; | 
|  | } | 
|  | return cyhal_parity; | 
|  | } | 
|  |  | 
|  | static uint32_t _convert_uart_stop_bits_z_to_cyhal(enum uart_config_stop_bits stop_bits) | 
|  | { | 
|  | uint32_t cyhal_stop_bits; | 
|  |  | 
|  | switch (stop_bits) { | 
|  | case UART_CFG_STOP_BITS_1: | 
|  | cyhal_stop_bits = 1u; | 
|  | break; | 
|  |  | 
|  | case UART_CFG_STOP_BITS_2: | 
|  | cyhal_stop_bits = 2u; | 
|  | break; | 
|  | default: | 
|  | cyhal_stop_bits = 1u; | 
|  | } | 
|  | return cyhal_stop_bits; | 
|  | } | 
|  |  | 
|  | static uint32_t _convert_uart_data_bits_z_to_cyhal(enum uart_config_data_bits data_bits) | 
|  | { | 
|  | uint32_t cyhal_data_bits; | 
|  |  | 
|  | switch (data_bits) { | 
|  | case UART_CFG_DATA_BITS_5: | 
|  | cyhal_data_bits = 1u; | 
|  | break; | 
|  |  | 
|  | case UART_CFG_DATA_BITS_6: | 
|  | cyhal_data_bits = 6u; | 
|  | break; | 
|  |  | 
|  | case UART_CFG_DATA_BITS_7: | 
|  | cyhal_data_bits = 7u; | 
|  | break; | 
|  |  | 
|  | case UART_CFG_DATA_BITS_8: | 
|  | cyhal_data_bits = 8u; | 
|  | break; | 
|  |  | 
|  | case UART_CFG_DATA_BITS_9: | 
|  | cyhal_data_bits = 9u; | 
|  | break; | 
|  |  | 
|  | default: | 
|  | cyhal_data_bits = 1u; | 
|  | } | 
|  | return cyhal_data_bits; | 
|  | } | 
|  |  | 
|  | static int32_t _get_hw_block_num(CySCB_Type *reg_addr) | 
|  | { | 
|  | uint32_t i; | 
|  |  | 
|  | for (i = 0u; i < _SCB_ARRAY_SIZE; i++) { | 
|  | if (_CYHAL_SCB_BASE_ADDRESSES[i] == reg_addr) { | 
|  | return i; | 
|  | } | 
|  | } | 
|  |  | 
|  | return -1; | 
|  | } | 
|  |  | 
|  | static int ifx_cat1_uart_poll_in(const struct device *dev, unsigned char *c) | 
|  | { | 
|  | cy_rslt_t rec; | 
|  | struct ifx_cat1_uart_data *data = dev->data; | 
|  |  | 
|  | rec = cyhal_uart_getc(&data->obj, c, 0u); | 
|  |  | 
|  | return ((rec == CY_SCB_UART_RX_NO_DATA) ? -1 : 0); | 
|  | } | 
|  |  | 
|  | static void ifx_cat1_uart_poll_out(const struct device *dev, unsigned char c) | 
|  | { | 
|  | struct ifx_cat1_uart_data *data = dev->data; | 
|  |  | 
|  | (void) cyhal_uart_putc(&data->obj, (uint32_t)c); | 
|  | } | 
|  |  | 
|  | static int ifx_cat1_uart_err_check(const struct device *dev) | 
|  | { | 
|  | struct ifx_cat1_uart_data *data = dev->data; | 
|  | uint32_t status = Cy_SCB_UART_GetRxFifoStatus(data->obj.base); | 
|  | int errors = 0; | 
|  |  | 
|  | if (status & CY_SCB_UART_RX_OVERFLOW) { | 
|  | errors |= UART_ERROR_OVERRUN; | 
|  | } | 
|  |  | 
|  | if (status & CY_SCB_UART_RX_ERR_PARITY) { | 
|  | errors |= UART_ERROR_PARITY; | 
|  | } | 
|  |  | 
|  | if (status & CY_SCB_UART_RX_ERR_FRAME) { | 
|  | errors |= UART_ERROR_FRAMING; | 
|  | } | 
|  |  | 
|  | return errors; | 
|  | } | 
|  |  | 
|  | static int ifx_cat1_uart_configure(const struct device *dev, | 
|  | const struct uart_config *cfg) | 
|  | { | 
|  | __ASSERT_NO_MSG(cfg != NULL); | 
|  |  | 
|  | cy_rslt_t result; | 
|  | struct ifx_cat1_uart_data *data = dev->data; | 
|  |  | 
|  | cyhal_uart_cfg_t uart_cfg = { | 
|  | .data_bits = _convert_uart_data_bits_z_to_cyhal(cfg->data_bits), | 
|  | .stop_bits = _convert_uart_stop_bits_z_to_cyhal(cfg->stop_bits), | 
|  | .parity = _convert_uart_parity_z_to_cyhal(cfg->parity) | 
|  | }; | 
|  |  | 
|  | /* Store Uart Zephyr configuration (uart config) into data structure */ | 
|  | data->cfg = *cfg; | 
|  |  | 
|  | /* Configure parity, data and stop bits */ | 
|  | result = cyhal_uart_configure(&data->obj, &uart_cfg); | 
|  |  | 
|  | /* Configure the baud rate */ | 
|  | if (result == CY_RSLT_SUCCESS) { | 
|  | result = cyhal_uart_set_baud(&data->obj, cfg->baudrate, NULL); | 
|  | } | 
|  |  | 
|  | /* Enable RTS/CTS flow control */ | 
|  | if ((result == CY_RSLT_SUCCESS) && cfg->flow_ctrl) { | 
|  | result = cyhal_uart_enable_flow_control(&data->obj, true, true); | 
|  | } | 
|  |  | 
|  | return (result == CY_RSLT_SUCCESS) ? 0 : -ENOTSUP; | 
|  | }; | 
|  |  | 
|  | static int ifx_cat1_uart_config_get(const struct device *dev, | 
|  | struct uart_config *cfg) | 
|  | { | 
|  | ARG_UNUSED(dev); | 
|  |  | 
|  | struct ifx_cat1_uart_data *const data = dev->data; | 
|  |  | 
|  | if (cfg == NULL) { | 
|  | return -EINVAL; | 
|  | } | 
|  |  | 
|  | *cfg = data->cfg; | 
|  | return 0; | 
|  | } | 
|  |  | 
|  | #ifdef CONFIG_UART_INTERRUPT_DRIVEN | 
|  |  | 
|  | /* Uart event callback for Interrupt driven mode */ | 
|  | static void _uart_event_callback_irq_mode(void *arg, cyhal_uart_event_t event) | 
|  | { | 
|  | ARG_UNUSED(event); | 
|  |  | 
|  | const struct device *dev = (const struct device *) arg; | 
|  | struct ifx_cat1_uart_data *const data = dev->data; | 
|  |  | 
|  | if (data->irq_cb != NULL) { | 
|  | data->irq_cb(dev, data->irq_cb_data); | 
|  | } | 
|  | } | 
|  |  | 
|  | /* Fill FIFO with data */ | 
|  | static int ifx_cat1_uart_fifo_fill(const struct device *dev, | 
|  | const uint8_t *tx_data, int size) | 
|  | { | 
|  | struct ifx_cat1_uart_data *const data = dev->data; | 
|  | size_t _size = (size_t) size; | 
|  |  | 
|  | (void)cyhal_uart_write(&data->obj, (uint8_t *) tx_data,  &_size); | 
|  | return (int) _size; | 
|  | } | 
|  |  | 
|  | /* Read data from FIFO */ | 
|  | static int ifx_cat1_uart_fifo_read(const struct device *dev, | 
|  | uint8_t *rx_data, const int size) | 
|  | { | 
|  | struct ifx_cat1_uart_data *const data = dev->data; | 
|  | size_t _size = (size_t) size; | 
|  |  | 
|  | (void)cyhal_uart_read(&data->obj, rx_data, &_size); | 
|  | return (int) _size; | 
|  | } | 
|  |  | 
|  | /* Enable TX interrupt */ | 
|  | static void ifx_cat1_uart_irq_tx_enable(const struct device *dev) | 
|  | { | 
|  | struct ifx_cat1_uart_data *const data = dev->data; | 
|  | const struct ifx_cat1_uart_config *const config = dev->config; | 
|  |  | 
|  | cyhal_uart_enable_event(&data->obj, | 
|  | (cyhal_uart_event_t) CYHAL_UART_IRQ_TX_EMPTY, | 
|  | config->irq_priority, 1); | 
|  | } | 
|  |  | 
|  | /* Disable TX interrupt */ | 
|  | static void ifx_cat1_uart_irq_tx_disable(const struct device *dev) | 
|  | { | 
|  | struct ifx_cat1_uart_data *const data = dev->data; | 
|  | const struct ifx_cat1_uart_config *const config = dev->config; | 
|  |  | 
|  | cyhal_uart_enable_event(&data->obj, | 
|  | (cyhal_uart_event_t) CYHAL_UART_IRQ_TX_EMPTY, | 
|  | config->irq_priority, 0); | 
|  | } | 
|  |  | 
|  | /* Check if UART TX buffer can accept a new char */ | 
|  | static int ifx_cat1_uart_irq_tx_ready(const struct device *dev) | 
|  | { | 
|  | struct ifx_cat1_uart_data *const data = dev->data; | 
|  | uint32_t mask = Cy_SCB_GetTxInterruptStatusMasked(data->obj.base); | 
|  |  | 
|  | return (((mask & (CY_SCB_UART_TX_NOT_FULL | SCB_INTR_TX_EMPTY_Msk)) != 0u) ? 1 : 0); | 
|  | } | 
|  |  | 
|  | /* Check if UART TX block finished transmission */ | 
|  | static int ifx_cat1_uart_irq_tx_complete(const struct device *dev) | 
|  | { | 
|  | struct ifx_cat1_uart_data *const data = dev->data; | 
|  |  | 
|  | return (int) !(cyhal_uart_is_tx_active(&data->obj)); | 
|  | } | 
|  |  | 
|  | /* Enable RX interrupt */ | 
|  | static void ifx_cat1_uart_irq_rx_enable(const struct device *dev) | 
|  | { | 
|  | struct ifx_cat1_uart_data *const data = dev->data; | 
|  | const struct ifx_cat1_uart_config *const config = dev->config; | 
|  |  | 
|  | cyhal_uart_enable_event(&data->obj, | 
|  | (cyhal_uart_event_t) CYHAL_UART_IRQ_RX_NOT_EMPTY, | 
|  | config->irq_priority, 1); | 
|  | } | 
|  |  | 
|  | /* Disable TX interrupt */ | 
|  | static void ifx_cat1_uart_irq_rx_disable(const struct device *dev) | 
|  | { | 
|  | struct ifx_cat1_uart_data *const data = dev->data; | 
|  | const struct ifx_cat1_uart_config *const config = dev->config; | 
|  |  | 
|  | cyhal_uart_enable_event(&data->obj, | 
|  | (cyhal_uart_event_t) CYHAL_UART_IRQ_RX_NOT_EMPTY, | 
|  | config->irq_priority, 0); | 
|  | } | 
|  |  | 
|  | /* Check if UART RX buffer has a received char */ | 
|  | static int ifx_cat1_uart_irq_rx_ready(const struct device *dev) | 
|  | { | 
|  | struct ifx_cat1_uart_data *const data = dev->data; | 
|  |  | 
|  | return cyhal_uart_readable(&data->obj) ? 1 : 0; | 
|  | } | 
|  |  | 
|  | /* Enable Error interrupts */ | 
|  | static void ifx_cat1_uart_irq_err_enable(const struct device *dev) | 
|  | { | 
|  | struct ifx_cat1_uart_data *const data = dev->data; | 
|  | const struct ifx_cat1_uart_config *const config = dev->config; | 
|  |  | 
|  | cyhal_uart_enable_event(&data->obj, (cyhal_uart_event_t) | 
|  | (CYHAL_UART_IRQ_TX_ERROR | CYHAL_UART_IRQ_RX_ERROR), | 
|  | config->irq_priority, 1); | 
|  | } | 
|  |  | 
|  | /* Disable Error interrupts */ | 
|  | static void ifx_cat1_uart_irq_err_disable(const struct device *dev) | 
|  | { | 
|  | struct ifx_cat1_uart_data *const data = dev->data; | 
|  | const struct ifx_cat1_uart_config *const config = dev->config; | 
|  |  | 
|  | cyhal_uart_enable_event(&data->obj, (cyhal_uart_event_t) | 
|  | (CYHAL_UART_IRQ_TX_ERROR | CYHAL_UART_IRQ_RX_ERROR), | 
|  | config->irq_priority, 0); | 
|  | } | 
|  |  | 
|  | /* Check if any IRQs is pending */ | 
|  | static int ifx_cat1_uart_irq_is_pending(const struct device *dev) | 
|  | { | 
|  | struct ifx_cat1_uart_data *const data = dev->data; | 
|  | uint32_t intcause = Cy_SCB_GetInterruptCause(data->obj.base); | 
|  |  | 
|  | return (int) (intcause & (CY_SCB_TX_INTR | CY_SCB_RX_INTR)); | 
|  | } | 
|  |  | 
|  | /* Start processing interrupts in ISR. | 
|  | * This function should be called the first thing in the ISR. Calling | 
|  | * uart_irq_rx_ready(), uart_irq_tx_ready(), uart_irq_tx_complete() | 
|  | * allowed only after this. | 
|  | */ | 
|  | static int ifx_cat1_uart_irq_update(const struct device *dev) | 
|  | { | 
|  | struct ifx_cat1_uart_data *const data = dev->data; | 
|  | int status = 1; | 
|  |  | 
|  | if (((ifx_cat1_uart_irq_is_pending(dev) & CY_SCB_RX_INTR) != 0u) && | 
|  | (Cy_SCB_UART_GetNumInRxFifo(data->obj.base) == 0u)) { | 
|  | status = 0; | 
|  | } | 
|  |  | 
|  | return status; | 
|  | } | 
|  |  | 
|  | static void ifx_cat1_uart_irq_callback_set(const struct device *dev, | 
|  | uart_irq_callback_user_data_t cb, | 
|  | void *cb_data) | 
|  | { | 
|  | struct ifx_cat1_uart_data *data = dev->data; | 
|  | cyhal_uart_t *uart_obj = &data->obj; | 
|  |  | 
|  | /* Store user callback info */ | 
|  | data->irq_cb = cb; | 
|  | data->irq_cb_data = cb_data; | 
|  |  | 
|  | /* Register a uart general callback handler  */ | 
|  | cyhal_uart_register_callback(uart_obj, _uart_event_callback_irq_mode, (void *) dev); | 
|  | } | 
|  | #endif /* CONFIG_UART_INTERRUPT_DRIVEN */ | 
|  |  | 
|  |  | 
|  | static int ifx_cat1_uart_init(const struct device *dev) | 
|  | { | 
|  | struct ifx_cat1_uart_data *const data = dev->data; | 
|  | const struct ifx_cat1_uart_config *const config = dev->config; | 
|  | cy_rslt_t result; | 
|  | int ret; | 
|  |  | 
|  | cyhal_uart_configurator_t uart_init_cfg = { | 
|  | .resource = &data->hw_resource, | 
|  | .config = &_cyhal_uart_default_config, | 
|  | .clock = &data->clock, | 
|  | }; | 
|  |  | 
|  | /* Dedicate SCB HW resource */ | 
|  | data->hw_resource.type = CYHAL_RSC_SCB; | 
|  | data->hw_resource.block_num = _get_hw_block_num(config->reg_addr); | 
|  |  | 
|  | /* Configure dt provided device signals when available */ | 
|  | ret = pinctrl_apply_state(config->pcfg, PINCTRL_STATE_DEFAULT); | 
|  | if (ret < 0) { | 
|  | return ret; | 
|  | } | 
|  |  | 
|  | /* Allocates clock for selected IP block */ | 
|  | result = _cyhal_utils_allocate_clock(&data->clock, &data->hw_resource, | 
|  | CYHAL_CLOCK_BLOCK_PERIPHERAL_16BIT, true); | 
|  | if (result != CY_RSLT_SUCCESS) { | 
|  | return -ENOTSUP; | 
|  | } | 
|  |  | 
|  | /* Assigns a programmable divider to a selected IP block */ | 
|  | en_clk_dst_t clk_idx = _cyhal_scb_get_clock_index(uart_init_cfg.resource->block_num); | 
|  |  | 
|  | result = _cyhal_utils_peri_pclk_assign_divider(clk_idx, uart_init_cfg.clock); | 
|  | if (result != CY_RSLT_SUCCESS) { | 
|  | return -ENOTSUP; | 
|  | } | 
|  |  | 
|  | /* Initialize the UART peripheral */ | 
|  | result = cyhal_uart_init_cfg(&data->obj, &uart_init_cfg); | 
|  | if (result != CY_RSLT_SUCCESS) { | 
|  | return -ENOTSUP; | 
|  | } | 
|  |  | 
|  | /* Perform initial Uart configuration */ | 
|  | data->obj.is_clock_owned = true; | 
|  | ret = ifx_cat1_uart_configure(dev, &config->dt_cfg); | 
|  |  | 
|  | return ret; | 
|  | } | 
|  |  | 
|  | static const struct uart_driver_api ifx_cat1_uart_driver_api = { | 
|  | .poll_in = ifx_cat1_uart_poll_in, | 
|  | .poll_out = ifx_cat1_uart_poll_out, | 
|  | .err_check = ifx_cat1_uart_err_check, | 
|  |  | 
|  | #ifdef CONFIG_UART_USE_RUNTIME_CONFIGURE | 
|  | .configure = ifx_cat1_uart_configure, | 
|  | .config_get = ifx_cat1_uart_config_get, | 
|  | #endif /* CONFIG_UART_USE_RUNTIME_CONFIGURE */ | 
|  |  | 
|  | #ifdef CONFIG_UART_INTERRUPT_DRIVEN | 
|  | .fifo_fill = ifx_cat1_uart_fifo_fill, | 
|  | .fifo_read = ifx_cat1_uart_fifo_read, | 
|  | .irq_tx_enable = ifx_cat1_uart_irq_tx_enable, | 
|  | .irq_tx_disable = ifx_cat1_uart_irq_tx_disable, | 
|  | .irq_tx_ready = ifx_cat1_uart_irq_tx_ready, | 
|  | .irq_rx_enable = ifx_cat1_uart_irq_rx_enable, | 
|  | .irq_rx_disable = ifx_cat1_uart_irq_rx_disable, | 
|  | .irq_tx_complete = ifx_cat1_uart_irq_tx_complete, | 
|  | .irq_rx_ready = ifx_cat1_uart_irq_rx_ready, | 
|  | .irq_err_enable = ifx_cat1_uart_irq_err_enable, | 
|  | .irq_err_disable = ifx_cat1_uart_irq_err_disable, | 
|  | .irq_is_pending = ifx_cat1_uart_irq_is_pending, | 
|  | .irq_update = ifx_cat1_uart_irq_update, | 
|  | .irq_callback_set = ifx_cat1_uart_irq_callback_set, | 
|  | #endif    /* CONFIG_UART_INTERRUPT_DRIVEN */ | 
|  | }; | 
|  |  | 
|  | #define INFINEON_CAT1_UART_INIT(n)							     \ | 
|  | PINCTRL_DT_INST_DEFINE(n);							     \ | 
|  | static struct ifx_cat1_uart_data ifx_cat1_uart##n##_data;			     \ | 
|  | \ | 
|  | static struct ifx_cat1_uart_config ifx_cat1_uart##n##_cfg = {			     \ | 
|  | .dt_cfg.baudrate = DT_INST_PROP(n, current_speed),			     \ | 
|  | .dt_cfg.parity = DT_INST_ENUM_IDX_OR(n, parity, UART_CFG_PARITY_NONE),	     \ | 
|  | .dt_cfg.stop_bits = DT_INST_ENUM_IDX_OR(n, stop_bits, UART_CFG_STOP_BITS_1), \ | 
|  | .dt_cfg.data_bits = DT_INST_ENUM_IDX_OR(n, data_bits, UART_CFG_DATA_BITS_8), \ | 
|  | .dt_cfg.flow_ctrl = DT_INST_PROP(n, hw_flow_control),			     \ | 
|  | .pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(n),				     \ | 
|  | .reg_addr = (CySCB_Type *)DT_INST_REG_ADDR(n),				     \ | 
|  | .irq_priority = DT_INST_IRQ(n, priority)				     \ | 
|  | };										     \ | 
|  | \ | 
|  | DEVICE_DT_INST_DEFINE(n,							     \ | 
|  | &ifx_cat1_uart_init, NULL,				     \ | 
|  | &ifx_cat1_uart##n##_data,					     \ | 
|  | &ifx_cat1_uart##n##_cfg, PRE_KERNEL_1,			     \ | 
|  | CONFIG_SERIAL_INIT_PRIORITY,				     \ | 
|  | &ifx_cat1_uart_driver_api); | 
|  |  | 
|  | DT_INST_FOREACH_STATUS_OKAY(INFINEON_CAT1_UART_INIT) |