1 /*
2  * Copyright (c) 2020, Seagate Technology LLC
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #ifndef ZEPHYR_DRIVERS_SERIAL_UART_LPC11U6X_H_
8 #define ZEPHYR_DRIVERS_SERIAL_UART_LPC11U6X_H_
9 
10 #define LPC11U6X_UART0_CLK 14745600
11 
12 #define LPC11U6X_UART0_LCR_WLS_5BITS             0
13 #define LPC11U6X_UART0_LCR_WLS_6BITS             1
14 #define LPC11U6X_UART0_LCR_WLS_7BITS             2
15 #define LPC11U6X_UART0_LCR_WLS_8BITS             3
16 #define LPC11U6X_UART0_LCR_STOP_1BIT             (0 << 2)
17 #define LPC11U6X_UART0_LCR_STOP_2BIT             (1 << 2)
18 #define LPC11U6X_UART0_LCR_PARTIY_ENABLE         (1 << 3)
19 #define LPC11U6X_UART0_LCR_PARTIY_ODD            (0 << 4)
20 #define LPC11U6X_UART0_LCR_PARTIY_EVEN           (1 << 4)
21 
22 #define LPC11U6X_UART0_LCR_DLAB                  (1 << 7)
23 
24 #define LPC11U6X_UART0_FCR_FIFO_EN               (1 << 0)
25 
26 #define LPC11U6X_UART0_LSR_RDR                   (1 << 0)
27 #define LPC11U6X_UART0_LSR_OE                    (1 << 1)
28 #define LPC11U6X_UART0_LSR_PE                    (1 << 2)
29 #define LPC11U6X_UART0_LSR_FE                    (1 << 3)
30 #define LPC11U6X_UART0_LSR_BI                    (1 << 4)
31 #define LPC11U6X_UART0_LSR_THRE                  (1 << 5)
32 #define LPC11U6X_UART0_LSR_TEMT                  (1 << 6)
33 #define LPC11U6X_UART0_LSR_RXFE                  (1 << 7)
34 
35 #define LPC11U6X_UART0_IER_RBRINTEN              (1 << 0)
36 #define LPC11U6X_UART0_IER_THREINTEN             (1 << 1)
37 #define LPC11U6X_UART0_IER_RLSINTEN              (1 << 2)
38 #define LPC11U6X_UART0_IER_MASK                  (0x30F)
39 
40 #define LPC11U6X_UART0_IIR_STATUS                (0x1 << 0)
41 #define LPC11U6X_UART0_IIR_INTID(x)              (((x) >> 1) & 0x7)
42 #define LPC11U6X_UART0_IIR_INTID_RLS             0x3
43 #define LPC11U6X_UART0_IIR_INTID_RDA             0x2
44 #define LPC11U6X_UART0_IIR_INTID_CTI             0x6
45 #define LPC11U6X_UART0_IIR_INTID_THRE            0x1
46 
47 #define LPC11U6X_UART0_FIFO_SIZE                 16
48 
49 #define LPC11U6X_UARTX_CFG_ENABLE                (0x1 << 0)
50 #define LPC11U6X_UARTX_CFG_DATALEN_7BIT          (0x0 << 2)
51 #define LPC11U6X_UARTX_CFG_DATALEN_8BIT          (0x1 << 2)
52 #define LPC11U6X_UARTX_CFG_DATALEN_9BIT          (0x2 << 2)
53 #define LPC11U6X_UARTX_CFG_PARITY_NONE           (0x0 << 4)
54 #define LPC11U6X_UARTX_CFG_PARITY_EVEN           (0x2 << 4)
55 #define LPC11U6X_UARTX_CFG_PARITY_ODD            (0x3 << 4)
56 #define LPC11U6X_UARTX_CFG_STOP_1BIT             (0x0 << 6)
57 #define LPC11U6X_UARTX_CFG_STOP_2BIT             (0x1 << 6)
58 
59 #define LPC11U6X_UARTX_CFG_MASK                  (0x00FCDAFD)
60 
61 #define LPC11U6X_UARTX_STAT_RXRDY                (1 << 0)
62 #define LPC11U6X_UARTX_STAT_TXRDY                (1 << 2)
63 #define LPC11U6X_UARTX_STAT_TXIDLE               (1 << 3)
64 #define LPC11U6X_UARTX_STAT_OVERRUNINT           (1 << 8)
65 #define LPC11U6X_UARTX_STAT_FRAMERRINT           (1 << 13)
66 #define LPC11U6X_UARTX_STAT_PARITYERRINT         (1 << 14)
67 
68 #define LPC11U6X_UARTX_BRG_MASK                  (0xFFFF)
69 
70 #define LPC11U6X_UARTX_INT_EN_SET_RXRDYEN        (1 << 0)
71 #define LPC11U6X_UARTX_INT_EN_SET_TXRDYEN        (1 << 2)
72 #define LPC11U6X_UARTX_INT_EN_SET_OVERRUNEN      (1 << 8)
73 #define LPC11U6X_UARTX_INT_EN_SET_FRAMERREN      (1 << 13)
74 #define LPC11U6X_UARTX_INT_EN_SET_PARITYERREN    (1 << 14)
75 #define LPC11U6X_UARTX_INT_EN_SET_MASK           (0x0001F96D)
76 
77 #define LPC11U6X_UARTX_INT_EN_CLR_RXRDYCLR       (1 << 0)
78 #define LPC11U6X_UARTX_INT_EN_CLR_TXRDYCLR       (1 << 2)
79 #define LPC11U6X_UARTX_INT_EN_CLR_OVERRUNCLR     (1 << 8)
80 #define LPC11U6X_UARTX_INT_EN_CLR_FRAMERRCLR     (1 << 13)
81 #define LPC11U6X_UARTX_INT_EN_CLR_PARITYERRCLR   (1 << 14)
82 
83 #define LPC11U6X_UARTX_INT_STAT_RXRDY            (1 << 0)
84 #define LPC11U6X_UARTX_INT_STAT_TXRDY            (1 << 2)
85 #define LPC11U6X_UARTX_INT_STAT_OVERRUN          (1 << 8)
86 #define LPC11U6X_UARTX_INT_STAT_FRAMERR          (1 << 13)
87 #define LPC11U6X_UARTX_INT_STAT_PARITYERR        (1 << 14)
88 
89 #define LPC11U6X_UARTX_DEVICE_PER_IRQ            2
90 
91 struct lpc11u6x_uart0_regs {
92 	union {
93 		volatile const uint32_t rbr; /* RX buffer (RO) */
94 		volatile uint32_t thr;       /* TX buffer (WO) */
95 		volatile uint32_t dll;       /* Divisor latch LSB */
96 	};
97 	union {
98 		volatile uint32_t dlm;       /* Divisor latch MSB */
99 		volatile uint32_t ier;       /* Interrupt enable */
100 	};
101 	union {
102 		volatile uint32_t iir;       /* Interrupt ID */
103 		volatile uint32_t fcr;       /* FIFO Control */
104 	};
105 	volatile uint32_t lcr;               /* Line Control */
106 	volatile uint32_t mcr;               /* Modem Control */
107 	volatile uint32_t lsr;               /* Line Status */
108 	volatile uint32_t msr;               /* Modem Status */
109 	volatile uint32_t scr;               /* Scratch pad */
110 	volatile uint32_t acr;               /* Auto-baud Control */
111 	volatile uint32_t icr;               /* IrDA Control */
112 	volatile uint32_t fdr;               /* Fractional Divider */
113 	volatile uint32_t osr;               /* Oversampling register */
114 	volatile uint32_t ter;               /* Transmit enable */
115 	volatile uint32_t reserved1[3];
116 	volatile uint32_t hden;              /* Half duplex */
117 	volatile uint32_t reserved2;
118 	volatile uint32_t sci_ctrl;          /* Smart card interface */
119 	volatile uint32_t rs485_ctrl;        /* RS-485 control */
120 	volatile uint32_t rs485_addr_match;  /* RS-485 address match */
121 	volatile uint32_t rs485_dly;         /* RS-485 delay direction control
122 					      * delay
123 					      */
124 	volatile uint32_t sync_ctrl;         /* Synchronous mode control */
125 };
126 
127 struct lpc11u6x_uart0_config {
128 	struct lpc11u6x_uart0_regs *uart0;
129 	const char *clock_drv_name;
130 	const char *rx_pinmux_drv_name;
131 	const char *tx_pinmux_drv_name;
132 	uint32_t baudrate;
133 	uint32_t clkid;
134 	uint8_t rx_pin;
135 	uint8_t rx_func;
136 	uint8_t tx_pin;
137 	uint8_t tx_func;
138 #ifdef CONFIG_UART_INTERRUPT_DRIVEN
139 	void (*irq_config_func)(const struct device *dev);
140 #endif /* CONFIG_UART_INTERRUPT_DRIVEN */
141 };
142 
143 struct lpc11u6x_uart0_data {
144 	uint32_t baudrate;
145 	uint8_t parity;
146 	uint8_t stop_bits;
147 	uint8_t data_bits;
148 	uint8_t flow_ctrl;
149 #ifdef CONFIG_UART_INTERRUPT_DRIVEN
150 	uart_irq_callback_user_data_t cb;
151 	void *cb_data;
152 	uint32_t cached_iir;
153 #endif /* CONFIG_UART_INTERRUPT_DRIVEN */
154 };
155 
156 struct lpc11u6x_uartx_regs {
157 	volatile uint32_t cfg;               /* Configuration register */
158 	volatile uint32_t ctl;               /* Control register */
159 	volatile uint32_t stat;              /* Status register */
160 	volatile uint32_t int_en_set;        /* Interrupt enable and set */
161 	volatile uint32_t int_en_clr;        /* Interrupt enable clear */
162 	volatile const uint32_t rx_dat;      /* Receiver data */
163 	volatile const uint32_t rx_dat_stat; /* Receiver data status */
164 	volatile uint32_t tx_dat;            /* Transmit data */
165 	volatile uint32_t brg;               /* Baud rate generator */
166 	volatile const uint32_t int_stat;    /* Interrupt status */
167 	volatile uint32_t osr;               /* Oversample selection */
168 	volatile uint32_t addr;              /* Address regiser*/
169 };
170 
171 struct lpc11u6x_uartx_config {
172 	struct lpc11u6x_uartx_regs *base;
173 	const char *clock_drv_name;
174 	const char *rx_pinmux_drv_name;
175 	const char *tx_pinmux_drv_name;
176 	uint32_t baudrate;
177 	uint32_t clkid;
178 	uint8_t rx_pin;
179 	uint8_t rx_func;
180 	uint8_t tx_pin;
181 	uint8_t tx_func;
182 };
183 
184 struct lpc11u6x_uartx_data {
185 	uint32_t baudrate;
186 	uint8_t parity;
187 	uint8_t stop_bits;
188 	uint8_t data_bits;
189 	uint8_t flow_ctrl;
190 #ifdef CONFIG_UART_INTERRUPT_DRIVEN
191 	uart_irq_callback_user_data_t cb;
192 	void *cb_data;
193 #endif /* CONFIG_UART_INTERRUPT_DRIVEN */
194 };
195 
196 /* Since UART1 and UART4 share the same IRQ (as well as UART2 and UART3),
197  * we need to give the ISR a way to know all the devices that should be
198  * notified when said IRQ is raied
199  */
200 struct lpc11u6x_uartx_shared_irq {
201 	const struct device *devices[LPC11U6X_UARTX_DEVICE_PER_IRQ];
202 };
203 
204 #if CONFIG_UART_INTERRUPT_DRIVEN &&				\
205 	(DT_NODE_HAS_STATUS(DT_NODELABEL(uart1), okay) ||	\
206 	 DT_NODE_HAS_STATUS(DT_NODELABEL(uart4), okay))
207 static void lpc11u6x_uartx_isr_config_1(const struct device *dev);
208 #endif /* CONFIG_UART_INTERRUPT_DRIVEN &&
209 	* (DT_NODE_HAS_STATUS(DT_NODELABEL(uart2), okay) ||
210 	* DT_NODE_HAS_STATUS(DT_NODELABEL(uart3), okay))
211 	*/
212 
213 #if CONFIG_UART_INTERRUPT_DRIVEN &&				\
214 	(DT_NODE_HAS_STATUS(DT_NODELABEL(uart2), okay) ||	\
215 	 DT_NODE_HAS_STATUS(DT_NODELABEL(uart3), okay))
216 static void lpc11u6x_uartx_isr_config_2(const struct device *dev);
217 #endif /* CONFIG_UART_INTERRUPT_DRIVEN &&
218 	* (DT_NODE_HAS_STATUS(DT_NODELABEL(uart2), okay) ||
219 	* DT_NODE_HAS_STATUS(DT_NODELABEL(uart3), okay))
220 	*/
221 #endif /* ZEPHYR_DRIVERS_SERIAL_UART_LPC11U6X_H_ */
222