1 /*
2 * Copyright (c) 2017, Christian Taedcke
3 * Copyright (c) 2020 Lemonbeat GmbH
4 *
5 * SPDX-License-Identifier: Apache-2.0
6 */
7
8 #include <errno.h>
9 #include <zephyr/drivers/uart.h>
10 #include <zephyr/irq.h>
11 #include <zephyr/pm/device.h>
12 #include <em_usart.h>
13 #include <em_cmu.h>
14 #include <soc.h>
15
16 #ifdef CONFIG_PINCTRL
17 #include <zephyr/drivers/pinctrl.h>
18 #else
19 #include <em_gpio.h>
20 #endif /* CONFIG_PINCTRL */
21
22 #if DT_NODE_HAS_PROP(id, peripheral_id)
23 #define USART_PREFIX cmuClock_USART
24 #define UART_PREFIX cmuClock_UART
25 #define CLOCK_USART(id) _CONCAT(USART_PREFIX, id)
26 #define CLOCK_UART(id) _CONCAT(UART_PREFIX, id)
27 #define GET_GECKO_USART_CLOCK(id) \
28 .clock = CLOCK_USART(DT_INST_PROP(id, peripheral_id)),
29 #define GET_GECKO_UART_CLOCK(id) \
30 .clock = CLOCK_UART(DT_INST_PROP(id, peripheral_id)),
31 #else
32 #if (USART_COUNT == 1)
33 #define CLOCK_USART(ref) (((ref) == USART0) ? cmuClock_USART0 \
34 : -1)
35 #elif (USART_COUNT == 2)
36 #define CLOCK_USART(ref) (((ref) == USART0) ? cmuClock_USART0 \
37 : ((ref) == USART1) ? cmuClock_USART1 \
38 : -1)
39 #elif (USART_COUNT == 3)
40 #define CLOCK_USART(ref) (((ref) == USART0) ? cmuClock_USART0 \
41 : ((ref) == USART1) ? cmuClock_USART1 \
42 : ((ref) == USART2) ? cmuClock_USART2 \
43 : -1)
44 #elif (USART_COUNT == 4)
45 #define CLOCK_USART(ref) (((ref) == USART0) ? cmuClock_USART0 \
46 : ((ref) == USART1) ? cmuClock_USART1 \
47 : ((ref) == USART2) ? cmuClock_USART2 \
48 : ((ref) == USART3) ? cmuClock_USART3 \
49 : -1)
50 #elif (USART_COUNT == 5)
51 #define CLOCK_USART(ref) (((ref) == USART0) ? cmuClock_USART0 \
52 : ((ref) == USART1) ? cmuClock_USART1 \
53 : ((ref) == USART2) ? cmuClock_USART2 \
54 : ((ref) == USART3) ? cmuClock_USART3 \
55 : ((ref) == USART4) ? cmuClock_USART4 \
56 : -1)
57 #elif (USART_COUNT == 6)
58 #define CLOCK_USART(ref) (((ref) == USART0) ? cmuClock_USART0 \
59 : ((ref) == USART1) ? cmuClock_USART1 \
60 : ((ref) == USART2) ? cmuClock_USART2 \
61 : ((ref) == USART3) ? cmuClock_USART3 \
62 : ((ref) == USART4) ? cmuClock_USART4 \
63 : ((ref) == USART5) ? cmuClock_USART5 \
64 : -1)
65 #else
66 #error "Undefined number of USARTs."
67 #endif /* USART_COUNT */
68
69 #define CLOCK_UART(ref) (((ref) == UART0) ? cmuClock_UART0 \
70 : ((ref) == UART1) ? cmuClock_UART1 \
71 : -1)
72 #define GET_GECKO_USART_CLOCK(id) \
73 .clock = CLOCK_USART((USART_TypeDef *)DT_INST_REG_ADDR(id)),
74 #define GET_GECKO_UART_CLOCK(id) \
75 .clock = CLOCK_UART((USART_TypeDef *)DT_INST_REG_ADDR(id)),
76 #endif /* DT_NODE_HAS_PROP(id, peripheral_id) */
77
78 /* Helper define to determine if SOC supports hardware flow control */
79 #if ((_SILICON_LABS_32B_SERIES > 0) || \
80 (defined(_USART_ROUTEPEN_RTSPEN_MASK) && \
81 defined(_USART_ROUTEPEN_CTSPEN_MASK)))
82 #define HW_FLOWCONTROL_IS_SUPPORTED_BY_SOC
83 #endif
84
85 #define HAS_HFC_OR(inst) DT_INST_PROP(inst, hw_flow_control) ||
86
87 #define DT_DRV_COMPAT silabs_gecko_uart
88
89 /* Has any enabled uart instance hw-flow-control enabled? */
90 #define UART_GECKO_UART_HW_FLOW_CONTROL_ENABLED \
91 DT_INST_FOREACH_STATUS_OKAY(HAS_HFC_OR) 0
92
93 #undef DT_DRV_COMPAT
94 #define DT_DRV_COMPAT silabs_gecko_usart
95
96 /* Has any enabled usart instance hw-flow-control enabled? */
97 #define UART_GECKO_USART_HW_FLOW_CONTROL_ENABLED \
98 DT_INST_FOREACH_STATUS_OKAY(HAS_HFC_OR) 0
99
100 #if UART_GECKO_USART_HW_FLOW_CONTROL_ENABLED || \
101 UART_GECKO_UART_HW_FLOW_CONTROL_ENABLED
102 #define UART_GECKO_HW_FLOW_CONTROL
103 #endif
104
105 /* Sanity check for hardware flow control */
106 #if defined(UART_GECKO_HW_FLOW_CONTROL) && \
107 (!(defined(HW_FLOWCONTROL_IS_SUPPORTED_BY_SOC)))
108 #error "Hardware flow control is activated for at least one UART/USART, \
109 but not supported by this SOC"
110 #endif
111
112 #if defined(UART_GECKO_HW_FLOW_CONTROL) && \
113 (!defined(CONFIG_SOC_GECKO_HAS_INDIVIDUAL_PIN_LOCATION) && \
114 !defined(GPIO_USART_ROUTEEN_RTSPEN))
115 #error "Driver not supporting hardware flow control for this SOC"
116 #endif
117
118 /**
119 * @brief Config struct for UART
120 */
121
122 struct uart_gecko_config {
123 #ifdef CONFIG_PINCTRL
124 const struct pinctrl_dev_config *pcfg;
125 #endif /* CONFIG_PINCTRL */
126 USART_TypeDef *base;
127 CMU_Clock_TypeDef clock;
128 #ifdef CONFIG_UART_INTERRUPT_DRIVEN
129 void (*irq_config_func)(const struct device *dev);
130 #endif /* CONFIG_UART_INTERRUPT_DRIVEN */
131 #ifndef CONFIG_PINCTRL
132 struct soc_gpio_pin pin_rx;
133 struct soc_gpio_pin pin_tx;
134 #ifdef UART_GECKO_HW_FLOW_CONTROL
135 struct soc_gpio_pin pin_rts;
136 struct soc_gpio_pin pin_cts;
137 #endif /* UART_GECKO_HW_FLOW_CONTROL */
138 #ifdef CONFIG_SOC_GECKO_HAS_INDIVIDUAL_PIN_LOCATION
139 uint8_t loc_rx;
140 uint8_t loc_tx;
141 #ifdef UART_GECKO_HW_FLOW_CONTROL
142 uint8_t loc_rts;
143 uint8_t loc_cts;
144 #endif /* UART_GECKO_HW_FLOW_CONTROL */
145 #else /* CONFIG_SOC_GECKO_HAS_INDIVIDUAL_PIN_LOCATION */
146 uint8_t loc;
147 #endif /* CONFIG_SOC_GECKO_HAS_INDIVIDUAL_PIN_LOCATION */
148 #endif
149 };
150
151 struct uart_gecko_data {
152 struct uart_config *uart_cfg;
153 #ifdef CONFIG_UART_INTERRUPT_DRIVEN
154 uart_irq_callback_user_data_t callback;
155 void *cb_data;
156 #endif
157 };
158
uart_gecko_poll_in(const struct device * dev,unsigned char * c)159 static int uart_gecko_poll_in(const struct device *dev, unsigned char *c)
160 {
161 const struct uart_gecko_config *config = dev->config;
162 uint32_t flags = USART_StatusGet(config->base);
163
164 if (flags & USART_STATUS_RXDATAV) {
165 *c = USART_Rx(config->base);
166 return 0;
167 }
168
169 return -1;
170 }
171
uart_gecko_poll_out(const struct device * dev,unsigned char c)172 static void uart_gecko_poll_out(const struct device *dev, unsigned char c)
173 {
174 const struct uart_gecko_config *config = dev->config;
175
176 USART_Tx(config->base, c);
177 }
178
uart_gecko_err_check(const struct device * dev)179 static int uart_gecko_err_check(const struct device *dev)
180 {
181 const struct uart_gecko_config *config = dev->config;
182 uint32_t flags = USART_IntGet(config->base);
183 int err = 0;
184
185 if (flags & USART_IF_RXOF) {
186 err |= UART_ERROR_OVERRUN;
187 }
188
189 if (flags & USART_IF_PERR) {
190 err |= UART_ERROR_PARITY;
191 }
192
193 if (flags & USART_IF_FERR) {
194 err |= UART_ERROR_FRAMING;
195 }
196
197 USART_IntClear(config->base, USART_IF_RXOF |
198 USART_IF_PERR |
199 USART_IF_FERR);
200
201 return err;
202 }
203
204 #ifdef CONFIG_UART_INTERRUPT_DRIVEN
uart_gecko_fifo_fill(const struct device * dev,const uint8_t * tx_data,int len)205 static int uart_gecko_fifo_fill(const struct device *dev, const uint8_t *tx_data,
206 int len)
207 {
208 const struct uart_gecko_config *config = dev->config;
209 int num_tx = 0U;
210
211 while ((len - num_tx > 0) &&
212 (config->base->STATUS & USART_STATUS_TXBL)) {
213
214 config->base->TXDATA = (uint32_t)tx_data[num_tx++];
215 }
216
217 return num_tx;
218 }
219
uart_gecko_fifo_read(const struct device * dev,uint8_t * rx_data,const int len)220 static int uart_gecko_fifo_read(const struct device *dev, uint8_t *rx_data,
221 const int len)
222 {
223 const struct uart_gecko_config *config = dev->config;
224 int num_rx = 0U;
225
226 while ((len - num_rx > 0) &&
227 (config->base->STATUS & USART_STATUS_RXDATAV)) {
228
229 rx_data[num_rx++] = (uint8_t)config->base->RXDATA;
230 }
231
232 return num_rx;
233 }
234
uart_gecko_irq_tx_enable(const struct device * dev)235 static void uart_gecko_irq_tx_enable(const struct device *dev)
236 {
237 const struct uart_gecko_config *config = dev->config;
238 uint32_t mask = USART_IEN_TXBL | USART_IEN_TXC;
239
240 USART_IntEnable(config->base, mask);
241 }
242
uart_gecko_irq_tx_disable(const struct device * dev)243 static void uart_gecko_irq_tx_disable(const struct device *dev)
244 {
245 const struct uart_gecko_config *config = dev->config;
246 uint32_t mask = USART_IEN_TXBL | USART_IEN_TXC;
247
248 USART_IntDisable(config->base, mask);
249 }
250
uart_gecko_irq_tx_complete(const struct device * dev)251 static int uart_gecko_irq_tx_complete(const struct device *dev)
252 {
253 const struct uart_gecko_config *config = dev->config;
254 uint32_t flags = USART_IntGet(config->base);
255
256 USART_IntClear(config->base, USART_IF_TXC);
257
258 return (flags & USART_IF_TXC) != 0U;
259 }
260
uart_gecko_irq_tx_ready(const struct device * dev)261 static int uart_gecko_irq_tx_ready(const struct device *dev)
262 {
263 const struct uart_gecko_config *config = dev->config;
264 uint32_t flags = USART_IntGetEnabled(config->base);
265
266 return (flags & USART_IF_TXBL) != 0U;
267 }
268
uart_gecko_irq_rx_enable(const struct device * dev)269 static void uart_gecko_irq_rx_enable(const struct device *dev)
270 {
271 const struct uart_gecko_config *config = dev->config;
272 uint32_t mask = USART_IEN_RXDATAV;
273
274 USART_IntEnable(config->base, mask);
275 }
276
uart_gecko_irq_rx_disable(const struct device * dev)277 static void uart_gecko_irq_rx_disable(const struct device *dev)
278 {
279 const struct uart_gecko_config *config = dev->config;
280 uint32_t mask = USART_IEN_RXDATAV;
281
282 USART_IntDisable(config->base, mask);
283 }
284
uart_gecko_irq_rx_full(const struct device * dev)285 static int uart_gecko_irq_rx_full(const struct device *dev)
286 {
287 const struct uart_gecko_config *config = dev->config;
288 uint32_t flags = USART_IntGet(config->base);
289
290 return (flags & USART_IF_RXDATAV) != 0U;
291 }
292
uart_gecko_irq_rx_ready(const struct device * dev)293 static int uart_gecko_irq_rx_ready(const struct device *dev)
294 {
295 const struct uart_gecko_config *config = dev->config;
296 uint32_t mask = USART_IEN_RXDATAV;
297
298 return (config->base->IEN & mask)
299 && uart_gecko_irq_rx_full(dev);
300 }
301
uart_gecko_irq_err_enable(const struct device * dev)302 static void uart_gecko_irq_err_enable(const struct device *dev)
303 {
304 const struct uart_gecko_config *config = dev->config;
305
306 USART_IntEnable(config->base, USART_IF_RXOF |
307 USART_IF_PERR |
308 USART_IF_FERR);
309 }
310
uart_gecko_irq_err_disable(const struct device * dev)311 static void uart_gecko_irq_err_disable(const struct device *dev)
312 {
313 const struct uart_gecko_config *config = dev->config;
314
315 USART_IntDisable(config->base, USART_IF_RXOF |
316 USART_IF_PERR |
317 USART_IF_FERR);
318 }
319
uart_gecko_irq_is_pending(const struct device * dev)320 static int uart_gecko_irq_is_pending(const struct device *dev)
321 {
322 return uart_gecko_irq_tx_ready(dev) || uart_gecko_irq_rx_ready(dev);
323 }
324
uart_gecko_irq_update(const struct device * dev)325 static int uart_gecko_irq_update(const struct device *dev)
326 {
327 return 1;
328 }
329
uart_gecko_irq_callback_set(const struct device * dev,uart_irq_callback_user_data_t cb,void * cb_data)330 static void uart_gecko_irq_callback_set(const struct device *dev,
331 uart_irq_callback_user_data_t cb,
332 void *cb_data)
333 {
334 struct uart_gecko_data *data = dev->data;
335
336 data->callback = cb;
337 data->cb_data = cb_data;
338 }
339
uart_gecko_isr(const struct device * dev)340 static void uart_gecko_isr(const struct device *dev)
341 {
342 struct uart_gecko_data *data = dev->data;
343
344 if (data->callback) {
345 data->callback(dev, data->cb_data);
346 }
347 }
348 #endif /* CONFIG_UART_INTERRUPT_DRIVEN */
349
350 /**
351 * @brief Subroutine initializer of UART pins
352 *
353 * @param dev UART device to configure
354 */
355 #ifndef CONFIG_PINCTRL
uart_gecko_init_pins(const struct device * dev)356 static void uart_gecko_init_pins(const struct device *dev)
357 {
358 const struct uart_gecko_config *config = dev->config;
359
360 /* Configure RX and TX */
361 GPIO_PinModeSet(config->pin_rx.port, config->pin_rx.pin,
362 config->pin_rx.mode, config->pin_rx.out);
363 GPIO_PinModeSet(config->pin_tx.port, config->pin_tx.pin,
364 config->pin_tx.mode, config->pin_tx.out);
365
366 #ifdef CONFIG_SOC_GECKO_HAS_INDIVIDUAL_PIN_LOCATION
367 /* For SOCs with configurable pin locations (set in SOC Kconfig) */
368 config->base->ROUTEPEN = USART_ROUTEPEN_RXPEN | USART_ROUTEPEN_TXPEN;
369 config->base->ROUTELOC0 =
370 (config->loc_tx << _USART_ROUTELOC0_TXLOC_SHIFT) |
371 (config->loc_rx << _USART_ROUTELOC0_RXLOC_SHIFT);
372 config->base->ROUTELOC1 = _USART_ROUTELOC1_RESETVALUE;
373 #elif defined(USART_ROUTE_RXPEN) && defined(USART_ROUTE_TXPEN)
374 /* For olders SOCs with only one pin location */
375 config->base->ROUTE = USART_ROUTE_RXPEN | USART_ROUTE_TXPEN
376 | (config->loc << 8);
377 #elif defined(GPIO_USART_ROUTEEN_RXPEN) && defined(GPIO_USART_ROUTEEN_TXPEN)
378 GPIO->USARTROUTE[USART_NUM(config->base)].ROUTEEN =
379 GPIO_USART_ROUTEEN_TXPEN | GPIO_USART_ROUTEEN_RXPEN;
380 GPIO->USARTROUTE[USART_NUM(config->base)].TXROUTE =
381 (config->pin_tx.pin << _GPIO_USART_TXROUTE_PIN_SHIFT) |
382 (config->pin_tx.port << _GPIO_USART_TXROUTE_PORT_SHIFT);
383 GPIO->USARTROUTE[USART_NUM(config->base)].RXROUTE =
384 (config->pin_rx.pin << _GPIO_USART_RXROUTE_PIN_SHIFT) |
385 (config->pin_rx.port << _GPIO_USART_RXROUTE_PORT_SHIFT);
386 #endif /* CONFIG_SOC_GECKO_HAS_INDIVIDUAL_PIN_LOCATION */
387
388 #ifdef UART_GECKO_HW_FLOW_CONTROL
389 const struct uart_gecko_data *data = dev->data;
390 const struct uart_config *uart_cfg = data->uart_cfg;
391 /* Configure HW flow control (RTS, CTS) */
392 if (uart_cfg->flow_ctrl) {
393 GPIO_PinModeSet(config->pin_rts.port, config->pin_rts.pin,
394 config->pin_rts.mode, config->pin_rts.out);
395 GPIO_PinModeSet(config->pin_cts.port, config->pin_cts.pin,
396 config->pin_cts.mode, config->pin_cts.out);
397
398 #ifdef CONFIG_SOC_GECKO_HAS_INDIVIDUAL_PIN_LOCATION
399 config->base->ROUTEPEN =
400 USART_ROUTEPEN_RXPEN |
401 USART_ROUTEPEN_TXPEN |
402 USART_ROUTEPEN_RTSPEN |
403 USART_ROUTEPEN_CTSPEN;
404
405 config->base->ROUTELOC1 =
406 (config->loc_rts << _USART_ROUTELOC1_RTSLOC_SHIFT) |
407 (config->loc_cts << _USART_ROUTELOC1_CTSLOC_SHIFT);
408 #elif defined(GPIO_USART_ROUTEEN_RTSPEN) && defined(GPIO_USART_ROUTEEN_CTSPEN)
409 GPIO->USARTROUTE[USART_NUM(config->base)].ROUTEEN =
410 GPIO_USART_ROUTEEN_TXPEN |
411 GPIO_USART_ROUTEEN_RXPEN |
412 GPIO_USART_ROUTEPEN_RTSPEN |
413 GPIO_USART_ROUTEPEN_CTSPEN;
414
415 GPIO->USARTROUTE[USART_NUM(config->base)].RTSROUTE =
416 (config->pin_rts.pin << _GPIO_USART_RTSROUTE_PIN_SHIFT) |
417 (config->pin_rts.port << _GPIO_USART_RTSROUTE_PORT_SHIFT);
418 GPIO->USARTROUTE[USART_NUM(config->base)].CTSROUTE =
419 (config->pin_cts.pin << _GPIO_USART_CTSROUTE_PIN_SHIFT) |
420 (config->pin_cts.port << _GPIO_USART_CTSROUTE_PORT_SHIFT);
421 #endif /* CONFIG_SOC_GECKO_HAS_INDIVIDUAL_PIN_LOCATION */
422 }
423 #endif /* UART_GECKO_HW_FLOW_CONTROL */
424 }
425 #endif /* !CONFIG_PINCTRL */
426
uart_gecko_cfg2ll_parity(enum uart_config_parity parity)427 static inline USART_Parity_TypeDef uart_gecko_cfg2ll_parity(enum uart_config_parity parity)
428 {
429 switch (parity) {
430 case UART_CFG_PARITY_ODD:
431 return usartOddParity;
432 case UART_CFG_PARITY_EVEN:
433 return usartEvenParity;
434 case UART_CFG_PARITY_NONE:
435 default:
436 return usartNoParity;
437 }
438 }
439
uart_gecko_ll2cfg_parity(USART_Parity_TypeDef parity)440 static inline enum uart_config_parity uart_gecko_ll2cfg_parity(USART_Parity_TypeDef parity)
441 {
442 switch (parity) {
443 case usartOddParity:
444 return UART_CFG_PARITY_ODD;
445 case usartEvenParity:
446 return UART_CFG_PARITY_EVEN;
447 case usartNoParity:
448 default:
449 return UART_CFG_PARITY_NONE;
450 }
451 }
452
uart_gecko_cfg2ll_stopbits(enum uart_config_stop_bits sb)453 static inline USART_Stopbits_TypeDef uart_gecko_cfg2ll_stopbits(enum uart_config_stop_bits sb)
454 {
455 switch (sb) {
456 case UART_CFG_STOP_BITS_0_5:
457 return usartStopbits0p5;
458 case UART_CFG_STOP_BITS_1:
459 return usartStopbits1;
460 case UART_CFG_STOP_BITS_2:
461 return usartStopbits2;
462 case UART_CFG_STOP_BITS_1_5:
463 return usartStopbits1p5;
464 default:
465 return usartStopbits1;
466 }
467 }
468
uart_gecko_ll2cfg_stopbits(USART_Stopbits_TypeDef sb)469 static inline enum uart_config_stop_bits uart_gecko_ll2cfg_stopbits(USART_Stopbits_TypeDef sb)
470 {
471 switch (sb) {
472 case usartStopbits0p5:
473 return UART_CFG_STOP_BITS_0_5;
474 case usartStopbits1:
475 return UART_CFG_STOP_BITS_1;
476 case usartStopbits1p5:
477 return UART_CFG_STOP_BITS_1_5;
478 case usartStopbits2:
479 return UART_CFG_STOP_BITS_2;
480 default:
481 return UART_CFG_STOP_BITS_1;
482 }
483 }
484
uart_gecko_cfg2ll_databits(enum uart_config_data_bits db,enum uart_config_parity p)485 static inline USART_Databits_TypeDef uart_gecko_cfg2ll_databits(enum uart_config_data_bits db,
486 enum uart_config_parity p)
487 {
488 switch (db) {
489 case UART_CFG_DATA_BITS_7:
490 if (p == UART_CFG_PARITY_NONE) {
491 return usartDatabits7;
492 } else {
493 return usartDatabits8;
494 }
495 case UART_CFG_DATA_BITS_9:
496 return usartDatabits9;
497 case UART_CFG_DATA_BITS_8:
498 default:
499 if (p == UART_CFG_PARITY_NONE) {
500 return usartDatabits8;
501 } else {
502 return usartDatabits9;
503 }
504 return usartDatabits8;
505 }
506 }
507
uart_gecko_ll2cfg_databits(USART_Databits_TypeDef db,USART_Parity_TypeDef p)508 static inline enum uart_config_data_bits uart_gecko_ll2cfg_databits(USART_Databits_TypeDef db,
509 USART_Parity_TypeDef p)
510 {
511 switch (db) {
512 case usartDatabits7:
513 if (p == usartNoParity) {
514 return UART_CFG_DATA_BITS_7;
515 } else {
516 return UART_CFG_DATA_BITS_6;
517 }
518 case usartDatabits9:
519 if (p == usartNoParity) {
520 return UART_CFG_DATA_BITS_9;
521 } else {
522 return UART_CFG_DATA_BITS_8;
523 }
524 case usartDatabits8:
525 default:
526 if (p == usartNoParity) {
527 return UART_CFG_DATA_BITS_8;
528 } else {
529 return UART_CFG_DATA_BITS_7;
530 }
531 }
532 }
533
534 #if UART_GECKO_HW_FLOW_CONTROL
535 /**
536 * @brief Get LL hardware flow control define from
537 * Zephyr hardware flow control option.
538 * @note Supports only UART_CFG_FLOW_CTRL_RTS_CTS and UART_CFG_FLOW_CTRL_RS485.
539 * @param fc: Zephyr hardware flow control option.
540 * @retval usartHwFlowControlCtsAndRts, or usartHwFlowControlNone.
541 */
uart_gecko_cfg2ll_hwctrl(enum uart_config_flow_control fc)542 static inline USART_HwFlowControl_TypeDef uart_gecko_cfg2ll_hwctrl(
543 enum uart_config_flow_control fc)
544 {
545 if (fc == UART_CFG_FLOW_CTRL_RTS_CTS) {
546 return usartHwFlowControlCtsAndRts;
547 }
548
549 return usartHwFlowControlNone;
550 }
551
552 /**
553 * @brief Get Zephyr hardware flow control option from
554 * LL hardware flow control define.
555 * @note Supports only usartHwFlowControlCtsAndRts.
556 * @param fc: LL hardware flow control definition.
557 * @retval UART_CFG_FLOW_CTRL_RTS_CTS, or UART_CFG_FLOW_CTRL_NONE.
558 */
uart_gecko_ll2cfg_hwctrl(USART_HwFlowControl_TypeDef fc)559 static inline enum uart_config_flow_control uart_gecko_ll2cfg_hwctrl(
560 USART_HwFlowControl_TypeDef fc)
561 {
562 if (fc == usartHwFlowControlCtsAndRts) {
563 return UART_CFG_FLOW_CTRL_RTS_CTS;
564 }
565
566 return UART_CFG_FLOW_CTRL_NONE;
567 }
568 #endif
569
570 #ifdef CONFIG_UART_USE_RUNTIME_CONFIGURE
uart_gecko_configure(const struct device * dev,const struct uart_config * cfg)571 static int uart_gecko_configure(const struct device *dev,
572 const struct uart_config *cfg)
573 {
574 const struct uart_gecko_config *config = dev->config;
575 USART_TypeDef *base = config->base;
576 struct uart_gecko_data *data = dev->data;
577 struct uart_config *uart_cfg = data->uart_cfg;
578
579 if (uart_cfg->parity != cfg->parity) {
580 return -ENOTSUP;
581 }
582
583 if (uart_cfg->stop_bits != cfg->stop_bits) {
584 return -ENOTSUP;
585 }
586
587 if (uart_cfg->data_bits != cfg->data_bits) {
588 return -ENOTSUP;
589 }
590
591 if (uart_cfg->flow_ctrl != cfg->flow_ctrl) {
592 return -ENOTSUP;
593 }
594
595 USART_BaudrateAsyncSet(base, 0, cfg->baudrate, usartOVS16);
596
597 /* Upon successful configuration, persist the syscall-passed
598 * uart_config.
599 * This allows restoring it, should the device return from a low-power
600 * mode in which register contents are lost.
601 */
602 *uart_cfg = *cfg;
603
604 return 0;
605 };
606
uart_gecko_config_get(const struct device * dev,struct uart_config * cfg)607 static int uart_gecko_config_get(const struct device *dev,
608 struct uart_config *cfg)
609 {
610 struct uart_gecko_data *data = dev->data;
611 struct uart_config *uart_cfg = data->uart_cfg;
612
613 cfg->baudrate = uart_cfg->baudrate;
614 cfg->parity = uart_cfg->parity;
615 cfg->stop_bits = uart_cfg->stop_bits;
616 cfg->data_bits = uart_cfg->data_bits;
617 cfg->flow_ctrl = uart_cfg->flow_ctrl;
618
619 return 0;
620 }
621 #endif /* CONFIG_UART_USE_RUNTIME_CONFIGURE */
622
623 /**
624 * @brief Main initializer for UART
625 *
626 * @param dev UART device to be initialized
627 * @return int 0
628 */
uart_gecko_init(const struct device * dev)629 static int uart_gecko_init(const struct device *dev)
630 {
631 #ifdef CONFIG_PINCTRL
632 int err;
633 #endif /* CONFIG_PINCTRL */
634 const struct uart_gecko_config *config = dev->config;
635 const struct uart_gecko_data *data = dev->data;
636 const struct uart_config *uart_cfg = data->uart_cfg;
637
638 USART_InitAsync_TypeDef usartInit = USART_INITASYNC_DEFAULT;
639
640 /* The peripheral and gpio clock are already enabled from soc and gpio driver */
641 /* Enable USART clock */
642 CMU_ClockEnable(config->clock, true);
643
644 /* Init USART */
645 usartInit.baudrate = uart_cfg->baudrate;
646 usartInit.parity = uart_gecko_cfg2ll_parity(uart_cfg->parity);
647 usartInit.stopbits = uart_gecko_cfg2ll_stopbits(uart_cfg->stop_bits);
648 usartInit.databits = uart_gecko_cfg2ll_databits(uart_cfg->data_bits, uart_cfg->parity);
649 #ifdef UART_GECKO_HW_FLOW_CONTROL
650 usartInit.hwFlowControl = uart_cfg->flow_ctrl ?
651 usartHwFlowControlCtsAndRts : usartHwFlowControlNone;
652 #endif
653 USART_InitAsync(config->base, &usartInit);
654
655 #ifdef CONFIG_PINCTRL
656 err = pinctrl_apply_state(config->pcfg, PINCTRL_STATE_DEFAULT);
657 if (err < 0) {
658 return err;
659 }
660 #else
661 /* Initialize USART pins */
662 uart_gecko_init_pins(dev);
663 #endif /* CONFIG_PINCTRL */
664
665 #ifdef CONFIG_UART_INTERRUPT_DRIVEN
666 config->irq_config_func(dev);
667 #endif
668
669 return 0;
670 }
671
672 #ifdef CONFIG_PM_DEVICE
uart_gecko_pm_action(const struct device * dev,enum pm_device_action action)673 static int uart_gecko_pm_action(const struct device *dev, enum pm_device_action action)
674 {
675 __maybe_unused const struct uart_gecko_config *config = dev->config;
676
677 switch (action) {
678 case PM_DEVICE_ACTION_SUSPEND:
679 #ifdef USART_STATUS_TXIDLE
680 /* Wait for TX FIFO to flush before suspending */
681 while (!(USART_StatusGet(config->base) & USART_STATUS_TXIDLE)) {
682 }
683 #endif
684 break;
685
686 case PM_DEVICE_ACTION_RESUME:
687 break;
688
689 default:
690 return -ENOTSUP;
691 }
692
693 return 0;
694 }
695 #endif
696
697 static DEVICE_API(uart, uart_gecko_driver_api) = {
698 .poll_in = uart_gecko_poll_in,
699 .poll_out = uart_gecko_poll_out,
700 .err_check = uart_gecko_err_check,
701 #ifdef CONFIG_UART_USE_RUNTIME_CONFIGURE
702 .configure = uart_gecko_configure,
703 .config_get = uart_gecko_config_get,
704 #endif /* CONFIG_UART_USE_RUNTIME_CONFIGURE */
705 #ifdef CONFIG_UART_INTERRUPT_DRIVEN
706 .fifo_fill = uart_gecko_fifo_fill,
707 .fifo_read = uart_gecko_fifo_read,
708 .irq_tx_enable = uart_gecko_irq_tx_enable,
709 .irq_tx_disable = uart_gecko_irq_tx_disable,
710 .irq_tx_complete = uart_gecko_irq_tx_complete,
711 .irq_tx_ready = uart_gecko_irq_tx_ready,
712 .irq_rx_enable = uart_gecko_irq_rx_enable,
713 .irq_rx_disable = uart_gecko_irq_rx_disable,
714 .irq_rx_ready = uart_gecko_irq_rx_ready,
715 .irq_err_enable = uart_gecko_irq_err_enable,
716 .irq_err_disable = uart_gecko_irq_err_disable,
717 .irq_is_pending = uart_gecko_irq_is_pending,
718 .irq_update = uart_gecko_irq_update,
719 .irq_callback_set = uart_gecko_irq_callback_set,
720 #endif
721 };
722
723 #undef DT_DRV_COMPAT
724 #define DT_DRV_COMPAT silabs_gecko_uart
725
726 #ifdef CONFIG_UART_INTERRUPT_DRIVEN
727 #define GECKO_UART_IRQ_HANDLER_DECL(idx) \
728 static void uart_gecko_config_func_##idx(const struct device *dev)
729 #define GECKO_UART_IRQ_HANDLER_FUNC(idx) \
730 .irq_config_func = uart_gecko_config_func_##idx,
731 #define GECKO_UART_IRQ_HANDLER(idx) \
732 static void uart_gecko_config_func_##idx(const struct device *dev) \
733 { \
734 IRQ_CONNECT(DT_INST_IRQ_BY_NAME(idx, rx, irq), \
735 DT_INST_IRQ_BY_NAME(idx, rx, priority), \
736 uart_gecko_isr, DEVICE_DT_INST_GET(idx), 0); \
737 IRQ_CONNECT(DT_INST_IRQ_BY_NAME(idx, tx, irq), \
738 DT_INST_IRQ_BY_NAME(idx, tx, priority), \
739 uart_gecko_isr, DEVICE_DT_INST_GET(idx), 0); \
740 \
741 irq_enable(DT_INST_IRQ_BY_NAME(idx, rx, irq)); \
742 irq_enable(DT_INST_IRQ_BY_NAME(idx, tx, irq)); \
743 }
744 #else /* CONFIG_UART_INTERRUPT_DRIVEN */
745 #define GECKO_UART_IRQ_HANDLER_DECL(idx)
746 #define GECKO_UART_IRQ_HANDLER_FUNC(idx)
747 #define GECKO_UART_IRQ_HANDLER(idx)
748 #endif /* CONFIG_UART_INTERRUPT_DRIVEN */
749
750 #ifdef CONFIG_SOC_GECKO_HAS_INDIVIDUAL_PIN_LOCATION
751 #define GECKO_UART_RX_TX_PIN_LOCATIONS(idx) \
752 .loc_rx = DT_INST_PROP_BY_IDX(idx, location_rx, 0), \
753 .loc_tx = DT_INST_PROP_BY_IDX(idx, location_tx, 0),
754 #define VALIDATE_GECKO_UART_RX_TX_PIN_LOCATIONS(idx)
755 #else
756 #define GECKO_UART_RX_TX_PIN_LOCATIONS(idx) \
757 .loc = DT_INST_PROP_BY_IDX(idx, location_rx, 0),
758 #define VALIDATE_GECKO_UART_RX_TX_PIN_LOCATIONS(idx) \
759 BUILD_ASSERT(DT_INST_PROP_BY_IDX(idx, location_rx, 0) == \
760 DT_INST_PROP_BY_IDX(idx, location_tx, 0), \
761 "DTS location-* properties must have identical value")
762 #endif
763
764 #define PIN_UART_RXD(idx) \
765 { \
766 DT_INST_PROP_BY_IDX(idx, location_rx, 1), \
767 DT_INST_PROP_BY_IDX(idx, location_rx, 2), \
768 gpioModeInput, 1 \
769 }
770 #define PIN_UART_TXD(idx) \
771 { \
772 DT_INST_PROP_BY_IDX(idx, location_tx, 1), \
773 DT_INST_PROP_BY_IDX(idx, location_tx, 2), \
774 gpioModePushPull, 1 \
775 }
776
777 #define GECKO_UART_RX_TX_PINS(idx) \
778 .pin_rx = PIN_UART_RXD(idx), \
779 .pin_tx = PIN_UART_TXD(idx),
780
781 #ifdef UART_GECKO_HW_FLOW_CONTROL
782
783 #ifdef CONFIG_SOC_GECKO_HAS_INDIVIDUAL_PIN_LOCATION
784 #define GECKO_UART_RTS_CTS_PIN_LOCATIONS(idx) \
785 .loc_rts = COND_CODE_1(DT_INST_PROP(idx, hw_flow_control), \
786 (DT_INST_PROP_BY_IDX(idx, location_rts, 0)), \
787 (0)), \
788 .loc_cts = COND_CODE_1(DT_INST_PROP(idx, hw_flow_control), \
789 (DT_INST_PROP_BY_IDX(idx, location_cts, 0)), \
790 (0)),
791 #define VALIDATE_GECKO_UART_RTS_CTS_PIN_LOCATIONS(idx) \
792 COND_CODE_1(DT_INST_PROP(idx, hw_flow_control), \
793 (BUILD_ASSERT(DT_INST_NODE_HAS_PROP(idx, location_rts) && \
794 DT_INST_NODE_HAS_PROP(idx, location_cts), \
795 "DTS location-rts and location-cts are mandatory")), \
796 ())
797 #else /* CONFIG_SOC_GECKO_HAS_INDIVIDUAL_PIN_LOCATION */
798 /* Hardware flow control not supported for these SOCs */
799 #define GECKO_UART_RTS_CTS_PIN_LOCATIONS(idx)
800 #define VALIDATE_GECKO_UART_RTS_CTS_PIN_LOCATIONS(idx)
801 #endif /* CONFIG_SOC_GECKO_HAS_INDIVIDUAL_PIN_LOCATION */
802
803 #define PIN_UART_RTS(idx) \
804 COND_CODE_1(DT_INST_PROP(idx, hw_flow_control), \
805 ({ \
806 DT_INST_PROP_BY_IDX(idx, location_rts, 1), \
807 DT_INST_PROP_BY_IDX(idx, location_rts, 2), \
808 gpioModePushPull, 1 \
809 }), \
810 ({0}))
811
812 #define PIN_UART_CTS(idx) \
813 COND_CODE_1(DT_INST_PROP(idx, hw_flow_control), \
814 ({ \
815 DT_INST_PROP_BY_IDX(idx, location_cts, 1), \
816 DT_INST_PROP_BY_IDX(idx, location_cts, 2), \
817 gpioModeInput, 1 \
818 }), \
819 ({0}))
820
821 #define GECKO_UART_RTS_CTS_PINS(idx) \
822 .pin_rts = PIN_UART_RTS(idx), \
823 .pin_cts = PIN_UART_CTS(idx),
824
825 #else /* UART_GECKO_HW_FLOW_CONTROL */
826
827 #define GECKO_UART_RTS_CTS_PIN_LOCATIONS(idx)
828 #define VALIDATE_GECKO_UART_RTS_CTS_PIN_LOCATIONS(idx)
829 #define GECKO_UART_RTS_CTS_PINS(idx)
830
831 #endif /* UART_GECKO_HW_FLOW_CONTROL */
832
833 #define GECKO_UART_INIT(idx) \
834 VALIDATE_GECKO_UART_RX_TX_PIN_LOCATIONS(idx); \
835 VALIDATE_GECKO_UART_RTS_CTS_PIN_LOCATIONS(idx); \
836 \
837 GECKO_UART_IRQ_HANDLER_DECL(idx); \
838 PM_DEVICE_DT_INST_DEFINE(idx, uart_gecko_pm_action); \
839 \
840 static struct uart_config uart_cfg_##idx = { \
841 .baudrate = DT_INST_PROP(idx, current_speed), \
842 .parity = DT_INST_ENUM_IDX(idx, parity), \
843 .stop_bits = DT_INST_ENUM_IDX(idx, stop_bits), \
844 .data_bits = DT_INST_ENUM_IDX(idx, data_bits), \
845 .flow_ctrl = DT_INST_PROP(idx, hw_flow_control) \
846 ? UART_CFG_FLOW_CTRL_RTS_CTS \
847 : UART_CFG_FLOW_CTRL_NONE, \
848 }; \
849 \
850 static const struct uart_gecko_config uart_gecko_cfg_##idx = { \
851 .base = (USART_TypeDef *)DT_INST_REG_ADDR(idx), \
852 GET_GECKO_UART_CLOCK(idx) \
853 GECKO_UART_RX_TX_PINS(idx) \
854 GECKO_UART_RTS_CTS_PINS(idx) \
855 GECKO_UART_RX_TX_PIN_LOCATIONS(idx) \
856 GECKO_UART_RTS_CTS_PIN_LOCATIONS(idx) \
857 GECKO_UART_IRQ_HANDLER_FUNC(idx) \
858 }; \
859 \
860 \
861 static struct uart_gecko_data uart_gecko_data_##idx = { \
862 .uart_cfg = &uart_cfg_##idx, \
863 }; \
864 \
865 DEVICE_DT_INST_DEFINE(idx, uart_gecko_init, PM_DEVICE_DT_INST_GET(idx), \
866 &uart_gecko_data_##idx, &uart_gecko_cfg_##idx, \
867 PRE_KERNEL_1, CONFIG_SERIAL_INIT_PRIORITY, \
868 &uart_gecko_driver_api); \
869 \
870 GECKO_UART_IRQ_HANDLER(idx)
871
872 DT_INST_FOREACH_STATUS_OKAY(GECKO_UART_INIT)
873
874 #undef DT_DRV_COMPAT
875 #define DT_DRV_COMPAT silabs_gecko_usart
876
877 #ifdef CONFIG_UART_INTERRUPT_DRIVEN
878 #define GECKO_USART_IRQ_HANDLER_DECL(idx) \
879 static void usart_gecko_config_func_##idx(const struct device *dev)
880 #define GECKO_USART_IRQ_HANDLER_FUNC(idx) \
881 .irq_config_func = usart_gecko_config_func_##idx,
882 #define GECKO_USART_IRQ_HANDLER(idx) \
883 static void usart_gecko_config_func_##idx(const struct device *dev) \
884 { \
885 IRQ_CONNECT(DT_INST_IRQ_BY_NAME(idx, rx, irq), \
886 DT_INST_IRQ_BY_NAME(idx, rx, priority), \
887 uart_gecko_isr, DEVICE_DT_INST_GET(idx), 0); \
888 IRQ_CONNECT(DT_INST_IRQ_BY_NAME(idx, tx, irq), \
889 DT_INST_IRQ_BY_NAME(idx, tx, priority), \
890 uart_gecko_isr, DEVICE_DT_INST_GET(idx), 0); \
891 \
892 irq_enable(DT_INST_IRQ_BY_NAME(idx, rx, irq)); \
893 irq_enable(DT_INST_IRQ_BY_NAME(idx, tx, irq)); \
894 }
895 #else
896 #define GECKO_USART_IRQ_HANDLER_DECL(idx)
897 #define GECKO_USART_IRQ_HANDLER_FUNC(idx)
898 #define GECKO_USART_IRQ_HANDLER(idx)
899 #endif
900
901 #ifdef CONFIG_PINCTRL
902 #define GECKO_USART_INIT(idx) \
903 PINCTRL_DT_INST_DEFINE(idx); \
904 GECKO_USART_IRQ_HANDLER_DECL(idx); \
905 PM_DEVICE_DT_INST_DEFINE(idx, uart_gecko_pm_action); \
906 \
907 static struct uart_config uart_cfg_##idx = { \
908 .baudrate = DT_INST_PROP(idx, current_speed), \
909 .parity = DT_INST_ENUM_IDX(idx, parity), \
910 .stop_bits = DT_INST_ENUM_IDX(idx, stop_bits), \
911 .data_bits = DT_INST_ENUM_IDX(idx, data_bits), \
912 .flow_ctrl = DT_INST_PROP(idx, hw_flow_control) \
913 ? UART_CFG_FLOW_CTRL_RTS_CTS \
914 : UART_CFG_FLOW_CTRL_NONE, \
915 }; \
916 \
917 static const struct uart_gecko_config usart_gecko_cfg_##idx = { \
918 .pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(idx), \
919 .base = (USART_TypeDef *)DT_INST_REG_ADDR(idx), \
920 GET_GECKO_USART_CLOCK(idx) \
921 GECKO_USART_IRQ_HANDLER_FUNC(idx) \
922 } ; \
923 \
924 static struct uart_gecko_data usart_gecko_data_##idx = { \
925 .uart_cfg = &uart_cfg_##idx, \
926 }; \
927 \
928 DEVICE_DT_INST_DEFINE(idx, uart_gecko_init, PM_DEVICE_DT_INST_GET(idx), \
929 &usart_gecko_data_##idx, \
930 &usart_gecko_cfg_##idx, PRE_KERNEL_1, \
931 CONFIG_SERIAL_INIT_PRIORITY, \
932 &uart_gecko_driver_api); \
933 \
934 GECKO_USART_IRQ_HANDLER(idx)
935 #else
936 #define GECKO_USART_INIT(idx) \
937 VALIDATE_GECKO_UART_RX_TX_PIN_LOCATIONS(idx); \
938 VALIDATE_GECKO_UART_RTS_CTS_PIN_LOCATIONS(idx); \
939 \
940 GECKO_USART_IRQ_HANDLER_DECL(idx); \
941 PM_DEVICE_DT_INST_DEFINE(idx, uart_gecko_pm_action); \
942 \
943 static struct uart_config uart_cfg_##idx = { \
944 .baudrate = DT_INST_PROP(idx, current_speed), \
945 .parity = DT_INST_ENUM_IDX(idx, parity), \
946 .stop_bits = DT_INST_ENUM_IDX(idx, stop_bits), \
947 .data_bits = DT_INST_ENUM_IDX(idx, data_bits), \
948 .flow_ctrl = DT_INST_PROP(idx, hw_flow_control) \
949 ? UART_CFG_FLOW_CTRL_RTS_CTS \
950 : UART_CFG_FLOW_CTRL_NONE, \
951 }; \
952 \
953 static const struct uart_gecko_config usart_gecko_cfg_##idx = { \
954 .base = (USART_TypeDef *)DT_INST_REG_ADDR(idx), \
955 GET_GECKO_USART_CLOCK(idx) \
956 GECKO_UART_RX_TX_PINS(idx) \
957 GECKO_UART_RTS_CTS_PINS(idx) \
958 GECKO_UART_RX_TX_PIN_LOCATIONS(idx) \
959 GECKO_UART_RTS_CTS_PIN_LOCATIONS(idx) \
960 GECKO_USART_IRQ_HANDLER_FUNC(idx) \
961 }; \
962 \
963 static struct uart_gecko_data usart_gecko_data_##idx = { \
964 .uart_cfg = &uart_cfg_##idx, \
965 }; \
966 \
967 DEVICE_DT_INST_DEFINE(idx, uart_gecko_init, PM_DEVICE_DT_INST_GET(idx), \
968 &usart_gecko_data_##idx, \
969 &usart_gecko_cfg_##idx, PRE_KERNEL_1, \
970 CONFIG_SERIAL_INIT_PRIORITY, \
971 &uart_gecko_driver_api); \
972 \
973 GECKO_USART_IRQ_HANDLER(idx)
974 #endif
975
976 DT_INST_FOREACH_STATUS_OKAY(GECKO_USART_INIT)
977