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