1 /*
2  * SPDX-License-Identifier: Apache-2.0
3  *
4  * Copyright (c) 2024 Realtek Semiconductor Corporation, SIBG-SD7
5  * Author: Lin Yu-Cheng <lin_yu_cheng@realtek.com>
6  */
7 
8 #define DT_DRV_COMPAT realtek_rts5912_uart
9 
10 #include <zephyr/kernel.h>
11 #include <zephyr/drivers/pinctrl.h>
12 #include <zephyr/drivers/uart.h>
13 #include <zephyr/drivers/gpio.h>
14 #include <zephyr/drivers/clock_control.h>
15 #include <zephyr/drivers/clock_control/clock_control_rts5912.h>
16 #include <zephyr/logging/log.h>
17 
18 LOG_MODULE_REGISTER(uart_rts5912, CONFIG_UART_LOG_LEVEL);
19 
20 BUILD_ASSERT(CONFIG_UART_RTS5912_INIT_PRIORITY < CONFIG_SERIAL_INIT_PRIORITY,
21 	     "The uart_realtek_rts5912 driver must be initialized before the uart_ns16550 driver");
22 
23 /* device config */
24 struct uart_rts5912_device_config {
25 	const struct pinctrl_dev_config *pcfg;
26 	const struct device *clk_dev;
27 	struct rts5912_sccon_subsys sccon_cfg;
28 };
29 
30 /** Device data structure */
31 struct uart_rts5912_dev_data {
32 };
33 
rts5912_uart_init(const struct device * dev)34 static int rts5912_uart_init(const struct device *dev)
35 {
36 	const struct uart_rts5912_device_config *const dev_cfg = dev->config;
37 	int rc;
38 
39 	if (!device_is_ready(dev_cfg->clk_dev)) {
40 		return -ENODEV;
41 	}
42 
43 	rc = clock_control_on(dev_cfg->clk_dev, (clock_control_subsys_t)&dev_cfg->sccon_cfg);
44 	if (rc != 0) {
45 		return rc;
46 	}
47 
48 	rc = pinctrl_apply_state(dev_cfg->pcfg, PINCTRL_STATE_DEFAULT);
49 	if (rc != 0) {
50 		return rc;
51 	}
52 
53 	return 0;
54 }
55 
56 #define UART_RTS5912_DEVICE_INIT(n)                                                                \
57 	PINCTRL_DT_INST_DEFINE(n);                                                                 \
58                                                                                                    \
59 	static const struct uart_rts5912_device_config uart_rts5912_dev_cfg_##n = {                \
60 		.pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(n),                                         \
61 		.clk_dev = DEVICE_DT_GET(DT_INST_CLOCKS_CTLR(n)),                                  \
62 		.sccon_cfg =                                                                       \
63 			{                                                                          \
64 				.clk_grp = DT_INST_CLOCKS_CELL_BY_NAME(n, uart##n, clk_grp),       \
65 				.clk_idx = DT_INST_CLOCKS_CELL_BY_NAME(n, uart##n, clk_idx),       \
66 			},                                                                         \
67 	};                                                                                         \
68                                                                                                    \
69 	static struct uart_rts5912_dev_data uart_rts5912_dev_data_##n;                             \
70                                                                                                    \
71 	DEVICE_DT_INST_DEFINE(n, &rts5912_uart_init, NULL, &uart_rts5912_dev_data_##n,             \
72 			      &uart_rts5912_dev_cfg_##n, PRE_KERNEL_1,                             \
73 			      CONFIG_UART_RTS5912_INIT_PRIORITY, NULL);
74 
75 DT_INST_FOREACH_STATUS_OKAY(UART_RTS5912_DEVICE_INIT)
76