1 /*
2 * Copyright (c) 2023 ENE Technology Inc.
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #define DT_DRV_COMPAT ene_kb1200_uart
8
9 #include <zephyr/kernel.h>
10 #include <zephyr/drivers/uart.h>
11 #include <zephyr/drivers/pinctrl.h>
12 #include <reg/ser.h>
13
14 struct kb1200_uart_config {
15 #ifdef CONFIG_UART_INTERRUPT_DRIVEN
16 void (*irq_cfg_func)(void);
17 #endif
18 struct serial_regs *ser;
19 const struct pinctrl_dev_config *pcfg;
20 };
21
22 struct kb1200_uart_data {
23 uart_irq_callback_user_data_t callback;
24 struct uart_config current_config;
25 void *callback_data;
26 uint8_t pending_flag_data;
27 };
28
kb1200_uart_err_check(const struct device * dev)29 static int kb1200_uart_err_check(const struct device *dev)
30 {
31 const struct kb1200_uart_config *config = dev->config;
32 int err = 0;
33
34 if (config->ser->SERSTS & SERSTS_RX_OVERRUN) {
35 err |= UART_ERROR_OVERRUN;
36 }
37 if (config->ser->SERSTS & SERSTS_PARITY_ERROR) {
38 err |= UART_ERROR_PARITY;
39 }
40 if (config->ser->SERSTS & SERSTS_FRAME_ERROR) {
41 err |= UART_ERROR_FRAMING;
42 }
43 return err;
44 }
45
46 #ifdef CONFIG_UART_USE_RUNTIME_CONFIGURE
kb1200_uart_configure(const struct device * dev,const struct uart_config * cfg)47 static int kb1200_uart_configure(const struct device *dev, const struct uart_config *cfg)
48 {
49 uint16_t reg_baudrate = 0;
50 uint8_t reg_parity = 0;
51 int ret = 0;
52 const struct kb1200_uart_config *config = dev->config;
53 struct kb1200_uart_data *data = dev->data;
54
55 reg_baudrate = (DIVIDER_BASE_CLK / cfg->baudrate) - 1;
56
57 switch (cfg->parity) {
58 case UART_CFG_PARITY_NONE:
59 reg_parity = SERCFG_PARITY_NONE;
60 break;
61 case UART_CFG_PARITY_ODD:
62 reg_parity = SERCFG_PARITY_ODD;
63 break;
64 case UART_CFG_PARITY_EVEN:
65 reg_parity = SERCFG_PARITY_EVEN;
66 break;
67 case UART_CFG_PARITY_MARK:
68 case UART_CFG_PARITY_SPACE:
69 default:
70 ret = -ENOTSUP;
71 break;
72 }
73
74 switch (cfg->stop_bits) {
75 case UART_CFG_STOP_BITS_1:
76 break;
77 case UART_CFG_STOP_BITS_0_5:
78 case UART_CFG_STOP_BITS_1_5:
79 case UART_CFG_STOP_BITS_2:
80 default:
81 ret = -ENOTSUP;
82 break;
83 }
84
85 switch (cfg->data_bits) {
86 case UART_CFG_DATA_BITS_8:
87 break;
88 case UART_CFG_DATA_BITS_5:
89 case UART_CFG_DATA_BITS_6:
90 case UART_CFG_DATA_BITS_7:
91 case UART_CFG_DATA_BITS_9:
92 default:
93 ret = -ENOTSUP;
94 break;
95 }
96
97 switch (cfg->flow_ctrl) {
98 case UART_CFG_FLOW_CTRL_NONE:
99 break;
100 case UART_CFG_FLOW_CTRL_RTS_CTS:
101 case UART_CFG_FLOW_CTRL_DTR_DSR:
102 case UART_CFG_FLOW_CTRL_RS485:
103 default:
104 ret = -ENOTSUP;
105 break;
106 }
107 config->ser->SERCFG =
108 (reg_baudrate << 16) | (reg_parity << 2) | (SERIE_RX_ENABLE | SERIE_TX_ENABLE);
109 config->ser->SERCTRL = SERCTRL_MODE1;
110 data->current_config = *cfg;
111 return ret;
112 }
113
kb1200_uart_config_get(const struct device * dev,struct uart_config * cfg)114 static int kb1200_uart_config_get(const struct device *dev, struct uart_config *cfg)
115 {
116 struct kb1200_uart_data *data = dev->data;
117
118 *cfg = data->current_config;
119 return 0;
120 }
121 #endif /* CONFIG_UART_USE_RUNTIME_CONFIGURE */
122
123 #ifdef CONFIG_UART_INTERRUPT_DRIVEN
kb1200_uart_fifo_fill(const struct device * dev,const uint8_t * tx_data,int size)124 static int kb1200_uart_fifo_fill(const struct device *dev, const uint8_t *tx_data, int size)
125 {
126 const struct kb1200_uart_config *config = dev->config;
127 uint16_t tx_bytes = 0U;
128
129 while ((size - tx_bytes) > 0) {
130 /* Check Tx FIFO not Full*/
131 while (config->ser->SERSTS & SERSTS_TX_FULL)
132 ;
133 /* Put a character into Tx FIFO */
134 config->ser->SERTBUF = tx_data[tx_bytes];
135 tx_bytes++;
136 }
137 return tx_bytes;
138 }
139
kb1200_uart_fifo_read(const struct device * dev,uint8_t * rx_data,const int size)140 static int kb1200_uart_fifo_read(const struct device *dev, uint8_t *rx_data, const int size)
141 {
142 const struct kb1200_uart_config *config = dev->config;
143 uint16_t rx_bytes = 0U;
144
145 /* Check Rx FIFO not Empty*/
146 while ((size - rx_bytes > 0) && (!(config->ser->SERSTS & SERSTS_RX_EMPTY))) {
147 /* Put a character into Tx FIFO */
148 rx_data[rx_bytes] = config->ser->SERRBUF;
149 rx_bytes++;
150 }
151 return rx_bytes;
152 }
153
kb1200_uart_irq_tx_enable(const struct device * dev)154 static void kb1200_uart_irq_tx_enable(const struct device *dev)
155 {
156 const struct kb1200_uart_config *config = dev->config;
157
158 config->ser->SERPF = SERPF_TX_EMPTY;
159 config->ser->SERIE |= SERIE_TX_ENABLE;
160 }
161
kb1200_uart_irq_tx_disable(const struct device * dev)162 static void kb1200_uart_irq_tx_disable(const struct device *dev)
163 {
164 const struct kb1200_uart_config *config = dev->config;
165
166 config->ser->SERIE &= ~SERIE_TX_ENABLE;
167 config->ser->SERPF = SERPF_TX_EMPTY;
168 }
169
kb1200_uart_irq_tx_ready(const struct device * dev)170 static int kb1200_uart_irq_tx_ready(const struct device *dev)
171 {
172 struct kb1200_uart_data *data = dev->data;
173
174 return (data->pending_flag_data & SERPF_TX_EMPTY) ? 1 : 0;
175 }
176
kb1200_uart_irq_rx_enable(const struct device * dev)177 static void kb1200_uart_irq_rx_enable(const struct device *dev)
178 {
179 const struct kb1200_uart_config *config = dev->config;
180
181 config->ser->SERPF = SERPF_RX_CNT_FULL;
182 config->ser->SERIE |= SERIE_RX_ENABLE;
183 }
184
kb1200_uart_irq_rx_disable(const struct device * dev)185 static void kb1200_uart_irq_rx_disable(const struct device *dev)
186 {
187 const struct kb1200_uart_config *config = dev->config;
188
189 config->ser->SERIE &= (~SERIE_RX_ENABLE);
190 config->ser->SERPF = SERPF_RX_CNT_FULL;
191 }
192
kb1200_uart_irq_rx_ready(const struct device * dev)193 static int kb1200_uart_irq_rx_ready(const struct device *dev)
194 {
195 struct kb1200_uart_data *data = dev->data;
196
197 return (data->pending_flag_data & SERPF_RX_CNT_FULL) ? 1 : 0;
198 }
199
kb1200_uart_irq_err_enable(const struct device * dev)200 static void kb1200_uart_irq_err_enable(const struct device *dev)
201 {
202 const struct kb1200_uart_config *config = dev->config;
203
204 config->ser->SERPF = SERPF_RX_ERROR;
205 config->ser->SERIE |= SERIE_RX_ERROR;
206 }
207
kb1200_uart_irq_err_disable(const struct device * dev)208 static void kb1200_uart_irq_err_disable(const struct device *dev)
209 {
210 const struct kb1200_uart_config *config = dev->config;
211
212 config->ser->SERIE &= (~SERIE_RX_ERROR);
213 config->ser->SERPF = SERPF_RX_ERROR;
214 }
215
kb1200_uart_irq_is_pending(const struct device * dev)216 static int kb1200_uart_irq_is_pending(const struct device *dev)
217 {
218 struct kb1200_uart_data *data = dev->data;
219
220 return (data->pending_flag_data) ? 1 : 0;
221 }
222
kb1200_uart_irq_update(const struct device * dev)223 static int kb1200_uart_irq_update(const struct device *dev)
224 {
225 struct kb1200_uart_data *data = dev->data;
226 const struct kb1200_uart_config *config = dev->config;
227
228 data->pending_flag_data = (config->ser->SERPF) & (config->ser->SERIE);
229 /*clear pending flag*/
230 config->ser->SERPF = data->pending_flag_data;
231 return 1;
232 }
233
kb1200_uart_irq_callback_set(const struct device * dev,uart_irq_callback_user_data_t cb,void * cb_data)234 static void kb1200_uart_irq_callback_set(const struct device *dev, uart_irq_callback_user_data_t cb,
235 void *cb_data)
236 {
237 struct kb1200_uart_data *data = dev->data;
238
239 data->callback = cb;
240 data->callback_data = cb_data;
241 }
242
kb1200_uart_irq_handler(const struct device * dev)243 static void kb1200_uart_irq_handler(const struct device *dev)
244 {
245 struct kb1200_uart_data *data = dev->data;
246
247 if (data->callback) {
248 data->callback(dev, data->callback_data);
249 }
250 }
251 #endif /* CONFIG_UART_INTERRUPT_DRIVEN */
252
kb1200_uart_poll_in(const struct device * dev,unsigned char * c)253 static int kb1200_uart_poll_in(const struct device *dev, unsigned char *c)
254 {
255 #ifdef CONFIG_UART_INTERRUPT_DRIVEN
256 return kb1200_uart_fifo_read(dev, c, 1) ? 0 : -1;
257 #else
258 const struct kb1200_uart_config *config = dev->config;
259
260 /* Check Rx FIFO not Empty*/
261 if (config->ser->SERSTS & SERSTS_RX_EMPTY) {
262 return -1;
263 }
264 /* Put a character into Tx FIFO */
265 *c = config->ser->SERRBUF;
266 return 0;
267 #endif /* CONFIG_UART_INTERRUPT_DRIVEN */
268 }
269
kb1200_uart_poll_out(const struct device * dev,unsigned char c)270 static void kb1200_uart_poll_out(const struct device *dev, unsigned char c)
271 {
272 #ifdef CONFIG_UART_INTERRUPT_DRIVEN
273 kb1200_uart_fifo_fill(dev, &c, 1);
274 #else
275 const struct kb1200_uart_config *config = dev->config;
276
277 /* Wait Tx FIFO not Full*/
278 while (config->ser->SERSTS & SER_TxFull) {
279 ;
280 }
281 /* Put a character into Tx FIFO */
282 config->ser->SERTBUF = c;
283 #endif /* CONFIG_UART_INTERRUPT_DRIVEN */
284 }
285
286 static DEVICE_API(uart, kb1200_uart_api) = {
287 .poll_in = kb1200_uart_poll_in,
288 .poll_out = kb1200_uart_poll_out,
289 .err_check = kb1200_uart_err_check,
290 #ifdef CONFIG_UART_USE_RUNTIME_CONFIGURE
291 .configure = kb1200_uart_configure,
292 .config_get = kb1200_uart_config_get,
293 #endif /* CONFIG_UART_USE_RUNTIME_CONFIGURE */
294 #ifdef CONFIG_UART_INTERRUPT_DRIVEN
295 .fifo_fill = kb1200_uart_fifo_fill,
296 .fifo_read = kb1200_uart_fifo_read,
297 .irq_tx_enable = kb1200_uart_irq_tx_enable,
298 .irq_tx_disable = kb1200_uart_irq_tx_disable,
299 .irq_tx_ready = kb1200_uart_irq_tx_ready,
300 .irq_rx_enable = kb1200_uart_irq_rx_enable,
301 .irq_rx_disable = kb1200_uart_irq_rx_disable,
302 .irq_rx_ready = kb1200_uart_irq_rx_ready,
303 .irq_err_enable = kb1200_uart_irq_err_enable,
304 .irq_err_disable = kb1200_uart_irq_err_disable,
305 .irq_is_pending = kb1200_uart_irq_is_pending,
306 .irq_update = kb1200_uart_irq_update,
307 .irq_callback_set = kb1200_uart_irq_callback_set,
308 #endif /* CONFIG_UART_INTERRUPT_DRIVEN */
309 };
310
311 #ifdef CONFIG_UART_INTERRUPT_DRIVEN
312
313 /* GPIO module instances */
314 #define KB1200_UART_DEV(inst) DEVICE_DT_INST_GET(inst),
315 static const struct device *const uart_devices[] = {DT_INST_FOREACH_STATUS_OKAY(KB1200_UART_DEV)};
kb1200_uart_isr_wrap(const struct device * dev)316 static void kb1200_uart_isr_wrap(const struct device *dev)
317 {
318 for (size_t i = 0; i < ARRAY_SIZE(uart_devices); i++) {
319 const struct device *dev_ = uart_devices[i];
320 const struct kb1200_uart_config *config = dev_->config;
321
322 if (config->ser->SERIE & config->ser->SERPF) {
323 kb1200_uart_irq_handler(dev_);
324 }
325 }
326 }
327 #endif /* CONFIG_UART_INTERRUPT_DRIVEN */
328
kb1200_uart_init(const struct device * dev)329 static int kb1200_uart_init(const struct device *dev)
330 {
331 int ret;
332 const struct kb1200_uart_config *config = dev->config;
333 struct kb1200_uart_data *data = dev->data;
334
335 ret = pinctrl_apply_state(config->pcfg, PINCTRL_STATE_DEFAULT);
336 if (ret != 0) {
337 return ret;
338 }
339
340 kb1200_uart_configure(dev, &data->current_config);
341 #ifdef CONFIG_UART_INTERRUPT_DRIVEN
342 config->irq_cfg_func();
343 #endif /* CONFIG_UART_INTERRUPT_DRIVEN */
344
345 return 0;
346 }
347
348 #ifdef CONFIG_UART_INTERRUPT_DRIVEN
349 static bool init_irq = true;
kb1200_uart_irq_init(void)350 static void kb1200_uart_irq_init(void)
351 {
352 if (init_irq) {
353 init_irq = false;
354 IRQ_CONNECT(DT_INST_IRQN(0), DT_INST_IRQ(0, priority), kb1200_uart_isr_wrap, NULL,
355 0);
356 irq_enable(DT_INST_IRQN(0));
357 }
358 }
359 #endif /* CONFIG_UART_INTERRUPT_DRIVEN */
360
361 #define KB1200_UART_INIT(n) \
362 PINCTRL_DT_INST_DEFINE(n); \
363 static struct kb1200_uart_data kb1200_uart_data_##n = { \
364 .current_config = { \
365 .baudrate = DT_INST_PROP(n, current_speed), \
366 .parity = UART_CFG_PARITY_NONE, \
367 .stop_bits = UART_CFG_STOP_BITS_1, \
368 .data_bits = UART_CFG_DATA_BITS_8, \
369 .flow_ctrl = UART_CFG_FLOW_CTRL_NONE, \
370 }, \
371 }; \
372 static const struct kb1200_uart_config kb1200_uart_config_##n = { \
373 IF_ENABLED(CONFIG_UART_INTERRUPT_DRIVEN, (.irq_cfg_func = kb1200_uart_irq_init,)) \
374 .ser = (struct serial_regs *)DT_INST_REG_ADDR(n), \
375 .pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(n)}; \
376 DEVICE_DT_INST_DEFINE(n, kb1200_uart_init, NULL, &kb1200_uart_data_##n, \
377 &kb1200_uart_config_##n, PRE_KERNEL_1, CONFIG_SERIAL_INIT_PRIORITY, \
378 &kb1200_uart_api);
379
380 DT_INST_FOREACH_STATUS_OKAY(KB1200_UART_INIT)
381