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