1 /*
2 * Copyright (c) 2021, Linaro Limited.
3 * Copyright 2025 Arm Limited and/or its affiliates <open-source-office@arm.com>
4 *
5 * SPDX-License-Identifier: Apache-2.0
6 */
7
8 #define DT_DRV_COMPAT arm_cmsdk_uart
9
10 /**
11 * @brief Driver for UART on ARM CMSDK APB UART.
12 *
13 * UART has two wires for RX and TX, and does not provide CTS or RTS.
14 */
15
16 #include <zephyr/kernel.h>
17 #include <zephyr/arch/cpu.h>
18 #include <zephyr/drivers/clock_control/arm_clock_control.h>
19 #include <zephyr/drivers/pinctrl.h>
20 #include <zephyr/sys/__assert.h>
21 #include <zephyr/init.h>
22 #include <zephyr/drivers/uart.h>
23 #include <zephyr/linker/sections.h>
24 #include <zephyr/irq.h>
25
26 /* UART registers struct */
27 struct uart_cmsdk_apb {
28 /* offset: 0x000 (r/w) data register */
29 volatile uint32_t data;
30 /* offset: 0x004 (r/w) status register */
31 volatile uint32_t state;
32 /* offset: 0x008 (r/w) control register */
33 volatile uint32_t ctrl;
34 union {
35 /* offset: 0x00c (r/ ) interrupt status register */
36 volatile uint32_t intstatus;
37 /* offset: 0x00c ( /w) interrupt clear register */
38 volatile uint32_t intclear;
39 };
40 /* offset: 0x010 (r/w) baudrate divider register */
41 volatile uint32_t bauddiv;
42 };
43
44 /* UART Bits */
45 /* CTRL Register */
46 #define UART_TX_EN (1 << 0)
47 #define UART_RX_EN (1 << 1)
48 #define UART_TX_IN_EN (1 << 2)
49 #define UART_RX_IN_EN (1 << 3)
50 #define UART_TX_OV_EN (1 << 4)
51 #define UART_RX_OV_EN (1 << 5)
52 #define UART_HS_TM_TX (1 << 6)
53
54 /* STATE Register */
55 #define UART_TX_BF (1 << 0)
56 #define UART_RX_BF (1 << 1)
57 #define UART_TX_B_OV (1 << 2)
58 #define UART_RX_B_OV (1 << 3)
59
60 /* INTSTATUS Register */
61 #define UART_TX_IN (1 << 0)
62 #define UART_RX_IN (1 << 1)
63 #define UART_TX_OV_IN (1 << 2)
64 #define UART_RX_OV_IN (1 << 3)
65
66 struct uart_cmsdk_apb_config {
67 volatile struct uart_cmsdk_apb *uart;
68 uint32_t sys_clk_freq;
69 const struct pinctrl_dev_config *pctrl;
70 #ifdef CONFIG_UART_INTERRUPT_DRIVEN
71 uart_irq_config_func_t irq_config_func;
72 #endif
73 };
74
75 /* Device data structure */
76 struct uart_cmsdk_apb_dev_data {
77 uint32_t baud_rate; /* Baud rate */
78 #ifdef CONFIG_UART_INTERRUPT_DRIVEN
79 uart_irq_callback_user_data_t irq_cb;
80 void *irq_cb_data;
81 #endif
82 /* UART Clock control in Active State */
83 const struct arm_clock_control_t uart_cc_as;
84 /* UART Clock control in Sleep State */
85 const struct arm_clock_control_t uart_cc_ss;
86 /* UART Clock control in Deep Sleep State */
87 const struct arm_clock_control_t uart_cc_dss;
88 };
89
90 static DEVICE_API(uart, uart_cmsdk_apb_driver_api);
91 #ifdef CONFIG_UART_INTERRUPT_DRIVEN
92 static void uart_cmsdk_apb_isr(const struct device *dev);
93 #endif
94
95 /**
96 * @brief Set the baud rate
97 *
98 * This routine set the given baud rate for the UART.
99 *
100 * @param dev UART device struct
101 */
baudrate_set(const struct device * dev)102 static void baudrate_set(const struct device *dev)
103 {
104 const struct uart_cmsdk_apb_config * const dev_cfg = dev->config;
105 struct uart_cmsdk_apb_dev_data *const dev_data = dev->data;
106 /*
107 * If baudrate and/or sys_clk_freq are 0 the configuration remains
108 * unchanged. It can be useful in case that Zephyr it is run via
109 * a bootloader that brings up the serial and sets the baudrate.
110 */
111 if ((dev_data->baud_rate != 0U) && (dev_cfg->sys_clk_freq != 0U)) {
112 /* calculate baud rate divisor */
113 dev_cfg->uart->bauddiv = (dev_cfg->sys_clk_freq / dev_data->baud_rate);
114 }
115 }
116
117 /**
118 * @brief Initialize UART channel
119 *
120 * This routine is called to reset the chip in a quiescent state.
121 * It is assumed that this function is called only once per UART.
122 *
123 * @param dev UART device struct
124 *
125 * @return 0
126 */
uart_cmsdk_apb_init(const struct device * dev)127 static int uart_cmsdk_apb_init(const struct device *dev)
128 {
129 const struct uart_cmsdk_apb_config * const dev_cfg = dev->config;
130 int ret = pinctrl_apply_state(dev_cfg->pctrl, PINCTRL_STATE_DEFAULT);
131
132 /* some pins are not available externally so,
133 * ignore if there is no entry for them
134 */
135 if (ret != -ENOENT) {
136 return ret;
137 }
138
139 #ifdef CONFIG_CLOCK_CONTROL
140 /* Enable clock for subsystem */
141 const struct device *const clk = DEVICE_DT_GET(DT_INST_CLOCKS_CTLR_BY_IDX(0, 1));
142 struct uart_cmsdk_apb_dev_data * const data = dev->data;
143
144 if (!device_is_ready(clk)) {
145 return -ENODEV;
146 }
147
148 #ifdef CONFIG_SOC_SERIES_BEETLE
149 clock_control_on(clk, (clock_control_subsys_t) &data->uart_cc_as);
150 clock_control_on(clk, (clock_control_subsys_t) &data->uart_cc_ss);
151 clock_control_on(clk, (clock_control_subsys_t) &data->uart_cc_dss);
152 #endif /* CONFIG_SOC_SERIES_BEETLE */
153 #endif /* CONFIG_CLOCK_CONTROL */
154
155 /* Set baud rate */
156 baudrate_set(dev);
157
158 /* Enable receiver and transmitter */
159 dev_cfg->uart->ctrl = UART_RX_EN | UART_TX_EN;
160
161 #ifdef CONFIG_UART_INTERRUPT_DRIVEN
162 dev_cfg->irq_config_func(dev);
163 #endif
164
165 return 0;
166 }
167
168 /**
169 * @brief Poll the device for input.
170 *
171 * @param dev UART device struct
172 * @param c Pointer to character
173 *
174 * @return 0 if a character arrived, -1 if the input buffer if empty.
175 */
176
uart_cmsdk_apb_poll_in(const struct device * dev,unsigned char * c)177 static int uart_cmsdk_apb_poll_in(const struct device *dev, unsigned char *c)
178 {
179 const struct uart_cmsdk_apb_config *dev_cfg = dev->config;
180
181 /* If the receiver is not ready returns -1 */
182 if (!(dev_cfg->uart->state & UART_RX_BF)) {
183 return -1;
184 }
185
186 /* got a character */
187 *c = (unsigned char)dev_cfg->uart->data;
188
189 return 0;
190 }
191
192 /**
193 * @brief Output a character in polled mode.
194 *
195 * Checks if the transmitter is empty. If empty, a character is written to
196 * the data register.
197 *
198 * @param dev UART device struct
199 * @param c Character to send
200 */
uart_cmsdk_apb_poll_out(const struct device * dev,unsigned char c)201 static void uart_cmsdk_apb_poll_out(const struct device *dev,
202 unsigned char c)
203 {
204 const struct uart_cmsdk_apb_config *dev_cfg = dev->config;
205
206 /* Wait for transmitter to be ready */
207 while (dev_cfg->uart->state & UART_TX_BF) {
208 ; /* Wait */
209 }
210
211 /* Send a character */
212 dev_cfg->uart->data = (uint32_t)c;
213 }
214
215 #ifdef CONFIG_UART_INTERRUPT_DRIVEN
216 /**
217 * @brief Fill FIFO with data
218 *
219 * @param dev UART device struct
220 * @param tx_data Data to transmit
221 * @param len Number of bytes to send
222 *
223 * @return the number of characters that have been read
224 */
uart_cmsdk_apb_fifo_fill(const struct device * dev,const uint8_t * tx_data,int len)225 static int uart_cmsdk_apb_fifo_fill(const struct device *dev,
226 const uint8_t *tx_data, int len)
227 {
228 const struct uart_cmsdk_apb_config *dev_cfg = dev->config;
229
230 /*
231 * No hardware FIFO present. Only 1 byte
232 * to write if TX buffer is empty.
233 */
234 if (len && !(dev_cfg->uart->state & UART_TX_BF)) {
235 /*
236 * Clear TX int. pending flag before pushing byte to "FIFO".
237 * If TX interrupt is enabled the UART_TX_IN bit will be set
238 * again automatically by the UART hardware machinery once
239 * the "FIFO" becomes empty again.
240 */
241 dev_cfg->uart->intclear = UART_TX_IN;
242 dev_cfg->uart->data = *tx_data;
243 return 1;
244 }
245
246 return 0;
247 }
248
249 /**
250 * @brief Read data from FIFO
251 *
252 * @param dev UART device struct
253 * @param rx_data Pointer to data container
254 * @param size Container size in bytes
255 *
256 * @return the number of characters that have been read
257 */
uart_cmsdk_apb_fifo_read(const struct device * dev,uint8_t * rx_data,const int size)258 static int uart_cmsdk_apb_fifo_read(const struct device *dev,
259 uint8_t *rx_data, const int size)
260 {
261 const struct uart_cmsdk_apb_config *dev_cfg = dev->config;
262
263 /*
264 * No hardware FIFO present. Only 1 byte
265 * to read if RX buffer is full.
266 */
267 if (size && dev_cfg->uart->state & UART_RX_BF) {
268 /*
269 * Clear RX int. pending flag before popping byte from "FIFO".
270 * If RX interrupt is enabled the UART_RX_IN bit will be set
271 * again automatically by the UART hardware machinery once
272 * the "FIFO" becomes full again.
273 */
274 dev_cfg->uart->intclear = UART_RX_IN;
275 *rx_data = (unsigned char)dev_cfg->uart->data;
276 return 1;
277 }
278
279 return 0;
280 }
281
282 /**
283 * @brief Enable TX interrupt
284 *
285 * @param dev UART device struct
286 */
uart_cmsdk_apb_irq_tx_enable(const struct device * dev)287 static void uart_cmsdk_apb_irq_tx_enable(const struct device *dev)
288 {
289 const struct uart_cmsdk_apb_config *dev_cfg = dev->config;
290 unsigned int key;
291
292 dev_cfg->uart->ctrl |= UART_TX_IN_EN;
293 /* The expectation is that TX is a level interrupt, active for as
294 * long as TX buffer is empty. But in CMSDK UART it's an edge
295 * interrupt, firing on a state change of TX buffer from full to
296 * empty. So, we need to "prime" it here by calling ISR directly,
297 * to get interrupt processing going, as there is no previous
298 * full state to allow a transition from full to empty buffer
299 * that will trigger a TX interrupt.
300 */
301 key = irq_lock();
302 uart_cmsdk_apb_isr(dev);
303 irq_unlock(key);
304 }
305
306 /**
307 * @brief Disable TX interrupt
308 *
309 * @param dev UART device struct
310 */
uart_cmsdk_apb_irq_tx_disable(const struct device * dev)311 static void uart_cmsdk_apb_irq_tx_disable(const struct device *dev)
312 {
313 const struct uart_cmsdk_apb_config *dev_cfg = dev->config;
314
315 dev_cfg->uart->ctrl &= ~UART_TX_IN_EN;
316 /* Clear any pending TX interrupt after disabling it */
317 dev_cfg->uart->intclear = UART_TX_IN;
318 }
319
320 /**
321 * @brief Verify if Tx interrupt has been raised
322 *
323 * @param dev UART device struct
324 *
325 * @return 1 if an interrupt is ready, 0 otherwise
326 */
uart_cmsdk_apb_irq_tx_ready(const struct device * dev)327 static int uart_cmsdk_apb_irq_tx_ready(const struct device *dev)
328 {
329 const struct uart_cmsdk_apb_config *dev_cfg = dev->config;
330
331 return !(dev_cfg->uart->state & UART_TX_BF);
332 }
333
334 /**
335 * @brief Enable RX interrupt
336 *
337 * @param dev UART device struct
338 */
uart_cmsdk_apb_irq_rx_enable(const struct device * dev)339 static void uart_cmsdk_apb_irq_rx_enable(const struct device *dev)
340 {
341 const struct uart_cmsdk_apb_config *dev_cfg = dev->config;
342
343 dev_cfg->uart->ctrl |= UART_RX_IN_EN;
344 }
345
346 /**
347 * @brief Disable RX interrupt
348 *
349 * @param dev UART device struct
350 */
uart_cmsdk_apb_irq_rx_disable(const struct device * dev)351 static void uart_cmsdk_apb_irq_rx_disable(const struct device *dev)
352 {
353 const struct uart_cmsdk_apb_config *dev_cfg = dev->config;
354
355 dev_cfg->uart->ctrl &= ~UART_RX_IN_EN;
356 /* Clear any pending RX interrupt after disabling it */
357 dev_cfg->uart->intclear = UART_RX_IN;
358 }
359
360 /**
361 * @brief Verify if Tx complete interrupt has been raised
362 *
363 * @param dev UART device struct
364 *
365 * @return 1 if an interrupt is ready, 0 otherwise
366 */
uart_cmsdk_apb_irq_tx_complete(const struct device * dev)367 static int uart_cmsdk_apb_irq_tx_complete(const struct device *dev)
368 {
369 return uart_cmsdk_apb_irq_tx_ready(dev);
370 }
371
372 /**
373 * @brief Verify if Rx interrupt has been raised
374 *
375 * @param dev UART device struct
376 *
377 * @return 1 if an interrupt is ready, 0 otherwise
378 */
uart_cmsdk_apb_irq_rx_ready(const struct device * dev)379 static int uart_cmsdk_apb_irq_rx_ready(const struct device *dev)
380 {
381 const struct uart_cmsdk_apb_config *dev_cfg = dev->config;
382
383 return (dev_cfg->uart->state & UART_RX_BF) == UART_RX_BF;
384 }
385
386 /**
387 * @brief Enable error interrupt
388 *
389 * @param dev UART device struct
390 */
uart_cmsdk_apb_irq_err_enable(const struct device * dev)391 static void uart_cmsdk_apb_irq_err_enable(const struct device *dev)
392 {
393 ARG_UNUSED(dev);
394 }
395
396 /**
397 * @brief Disable error interrupt
398 *
399 * @param dev UART device struct
400 */
uart_cmsdk_apb_irq_err_disable(const struct device * dev)401 static void uart_cmsdk_apb_irq_err_disable(const struct device *dev)
402 {
403 ARG_UNUSED(dev);
404 }
405
406 /**
407 * @brief Verify if Tx or Rx interrupt is pending
408 *
409 * @param dev UART device struct
410 *
411 * @return 1 if Tx or Rx interrupt is pending, 0 otherwise
412 */
uart_cmsdk_apb_irq_is_pending(const struct device * dev)413 static int uart_cmsdk_apb_irq_is_pending(const struct device *dev)
414 {
415 return uart_cmsdk_apb_irq_rx_ready(dev) || uart_cmsdk_apb_irq_tx_ready(dev);
416 }
417
418 /**
419 * @brief Update the interrupt status
420 *
421 * @param dev UART device struct
422 *
423 * @return always 1
424 */
uart_cmsdk_apb_irq_update(const struct device * dev)425 static int uart_cmsdk_apb_irq_update(const struct device *dev)
426 {
427 return 1;
428 }
429
430 /**
431 * @brief Set the callback function pointer for an Interrupt.
432 *
433 * @param dev UART device structure
434 * @param cb Callback function pointer.
435 */
uart_cmsdk_apb_irq_callback_set(const struct device * dev,uart_irq_callback_user_data_t cb,void * cb_data)436 static void uart_cmsdk_apb_irq_callback_set(const struct device *dev,
437 uart_irq_callback_user_data_t cb,
438 void *cb_data)
439 {
440 struct uart_cmsdk_apb_dev_data *data = dev->data;
441
442 data->irq_cb = cb;
443 data->irq_cb_data = cb_data;
444 }
445
446 /**
447 * @brief Interrupt service routine.
448 *
449 * Calls the callback function, if exists.
450 *
451 * @param arg argument to interrupt service routine.
452 */
uart_cmsdk_apb_isr(const struct device * dev)453 static void uart_cmsdk_apb_isr(const struct device *dev)
454 {
455 struct uart_cmsdk_apb_dev_data *data = dev->data;
456
457 /* Verify if the callback has been registered */
458 if (data->irq_cb) {
459 data->irq_cb(dev, data->irq_cb_data);
460 }
461 }
462
463 #endif /* CONFIG_UART_INTERRUPT_DRIVEN */
464
465
466 static DEVICE_API(uart, uart_cmsdk_apb_driver_api) = {
467 .poll_in = uart_cmsdk_apb_poll_in,
468 .poll_out = uart_cmsdk_apb_poll_out,
469 #ifdef CONFIG_UART_INTERRUPT_DRIVEN
470 .fifo_fill = uart_cmsdk_apb_fifo_fill,
471 .fifo_read = uart_cmsdk_apb_fifo_read,
472 .irq_tx_enable = uart_cmsdk_apb_irq_tx_enable,
473 .irq_tx_disable = uart_cmsdk_apb_irq_tx_disable,
474 .irq_tx_ready = uart_cmsdk_apb_irq_tx_ready,
475 .irq_rx_enable = uart_cmsdk_apb_irq_rx_enable,
476 .irq_rx_disable = uart_cmsdk_apb_irq_rx_disable,
477 .irq_tx_complete = uart_cmsdk_apb_irq_tx_complete,
478 .irq_rx_ready = uart_cmsdk_apb_irq_rx_ready,
479 .irq_err_enable = uart_cmsdk_apb_irq_err_enable,
480 .irq_err_disable = uart_cmsdk_apb_irq_err_disable,
481 .irq_is_pending = uart_cmsdk_apb_irq_is_pending,
482 .irq_update = uart_cmsdk_apb_irq_update,
483 .irq_callback_set = uart_cmsdk_apb_irq_callback_set,
484 #endif /* CONFIG_UART_INTERRUPT_DRIVEN */
485 };
486
487 #if DT_NODE_HAS_STATUS_OKAY(DT_DRV_INST(0))
488
489 #ifdef CONFIG_UART_INTERRUPT_DRIVEN
490 static void uart_cmsdk_apb_irq_config_func_0(const struct device *dev);
491 #endif
492 PINCTRL_DT_INST_DEFINE(0);
493 static const struct uart_cmsdk_apb_config uart_cmsdk_apb_dev_cfg_0 = {
494 .uart = (volatile struct uart_cmsdk_apb *)DT_INST_REG_ADDR(0),
495 .sys_clk_freq = DT_INST_PROP_BY_PHANDLE(0, clocks, clock_frequency),
496 .pctrl = PINCTRL_DT_INST_DEV_CONFIG_GET(0),
497 #ifdef CONFIG_UART_INTERRUPT_DRIVEN
498 .irq_config_func = uart_cmsdk_apb_irq_config_func_0,
499 #endif
500 };
501
502 static struct uart_cmsdk_apb_dev_data uart_cmsdk_apb_dev_data_0 = {
503 .baud_rate = DT_INST_PROP(0, current_speed),
504 .uart_cc_as = {.bus = CMSDK_APB, .state = SOC_ACTIVE,
505 .device = DT_INST_REG_ADDR(0),},
506 .uart_cc_ss = {.bus = CMSDK_APB, .state = SOC_SLEEP,
507 .device = DT_INST_REG_ADDR(0),},
508 .uart_cc_dss = {.bus = CMSDK_APB, .state = SOC_DEEPSLEEP,
509 .device = DT_INST_REG_ADDR(0),},
510 };
511
512 DEVICE_DT_INST_DEFINE(0,
513 uart_cmsdk_apb_init,
514 NULL,
515 &uart_cmsdk_apb_dev_data_0,
516 &uart_cmsdk_apb_dev_cfg_0, PRE_KERNEL_1,
517 CONFIG_SERIAL_INIT_PRIORITY,
518 &uart_cmsdk_apb_driver_api);
519
520 #ifdef CONFIG_UART_INTERRUPT_DRIVEN
521 #if DT_NUM_IRQS(DT_DRV_INST(0)) == 1
uart_cmsdk_apb_irq_config_func_0(const struct device * dev)522 static void uart_cmsdk_apb_irq_config_func_0(const struct device *dev)
523 {
524 IRQ_CONNECT(DT_INST_IRQN(0),
525 DT_INST_IRQ(0, priority),
526 uart_cmsdk_apb_isr,
527 DEVICE_DT_INST_GET(0),
528 0);
529 irq_enable(DT_INST_IRQN(0));
530 }
531 #else
uart_cmsdk_apb_irq_config_func_0(const struct device * dev)532 static void uart_cmsdk_apb_irq_config_func_0(const struct device *dev)
533 {
534 IRQ_CONNECT(DT_INST_IRQ_BY_NAME(0, tx, irq),
535 DT_INST_IRQ_BY_NAME(0, tx, priority),
536 uart_cmsdk_apb_isr,
537 DEVICE_DT_INST_GET(0),
538 0);
539 irq_enable(DT_INST_IRQ_BY_NAME(0, tx, irq));
540
541 IRQ_CONNECT(DT_INST_IRQ_BY_NAME(0, rx, irq),
542 DT_INST_IRQ_BY_NAME(0, rx, priority),
543 uart_cmsdk_apb_isr,
544 DEVICE_DT_INST_GET(0),
545 0);
546 irq_enable(DT_INST_IRQ_BY_NAME(0, rx, irq));
547 }
548 #endif
549 #endif
550
551 #endif /* DT_NODE_HAS_STATUS_OKAY(DT_DRV_INST(0)) */
552
553 #if DT_NODE_HAS_STATUS_OKAY(DT_DRV_INST(1))
554
555 #ifdef CONFIG_UART_INTERRUPT_DRIVEN
556 static void uart_cmsdk_apb_irq_config_func_1(const struct device *dev);
557 #endif
558 PINCTRL_DT_INST_DEFINE(1);
559 static const struct uart_cmsdk_apb_config uart_cmsdk_apb_dev_cfg_1 = {
560 .uart = (volatile struct uart_cmsdk_apb *)DT_INST_REG_ADDR(1),
561 .sys_clk_freq = DT_INST_PROP_BY_PHANDLE(1, clocks, clock_frequency),
562 .pctrl = PINCTRL_DT_INST_DEV_CONFIG_GET(1),
563 #ifdef CONFIG_UART_INTERRUPT_DRIVEN
564 .irq_config_func = uart_cmsdk_apb_irq_config_func_1,
565 #endif
566 };
567
568 static struct uart_cmsdk_apb_dev_data uart_cmsdk_apb_dev_data_1 = {
569 .baud_rate = DT_INST_PROP(1, current_speed),
570 .uart_cc_as = {.bus = CMSDK_APB, .state = SOC_ACTIVE,
571 .device = DT_INST_REG_ADDR(1),},
572 .uart_cc_ss = {.bus = CMSDK_APB, .state = SOC_SLEEP,
573 .device = DT_INST_REG_ADDR(1),},
574 .uart_cc_dss = {.bus = CMSDK_APB, .state = SOC_DEEPSLEEP,
575 .device = DT_INST_REG_ADDR(1),},
576 };
577
578 DEVICE_DT_INST_DEFINE(1,
579 uart_cmsdk_apb_init,
580 NULL,
581 &uart_cmsdk_apb_dev_data_1,
582 &uart_cmsdk_apb_dev_cfg_1, PRE_KERNEL_1,
583 CONFIG_SERIAL_INIT_PRIORITY,
584 &uart_cmsdk_apb_driver_api);
585
586 #ifdef CONFIG_UART_INTERRUPT_DRIVEN
587 #if DT_NUM_IRQS(DT_DRV_INST(1)) == 1
uart_cmsdk_apb_irq_config_func_1(const struct device * dev)588 static void uart_cmsdk_apb_irq_config_func_1(const struct device *dev)
589 {
590 IRQ_CONNECT(DT_INST_IRQN(1),
591 DT_INST_IRQ(1, priority),
592 uart_cmsdk_apb_isr,
593 DEVICE_DT_INST_GET(1),
594 0);
595 irq_enable(DT_INST_IRQN(1));
596 }
597 #else
uart_cmsdk_apb_irq_config_func_1(const struct device * dev)598 static void uart_cmsdk_apb_irq_config_func_1(const struct device *dev)
599 {
600 IRQ_CONNECT(DT_INST_IRQ_BY_NAME(1, tx, irq),
601 DT_INST_IRQ_BY_NAME(1, tx, priority),
602 uart_cmsdk_apb_isr,
603 DEVICE_DT_INST_GET(1),
604 0);
605 irq_enable(DT_INST_IRQ_BY_NAME(1, tx, irq));
606
607 IRQ_CONNECT(DT_INST_IRQ_BY_NAME(1, rx, irq),
608 DT_INST_IRQ_BY_NAME(1, rx, priority),
609 uart_cmsdk_apb_isr,
610 DEVICE_DT_INST_GET(1),
611 0);
612 irq_enable(DT_INST_IRQ_BY_NAME(1, rx, irq));
613 }
614 #endif
615 #endif
616
617 #endif /* DT_NODE_HAS_STATUS_OKAY(DT_DRV_INST(1)) */
618
619 #if DT_NODE_HAS_STATUS_OKAY(DT_DRV_INST(2))
620
621 #ifdef CONFIG_UART_INTERRUPT_DRIVEN
622 static void uart_cmsdk_apb_irq_config_func_2(const struct device *dev);
623 #endif
624 PINCTRL_DT_INST_DEFINE(2);
625 static const struct uart_cmsdk_apb_config uart_cmsdk_apb_dev_cfg_2 = {
626 .uart = (volatile struct uart_cmsdk_apb *)DT_INST_REG_ADDR(2),
627 .sys_clk_freq = DT_INST_PROP_BY_PHANDLE(2, clocks, clock_frequency),
628 .pctrl = PINCTRL_DT_INST_DEV_CONFIG_GET(2),
629 #ifdef CONFIG_UART_INTERRUPT_DRIVEN
630 .irq_config_func = uart_cmsdk_apb_irq_config_func_2,
631 #endif
632 };
633
634 static struct uart_cmsdk_apb_dev_data uart_cmsdk_apb_dev_data_2 = {
635 .baud_rate = DT_INST_PROP(2, current_speed),
636 .uart_cc_as = {.bus = CMSDK_APB, .state = SOC_ACTIVE,
637 .device = DT_INST_REG_ADDR(2),},
638 .uart_cc_ss = {.bus = CMSDK_APB, .state = SOC_SLEEP,
639 .device = DT_INST_REG_ADDR(2),},
640 .uart_cc_dss = {.bus = CMSDK_APB, .state = SOC_DEEPSLEEP,
641 .device = DT_INST_REG_ADDR(2),},
642 };
643
644 DEVICE_DT_INST_DEFINE(2,
645 uart_cmsdk_apb_init,
646 NULL,
647 &uart_cmsdk_apb_dev_data_2,
648 &uart_cmsdk_apb_dev_cfg_2, PRE_KERNEL_1,
649 CONFIG_SERIAL_INIT_PRIORITY,
650 &uart_cmsdk_apb_driver_api);
651
652 #ifdef CONFIG_UART_INTERRUPT_DRIVEN
653 #if DT_NUM_IRQS(DT_DRV_INST(2)) == 1
uart_cmsdk_apb_irq_config_func_2(const struct device * dev)654 static void uart_cmsdk_apb_irq_config_func_2(const struct device *dev)
655 {
656 IRQ_CONNECT(DT_INST_IRQN(2),
657 DT_INST_IRQ_BY_NAME(2, priority, irq),
658 uart_cmsdk_apb_isr,
659 DEVICE_DT_INST_GET(2),
660 0);
661 irq_enable(DT_INST_IRQN(2));
662 }
663 #else
uart_cmsdk_apb_irq_config_func_2(const struct device * dev)664 static void uart_cmsdk_apb_irq_config_func_2(const struct device *dev)
665 {
666 IRQ_CONNECT(DT_INST_IRQ_BY_NAME(2, tx, irq),
667 DT_INST_IRQ_BY_NAME(2, tx, priority),
668 uart_cmsdk_apb_isr,
669 DEVICE_DT_INST_GET(2),
670 0);
671 irq_enable(DT_INST_IRQ_BY_NAME(2, tx, irq));
672
673 IRQ_CONNECT(DT_INST_IRQ_BY_NAME(2, rx, irq),
674 DT_INST_IRQ_BY_NAME(2, rx, priority),
675 uart_cmsdk_apb_isr,
676 DEVICE_DT_INST_GET(2),
677 0);
678 irq_enable(DT_INST_IRQ_BY_NAME(2, rx, irq));
679 }
680 #endif
681 #endif
682
683 #endif /* DT_NODE_HAS_STATUS_OKAY(DT_DRV_INST(2)) */
684
685 #if DT_NODE_HAS_STATUS_OKAY(DT_DRV_INST(3))
686
687 #ifdef CONFIG_UART_INTERRUPT_DRIVEN
688 static void uart_cmsdk_apb_irq_config_func_3(const struct device *dev);
689 #endif
690 PINCTRL_DT_INST_DEFINE(3);
691 static const struct uart_cmsdk_apb_config uart_cmsdk_apb_dev_cfg_3 = {
692 .uart = (volatile struct uart_cmsdk_apb *)DT_INST_REG_ADDR(3),
693 .sys_clk_freq = DT_INST_PROP_BY_PHANDLE(3, clocks, clock_frequency),
694 .pctrl = PINCTRL_DT_INST_DEV_CONFIG_GET(3),
695 #ifdef CONFIG_UART_INTERRUPT_DRIVEN
696 .irq_config_func = uart_cmsdk_apb_irq_config_func_3,
697 #endif
698 };
699
700 static struct uart_cmsdk_apb_dev_data uart_cmsdk_apb_dev_data_3 = {
701 .baud_rate = DT_INST_PROP(3, current_speed),
702 .uart_cc_as = {.bus = CMSDK_APB, .state = SOC_ACTIVE,
703 .device = DT_INST_REG_ADDR(3),},
704 .uart_cc_ss = {.bus = CMSDK_APB, .state = SOC_SLEEP,
705 .device = DT_INST_REG_ADDR(3),},
706 .uart_cc_dss = {.bus = CMSDK_APB, .state = SOC_DEEPSLEEP,
707 .device = DT_INST_REG_ADDR(3),},
708 };
709
710 DEVICE_DT_INST_DEFINE(3,
711 uart_cmsdk_apb_init,
712 NULL,
713 &uart_cmsdk_apb_dev_data_3,
714 &uart_cmsdk_apb_dev_cfg_3, PRE_KERNEL_1,
715 CONFIG_SERIAL_INIT_PRIORITY,
716 &uart_cmsdk_apb_driver_api);
717
718 #ifdef CONFIG_UART_INTERRUPT_DRIVEN
719 #if DT_NUM_IRQS(DT_DRV_INST(3)) == 1
uart_cmsdk_apb_irq_config_func_3(const struct device * dev)720 static void uart_cmsdk_apb_irq_config_func_3(const struct device *dev)
721 {
722 IRQ_CONNECT(DT_INST_IRQN(3),
723 DT_INST_IRQ(3, priority),
724 uart_cmsdk_apb_isr,
725 DEVICE_DT_INST_GET(3),
726 0);
727 irq_enable(DT_INST_IRQN(3));
728 }
729 #else
uart_cmsdk_apb_irq_config_func_3(const struct device * dev)730 static void uart_cmsdk_apb_irq_config_func_3(const struct device *dev)
731 {
732 IRQ_CONNECT(DT_INST_IRQ_BY_NAME(3, tx, irq),
733 DT_INST_IRQ_BY_NAME(3, tx, priority),
734 uart_cmsdk_apb_isr,
735 DEVICE_DT_INST_GET(3),
736 0);
737 irq_enable(DT_INST_IRQ_BY_NAME(3, tx, irq));
738
739 IRQ_CONNECT(DT_INST_IRQ_BY_NAME(3, rx, irq),
740 DT_INST_IRQ_BY_NAME(3, rx, priority),
741 uart_cmsdk_apb_isr,
742 DEVICE_DT_INST_GET(3),
743 0);
744 irq_enable(DT_INST_IRQ_BY_NAME(3, rx, irq));
745 }
746 #endif
747 #endif
748
749 #endif /* DT_NODE_HAS_STATUS_OKAY(DT_DRV_INST(3)) */
750
751 #if DT_NODE_HAS_STATUS_OKAY(DT_DRV_INST(4))
752 #ifdef CONFIG_UART_INTERRUPT_DRIVEN
753 static void uart_cmsdk_apb_irq_config_func_4(const struct device *dev);
754 #endif
755 PINCTRL_DT_INST_DEFINE(4);
756 static const struct uart_cmsdk_apb_config uart_cmsdk_apb_dev_cfg_4 = {
757 .uart = (volatile struct uart_cmsdk_apb *)DT_INST_REG_ADDR(4),
758 .sys_clk_freq = DT_INST_PROP_BY_PHANDLE(4, clocks, clock_frequency),
759 .pctrl = PINCTRL_DT_INST_DEV_CONFIG_GET(4),
760 #ifdef CONFIG_UART_INTERRUPT_DRIVEN
761 .irq_config_func = uart_cmsdk_apb_irq_config_func_4,
762 #endif
763 };
764
765 static struct uart_cmsdk_apb_dev_data uart_cmsdk_apb_dev_data_4 = {
766 .baud_rate = DT_INST_PROP(4, current_speed),
767 .uart_cc_as = {.bus = CMSDK_APB, .state = SOC_ACTIVE,
768 .device = DT_INST_REG_ADDR(4),},
769 .uart_cc_ss = {.bus = CMSDK_APB, .state = SOC_SLEEP,
770 .device = DT_INST_REG_ADDR(4),},
771 .uart_cc_dss = {.bus = CMSDK_APB, .state = SOC_DEEPSLEEP,
772 .device = DT_INST_REG_ADDR(4),},
773 };
774
775 DEVICE_DT_INST_DEFINE(4,
776 uart_cmsdk_apb_init,
777 NULL,
778 &uart_cmsdk_apb_dev_data_4,
779 &uart_cmsdk_apb_dev_cfg_4, PRE_KERNEL_1,
780 CONFIG_SERIAL_INIT_PRIORITY,
781 &uart_cmsdk_apb_driver_api);
782
783 #ifdef CONFIG_UART_INTERRUPT_DRIVEN
784 #if DT_NUM_IRQS(DT_DRV_INST(4)) == 1
uart_cmsdk_apb_irq_config_func_4(const struct device * dev)785 static void uart_cmsdk_apb_irq_config_func_4(const struct device *dev)
786 {
787 IRQ_CONNECT(DT_INST_IRQN(4),
788 DT_INST_IRQ_BY_NAME(4, priority, irq),
789 uart_cmsdk_apb_isr,
790 DEVICE_DT_INST_GET(4),
791 0);
792 irq_enable(DT_INST_IRQN(4));
793 }
794 #else
uart_cmsdk_apb_irq_config_func_4(const struct device * dev)795 static void uart_cmsdk_apb_irq_config_func_4(const struct device *dev)
796 {
797 IRQ_CONNECT(DT_INST_IRQ_BY_NAME(4, tx, irq),
798 DT_INST_IRQ_BY_NAME(4, tx, priority),
799 uart_cmsdk_apb_isr,
800 DEVICE_DT_INST_GET(4),
801 0);
802 irq_enable(DT_INST_IRQ_BY_NAME(4, tx, irq));
803
804 IRQ_CONNECT(DT_INST_IRQ_BY_NAME(4, rx, irq),
805 DT_INST_IRQ_BY_NAME(4, rx, priority),
806 uart_cmsdk_apb_isr,
807 DEVICE_DT_INST_GET(4),
808 0);
809 irq_enable(DT_INST_IRQ_BY_NAME(4, rx, irq));
810 }
811 #endif
812 #endif
813
814 #endif /* DT_NODE_HAS_STATUS_OKAY(DT_DRV_INST(4)) */
815