1 /*
2 * Copyright (c) 2025 Silicon Laboratories Inc.
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #define DT_DRV_COMPAT silabs_usart_uart
8
9 #include <errno.h>
10 #include <zephyr/drivers/clock_control.h>
11 #include <zephyr/drivers/clock_control/clock_control_silabs.h>
12 #include <zephyr/drivers/pinctrl.h>
13 #include <zephyr/drivers/uart.h>
14 #include <zephyr/irq.h>
15 #include <zephyr/logging/log.h>
16 #include <zephyr/pm/device.h>
17 #include <zephyr/pm/policy.h>
18 #include <em_usart.h>
19 #ifdef CONFIG_UART_SILABS_USART_ASYNC
20 #include <zephyr/drivers/dma.h>
21 #include <zephyr/drivers/dma/dma_silabs_ldma.h>
22 #endif
23
24 LOG_MODULE_REGISTER(uart_silabs_usart, CONFIG_UART_LOG_LEVEL);
25
26 #define SILABS_USART_TIMER_COMPARE_VALUE 0xff
27 #define SILABS_USART_TIMEOUT_TO_TIMERCOUNTER(timeout, baudrate) \
28 ((timeout * NSEC_PER_USEC) / ((NSEC_PER_SEC / baudrate) * SILABS_USART_TIMER_COMPARE_VALUE))
29
30 #ifdef CONFIG_UART_SILABS_USART_ASYNC
31 struct uart_dma_channel {
32 const struct device *dma_dev;
33 uint32_t dma_channel;
34 struct dma_block_config blk_cfg;
35 struct dma_config dma_cfg;
36 uint8_t priority;
37 uint8_t *buffer;
38 size_t buffer_length;
39 volatile size_t counter;
40 size_t offset;
41 int32_t timeout_cnt;
42 int32_t timeout;
43 bool enabled;
44 };
45 #endif
46 struct uart_silabs_config {
47 const struct pinctrl_dev_config *pcfg;
48 const struct device *clock_dev;
49 const struct silabs_clock_control_cmu_config clock_cfg;
50 USART_TypeDef *base;
51 void (*irq_config_func)(const struct device *dev);
52 };
53
54 enum uart_silabs_pm_lock {
55 UART_SILABS_PM_LOCK_TX,
56 UART_SILABS_PM_LOCK_TX_POLL,
57 UART_SILABS_PM_LOCK_RX,
58 UART_SILABS_PM_LOCK_COUNT,
59 };
60
61 struct uart_silabs_data {
62 struct uart_config *uart_cfg;
63 #ifdef CONFIG_UART_INTERRUPT_DRIVEN
64 uart_irq_callback_user_data_t callback;
65 void *cb_data;
66 #endif
67 #ifdef CONFIG_UART_SILABS_USART_ASYNC
68 const struct device *uart_dev;
69 uart_callback_t async_cb;
70 void *async_user_data;
71 struct uart_dma_channel dma_rx;
72 struct uart_dma_channel dma_tx;
73 uint8_t *rx_next_buffer;
74 size_t rx_next_buffer_len;
75 #endif
76 #ifdef CONFIG_PM
77 ATOMIC_DEFINE(pm_lock, UART_SILABS_PM_LOCK_COUNT);
78 #endif
79 };
80
81 static int uart_silabs_pm_action(const struct device *dev, enum pm_device_action action);
82
83 /**
84 * @brief Get PM lock on low power states
85 *
86 * @param dev UART device struct
87 * @param lock UART PM lock type
88 *
89 * @return true if lock was taken, false otherwise
90 */
uart_silabs_pm_lock_get(const struct device * dev,enum uart_silabs_pm_lock lock)91 static bool uart_silabs_pm_lock_get(const struct device *dev, enum uart_silabs_pm_lock lock)
92 {
93 #ifdef CONFIG_PM
94 struct uart_silabs_data *data = dev->data;
95 bool was_locked = atomic_test_and_set_bit(data->pm_lock, lock);
96
97 if (!was_locked) {
98 /* Lock out low-power states that would interfere with UART traffic */
99 pm_policy_state_lock_get(PM_STATE_SUSPEND_TO_IDLE, PM_ALL_SUBSTATES);
100 pm_policy_state_lock_get(PM_STATE_STANDBY, PM_ALL_SUBSTATES);
101 }
102
103 return !was_locked;
104 #else
105 return false;
106 #endif
107 }
108
109 /**
110 * @brief Release PM lock on low power states
111 *
112 * @param dev UART device struct
113 * @param lock UART PM lock type
114 *
115 * @return true if lock was released, false otherwise
116 */
uart_silabs_pm_lock_put(const struct device * dev,enum uart_silabs_pm_lock lock)117 static bool uart_silabs_pm_lock_put(const struct device *dev, enum uart_silabs_pm_lock lock)
118 {
119 #ifdef CONFIG_PM
120 struct uart_silabs_data *data = dev->data;
121 bool was_locked = atomic_test_and_clear_bit(data->pm_lock, lock);
122
123 if (was_locked) {
124 /* Unlock low-power states that would interfere with UART traffic */
125 pm_policy_state_lock_put(PM_STATE_SUSPEND_TO_IDLE, PM_ALL_SUBSTATES);
126 pm_policy_state_lock_put(PM_STATE_STANDBY, PM_ALL_SUBSTATES);
127 }
128
129 return was_locked;
130 #else
131 return false;
132 #endif
133 }
134
uart_silabs_poll_in(const struct device * dev,unsigned char * c)135 static int uart_silabs_poll_in(const struct device *dev, unsigned char *c)
136 {
137 const struct uart_silabs_config *config = dev->config;
138 uint32_t flags = USART_StatusGet(config->base);
139
140 if (flags & USART_STATUS_RXDATAV) {
141 *c = USART_Rx(config->base);
142 return 0;
143 }
144
145 return -1;
146 }
147
uart_silabs_poll_out(const struct device * dev,unsigned char c)148 static void uart_silabs_poll_out(const struct device *dev, unsigned char c)
149 {
150 const struct uart_silabs_config *config = dev->config;
151
152 if (uart_silabs_pm_lock_get(dev, UART_SILABS_PM_LOCK_TX_POLL)) {
153 USART_IntEnable(config->base, USART_IF_TXC);
154 }
155
156 USART_Tx(config->base, c);
157 }
158
uart_silabs_err_check(const struct device * dev)159 static int uart_silabs_err_check(const struct device *dev)
160 {
161 const struct uart_silabs_config *config = dev->config;
162 uint32_t flags = USART_IntGet(config->base);
163 int err = 0;
164
165 if (flags & USART_IF_RXOF) {
166 err |= UART_ERROR_OVERRUN;
167 }
168
169 if (flags & USART_IF_PERR) {
170 err |= UART_ERROR_PARITY;
171 }
172
173 if (flags & USART_IF_FERR) {
174 err |= UART_ERROR_FRAMING;
175 }
176
177 USART_IntClear(config->base, USART_IF_RXOF | USART_IF_PERR | USART_IF_FERR);
178
179 return err;
180 }
181
182 #ifdef CONFIG_UART_INTERRUPT_DRIVEN
uart_silabs_fifo_fill(const struct device * dev,const uint8_t * tx_data,int len)183 static int uart_silabs_fifo_fill(const struct device *dev, const uint8_t *tx_data, int len)
184 {
185 const struct uart_silabs_config *config = dev->config;
186 int i = 0;
187
188 while ((i < len) && (config->base->STATUS & USART_STATUS_TXBL)) {
189 config->base->TXDATA = tx_data[i++];
190 }
191
192 return i;
193 }
194
uart_silabs_fifo_read(const struct device * dev,uint8_t * rx_data,const int len)195 static int uart_silabs_fifo_read(const struct device *dev, uint8_t *rx_data, const int len)
196 {
197 const struct uart_silabs_config *config = dev->config;
198 int i = 0;
199
200 while ((i < len) && (config->base->STATUS & USART_STATUS_RXDATAV)) {
201 rx_data[i++] = (uint8_t)config->base->RXDATA;
202 }
203
204 return i;
205 }
206
uart_silabs_irq_tx_enable(const struct device * dev)207 static void uart_silabs_irq_tx_enable(const struct device *dev)
208 {
209 const struct uart_silabs_config *config = dev->config;
210
211 (void)uart_silabs_pm_lock_get(dev, UART_SILABS_PM_LOCK_TX);
212 USART_IntEnable(config->base, USART_IEN_TXBL | USART_IEN_TXC);
213 }
214
uart_silabs_irq_tx_disable(const struct device * dev)215 static void uart_silabs_irq_tx_disable(const struct device *dev)
216 {
217 const struct uart_silabs_config *config = dev->config;
218
219 USART_IntDisable(config->base, USART_IEN_TXBL | USART_IEN_TXC);
220 (void)uart_silabs_pm_lock_put(dev, UART_SILABS_PM_LOCK_TX);
221 }
222
uart_silabs_irq_tx_complete(const struct device * dev)223 static int uart_silabs_irq_tx_complete(const struct device *dev)
224 {
225 const struct uart_silabs_config *config = dev->config;
226 uint32_t flags = USART_IntGet(config->base);
227
228 USART_IntClear(config->base, USART_IF_TXC);
229
230 return !!(flags & USART_IF_TXC);
231 }
232
uart_silabs_irq_tx_ready(const struct device * dev)233 static int uart_silabs_irq_tx_ready(const struct device *dev)
234 {
235 const struct uart_silabs_config *config = dev->config;
236 uint32_t flags = USART_IntGetEnabled(config->base);
237
238 return !!(flags & USART_IF_TXBL);
239 }
240
uart_silabs_irq_rx_enable(const struct device * dev)241 static void uart_silabs_irq_rx_enable(const struct device *dev)
242 {
243 const struct uart_silabs_config *config = dev->config;
244
245 (void)uart_silabs_pm_lock_get(dev, UART_SILABS_PM_LOCK_RX);
246 USART_IntEnable(config->base, USART_IEN_RXDATAV);
247 }
248
uart_silabs_irq_rx_disable(const struct device * dev)249 static void uart_silabs_irq_rx_disable(const struct device *dev)
250 {
251 const struct uart_silabs_config *config = dev->config;
252
253 USART_IntDisable(config->base, USART_IEN_RXDATAV);
254 (void)uart_silabs_pm_lock_put(dev, UART_SILABS_PM_LOCK_RX);
255 }
256
uart_silabs_irq_rx_full(const struct device * dev)257 static int uart_silabs_irq_rx_full(const struct device *dev)
258 {
259 const struct uart_silabs_config *config = dev->config;
260 uint32_t flags = USART_IntGet(config->base);
261
262 return !!(flags & USART_IF_RXDATAV);
263 }
264
uart_silabs_irq_rx_ready(const struct device * dev)265 static int uart_silabs_irq_rx_ready(const struct device *dev)
266 {
267 const struct uart_silabs_config *config = dev->config;
268
269 return (config->base->IEN & USART_IEN_RXDATAV) && uart_silabs_irq_rx_full(dev);
270 }
271
uart_silabs_irq_err_enable(const struct device * dev)272 static void uart_silabs_irq_err_enable(const struct device *dev)
273 {
274 const struct uart_silabs_config *config = dev->config;
275
276 USART_IntEnable(config->base, USART_IF_RXOF | USART_IF_PERR | USART_IF_FERR);
277 }
278
uart_silabs_irq_err_disable(const struct device * dev)279 static void uart_silabs_irq_err_disable(const struct device *dev)
280 {
281 const struct uart_silabs_config *config = dev->config;
282
283 USART_IntDisable(config->base, USART_IF_RXOF | USART_IF_PERR | USART_IF_FERR);
284 }
285
uart_silabs_irq_is_pending(const struct device * dev)286 static int uart_silabs_irq_is_pending(const struct device *dev)
287 {
288 return uart_silabs_irq_tx_ready(dev) || uart_silabs_irq_rx_ready(dev);
289 }
290
uart_silabs_irq_update(const struct device * dev)291 static int uart_silabs_irq_update(const struct device *dev)
292 {
293 return 1;
294 }
295
uart_silabs_irq_callback_set(const struct device * dev,uart_irq_callback_user_data_t cb,void * cb_data)296 static void uart_silabs_irq_callback_set(const struct device *dev, uart_irq_callback_user_data_t cb,
297 void *cb_data)
298 {
299 struct uart_silabs_data *data = dev->data;
300
301 data->callback = cb;
302 data->cb_data = cb_data;
303 }
304 #endif /* CONFIG_UART_INTERRUPT_DRIVEN */
305
306 #ifdef CONFIG_UART_SILABS_USART_ASYNC
async_user_callback(struct uart_silabs_data * data,struct uart_event * event)307 static inline void async_user_callback(struct uart_silabs_data *data, struct uart_event *event)
308 {
309 if (data->async_cb) {
310 data->async_cb(data->uart_dev, event, data->async_user_data);
311 }
312 }
313
async_evt_rx_rdy(struct uart_silabs_data * data)314 static inline void async_evt_rx_rdy(struct uart_silabs_data *data)
315 {
316 struct uart_event event = {
317 .type = UART_RX_RDY,
318 .data.rx.buf = data->dma_rx.buffer,
319 .data.rx.len = data->dma_rx.counter - data->dma_rx.offset,
320 .data.rx.offset = data->dma_rx.offset
321 };
322
323 data->dma_rx.offset = data->dma_rx.counter;
324
325 if (event.data.rx.len > 0) {
326 async_user_callback(data, &event);
327 }
328 }
329
async_evt_tx_done(struct uart_silabs_data * data)330 static inline void async_evt_tx_done(struct uart_silabs_data *data)
331 {
332 struct uart_event event = {
333 .type = UART_TX_DONE,
334 .data.tx.buf = data->dma_tx.buffer,
335 .data.tx.len = data->dma_tx.counter
336 };
337
338 data->dma_tx.buffer_length = 0;
339 data->dma_tx.counter = 0;
340
341 async_user_callback(data, &event);
342 }
343
async_evt_tx_abort(struct uart_silabs_data * data)344 static inline void async_evt_tx_abort(struct uart_silabs_data *data)
345 {
346 struct uart_event event = {
347 .type = UART_TX_ABORTED,
348 .data.tx.buf = data->dma_tx.buffer,
349 .data.tx.len = data->dma_tx.counter
350 };
351
352 data->dma_tx.buffer_length = 0;
353 data->dma_tx.counter = 0;
354
355 async_user_callback(data, &event);
356 }
357
async_evt_rx_err(struct uart_silabs_data * data,int err_code)358 static inline void async_evt_rx_err(struct uart_silabs_data *data, int err_code)
359 {
360 struct uart_event event = {
361 .type = UART_RX_STOPPED,
362 .data.rx_stop.reason = err_code,
363 .data.rx_stop.data.len = data->dma_rx.counter,
364 .data.rx_stop.data.offset = 0,
365 .data.rx_stop.data.buf = data->dma_rx.buffer
366 };
367
368 async_user_callback(data, &event);
369 }
370
async_evt_rx_buf_release(struct uart_silabs_data * data)371 static inline void async_evt_rx_buf_release(struct uart_silabs_data *data)
372 {
373 struct uart_event evt = {
374 .type = UART_RX_BUF_RELEASED,
375 .data.rx_buf.buf = data->dma_rx.buffer,
376 };
377
378 async_user_callback(data, &evt);
379 }
380
async_evt_rx_buf_request(struct uart_silabs_data * data)381 static inline void async_evt_rx_buf_request(struct uart_silabs_data *data)
382 {
383 struct uart_event evt = {
384 .type = UART_RX_BUF_REQUEST,
385 };
386
387 async_user_callback(data, &evt);
388 }
389
uart_silabs_async_callback_set(const struct device * dev,uart_callback_t callback,void * user_data)390 static int uart_silabs_async_callback_set(const struct device *dev, uart_callback_t callback,
391 void *user_data)
392 {
393 struct uart_silabs_data *data = dev->data;
394
395 data->async_cb = callback;
396 data->async_user_data = user_data;
397
398 return 0;
399 }
400
uart_silabs_dma_replace_buffer(const struct device * dev)401 static void uart_silabs_dma_replace_buffer(const struct device *dev)
402 {
403 struct uart_silabs_data *data = dev->data;
404
405 data->dma_rx.offset = 0;
406 data->dma_rx.counter = 0;
407 data->dma_rx.buffer = data->rx_next_buffer;
408 data->dma_rx.buffer_length = data->rx_next_buffer_len;
409 data->rx_next_buffer = NULL;
410 data->rx_next_buffer_len = 0;
411
412 async_evt_rx_buf_request(data);
413 }
414
uart_silabs_dma_rx_flush(struct uart_silabs_data * data)415 static void uart_silabs_dma_rx_flush(struct uart_silabs_data *data)
416 {
417 struct dma_status stat;
418 size_t rx_rcv_len;
419
420 if (!dma_get_status(data->dma_rx.dma_dev, data->dma_rx.dma_channel, &stat)) {
421 rx_rcv_len = data->dma_rx.buffer_length - stat.pending_length;
422 if (rx_rcv_len > data->dma_rx.offset) {
423 data->dma_rx.counter = rx_rcv_len;
424 async_evt_rx_rdy(data);
425 }
426 }
427 }
428
uart_silabs_dma_rx_cb(const struct device * dma_dev,void * user_data,uint32_t channel,int status)429 void uart_silabs_dma_rx_cb(const struct device *dma_dev, void *user_data, uint32_t channel,
430 int status)
431 {
432 const struct device *uart_dev = user_data;
433 struct uart_silabs_data *data = uart_dev->data;
434 struct uart_event disabled_event = {.type = UART_RX_DISABLED};
435
436 if (status < 0) {
437 async_evt_rx_err(data, status);
438 return;
439 }
440
441 data->dma_rx.counter = data->dma_rx.buffer_length;
442
443 async_evt_rx_rdy(data);
444
445 if (data->rx_next_buffer) {
446 async_evt_rx_buf_release(data);
447 uart_silabs_dma_replace_buffer(uart_dev);
448 } else {
449 dma_stop(data->dma_rx.dma_dev, data->dma_rx.dma_channel);
450 data->dma_rx.enabled = false;
451 async_evt_rx_buf_release(data);
452 async_user_callback(data, &disabled_event);
453 }
454 }
455
uart_silabs_dma_tx_cb(const struct device * dma_dev,void * user_data,uint32_t channel,int status)456 void uart_silabs_dma_tx_cb(const struct device *dma_dev, void *user_data, uint32_t channel,
457 int status)
458 {
459 const struct device *uart_dev = user_data;
460 struct uart_silabs_data *data = uart_dev->data;
461
462 dma_stop(data->dma_tx.dma_dev, data->dma_tx.dma_channel);
463 data->dma_tx.enabled = false;
464 }
465
uart_silabs_async_tx(const struct device * dev,const uint8_t * tx_data,size_t buf_size,int32_t timeout)466 static int uart_silabs_async_tx(const struct device *dev, const uint8_t *tx_data, size_t buf_size,
467 int32_t timeout)
468 {
469 const struct uart_silabs_config *config = dev->config;
470 struct uart_silabs_data *data = dev->data;
471 int ret;
472
473 if (!data->dma_tx.dma_dev) {
474 return -ENODEV;
475 }
476
477 if (data->dma_tx.buffer_length) {
478 return -EBUSY;
479 }
480
481 data->dma_tx.buffer = (uint8_t *)tx_data;
482 data->dma_tx.buffer_length = buf_size;
483
484 /* User timeout is expressed as number of TCMP2 interrupt which occurs every
485 * SILABS_USART_TIMER_COMPARE_VALUE baud-times
486 */
487 if (data->uart_cfg->baudrate > 0 && timeout >= 0) {
488 data->dma_tx.timeout =
489 SILABS_USART_TIMEOUT_TO_TIMERCOUNTER(timeout, data->uart_cfg->baudrate);
490 } else {
491 data->dma_tx.timeout = 0;
492 }
493
494 data->dma_tx.blk_cfg.source_address = (uint32_t)data->dma_tx.buffer;
495 data->dma_tx.blk_cfg.block_size = data->dma_tx.buffer_length;
496
497 (void)uart_silabs_pm_lock_get(dev, UART_SILABS_PM_LOCK_TX);
498 USART_IntClear(config->base, USART_IF_TXC | USART_IF_TCMP2);
499 USART_IntEnable(config->base, USART_IF_TXC);
500 if (timeout >= 0) {
501 USART_IntEnable(config->base, USART_IF_TCMP2);
502 }
503
504 ret = dma_config(data->dma_tx.dma_dev, data->dma_tx.dma_channel, &data->dma_tx.dma_cfg);
505 if (ret) {
506 LOG_ERR("dma tx config error!");
507 return ret;
508 }
509
510 ret = dma_start(data->dma_tx.dma_dev, data->dma_tx.dma_channel);
511 if (ret) {
512 LOG_ERR("UART err: TX DMA start failed!");
513 return ret;
514 }
515
516 data->dma_tx.enabled = true;
517
518 return 0;
519 }
520
uart_silabs_async_tx_abort(const struct device * dev)521 static int uart_silabs_async_tx_abort(const struct device *dev)
522 {
523 const struct uart_silabs_config *config = dev->config;
524 struct uart_silabs_data *data = dev->data;
525 size_t tx_buffer_length = data->dma_tx.buffer_length;
526 struct dma_status stat;
527
528 if (!tx_buffer_length) {
529 return -EFAULT;
530 }
531
532 USART_IntDisable(config->base, USART_IF_TXC);
533 USART_IntDisable(config->base, USART_IF_TCMP2);
534 USART_IntClear(config->base, USART_IF_TXC | USART_IF_TCMP2);
535 (void)uart_silabs_pm_lock_put(dev, UART_SILABS_PM_LOCK_TX);
536
537 if (!dma_get_status(data->dma_tx.dma_dev, data->dma_tx.dma_channel, &stat)) {
538 data->dma_tx.counter = tx_buffer_length - stat.pending_length;
539 }
540
541 dma_stop(data->dma_tx.dma_dev, data->dma_tx.dma_channel);
542 data->dma_tx.enabled = false;
543
544 async_evt_tx_abort(data);
545
546 return 0;
547 }
548
uart_silabs_async_rx_enable(const struct device * dev,uint8_t * rx_buf,size_t buf_size,int32_t timeout)549 static int uart_silabs_async_rx_enable(const struct device *dev, uint8_t *rx_buf, size_t buf_size,
550 int32_t timeout)
551 {
552 const struct uart_silabs_config *config = dev->config;
553 struct uart_silabs_data *data = dev->data;
554 int ret;
555
556 if (!data->dma_rx.dma_dev) {
557 return -ENODEV;
558 }
559
560 if (data->dma_rx.enabled) {
561 LOG_WRN("RX was already enabled");
562 return -EBUSY;
563 }
564
565 data->dma_rx.offset = 0;
566 data->dma_rx.buffer = rx_buf;
567 data->dma_rx.buffer_length = buf_size;
568 data->dma_rx.counter = 0;
569
570 /* User timeout is expressed as number of TCMP1 interrupt which occurs every
571 * SILABS_USART_TIMER_COMPARE_VALUE baud-times
572 */
573 if (data->uart_cfg->baudrate > 0 && timeout >= 0) {
574 data->dma_rx.timeout =
575 SILABS_USART_TIMEOUT_TO_TIMERCOUNTER(timeout, data->uart_cfg->baudrate);
576 } else {
577 data->dma_rx.timeout = 0;
578 }
579
580 data->dma_rx.blk_cfg.block_size = buf_size;
581 data->dma_rx.blk_cfg.dest_address = (uint32_t)data->dma_rx.buffer;
582
583 ret = dma_config(data->dma_rx.dma_dev, data->dma_rx.dma_channel, &data->dma_rx.dma_cfg);
584
585 if (ret) {
586 LOG_ERR("UART ERR: RX DMA config failed!");
587 return -EINVAL;
588 }
589
590 if (dma_start(data->dma_rx.dma_dev, data->dma_rx.dma_channel)) {
591 LOG_ERR("UART ERR: RX DMA start failed!");
592 return -EFAULT;
593 }
594
595 (void)uart_silabs_pm_lock_get(dev, UART_SILABS_PM_LOCK_RX);
596 USART_IntClear(config->base, USART_IF_RXOF | USART_IF_TCMP1);
597 USART_IntEnable(config->base, USART_IF_RXOF);
598
599 if (timeout >= 0) {
600 USART_IntEnable(config->base, USART_IF_TCMP1);
601 }
602
603 data->dma_rx.enabled = true;
604
605 async_evt_rx_buf_request(data);
606
607 return ret;
608 }
609
uart_silabs_async_rx_disable(const struct device * dev)610 static int uart_silabs_async_rx_disable(const struct device *dev)
611 {
612 const struct uart_silabs_config *config = dev->config;
613 USART_TypeDef *usart = config->base;
614 struct uart_silabs_data *data = dev->data;
615 struct uart_event disabled_event = {.type = UART_RX_DISABLED};
616
617 if (!data->dma_rx.enabled) {
618 return -EFAULT;
619 }
620
621 dma_stop(data->dma_rx.dma_dev, data->dma_rx.dma_channel);
622
623 USART_IntDisable(usart, USART_IF_RXOF);
624 USART_IntDisable(usart, USART_IF_TCMP1);
625 USART_IntClear(usart, USART_IF_RXOF | USART_IF_TCMP1);
626 (void)uart_silabs_pm_lock_put(dev, UART_SILABS_PM_LOCK_RX);
627
628 if (!data->dma_rx.enabled) {
629 usart->CMD = USART_CMD_CLEARRX;
630 }
631
632 uart_silabs_dma_rx_flush(data);
633
634 async_evt_rx_buf_release(data);
635
636 if (data->rx_next_buffer) {
637 struct uart_event rx_next_buf_release_evt = {
638 .type = UART_RX_BUF_RELEASED,
639 .data.rx_buf.buf = data->rx_next_buffer,
640 };
641 async_user_callback(data, &rx_next_buf_release_evt);
642 }
643
644 data->rx_next_buffer = NULL;
645 data->rx_next_buffer_len = 0;
646
647 data->dma_rx.enabled = false;
648
649 async_user_callback(data, &disabled_event);
650
651 return 0;
652 }
653
uart_silabs_async_rx_buf_rsp(const struct device * dev,uint8_t * buf,size_t len)654 static int uart_silabs_async_rx_buf_rsp(const struct device *dev, uint8_t *buf, size_t len)
655 {
656 struct uart_silabs_data *data = dev->data;
657 unsigned int key;
658 int ret;
659
660 key = irq_lock();
661
662 if (data->rx_next_buffer) {
663 return -EBUSY;
664 } else if (!data->dma_rx.enabled) {
665 return -EACCES;
666 }
667
668 data->rx_next_buffer = buf;
669 data->rx_next_buffer_len = len;
670 data->dma_rx.blk_cfg.dest_address = (uint32_t)buf;
671 data->dma_rx.blk_cfg.block_size = len;
672
673 irq_unlock(key);
674
675 ret = silabs_ldma_append_block(data->dma_rx.dma_dev, data->dma_rx.dma_channel,
676 &data->dma_rx.dma_cfg);
677 if (ret) {
678 LOG_ERR("UART ERR: RX DMA append failed!");
679 return -EINVAL;
680 }
681
682 return ret;
683 }
684
uart_silabs_async_init(const struct device * dev)685 static int uart_silabs_async_init(const struct device *dev)
686 {
687 const struct uart_silabs_config *config = dev->config;
688 USART_TypeDef *usart = config->base;
689 struct uart_silabs_data *data = dev->data;
690
691 data->uart_dev = dev;
692
693 if (data->dma_rx.dma_dev) {
694 if (!device_is_ready(data->dma_rx.dma_dev)) {
695 return -ENODEV;
696 }
697 data->dma_rx.dma_channel = dma_request_channel(data->dma_rx.dma_dev, NULL);
698 }
699
700 if (data->dma_tx.dma_dev) {
701 if (!device_is_ready(data->dma_tx.dma_dev)) {
702 return -ENODEV;
703 }
704 data->dma_tx.dma_channel = dma_request_channel(data->dma_tx.dma_dev, NULL);
705 }
706
707 data->dma_rx.enabled = false;
708 data->dma_tx.enabled = false;
709
710 memset(&data->dma_rx.blk_cfg, 0, sizeof(data->dma_rx.blk_cfg));
711 data->dma_rx.blk_cfg.source_address = (uintptr_t)&(usart->RXDATA);
712 data->dma_rx.blk_cfg.dest_address = 0;
713 data->dma_rx.blk_cfg.source_addr_adj = DMA_ADDR_ADJ_NO_CHANGE;
714 data->dma_rx.blk_cfg.dest_addr_adj = DMA_ADDR_ADJ_INCREMENT;
715 data->dma_rx.dma_cfg.complete_callback_en = 1;
716 data->dma_rx.dma_cfg.channel_priority = 3;
717 data->dma_rx.dma_cfg.channel_direction = PERIPHERAL_TO_MEMORY;
718 data->dma_rx.dma_cfg.head_block = &data->dma_rx.blk_cfg;
719 data->dma_rx.dma_cfg.user_data = (void *)dev;
720 data->rx_next_buffer = NULL;
721 data->rx_next_buffer_len = 0;
722
723 memset(&data->dma_tx.blk_cfg, 0, sizeof(data->dma_tx.blk_cfg));
724 data->dma_tx.blk_cfg.dest_address = (uintptr_t)&(usart->TXDATA);
725 data->dma_tx.blk_cfg.source_address = 0;
726 data->dma_tx.blk_cfg.source_addr_adj = DMA_ADDR_ADJ_INCREMENT;
727 data->dma_tx.blk_cfg.dest_addr_adj = DMA_ADDR_ADJ_NO_CHANGE;
728 data->dma_tx.dma_cfg.complete_callback_en = 1;
729 data->dma_tx.dma_cfg.channel_direction = MEMORY_TO_PERIPHERAL;
730 data->dma_tx.dma_cfg.head_block = &data->dma_tx.blk_cfg;
731 data->dma_tx.dma_cfg.user_data = (void *)dev;
732
733 config->base->CMD = USART_CMD_CLEARRX | USART_CMD_CLEARTX;
734 config->base->TIMECMP1 =
735 USART_TIMECMP1_TSTOP_RXACT | USART_TIMECMP1_TSTART_RXEOF |
736 USART_TIMECMP1_RESTARTEN |
737 (SILABS_USART_TIMER_COMPARE_VALUE << _USART_TIMECMP1_TCMPVAL_SHIFT);
738 config->base->TIMECMP2 =
739 USART_TIMECMP2_TSTOP_TXST | USART_TIMECMP2_TSTART_TXEOF | USART_TIMECMP2_RESTARTEN |
740 (SILABS_USART_TIMER_COMPARE_VALUE << _USART_TIMECMP2_TCMPVAL_SHIFT);
741
742 return 0;
743 }
744 #endif /* CONFIG_UART_SILABS_USART_ASYNC */
745
uart_silabs_isr(const struct device * dev)746 static void uart_silabs_isr(const struct device *dev)
747 {
748 __maybe_unused struct uart_silabs_data *data = dev->data;
749 const struct uart_silabs_config *config = dev->config;
750 USART_TypeDef *usart = config->base;
751 uint32_t flags = USART_IntGet(usart);
752 #ifdef CONFIG_UART_SILABS_USART_ASYNC
753 struct dma_status stat;
754 #endif
755
756 if (flags & USART_IF_TXC) {
757 if (uart_silabs_pm_lock_put(dev, UART_SILABS_PM_LOCK_TX_POLL)) {
758 USART_IntDisable(usart, USART_IEN_TXC);
759 USART_IntClear(usart, USART_IF_TXC);
760 }
761 }
762 #ifdef CONFIG_UART_INTERRUPT_DRIVEN
763 if (data->callback) {
764 data->callback(dev, data->cb_data);
765 }
766 #endif
767 #ifdef CONFIG_UART_SILABS_USART_ASYNC
768 if (flags & USART_IF_TCMP1) {
769
770 data->dma_rx.timeout_cnt++;
771 if (data->dma_rx.timeout_cnt >= data->dma_rx.timeout) {
772 uart_silabs_dma_rx_flush(data);
773
774 usart->TIMECMP1 &= ~_USART_TIMECMP1_TSTART_MASK;
775 usart->TIMECMP1 |= USART_TIMECMP1_TSTART_RXEOF;
776 data->dma_rx.timeout_cnt = 0;
777 }
778
779 USART_IntClear(usart, USART_IF_TCMP1);
780 }
781 if (flags & USART_IF_RXOF) {
782 async_evt_rx_err(data, UART_ERROR_OVERRUN);
783
784 uart_silabs_async_rx_disable(dev);
785
786 USART_IntClear(usart, USART_IF_RXOF);
787 }
788 if (flags & USART_IF_TXC) {
789 if (!dma_get_status(data->dma_tx.dma_dev, data->dma_tx.dma_channel, &stat)) {
790 data->dma_tx.counter = data->dma_tx.buffer_length - stat.pending_length;
791 }
792
793 if (data->dma_tx.counter == data->dma_tx.buffer_length) {
794 USART_IntDisable(config->base, USART_IF_TXC);
795 USART_IntDisable(config->base, USART_IF_TCMP2);
796 USART_IntClear(usart, USART_IF_TXC | USART_IF_TCMP2);
797 (void)uart_silabs_pm_lock_put(dev, UART_SILABS_PM_LOCK_TX);
798
799 usart->TIMECMP2 &= ~_USART_TIMECMP2_TSTART_MASK;
800 usart->TIMECMP2 |= USART_TIMECMP2_TSTART_DISABLE;
801 }
802
803 async_evt_tx_done(data);
804 }
805 if (flags & USART_IF_TCMP2) {
806 data->dma_tx.timeout_cnt++;
807 if (data->dma_tx.timeout_cnt >= data->dma_tx.timeout) {
808 usart->TIMECMP2 &= ~_USART_TIMECMP2_TSTART_MASK;
809 usart->TIMECMP2 |= USART_TIMECMP2_TSTART_DISABLE;
810 data->dma_tx.timeout_cnt = 0;
811
812 uart_silabs_async_tx_abort(dev);
813 }
814
815 USART_IntClear(usart, USART_IF_TCMP2);
816 }
817 #endif /* CONFIG_UART_SILABS_USART_ASYNC */
818 }
819
uart_silabs_cfg2ll_parity(enum uart_config_parity parity)820 static inline USART_Parity_TypeDef uart_silabs_cfg2ll_parity(
821 enum uart_config_parity parity)
822 {
823 switch (parity) {
824 case UART_CFG_PARITY_ODD:
825 return usartOddParity;
826 case UART_CFG_PARITY_EVEN:
827 return usartEvenParity;
828 case UART_CFG_PARITY_NONE:
829 default:
830 return usartNoParity;
831 }
832 }
833
uart_silabs_cfg2ll_stopbits(enum uart_config_stop_bits sb)834 static inline USART_Stopbits_TypeDef uart_silabs_cfg2ll_stopbits(
835 enum uart_config_stop_bits sb)
836 {
837 switch (sb) {
838 case UART_CFG_STOP_BITS_0_5:
839 return usartStopbits0p5;
840 case UART_CFG_STOP_BITS_1:
841 return usartStopbits1;
842 case UART_CFG_STOP_BITS_2:
843 return usartStopbits2;
844 case UART_CFG_STOP_BITS_1_5:
845 return usartStopbits1p5;
846 default:
847 return usartStopbits1;
848 }
849 }
850
uart_silabs_cfg2ll_databits(enum uart_config_data_bits db,enum uart_config_parity p)851 static inline USART_Databits_TypeDef uart_silabs_cfg2ll_databits(
852 enum uart_config_data_bits db, enum uart_config_parity p)
853 {
854 switch (db) {
855 case UART_CFG_DATA_BITS_7:
856 if (p == UART_CFG_PARITY_NONE) {
857 return usartDatabits7;
858 } else {
859 return usartDatabits8;
860 }
861 case UART_CFG_DATA_BITS_9:
862 return usartDatabits9;
863 case UART_CFG_DATA_BITS_8:
864 default:
865 if (p == UART_CFG_PARITY_NONE) {
866 return usartDatabits8;
867 } else {
868 return usartDatabits9;
869 }
870 return usartDatabits8;
871 }
872 }
873
uart_silabs_cfg2ll_hwctrl(enum uart_config_flow_control fc)874 static inline USART_HwFlowControl_TypeDef uart_silabs_cfg2ll_hwctrl(
875 enum uart_config_flow_control fc)
876 {
877 if (fc == UART_CFG_FLOW_CTRL_RTS_CTS) {
878 return usartHwFlowControlCtsAndRts;
879 }
880
881 return usartHwFlowControlNone;
882 }
883
uart_silabs_ll2cfg_parity(USART_Parity_TypeDef parity)884 static inline enum uart_config_parity uart_silabs_ll2cfg_parity(USART_Parity_TypeDef parity)
885 {
886 switch (parity) {
887 case usartOddParity:
888 return UART_CFG_PARITY_ODD;
889 case usartEvenParity:
890 return UART_CFG_PARITY_EVEN;
891 case usartNoParity:
892 default:
893 return UART_CFG_PARITY_NONE;
894 }
895 }
896
uart_silabs_ll2cfg_stopbits(USART_Stopbits_TypeDef sb)897 static inline enum uart_config_stop_bits uart_silabs_ll2cfg_stopbits(USART_Stopbits_TypeDef sb)
898 {
899 switch (sb) {
900 case usartStopbits0p5:
901 return UART_CFG_STOP_BITS_0_5;
902 case usartStopbits1:
903 return UART_CFG_STOP_BITS_1;
904 case usartStopbits1p5:
905 return UART_CFG_STOP_BITS_1_5;
906 case usartStopbits2:
907 return UART_CFG_STOP_BITS_2;
908 default:
909 return UART_CFG_STOP_BITS_1;
910 }
911 }
912
uart_silabs_ll2cfg_databits(USART_Databits_TypeDef db,USART_Parity_TypeDef p)913 static inline enum uart_config_data_bits uart_silabs_ll2cfg_databits(USART_Databits_TypeDef db,
914 USART_Parity_TypeDef p)
915 {
916 switch (db) {
917 case usartDatabits7:
918 if (p == usartNoParity) {
919 return UART_CFG_DATA_BITS_7;
920 } else {
921 return UART_CFG_DATA_BITS_6;
922 }
923 case usartDatabits9:
924 if (p == usartNoParity) {
925 return UART_CFG_DATA_BITS_9;
926 } else {
927 return UART_CFG_DATA_BITS_8;
928 }
929 case usartDatabits8:
930 default:
931 if (p == usartNoParity) {
932 return UART_CFG_DATA_BITS_8;
933 } else {
934 return UART_CFG_DATA_BITS_7;
935 }
936 }
937 }
938
uart_silabs_ll2cfg_hwctrl(USART_HwFlowControl_TypeDef fc)939 static inline enum uart_config_flow_control uart_silabs_ll2cfg_hwctrl(
940 USART_HwFlowControl_TypeDef fc)
941 {
942 if (fc == usartHwFlowControlCtsAndRts) {
943 return UART_CFG_FLOW_CTRL_RTS_CTS;
944 }
945
946 return UART_CFG_FLOW_CTRL_NONE;
947 }
948
uart_silabs_configure_peripheral(const struct device * dev,bool enable)949 static void uart_silabs_configure_peripheral(const struct device *dev, bool enable)
950 {
951 const struct uart_silabs_config *config = dev->config;
952 const struct uart_silabs_data *data = dev->data;
953 USART_InitAsync_TypeDef usartInit = USART_INITASYNC_DEFAULT;
954
955 usartInit.baudrate = data->uart_cfg->baudrate;
956 usartInit.parity = uart_silabs_cfg2ll_parity(data->uart_cfg->parity);
957 usartInit.stopbits = uart_silabs_cfg2ll_stopbits(data->uart_cfg->stop_bits);
958 usartInit.databits = uart_silabs_cfg2ll_databits(data->uart_cfg->data_bits,
959 data->uart_cfg->parity);
960 usartInit.hwFlowControl = uart_silabs_cfg2ll_hwctrl(data->uart_cfg->flow_ctrl);
961 usartInit.enable = enable ? usartEnable : usartDisable;
962
963 USART_InitAsync(config->base, &usartInit);
964 }
965
966 #ifdef CONFIG_UART_USE_RUNTIME_CONFIGURE
uart_silabs_configure(const struct device * dev,const struct uart_config * cfg)967 static int uart_silabs_configure(const struct device *dev,
968 const struct uart_config *cfg)
969 {
970 const struct uart_silabs_config *config = dev->config;
971 USART_TypeDef *base = config->base;
972 struct uart_silabs_data *data = dev->data;
973
974 #ifdef CONFIG_UART_SILABS_USART_ASYNC
975 if (data->dma_rx.enabled || data->dma_tx.enabled) {
976 return -EBUSY;
977 }
978 #endif
979
980 if ((cfg->parity == UART_CFG_PARITY_MARK) ||
981 (cfg->parity == UART_CFG_PARITY_SPACE)) {
982 return -ENOSYS;
983 }
984
985 if (cfg->flow_ctrl == UART_CFG_FLOW_CTRL_DTR_DSR ||
986 cfg->flow_ctrl == UART_CFG_FLOW_CTRL_RS485) {
987 return -ENOSYS;
988 }
989
990 *data->uart_cfg = *cfg;
991 USART_Enable(base, usartDisable);
992
993 uart_silabs_configure_peripheral(dev, true);
994
995 return 0;
996 };
997
uart_silabs_config_get(const struct device * dev,struct uart_config * cfg)998 static int uart_silabs_config_get(const struct device *dev,
999 struct uart_config *cfg)
1000 {
1001 struct uart_silabs_data *data = dev->data;
1002 struct uart_config *uart_cfg = data->uart_cfg;
1003
1004 cfg->baudrate = uart_cfg->baudrate;
1005 cfg->parity = uart_cfg->parity;
1006 cfg->stop_bits = uart_cfg->stop_bits;
1007 cfg->data_bits = uart_cfg->data_bits;
1008 cfg->flow_ctrl = uart_cfg->flow_ctrl;
1009
1010 return 0;
1011 }
1012 #endif /* CONFIG_UART_USE_RUNTIME_CONFIGURE */
1013
uart_silabs_init(const struct device * dev)1014 static int uart_silabs_init(const struct device *dev)
1015 {
1016 int err;
1017 const struct uart_silabs_config *config = dev->config;
1018
1019 /* The peripheral and gpio clock are already enabled from soc and gpio driver */
1020 /* Enable USART clock */
1021 err = clock_control_on(config->clock_dev, (clock_control_subsys_t)&config->clock_cfg);
1022 if (err < 0) {
1023 return err;
1024 }
1025
1026 uart_silabs_configure_peripheral(dev, false);
1027
1028 config->irq_config_func(dev);
1029
1030 #ifdef CONFIG_UART_SILABS_USART_ASYNC
1031 err = uart_silabs_async_init(dev);
1032 if (err < 0) {
1033 return err;
1034 }
1035 #endif
1036 return pm_device_driver_init(dev, uart_silabs_pm_action);
1037 }
1038
uart_silabs_pm_action(const struct device * dev,enum pm_device_action action)1039 static int uart_silabs_pm_action(const struct device *dev, enum pm_device_action action)
1040 {
1041 int err;
1042 const struct uart_silabs_config *config = dev->config;
1043 __maybe_unused struct uart_silabs_data *data = dev->data;
1044
1045 if (action == PM_DEVICE_ACTION_RESUME) {
1046 err = clock_control_on(config->clock_dev,
1047 (clock_control_subsys_t)&config->clock_cfg);
1048 if (err < 0 && err != -EALREADY) {
1049 return err;
1050 }
1051
1052 err = pinctrl_apply_state(config->pcfg, PINCTRL_STATE_DEFAULT);
1053 if (err < 0) {
1054 return err;
1055 }
1056
1057 USART_Enable(config->base, usartEnable);
1058 } else if (IS_ENABLED(CONFIG_PM_DEVICE) && (action == PM_DEVICE_ACTION_SUSPEND)) {
1059 #ifdef CONFIG_UART_SILABS_USART_ASYNC
1060 /* Entering suspend requires there to be no active asynchronous calls. */
1061 __ASSERT_NO_MSG(!data->dma_rx.enabled);
1062 __ASSERT_NO_MSG(!data->dma_tx.enabled);
1063 #endif
1064 USART_Enable(config->base, usartDisable);
1065
1066 err = clock_control_off(config->clock_dev,
1067 (clock_control_subsys_t)&config->clock_cfg);
1068 if (err < 0) {
1069 return err;
1070 }
1071
1072 err = pinctrl_apply_state(config->pcfg, PINCTRL_STATE_SLEEP);
1073 if (err < 0 && err != -ENOENT) {
1074 return err;
1075 }
1076
1077 } else {
1078 return -ENOTSUP;
1079 }
1080
1081 return 0;
1082 }
1083
1084 static DEVICE_API(uart, uart_silabs_driver_api) = {
1085 .poll_in = uart_silabs_poll_in,
1086 .poll_out = uart_silabs_poll_out,
1087 .err_check = uart_silabs_err_check,
1088 #ifdef CONFIG_UART_USE_RUNTIME_CONFIGURE
1089 .configure = uart_silabs_configure,
1090 .config_get = uart_silabs_config_get,
1091 #endif
1092 #ifdef CONFIG_UART_INTERRUPT_DRIVEN
1093 .fifo_fill = uart_silabs_fifo_fill,
1094 .fifo_read = uart_silabs_fifo_read,
1095 .irq_tx_enable = uart_silabs_irq_tx_enable,
1096 .irq_tx_disable = uart_silabs_irq_tx_disable,
1097 .irq_tx_complete = uart_silabs_irq_tx_complete,
1098 .irq_tx_ready = uart_silabs_irq_tx_ready,
1099 .irq_rx_enable = uart_silabs_irq_rx_enable,
1100 .irq_rx_disable = uart_silabs_irq_rx_disable,
1101 .irq_rx_ready = uart_silabs_irq_rx_ready,
1102 .irq_err_enable = uart_silabs_irq_err_enable,
1103 .irq_err_disable = uart_silabs_irq_err_disable,
1104 .irq_is_pending = uart_silabs_irq_is_pending,
1105 .irq_update = uart_silabs_irq_update,
1106 .irq_callback_set = uart_silabs_irq_callback_set,
1107 #endif
1108 #ifdef CONFIG_UART_SILABS_USART_ASYNC
1109 .callback_set = uart_silabs_async_callback_set,
1110 .tx = uart_silabs_async_tx,
1111 .tx_abort = uart_silabs_async_tx_abort,
1112 .rx_enable = uart_silabs_async_rx_enable,
1113 .rx_disable = uart_silabs_async_rx_disable,
1114 .rx_buf_rsp = uart_silabs_async_rx_buf_rsp,
1115 #endif
1116 };
1117
1118 #ifdef CONFIG_UART_SILABS_USART_ASYNC
1119
1120 #define UART_DMA_CHANNEL_INIT(index, dir) \
1121 .dma_##dir = { \
1122 .dma_dev = DEVICE_DT_GET(DT_INST_DMAS_CTLR_BY_NAME(index, dir)), \
1123 .dma_cfg = { \
1124 .dma_slot = SILABS_LDMA_REQSEL_TO_SLOT( \
1125 DT_INST_DMAS_CELL_BY_NAME(index, dir, slot)), \
1126 .source_data_size = 1, \
1127 .dest_data_size = 1, \
1128 .source_burst_length = 1, \
1129 .dest_burst_length = 1, \
1130 .dma_callback = uart_silabs_dma_##dir##_cb, \
1131 } \
1132 },
1133 #define UART_DMA_CHANNEL(index, dir) \
1134 COND_CODE_1(DT_INST_NODE_HAS_PROP(index, dmas), \
1135 (UART_DMA_CHANNEL_INIT(index, dir)), ())
1136 #else
1137
1138 #define UART_DMA_CHANNEL(index, dir)
1139
1140 #endif
1141
1142 #define SILABS_USART_IRQ_HANDLER_FUNC(idx) .irq_config_func = usart_silabs_config_func_##idx,
1143 #define SILABS_USART_IRQ_HANDLER(idx) \
1144 static void usart_silabs_config_func_##idx(const struct device *dev) \
1145 { \
1146 IRQ_CONNECT(DT_INST_IRQ_BY_NAME(idx, rx, irq), \
1147 DT_INST_IRQ_BY_NAME(idx, rx, priority), uart_silabs_isr, \
1148 DEVICE_DT_INST_GET(idx), 0); \
1149 IRQ_CONNECT(DT_INST_IRQ_BY_NAME(idx, tx, irq), \
1150 DT_INST_IRQ_BY_NAME(idx, tx, priority), uart_silabs_isr, \
1151 DEVICE_DT_INST_GET(idx), 0); \
1152 \
1153 irq_enable(DT_INST_IRQ_BY_NAME(idx, rx, irq)); \
1154 irq_enable(DT_INST_IRQ_BY_NAME(idx, tx, irq)); \
1155 }
1156
1157 #define SILABS_USART_INIT(idx) \
1158 SILABS_USART_IRQ_HANDLER(idx); \
1159 PINCTRL_DT_INST_DEFINE(idx); \
1160 PM_DEVICE_DT_INST_DEFINE(idx, uart_silabs_pm_action); \
1161 \
1162 static struct uart_config uart_cfg_##idx = { \
1163 .baudrate = DT_INST_PROP(idx, current_speed), \
1164 .parity = DT_INST_ENUM_IDX(idx, parity), \
1165 .stop_bits = DT_INST_ENUM_IDX(idx, stop_bits), \
1166 .data_bits = DT_INST_ENUM_IDX(idx, data_bits), \
1167 .flow_ctrl = DT_INST_PROP(idx, hw_flow_control) ? UART_CFG_FLOW_CTRL_RTS_CTS \
1168 : UART_CFG_FLOW_CTRL_NONE, \
1169 }; \
1170 \
1171 static const struct uart_silabs_config uart_silabs_cfg_##idx = { \
1172 .pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(idx), \
1173 .base = (USART_TypeDef *)DT_INST_REG_ADDR(idx), \
1174 .clock_dev = DEVICE_DT_GET(DT_INST_CLOCKS_CTLR(idx)), \
1175 .clock_cfg = SILABS_DT_INST_CLOCK_CFG(idx), \
1176 SILABS_USART_IRQ_HANDLER_FUNC(idx) \
1177 }; \
1178 \
1179 static struct uart_silabs_data uart_silabs_data_##idx = { \
1180 .uart_cfg = &uart_cfg_##idx, \
1181 UART_DMA_CHANNEL(idx, rx) \
1182 UART_DMA_CHANNEL(idx, tx) \
1183 }; \
1184 \
1185 DEVICE_DT_INST_DEFINE(idx, uart_silabs_init, PM_DEVICE_DT_INST_GET(idx), \
1186 &uart_silabs_data_##idx, &uart_silabs_cfg_##idx, PRE_KERNEL_1, \
1187 CONFIG_SERIAL_INIT_PRIORITY, &uart_silabs_driver_api);
1188
1189 DT_INST_FOREACH_STATUS_OKAY(SILABS_USART_INIT)
1190