1 /*
2 * ===========================================================================================
3 *
4 * Filename: hal_uart.c
5 *
6 * Description: hal impl. of uart.
7 *
8 * Version: Melis3.0
9 * Create: 2019-11-14 14:20:56
10 * Revision: none
11 * Compiler: GCC:version 9.2.1 20170904 (release),ARM/embedded-7-branch revision 255204
12 *
13 * Author: bantao@allwinnertech.com
14 * Organization: SWC-BPD
15 * Last Modified: 2020-04-29 15:17:36
16 *
17 * ===========================================================================================
18 */
19
20 #include <hal_uart.h>
21 #include <hal_interrupt.h>
22 #include <hal_queue.h>
23 #include <hal_clk.h>
24 #include <hal_reset.h>
25 #include <hal_gpio.h>
26 #ifdef CONFIG_DRIVER_SYSCONFIG
27 #include <hal_cfg.h>
28 #include <script.h>
29 #endif
30 #include "uart.h"
31
32 #if (0)
33 #define UART_LOG_DEBUG
34 #endif
35 #define UART_INIT(fmt, ...) printf("uart: "fmt, ##__VA_ARGS__)
36 #define UART_ERR(fmt, ...) printf("uart: "fmt, ##__VA_ARGS__)
37
38 #ifdef UART_LOG_DEBUG
39 #define UART_INFO(fmt, ...) printf("[%s %d]"fmt, __func__, __LINE__, ##__VA_ARGS__)
40 #define UART_INFO_IRQ(fmt, ...) printf("[%s %d]"fmt, __func__, __LINE__, ##__VA_ARGS__)
41 #else
42 #define UART_INFO(fmt, ...)
43 #define UART_INFO_IRQ(fmt, ...)
44 #endif
45
46 static unsigned long sunxi_uart_port[] =
47 {
48 SUNXI_UART0_BASE, SUNXI_UART1_BASE, SUNXI_UART2_BASE, SUNXI_UART3_BASE
49 };
50 static const uint32_t g_uart_irqn[] = {SUNXI_IRQ_UART0, SUNXI_IRQ_UART1,
51 SUNXI_IRQ_UART2, SUNXI_IRQ_UART3
52 };
53 static sunxi_hal_version_t hal_uart_driver =
54 {
55 SUNXI_HAL_UART_API_VERSION,
56 SUNXI_HAL_UART_DRV_VERSION
57 };
58 static uart_priv_t g_uart_priv[UART_MAX];
59
60 static hal_mailbox_t uart_mailbox[UART_MAX];
61
62 static const uint32_t g_uart_baudrate_map[] =
63 {
64 300,
65 600,
66 1200,
67 2400,
68 4800,
69 9600,
70 19200,
71 38400,
72 57600,
73 115200,
74 230400,
75 576000,
76 921600,
77 500000,
78 1000000,
79 1500000,
80 3000000,
81 4000000,
82 };
83
84 //driver capabilities, support uart function only.
85 static const sunxi_hal_uart_capabilities_t driver_capabilities =
86 {
87 1, /* supports UART (Asynchronous) mode */
88 0, /* supports Synchronous Master mode */
89 0, /* supports Synchronous Slave mode */
90 0, /* supports UART Single-wire mode */
91 0, /* supports UART IrDA mode */
92 0, /* supports UART Smart Card mode */
93 0, /* Smart Card Clock generator available */
94 0, /* RTS Flow Control available */
95 0, /* CTS Flow Control available */
96 0, /* Transmit completed event: \ref ARM_UARTx_EVENT_TX_COMPLETE */
97 0, /* Signal receive character timeout event: \ref ARM_UARTx_EVENT_RX_TIMEOUT */
98 0, /* RTS Line: 0=not available, 1=available */
99 0, /* CTS Line: 0=not available, 1=available */
100 0, /* DTR Line: 0=not available, 1=available */
101 0, /* DSR Line: 0=not available, 1=available */
102 0, /* DCD Line: 0=not available, 1=available */
103 0, /* RI Line: 0=not available, 1=available */
104 0, /* Signal CTS change event: \ref ARM_UARTx_EVENT_CTS */
105 0, /* Signal DSR change event: \ref ARM_UARTx_EVENT_DSR */
106 0, /* Signal DCD change event: \ref ARM_UARTx_EVENT_DCD */
107 0, /* Signal RI change event: \ref ARM_UARTx_EVENT_RI */
108 0 /* Reserved */
109 };
110
111 #ifdef CONFIG_SUNXI_UART_SUPPORT_POLL
112
113 static poll_wakeup_func uart_drv_poll_wakeup = NULL;
114
hal_uart_check_poll_state(int32_t dev_id,short key)115 int32_t hal_uart_check_poll_state(int32_t dev_id, short key)
116 {
117 int ret = -1;
118 int32_t mask = 0;
119
120 if (key & POLLIN)
121 {
122 ret = hal_is_mailbox_empty((hal_mailbox_t)uart_mailbox[dev_id]);
123 if (ret == 1)
124 {
125 mask = 0;
126 }
127 else
128 {
129 mask |= POLLIN;
130 }
131 }
132
133 if (key & POLLOUT)
134 {
135 mask |= POLLOUT;
136 }
137 return mask;
138 }
139
hal_uart_poll_wakeup(int32_t dev_id,short key)140 int32_t hal_uart_poll_wakeup(int32_t dev_id, short key)
141 {
142 int ret = -1;
143
144 if (uart_drv_poll_wakeup)
145 {
146 ret = uart_drv_poll_wakeup(dev_id, key);
147 }
148
149 return ret;
150 }
151
hal_uart_register_poll_wakeup(poll_wakeup_func poll_wakeup)152 int32_t hal_uart_register_poll_wakeup(poll_wakeup_func poll_wakeup)
153 {
154 uart_drv_poll_wakeup = poll_wakeup;
155
156 return 0;
157 }
158
159 #endif
160
uart_port_is_valid(uart_port_t uart_port)161 static bool uart_port_is_valid(uart_port_t uart_port)
162 {
163 return (uart_port < UART_MAX);
164 }
165
uart_config_is_valid(const _uart_config_t * config)166 static bool uart_config_is_valid(const _uart_config_t *config)
167 {
168 return ((config->baudrate < UART_BAUDRATE_MAX) &&
169 (config->word_length <= UART_WORD_LENGTH_8) &&
170 (config->stop_bit <= UART_STOP_BIT_2) &&
171 (config->parity <= UART_PARITY_EVEN));
172 }
173
hal_uart_get_version(int32_t dev)174 sunxi_hal_version_t hal_uart_get_version(int32_t dev)
175 {
176 HAL_ARG_UNUSED(dev);
177 return hal_uart_driver;
178 }
179
hal_uart_get_capabilities(int32_t dev)180 sunxi_hal_uart_capabilities_t hal_uart_get_capabilities(int32_t dev)
181 {
182 HAL_ARG_UNUSED(dev);
183 return driver_capabilities;
184 }
185
uart_set_format(uart_port_t uart_port,uart_word_length_t word_length,uart_stop_bit_t stop_bit,uart_parity_t parity)186 static void uart_set_format(uart_port_t uart_port, uart_word_length_t word_length,
187 uart_stop_bit_t stop_bit, uart_parity_t parity)
188 {
189 const unsigned long uart_base = sunxi_uart_port[uart_port];
190 uart_priv_t *uart_priv = &g_uart_priv[uart_port];
191 uint32_t value;
192
193 value = hal_readb(uart_base + UART_LCR);
194
195 /* set word length */
196 value &= ~(UART_LCR_DLEN_MASK);
197 switch (word_length)
198 {
199 case UART_WORD_LENGTH_5:
200 value |= UART_LCR_WLEN5;
201 break;
202 case UART_WORD_LENGTH_6:
203 value |= UART_LCR_WLEN6;
204 break;
205 case UART_WORD_LENGTH_7:
206 value |= UART_LCR_WLEN7;
207 break;
208 case UART_WORD_LENGTH_8:
209 default:
210 value |= UART_LCR_WLEN8;
211 break;
212 }
213
214 /* set stop bit */
215 switch (stop_bit)
216 {
217 case UART_STOP_BIT_1:
218 default:
219 value &= ~(UART_LCR_STOP);
220 break;
221 case UART_STOP_BIT_2:
222 value |= UART_LCR_STOP;
223 break;
224 }
225
226 /* set parity bit */
227 value &= ~(UART_LCR_PARITY_MASK);
228 switch (parity)
229 {
230 case UART_PARITY_NONE:
231 value &= ~(UART_LCR_PARITY);
232 break;
233 case UART_PARITY_ODD:
234 value |= UART_LCR_PARITY;
235 break;
236 case UART_PARITY_EVEN:
237 value |= UART_LCR_PARITY;
238 value |= UART_LCR_EPAR;
239 break;
240 }
241
242 uart_priv->lcr = value;
243 hal_writeb(uart_priv->lcr, uart_base + UART_LCR);
244 }
245
246 #define CCM_UART_RST_OFFSET (16)
247 #define CCM_UART_GATING_OFFSET (0)
uart_reset(uart_port_t uart_port)248 static void uart_reset(uart_port_t uart_port)
249 {
250 int i;
251 unsigned int reg_val = 0;
252
253 /* 0x3001000(CCU) + 0x90c(UART_BGR_REG: UART Bus Gating Reset Register) */
254 /* reset */
255 reg_val = readl(0x0300190c);
256 reg_val &= ~(1 << (CCM_UART_RST_OFFSET + uart_port));
257 writel(reg_val, 0x0300190c);
258 for (i = 0; i < 100; i++)
259 ;
260
261 reg_val = readl(0x300190c);
262 reg_val |= (1 << (CCM_UART_RST_OFFSET + uart_port));
263 writel(reg_val, 0x300190c);
264
265 /* gating */
266 reg_val = readl(0x300190c);
267 reg_val &= ~(1 << (CCM_UART_GATING_OFFSET + uart_port));
268 writel(reg_val, 0x300190c);
269 for (i = 0; i < 100; i++)
270 ;
271 reg_val = readl(0x300190c);
272 reg_val |= (1 << (CCM_UART_GATING_OFFSET + uart_port));
273 writel(reg_val, 0x300190c);
274 }
275
uart_set_baudrate(uart_port_t uart_port,uart_baudrate_t baudrate)276 static void uart_set_baudrate(uart_port_t uart_port, uart_baudrate_t baudrate)
277 {
278 const unsigned long uart_base = sunxi_uart_port[uart_port];
279 uart_priv_t *uart_priv = &g_uart_priv[uart_port];
280 uint32_t actual_baudrate = g_uart_baudrate_map[baudrate];
281 uint32_t quot, uart_clk;
282
283 uart_clk = 24000000; /* FIXME: fixed to 24MHz */
284
285 quot = (uart_clk + 8 * actual_baudrate) / (16 * actual_baudrate);
286
287 UART_INFO("baudrate: %d, quot = %d\r\n", actual_baudrate, quot);
288
289 uart_priv->dlh = quot >> 8;
290 uart_priv->dll = quot & 0xff;
291
292 /* hold tx so that uart will update lcr and baud in the gap of tx */
293 hal_writeb(UART_HALT_HTX | UART_HALT_FORCECFG, uart_base + UART_HALT);
294 hal_writeb(uart_priv->lcr | UART_LCR_DLAB, uart_base + UART_LCR);
295 hal_writeb(uart_priv->dlh, uart_base + UART_DLH);
296 hal_writeb(uart_priv->dll, uart_base + UART_DLL);
297 hal_writeb(UART_HALT_HTX | UART_HALT_FORCECFG | UART_HALT_LCRUP, uart_base + UART_HALT);
298 /* FIXME: implement timeout */
299 while (hal_readb(uart_base + UART_HALT) & UART_HALT_LCRUP)
300 ;
301
302 /* In fact there are two DLABs(DLAB and DLAB_BAK) in the hardware implementation.
303 * The DLAB_BAK is sellected only when SW_UART_HALT_FORCECFG is set to 1,
304 * and this bit can be access no matter uart is busy or not.
305 * So we select the DLAB_BAK always by leaving SW_UART_HALT_FORCECFG to be 1. */
306 hal_writeb(uart_priv->lcr, uart_base + UART_LCR);
307 hal_writeb(UART_HALT_FORCECFG, uart_base + UART_HALT);
308 }
309
uart_set_fifo(uart_port_t uart_port,uint32_t value)310 static void uart_set_fifo(uart_port_t uart_port, uint32_t value)
311 {
312 const unsigned long uart_base = sunxi_uart_port[uart_port];
313 uart_priv_t *uart_priv = &g_uart_priv[uart_port];
314
315 uart_priv->fcr = value;
316 hal_writeb(uart_priv->fcr, uart_base + UART_FCR);
317 }
318
hal_uart_set_hardware_flowcontrol(uart_port_t uart_port)319 void hal_uart_set_hardware_flowcontrol(uart_port_t uart_port)
320 {
321 const unsigned long uart_base = sunxi_uart_port[uart_port];
322 uart_priv_t *uart_priv = &g_uart_priv[uart_port];
323 uint32_t value;
324
325 value = hal_readb(uart_base + UART_MCR);
326 value |= UART_MCR_DTR | UART_MCR_RTS | UART_MCR_AFE;
327 uart_priv->mcr = value;
328 hal_writeb(uart_priv->mcr, uart_base + UART_MCR);
329
330 /* enable with modem status interrupts */
331 value = hal_readb(uart_base + UART_IER);
332 value |= UART_IER_MSI;
333 uart_priv->ier = value;
334 hal_writeb(uart_priv->ier, uart_base + UART_IER);
335 }
336
hal_uart_disable_flowcontrol(uart_port_t uart_port)337 void hal_uart_disable_flowcontrol(uart_port_t uart_port)
338 {
339 const unsigned long uart_base = sunxi_uart_port[uart_port];
340 uart_priv_t *uart_priv = &g_uart_priv[uart_port];
341 uint32_t value;
342
343 value = hal_readb(uart_base + UART_MCR);
344 value &= ~(UART_MCR_DTR | UART_MCR_RTS | UART_MCR_AFE);
345 uart_priv->mcr = value;
346 hal_writeb(uart_priv->mcr, uart_base + UART_MCR);
347
348 /* disable with modem status interrupts */
349 value = hal_readb(uart_base + UART_IER);
350 value &= ~(UART_IER_MSI);
351 uart_priv->ier = value;
352 hal_writeb(uart_priv->ier, uart_base + UART_IER);
353 }
354
uart_force_idle(uart_port_t uart_port)355 static void uart_force_idle(uart_port_t uart_port)
356 {
357 const unsigned long uart_base = sunxi_uart_port[uart_port];
358 uart_priv_t *uart_priv = &g_uart_priv[uart_port];
359
360 if (uart_priv->fcr & UART_FCR_FIFO_EN)
361 {
362 hal_writeb(UART_FCR_FIFO_EN, uart_base + UART_FCR);
363 hal_writeb(UART_FCR_TXFIFO_RST
364 | UART_FCR_RXFIFO_RST
365 | UART_FCR_FIFO_EN, uart_base + UART_FCR);
366 hal_writeb(0, uart_base + UART_FCR);
367 }
368
369 hal_writeb(uart_priv->fcr, uart_base + UART_FCR);
370 (void)hal_readb(uart_base + UART_FCR);
371 }
372
uart_handle_busy(uart_port_t uart_port)373 static void uart_handle_busy(uart_port_t uart_port)
374 {
375 const unsigned long uart_base = sunxi_uart_port[uart_port];
376 uart_priv_t *uart_priv = &g_uart_priv[uart_port];
377
378 (void)hal_readb(uart_base + UART_USR);
379
380 /*
381 * Before reseting lcr, we should ensure than uart is not in busy
382 * state. Otherwise, a new busy interrupt will be introduced.
383 * It is wise to set uart into loopback mode, since it can cut down the
384 * serial in, then we should reset fifo(in my test, busy state
385 * (UART_USR_BUSY) can't be cleard until the fifo is empty).
386 */
387 hal_writeb(uart_priv->mcr | UART_MCR_LOOP, uart_base + UART_MCR);
388 uart_force_idle(uart_port);
389 hal_writeb(uart_priv->lcr, uart_base + UART_LCR);
390 hal_writeb(uart_priv->mcr, uart_base + UART_MCR);
391 }
392
hal_uart_handler_hook(uart_port_t uart_port)393 rt_weak void hal_uart_handler_hook(uart_port_t uart_port)
394 {
395 }
396
uart_handle_rx(uart_port_t uart_port,uint32_t lsr)397 static uint32_t uart_handle_rx(uart_port_t uart_port, uint32_t lsr)
398 {
399 const unsigned long uart_base = sunxi_uart_port[uart_port];
400 uint8_t ch = 0;
401
402 UART_INFO("IRQ uart%d handle rx \n", uart_port);
403 do
404 {
405 if (lsr & UART_LSR_DR)
406 {
407 ch = hal_readb(uart_base + UART_RBR);
408 hal_mailbox_send((hal_mailbox_t)uart_mailbox[uart_port], ch);
409 #ifdef CONFIG_SUNXI_UART_SUPPORT_POLL
410 hal_uart_poll_wakeup(uart_port, POLLIN);
411 #endif
412 }
413 lsr = hal_readb(uart_base + UART_LSR);
414 } while ((lsr & (UART_LSR_DR | UART_LSR_BI)));
415
416 /* wakeup console here */
417 hal_uart_handler_hook(uart_port);
418
419 return lsr;
420 }
421
422
uart_irq_handler(int irq,void * dev_id)423 static irqreturn_t uart_irq_handler(int irq, void *dev_id)
424 {
425 uart_priv_t *uart_priv = dev_id;
426 uart_port_t uart_port = uart_priv->uart_port;
427 const unsigned long uart_base = sunxi_uart_port[uart_port];
428 uint32_t iir, lsr;
429
430 iir = hal_readb(uart_base + UART_IIR) & UART_IIR_IID_MASK;
431 lsr = hal_readb(uart_base + UART_LSR);
432
433 UART_INFO_IRQ("IRQ uart%d lsr is %08x \n", uart_port, lsr);
434 if (iir == UART_IIR_IID_BUSBSY)
435 {
436 uart_handle_busy(uart_port);
437 }
438 else
439 {
440 if (lsr & (UART_LSR_DR | UART_LSR_BI))
441 {
442 lsr = uart_handle_rx(uart_port, lsr);
443 }
444 else if (iir & UART_IIR_IID_CHARTO)
445 /* has charto irq but no dr lsr? just read and ignore */
446 {
447 hal_readb(uart_base + UART_RBR);
448 }
449
450 /* if (lsr & UART_LSR_THRE)
451 {
452 uart_handle_tx(uart_port);
453 }*/
454 }
455 return 0;
456 }
457
uart_enable_irq(uart_port_t uart_port,uint32_t irq_type)458 static void uart_enable_irq(uart_port_t uart_port, uint32_t irq_type)
459 {
460 const unsigned long uart_base = sunxi_uart_port[uart_port];
461 uint32_t value;
462
463 value = hal_readb(uart_base + UART_IER);
464 value |= irq_type;
465 hal_writeb(value, uart_base + UART_IER);
466
467 }
468
uart_enable_busy_cfg(uart_port_t uart_port)469 static void uart_enable_busy_cfg(uart_port_t uart_port)
470 {
471 const unsigned long uart_base = sunxi_uart_port[uart_port];
472 uint32_t value;
473
474 value = hal_readb(uart_base + UART_HALT);
475 value |= UART_HALT_FORCECFG;
476 hal_writeb(value, uart_base + UART_HALT);
477 }
478
uart_clk_init(int bus,bool enable)479 static int uart_clk_init(int bus, bool enable)
480 {
481 hal_clk_status_t ret;
482 hal_reset_type_t reset_type = HAL_SUNXI_RESET;
483 u32 reset_id;
484 hal_clk_type_t clk_type = HAL_SUNXI_CCU;
485 hal_clk_id_t clk_id;
486 hal_clk_t clk;
487 struct reset_control *reset;
488
489 switch (bus)
490 {
491 case 0:
492 clk_id = SUNXI_CLK_UART0;
493 reset_id = SUNXI_RST_UART0;
494 break;
495 case 1:
496 clk_id = SUNXI_CLK_UART1;
497 reset_id = SUNXI_RST_UART1;
498 break;
499 case 2:
500 clk_id = SUNXI_CLK_UART2;
501 reset_id = SUNXI_RST_UART2;
502 break;
503 case 3:
504 clk_id = SUNXI_CLK_UART3;
505 reset_id = SUNXI_RST_UART3;
506 break;
507 default:
508 UART_ERR("uart%d is invalid\n", bus);
509 return -1;
510 }
511 if (enable)
512 {
513 reset = hal_reset_control_get(reset_type, reset_id);
514 hal_reset_control_deassert(reset);
515 hal_reset_control_put(reset);
516
517 clk = hal_clock_get(clk_type, clk_id);
518 ret = hal_clock_enable(clk);
519 if (ret)
520 {
521 UART_ERR("[uart%d] couldn't enable clk!\n", bus);
522 return -1;
523 }
524 }
525 else
526 {
527 clk = hal_clock_get(clk_type, clk_id);
528 ret = hal_clock_disable(clk);
529 if (ret)
530 {
531 UART_ERR("[uart%d] couldn't disable clk!\n", bus);
532 return -1;
533 }
534 }
535 return 0;
536 }
537
uart_pinctrl_init(uart_port_t uart_port)538 static void uart_pinctrl_init(uart_port_t uart_port)
539 {
540 #ifdef CONFIG_DRIVER_SYSCONFIG
541 user_gpio_set_t gpio_cfg[4];
542 int count, i;
543 char uart_name[16];
544 gpio_pin_t uart_pin[4];
545 gpio_muxsel_t uart_muxsel[4];
546
547 memset(gpio_cfg, 0, sizeof(gpio_cfg));
548 sprintf(uart_name, "uart%d", uart_port);
549 count = Hal_Cfg_GetGPIOSecKeyCount(uart_name);
550 if (!count)
551 {
552 UART_ERR("[uart%d] not support in sys_config\n", uart_port);
553 return ;
554 }
555 Hal_Cfg_GetGPIOSecData(uart_name, gpio_cfg, count);
556
557
558 for (i = 0; i < count; i++)
559 {
560 uart_pin[i] = (gpio_cfg[i].port - 1) * 32 + gpio_cfg[i].port_num;
561 uart_muxsel[i] = gpio_cfg[i].mul_sel;
562 hal_gpio_pinmux_set_function(uart_pin[i], uart_muxsel[i]);
563 }
564 #else
565 /* TODO:use sys_config instead it, but DSP does not support sys_config */
566 switch (uart_port)
567 {
568 case UART_0:
569 hal_gpio_set_pull(UART0_RX, GPIO_PULL_UP);
570 hal_gpio_pinmux_set_function(UART0_TX, UART0_GPIO_FUNCTION);//TX
571 hal_gpio_pinmux_set_function(UART0_RX, UART0_GPIO_FUNCTION);//RX
572 break;
573 case UART_1:
574 hal_gpio_set_pull(UART1_RX, GPIO_PULL_UP);
575 hal_gpio_pinmux_set_function(UART1_TX, UART1_GPIO_FUNCTION);//TX
576 hal_gpio_pinmux_set_function(UART1_RX, UART1_GPIO_FUNCTION);//RX
577 break;
578 case UART_2:
579 hal_gpio_set_pull(UART2_RX, GPIO_PULL_UP);
580 hal_gpio_pinmux_set_function(UART2_TX, UART2_GPIO_FUNCTION);//TX
581 hal_gpio_pinmux_set_function(UART2_RX, UART2_GPIO_FUNCTION);//RX
582 break;
583 case UART_3:
584 hal_gpio_set_pull(UART3_RX, GPIO_PULL_UP);
585 hal_gpio_pinmux_set_function(UART3_TX, UART3_GPIO_FUNCTION);//TX
586 hal_gpio_pinmux_set_function(UART3_RX, UART3_GPIO_FUNCTION);//RX
587 break;
588 default:
589 UART_ERR("[uart%d] not support \n", uart_port);
590 break;
591 }
592 #endif
593 }
594
uart_pinctrl_uninit(uart_port_t uart_port)595 static void uart_pinctrl_uninit(uart_port_t uart_port)
596 {
597 switch (uart_port)
598 {
599 case UART_0:
600 hal_gpio_pinmux_set_function(UART0_TX, GPIO_MUXSEL_DISABLED);//TX
601 hal_gpio_pinmux_set_function(UART0_RX, GPIO_MUXSEL_DISABLED);//RX
602 break;
603 case UART_1:
604 hal_gpio_pinmux_set_function(UART1_TX, GPIO_MUXSEL_DISABLED);//TX
605 hal_gpio_pinmux_set_function(UART1_RX, GPIO_MUXSEL_DISABLED);//RX
606 break;
607 case UART_2:
608 hal_gpio_pinmux_set_function(UART2_TX, GPIO_MUXSEL_DISABLED);//TX
609 hal_gpio_pinmux_set_function(UART2_RX, GPIO_MUXSEL_DISABLED);//RX
610 break;
611 case UART_3:
612 hal_gpio_pinmux_set_function(UART3_TX, GPIO_MUXSEL_DISABLED);//TX
613 hal_gpio_pinmux_set_function(UART3_RX, GPIO_MUXSEL_DISABLED);//RX
614 break;
615 default:
616 UART_ERR("[uart%d] not support \n", uart_port);
617 break;
618 }
619 }
620
621 /* default uart config */
622 _uart_config_t uart_defconfig =
623 {
624 .baudrate = UART_BAUDRATE_115200,
625 .word_length = UART_WORD_LENGTH_8,
626 .stop_bit = UART_STOP_BIT_1,
627 .parity = UART_PARITY_NONE,
628 };
629
hal_uart_init(int32_t uart_port)630 int32_t hal_uart_init(int32_t uart_port)
631 {
632 uart_priv_t *uart_priv = &g_uart_priv[uart_port];
633 uint32_t irqn = g_uart_irqn[uart_port];
634 uint32_t value = 0;
635 _uart_config_t *uart_config = &uart_defconfig;
636 char uart_name[12] = {0};
637
638 if ((!uart_port_is_valid(uart_port)) ||
639 (!uart_config_is_valid(uart_config)))
640 {
641 return HAL_UART_STATUS_ERROR_PARAMETER;
642 }
643
644 /* enable clk */
645 uart_clk_init(uart_port, true);
646
647 /* request gpio */
648 uart_pinctrl_init(uart_port);
649
650 /* config uart attributes */
651 uart_set_format(uart_port, uart_config->word_length,
652 uart_config->stop_bit, uart_config->parity);
653
654 /* force reset controller to disable transfer */
655 uart_reset(uart_port);
656
657 uart_set_baudrate(uart_port, uart_config->baudrate);
658
659 value |= UART_FCR_RXTRG_1_2 | UART_FCR_TXTRG_1_2 | UART_FCR_FIFO_EN;
660 uart_set_fifo(uart_port, value);
661
662 sprintf(uart_name, "uart%d", (int)uart_port);
663 if (uart_priv->uart_port == uart_port && uart_priv->irqn == irqn)
664 {
665 UART_ERR("irq for uart%ld already enabled\n", (long int)uart_port);
666 }
667 else
668 {
669 uart_priv->uart_port = uart_port;
670 uart_priv->irqn = irqn;
671
672 #if 1
673 if (request_irq(irqn, uart_irq_handler, 0, uart_name, uart_priv) < 0)
674 {
675 UART_ERR("request irq error\n");
676 return -1;
677 }
678 enable_irq(irqn);
679 #endif
680
681 #if 0
682 rt_hw_interrupt_install(irqn, uart_irq_handler, uart_priv, uart_name);
683 rt_hw_interrupt_umask(irqn);
684 #endif
685 }
686
687 uart_mailbox[uart_port] = hal_mailbox_create(uart_name, UART_FIFO_SIZE);
688 if (uart_mailbox[uart_port] == NULL)
689 {
690 UART_ERR("create mailbox fail\n");
691 return HAL_UART_STATUS_ERROR;
692 }
693
694 /* set uart IER */
695 uart_enable_irq(uart_port, UART_IER_RDI | UART_IER_RLSI);
696
697 /* force config */
698 uart_enable_busy_cfg(uart_port);
699
700 return SUNXI_HAL_OK;
701 }
702
hal_uart_deinit(int32_t uart_port)703 int32_t hal_uart_deinit(int32_t uart_port)
704 {
705 /* disable clk */
706 uart_clk_init(uart_port, false);
707 uart_pinctrl_uninit(uart_port);
708
709 return SUNXI_HAL_OK;
710 }
711
hal_uart_power_control(int32_t dev,sunxi_hal_power_state_e state)712 int32_t hal_uart_power_control(int32_t dev, sunxi_hal_power_state_e state)
713 {
714 return SUNXI_HAL_OK;
715 }
716
_uart_putc(int devid,char c)717 static int _uart_putc(int devid, char c)
718 {
719 volatile uint32_t *sed_buf;
720 volatile uint32_t *sta;
721
722 sed_buf = (uint32_t *)(sunxi_uart_port[devid] + UART_THR);
723 sta = (uint32_t *)(sunxi_uart_port[devid] + UART_USR);
724
725 /* FIFO status, contain valid data */
726 while (!(*sta & 0x02));
727 *sed_buf = c;
728
729 return 1;
730 }
731
hal_uart_put_char(int32_t dev,char c)732 int32_t hal_uart_put_char(int32_t dev, char c)
733 {
734 return _uart_putc(dev, c);
735 }
736
hal_uart_send(int32_t dev,const uint8_t * data,uint32_t num)737 int32_t hal_uart_send(int32_t dev, const uint8_t *data, uint32_t num)
738 {
739 int size;
740
741 hal_assert(data != NULL);
742
743 size = num;
744 while (num)
745 {
746 _uart_putc(dev, *data);
747
748 ++ data;
749 -- num;
750 }
751
752 return size - num;
753 }
754
_uart_getc(int devid)755 static int _uart_getc(int devid)
756 {
757 int ch = -1;
758 volatile uint32_t *rec_buf;
759 volatile uint32_t *sta;
760 volatile uint32_t *fifo;
761
762 rec_buf = (uint32_t *)(sunxi_uart_port[devid] + UART_RHB);
763 sta = (uint32_t *)(sunxi_uart_port[devid] + UART_USR);
764 fifo = (uint32_t *)(sunxi_uart_port[devid] + UART_RFL);
765
766 while (!(*fifo & 0x1ff));
767
768 /* Receive Data Available */
769 if (*sta & 0x08)
770 {
771 ch = *rec_buf & 0xff;
772 }
773
774 return ch;
775 }
776
hal_uart_get_char(int32_t dev)777 uint8_t hal_uart_get_char(int32_t dev)
778 {
779 return _uart_getc(dev);
780 }
781
hal_uart_receive_polling(int32_t dev,uint8_t * data,uint32_t num)782 int32_t hal_uart_receive_polling(int32_t dev, uint8_t *data, uint32_t num)
783 {
784 int ch;
785 int size;
786
787 hal_assert(data != NULL);
788 size = num;
789
790 while (num)
791 {
792 ch = _uart_getc(dev);
793 if (ch == -1)
794 {
795 break;
796 }
797
798 *data = ch;
799 data ++;
800 num --;
801
802 /* FIXME: maybe only used for console? move it away! */
803 if (ch == '\n')
804 {
805 break;
806 }
807 }
808
809 return size - num;
810 }
811
hal_uart_receive(int32_t dev,uint8_t * data,uint32_t num)812 int32_t hal_uart_receive(int32_t dev, uint8_t *data, uint32_t num)
813 {
814 unsigned int data_rev;
815 int i = 0;
816 int32_t ret = -1, rev_count = 0;
817
818 hal_assert(data != NULL);
819
820 for (i = 0; i < num; i++)
821 {
822 ret = hal_mailbox_recv((hal_mailbox_t)uart_mailbox[dev], &data_rev, -1);
823 if (ret == 0)
824 {
825 rev_count++;
826 *(data + i) = (uint8_t)data_rev;
827 }
828 else
829 {
830 UART_ERR("receive error");
831 break;
832 }
833 }
834
835 return rev_count;
836 }
837
hal_uart_receive_no_block(int32_t dev,uint8_t * data,uint32_t num,int32_t timeout)838 int32_t hal_uart_receive_no_block(int32_t dev, uint8_t *data, uint32_t num, int32_t timeout)
839 {
840 unsigned int data_rev;
841 int i = 0;
842 int32_t ret = -1, rev_count = 0;
843
844 hal_assert(data != NULL);
845
846 for (i = 0; i < num; i++)
847 {
848 ret = hal_mailbox_recv((hal_mailbox_t)uart_mailbox[dev], &data_rev, timeout);
849 if (ret == 0)
850 {
851 rev_count++;
852 *(data + i) = (uint8_t)data_rev;
853 }
854 else
855 {
856 break;
857 }
858 }
859
860 return rev_count;
861 }
862
863
hal_uart_transfer(int32_t dev,const void * data_out,void * data_in,uint32_t num)864 int32_t hal_uart_transfer(int32_t dev, const void *data_out,
865 void *data_in, uint32_t num)
866 {
867 return SUNXI_HAL_OK;
868 }
869
hal_uart_get_tx_count(int32_t dev)870 uint32_t hal_uart_get_tx_count(int32_t dev)
871 {
872 /* TODO: need verify */
873 return 0;
874 }
875
hal_uart_get_rx_count(int32_t dev)876 uint32_t hal_uart_get_rx_count(int32_t dev)
877 {
878 /* TODO: need verify */
879 return 0;
880 }
881
hal_uart_control(int32_t uart_port,int cmd,void * args)882 int32_t hal_uart_control(int32_t uart_port, int cmd, void *args)
883 {
884 _uart_config_t *uart_config;
885 uart_config = (_uart_config_t *)args;
886
887 /* config uart attributes */
888 uart_set_format(uart_port, uart_config->word_length,
889 uart_config->stop_bit, uart_config->parity);
890 uart_set_baudrate(uart_port, uart_config->baudrate);
891
892 return SUNXI_HAL_OK;
893 }
894
hal_uart_get_status(int32_t dev)895 sunxi_hal_uart_status_t hal_uart_get_status(int32_t dev)
896 {
897 sunxi_hal_uart_status_t status = {1, 1, 0, 0, 0, 0, 0, 0};
898
899 return status;
900 }
901
hal_uart_set_modem_control(int32_t dev,sunxi_hal_uart_modem_control_e control)902 int32_t hal_uart_set_modem_control(int32_t dev,
903 sunxi_hal_uart_modem_control_e control)
904 {
905 return SUNXI_HAL_OK;
906 }
907
hal_uart_get_modem_status(int32_t dev)908 sunxi_hal_uart_modem_status_t hal_uart_get_modem_status(int32_t dev)
909 {
910 sunxi_hal_uart_modem_status_t status = {0, 0, 0, 0, 0};
911
912 return status;
913 }
914
hal_uart_set_loopback(uart_port_t uart_port,bool enable)915 void hal_uart_set_loopback(uart_port_t uart_port, bool enable)
916 {
917 const unsigned long uart_base = sunxi_uart_port[uart_port];
918 uint32_t value;
919
920 value = hal_readb(uart_base + UART_MCR);
921 if (enable)
922 value |= UART_MCR_LOOP;
923 else
924 value &= ~(UART_MCR_LOOP);
925 hal_writeb(value, uart_base + UART_MCR);
926
927 }
928
serial_driver_init(void)929 int serial_driver_init(void)
930 {
931 UART_INFO("serial hal driver init");
932 return 0;
933 }
934
935