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