1 /*
2 * Copyright (c) 2023-2024 Analog Devices, Inc.
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include <zephyr/drivers/pinctrl.h>
8 #include <zephyr/drivers/uart.h>
9 #include <zephyr/kernel.h>
10 #include <zephyr/logging/log.h>
11 #include <zephyr/drivers/clock_control/adi_max32_clock_control.h>
12
13 #include <wrap_max32_uart.h>
14
15 #define DT_DRV_COMPAT adi_max32_uart
16
17 LOG_MODULE_REGISTER(uart_max32, CONFIG_UART_LOG_LEVEL);
18
19 struct max32_uart_config {
20 mxc_uart_regs_t *regs;
21 const struct pinctrl_dev_config *pctrl;
22 const struct device *clock;
23 struct max32_perclk perclk;
24 struct uart_config uart_conf;
25 #ifdef CONFIG_UART_INTERRUPT_DRIVEN
26 uart_irq_config_func_t irq_config_func;
27 #endif /* CONFIG_UART_INTERRUPT_DRIVEN */
28 };
29
30 struct max32_uart_data {
31 #ifdef CONFIG_UART_INTERRUPT_DRIVEN
32 uart_irq_callback_user_data_t cb; /* Interrupt callback */
33 void *cb_data; /* Interrupt callback arg */
34 uint32_t flags; /* Cached interrupt flags */
35 uint32_t status; /* Cached status flags */
36 #endif
37 struct uart_config conf; /* baudrate, stopbits, ... */
38 };
39
40 #ifdef CONFIG_UART_INTERRUPT_DRIVEN
41 static void uart_max32_isr(const struct device *dev);
42 #endif
43
api_poll_out(const struct device * dev,unsigned char c)44 static void api_poll_out(const struct device *dev, unsigned char c)
45 {
46 const struct max32_uart_config *cfg = dev->config;
47
48 MXC_UART_WriteCharacter(cfg->regs, c);
49 }
50
api_poll_in(const struct device * dev,unsigned char * c)51 static int api_poll_in(const struct device *dev, unsigned char *c)
52 {
53 int val;
54 const struct max32_uart_config *cfg = dev->config;
55
56 val = MXC_UART_ReadCharacterRaw(cfg->regs);
57 if (val >= 0) {
58 *c = (unsigned char)val;
59 } else {
60 return -1;
61 }
62
63 return 0;
64 }
65
api_err_check(const struct device * dev)66 static int api_err_check(const struct device *dev)
67 {
68 int err = 0;
69 uint32_t flags;
70 const struct max32_uart_config *cfg = dev->config;
71
72 flags = MXC_UART_GetFlags(cfg->regs);
73
74 if (flags & ADI_MAX32_UART_ERROR_FRAMING) {
75 err |= UART_ERROR_FRAMING;
76 }
77
78 if (flags & ADI_MAX32_UART_ERROR_PARITY) {
79 err |= UART_ERROR_PARITY;
80 }
81
82 if (flags & ADI_MAX32_UART_ERROR_OVERRUN) {
83 err |= UART_ERROR_OVERRUN;
84 }
85
86 return err;
87 }
88
api_configure(const struct device * dev,const struct uart_config * uart_cfg)89 static int api_configure(const struct device *dev, const struct uart_config *uart_cfg)
90 {
91 int err;
92 const struct max32_uart_config *const cfg = dev->config;
93 mxc_uart_regs_t *regs = cfg->regs;
94 struct max32_uart_data *data = dev->data;
95
96 /*
97 * Set parity
98 */
99 if (data->conf.parity != uart_cfg->parity) {
100 mxc_uart_parity_t mxc_parity;
101
102 switch (uart_cfg->parity) {
103 case UART_CFG_PARITY_NONE:
104 mxc_parity = ADI_MAX32_UART_CFG_PARITY_NONE;
105 break;
106 case UART_CFG_PARITY_ODD:
107 mxc_parity = ADI_MAX32_UART_CFG_PARITY_ODD;
108 break;
109 case UART_CFG_PARITY_EVEN:
110 mxc_parity = ADI_MAX32_UART_CFG_PARITY_EVEN;
111 break;
112 case UART_CFG_PARITY_MARK:
113 #if defined(ADI_MAX32_UART_CFG_PARITY_MARK)
114 mxc_parity = ADI_MAX32_UART_CFG_PARITY_MARK;
115 break;
116 #else
117 return -ENOTSUP;
118 #endif
119 case UART_CFG_PARITY_SPACE:
120 #if defined(ADI_MAX32_UART_CFG_PARITY_SPACE)
121 mxc_parity = ADI_MAX32_UART_CFG_PARITY_SPACE;
122 break;
123 #else
124 return -ENOTSUP;
125 #endif
126 default:
127 return -EINVAL;
128 }
129
130 err = MXC_UART_SetParity(regs, mxc_parity);
131 if (err < 0) {
132 return -ENOTSUP;
133 }
134 /* incase of success keep configuration */
135 data->conf.parity = uart_cfg->parity;
136 }
137
138 /*
139 * Set stop bit
140 */
141 if (data->conf.stop_bits != uart_cfg->stop_bits) {
142 if (uart_cfg->stop_bits == UART_CFG_STOP_BITS_1) {
143 err = MXC_UART_SetStopBits(regs, MXC_UART_STOP_1);
144 } else if (uart_cfg->stop_bits == UART_CFG_STOP_BITS_2) {
145 err = MXC_UART_SetStopBits(regs, MXC_UART_STOP_2);
146 } else {
147 return -ENOTSUP;
148 }
149 if (err < 0) {
150 return -ENOTSUP;
151 }
152 /* incase of success keep configuration */
153 data->conf.stop_bits = uart_cfg->stop_bits;
154 }
155
156 /*
157 * Set data bit
158 * Valid data for MAX32 is 5-6-7-8
159 * Valid data for Zepyhr is 0-1-2-3
160 * Added +5 to index match.
161 */
162 if (data->conf.data_bits != uart_cfg->data_bits) {
163 err = MXC_UART_SetDataSize(regs, (5 + uart_cfg->data_bits));
164 if (err < 0) {
165 return -ENOTSUP;
166 }
167 /* incase of success keep configuration */
168 data->conf.data_bits = uart_cfg->data_bits;
169 }
170
171 /*
172 * Set flow control
173 * Flow control not implemented yet so that only support no flow mode
174 */
175 if (data->conf.flow_ctrl != uart_cfg->flow_ctrl) {
176 if (uart_cfg->flow_ctrl != UART_CFG_FLOW_CTRL_NONE) {
177 return -ENOTSUP;
178 }
179 data->conf.flow_ctrl = uart_cfg->flow_ctrl;
180 }
181
182 /*
183 * Set baudrate
184 */
185 if (data->conf.baudrate != uart_cfg->baudrate) {
186 err = Wrap_MXC_UART_SetFrequency(regs, uart_cfg->baudrate, cfg->perclk.clk_src);
187 if (err < 0) {
188 return -ENOTSUP;
189 }
190 /* In case of success keep configuration */
191 data->conf.baudrate = uart_cfg->baudrate;
192 }
193 return 0;
194 }
195
196 #ifdef CONFIG_UART_USE_RUNTIME_CONFIGURE
197
api_config_get(const struct device * dev,struct uart_config * uart_cfg)198 static int api_config_get(const struct device *dev, struct uart_config *uart_cfg)
199 {
200 struct max32_uart_data *data = dev->data;
201
202 /* copy configs from global setting */
203 *uart_cfg = data->conf;
204
205 return 0;
206 }
207
208 #endif /* CONFIG_UART_USE_RUNTIME_CONFIGURE */
209
uart_max32_init(const struct device * dev)210 static int uart_max32_init(const struct device *dev)
211 {
212 int ret;
213 const struct max32_uart_config *const cfg = dev->config;
214 mxc_uart_regs_t *regs = cfg->regs;
215
216 if (!device_is_ready(cfg->clock)) {
217 LOG_ERR("Clock control device not ready");
218 return -ENODEV;
219 }
220
221 ret = MXC_UART_Shutdown(regs);
222 if (ret) {
223 return ret;
224 }
225
226 ret = clock_control_on(cfg->clock, (clock_control_subsys_t)&cfg->perclk);
227 if (ret != 0) {
228 LOG_ERR("Cannot enable UART clock");
229 return ret;
230 }
231
232 ret = pinctrl_apply_state(cfg->pctrl, PINCTRL_STATE_DEFAULT);
233 if (ret) {
234 return ret;
235 }
236
237 ret = api_configure(dev, &cfg->uart_conf);
238 if (ret) {
239 return ret;
240 }
241
242 ret = Wrap_MXC_UART_Init(regs);
243 if (ret) {
244 return ret;
245 }
246
247 #ifdef CONFIG_UART_INTERRUPT_DRIVEN
248 /* Clear any pending UART RX/TX interrupts */
249 MXC_UART_ClearFlags(regs, (ADI_MAX32_UART_INT_RX | ADI_MAX32_UART_INT_TX));
250 cfg->irq_config_func(dev);
251 #endif
252
253 return ret;
254 }
255
256 #ifdef CONFIG_UART_INTERRUPT_DRIVEN
257
api_fifo_fill(const struct device * dev,const uint8_t * tx_data,int size)258 static int api_fifo_fill(const struct device *dev, const uint8_t *tx_data, int size)
259 {
260 unsigned int num_tx = 0;
261 const struct max32_uart_config *cfg = dev->config;
262
263 num_tx = MXC_UART_WriteTXFIFO(cfg->regs, (unsigned char *)tx_data, size);
264
265 return (int)num_tx;
266 }
267
api_fifo_read(const struct device * dev,uint8_t * rx_data,const int size)268 static int api_fifo_read(const struct device *dev, uint8_t *rx_data, const int size)
269 {
270 unsigned int num_rx = 0;
271 const struct max32_uart_config *cfg = dev->config;
272
273 num_rx = MXC_UART_ReadRXFIFO(cfg->regs, (unsigned char *)rx_data, size);
274 if (num_rx == 0) {
275 MXC_UART_ClearFlags(cfg->regs, ADI_MAX32_UART_INT_RX);
276 }
277
278 return num_rx;
279 }
280
api_irq_tx_enable(const struct device * dev)281 static void api_irq_tx_enable(const struct device *dev)
282 {
283 const struct max32_uart_config *cfg = dev->config;
284 unsigned int key;
285
286 MXC_UART_EnableInt(cfg->regs, ADI_MAX32_UART_INT_TX | ADI_MAX32_UART_INT_TX_OEM);
287
288 key = irq_lock();
289 uart_max32_isr(dev);
290 irq_unlock(key);
291 }
292
api_irq_tx_disable(const struct device * dev)293 static void api_irq_tx_disable(const struct device *dev)
294 {
295 const struct max32_uart_config *cfg = dev->config;
296
297 MXC_UART_DisableInt(cfg->regs, ADI_MAX32_UART_INT_TX | ADI_MAX32_UART_INT_TX_OEM);
298 }
299
api_irq_tx_ready(const struct device * dev)300 static int api_irq_tx_ready(const struct device *dev)
301 {
302 struct max32_uart_data *const data = dev->data;
303 const struct max32_uart_config *cfg = dev->config;
304 uint32_t inten = Wrap_MXC_UART_GetRegINTEN(cfg->regs);
305
306 return ((inten & (ADI_MAX32_UART_INT_TX | ADI_MAX32_UART_INT_TX_OEM)) &&
307 !(data->status & MXC_F_UART_STATUS_TX_FULL));
308 }
309
api_irq_rx_enable(const struct device * dev)310 static void api_irq_rx_enable(const struct device *dev)
311 {
312 const struct max32_uart_config *cfg = dev->config;
313
314 MXC_UART_EnableInt(cfg->regs, ADI_MAX32_UART_INT_RX);
315 }
316
api_irq_rx_disable(const struct device * dev)317 static void api_irq_rx_disable(const struct device *dev)
318 {
319 const struct max32_uart_config *cfg = dev->config;
320
321 MXC_UART_DisableInt(cfg->regs, ADI_MAX32_UART_INT_RX);
322 }
323
api_irq_tx_complete(const struct device * dev)324 static int api_irq_tx_complete(const struct device *dev)
325 {
326 const struct max32_uart_config *cfg = dev->config;
327
328 if (MXC_UART_GetActive(cfg->regs) == E_BUSY) {
329 return 0;
330 } else {
331 return 1; /* transmission completed */
332 }
333 }
334
api_irq_rx_ready(const struct device * dev)335 static int api_irq_rx_ready(const struct device *dev)
336 {
337 struct max32_uart_data *const data = dev->data;
338 const struct max32_uart_config *cfg = dev->config;
339 uint32_t inten = Wrap_MXC_UART_GetRegINTEN(cfg->regs);
340
341 return ((inten & ADI_MAX32_UART_INT_RX) && !(data->status & ADI_MAX32_UART_RX_EMPTY));
342 }
343
api_irq_err_enable(const struct device * dev)344 static void api_irq_err_enable(const struct device *dev)
345 {
346 const struct max32_uart_config *cfg = dev->config;
347
348 MXC_UART_EnableInt(cfg->regs, ADI_MAX32_UART_ERROR_INTERRUPTS);
349 }
350
api_irq_err_disable(const struct device * dev)351 static void api_irq_err_disable(const struct device *dev)
352 {
353 const struct max32_uart_config *cfg = dev->config;
354
355 MXC_UART_DisableInt(cfg->regs, ADI_MAX32_UART_ERROR_INTERRUPTS);
356 }
357
api_irq_is_pending(const struct device * dev)358 static int api_irq_is_pending(const struct device *dev)
359 {
360 struct max32_uart_data *const data = dev->data;
361
362 return (data->flags & (ADI_MAX32_UART_INT_RX | ADI_MAX32_UART_INT_TX));
363 }
364
api_irq_update(const struct device * dev)365 static int api_irq_update(const struct device *dev)
366 {
367 struct max32_uart_data *const data = dev->data;
368 const struct max32_uart_config *const cfg = dev->config;
369
370 data->flags = MXC_UART_GetFlags(cfg->regs);
371 data->status = MXC_UART_GetStatus(cfg->regs);
372
373 MXC_UART_ClearFlags(cfg->regs, data->flags);
374
375 return 1;
376 }
377
api_irq_callback_set(const struct device * dev,uart_irq_callback_user_data_t cb,void * cb_data)378 static void api_irq_callback_set(const struct device *dev, uart_irq_callback_user_data_t cb,
379 void *cb_data)
380 {
381 struct max32_uart_data *const data = dev->data;
382
383 data->cb = cb;
384 data->cb_data = cb_data;
385 }
386
uart_max32_isr(const struct device * dev)387 static void uart_max32_isr(const struct device *dev)
388 {
389 struct max32_uart_data *data = dev->data;
390
391 if (data->cb) {
392 data->cb(dev, data->cb_data);
393 }
394 }
395
396 #endif /* CONFIG_UART_INTERRUPT_DRIVEN */
397
398 static DEVICE_API(uart, uart_max32_driver_api) = {
399 .poll_in = api_poll_in,
400 .poll_out = api_poll_out,
401 .err_check = api_err_check,
402 #ifdef CONFIG_UART_USE_RUNTIME_CONFIGURE
403 .configure = api_configure,
404 .config_get = api_config_get,
405 #endif /* CONFIG_UART_USE_RUNTIME_CONFIGURE */
406 #ifdef CONFIG_UART_INTERRUPT_DRIVEN
407 .fifo_fill = api_fifo_fill,
408 .fifo_read = api_fifo_read,
409 .irq_tx_enable = api_irq_tx_enable,
410 .irq_tx_disable = api_irq_tx_disable,
411 .irq_tx_ready = api_irq_tx_ready,
412 .irq_rx_enable = api_irq_rx_enable,
413 .irq_rx_disable = api_irq_rx_disable,
414 .irq_tx_complete = api_irq_tx_complete,
415 .irq_rx_ready = api_irq_rx_ready,
416 .irq_err_enable = api_irq_err_enable,
417 .irq_err_disable = api_irq_err_disable,
418 .irq_is_pending = api_irq_is_pending,
419 .irq_update = api_irq_update,
420 .irq_callback_set = api_irq_callback_set,
421 #endif /* CONFIG_UART_INTERRUPT_DRIVEN */
422 };
423
424 #define MAX32_UART_INIT(_num) \
425 PINCTRL_DT_INST_DEFINE(_num); \
426 IF_ENABLED(CONFIG_UART_INTERRUPT_DRIVEN, \
427 (static void uart_max32_irq_init_##_num(const struct device *dev) \
428 { \
429 IRQ_CONNECT(DT_INST_IRQN(_num), DT_INST_IRQ(_num, priority), \
430 uart_max32_isr, DEVICE_DT_INST_GET(_num), 0); \
431 irq_enable(DT_INST_IRQN(_num)); \
432 })); \
433 static const struct max32_uart_config max32_uart_config_##_num = { \
434 .regs = (mxc_uart_regs_t *)DT_INST_REG_ADDR(_num), \
435 .pctrl = PINCTRL_DT_INST_DEV_CONFIG_GET(_num), \
436 .clock = DEVICE_DT_GET(DT_INST_CLOCKS_CTLR(_num)), \
437 .perclk.bus = DT_INST_CLOCKS_CELL(_num, offset), \
438 .perclk.bit = DT_INST_CLOCKS_CELL(_num, bit), \
439 .perclk.clk_src = \
440 DT_INST_PROP_OR(_num, clock_source, ADI_MAX32_PRPH_CLK_SRC_PCLK), \
441 .uart_conf.baudrate = DT_INST_PROP_OR(_num, current_speed, 115200), \
442 .uart_conf.parity = DT_INST_ENUM_IDX_OR(_num, parity, UART_CFG_PARITY_NONE), \
443 .uart_conf.data_bits = DT_INST_ENUM_IDX_OR(_num, data_bits, UART_CFG_DATA_BITS_8), \
444 .uart_conf.stop_bits = DT_INST_ENUM_IDX_OR(_num, stop_bits, UART_CFG_STOP_BITS_1), \
445 .uart_conf.flow_ctrl = \
446 DT_INST_PROP_OR(_num, hw_flow_control, UART_CFG_FLOW_CTRL_NONE), \
447 IF_ENABLED(CONFIG_UART_INTERRUPT_DRIVEN, \
448 (.irq_config_func = uart_max32_irq_init_##_num,))}; \
449 static struct max32_uart_data max32_uart_data##_num = { \
450 IF_ENABLED(CONFIG_UART_INTERRUPT_DRIVEN, (.cb = NULL,))}; \
451 DEVICE_DT_INST_DEFINE(_num, uart_max32_init, NULL, &max32_uart_data##_num, \
452 &max32_uart_config_##_num, PRE_KERNEL_1, \
453 CONFIG_SERIAL_INIT_PRIORITY, (void *)&uart_max32_driver_api);
454
455 DT_INST_FOREACH_STATUS_OKAY(MAX32_UART_INIT)
456