1 /*
2 * Copyright (c) 2006-2025 RT-Thread Development Team
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6 #include <rtthread.h>
7 #include <ioremap.h>
8 #include "board.h"
9 #include "drv_pinctrl.h"
10 #include <rtdbg.h>
11
12 #define DBG_TAG "PINCTRL"
13 #ifdef RT_DEBUG
14 #define DBG_LVL DBG_LOG
15 #else
16 #define DBG_LVL DBG_WARNING
17 #endif
18 #define DBG_COLOR
19
20 #define MAX_NUM_PIN 64
21
22 #define IO_CFG_SEL_MASK 0x7
23 #define IO_CFG_SEL_OFFSET 11
24 #define IO_CFG_IE_MASK 0x1
25 #define IO_CFG_IE_OFFSET 8
26 #define IO_CFG_OE_MASK 0x1
27 #define IO_CFG_OE_OFFSET 7
28 #define IO_CFG_PU_MASK 0x1
29 #define IO_CFG_PU_OFFSET 6
30 #define IO_CFG_PD_MASK 0x1
31 #define IO_CFG_PD_OFFSET 5
32 #define IO_CFG_DRV_MASK 0xF
33 #define IO_CFG_DRV_OFFSET 1
34 #define IO_CFG_ST_MASK 0x1
35 #define IO_CFG_ST_OFFSET 0
36
37 volatile static rt_ubase_t pinctrl_base;
38
check_pin(rt_uint32_t pin)39 static int check_pin(rt_uint32_t pin)
40 {
41 if (pin < 0 || pin > MAX_NUM_PIN)
42 {
43 LOG_E("pin %d is not valid\n", pin);
44 return -RT_EINVAL;
45 }
46 return 0;
47 }
48
_read32(rt_uint32_t pin)49 rt_inline rt_uint32_t _read32(rt_uint32_t pin)
50 {
51 return HWREG32(pinctrl_base + (pin * 4));
52 }
53
_write32(rt_uint32_t pin,rt_uint32_t value)54 rt_inline void _write32(rt_uint32_t pin, rt_uint32_t value)
55 {
56 HWREG32(pinctrl_base + (pin * 4)) = value;
57 }
58
k230_pinctrl_set_function(rt_uint32_t pin,rt_uint32_t func)59 void k230_pinctrl_set_function(rt_uint32_t pin, rt_uint32_t func)
60 {
61 if (check_pin(pin) != 0)
62 return;
63 if (func > IOMUX_FUNC5)
64 return;
65
66 rt_uint32_t val = _read32(pin);
67 val &= ~(IO_CFG_SEL_MASK << IO_CFG_SEL_OFFSET); /* Clear bits 11-13 */
68 /* Set bits 11-13 to the function value */
69 val |= (func << IO_CFG_SEL_OFFSET);
70 _write32(pin, val);
71 }
72
k230_pinctrl_set_ie(rt_uint32_t pin,rt_uint32_t ie)73 void k230_pinctrl_set_ie(rt_uint32_t pin, rt_uint32_t ie)
74 {
75 if (check_pin(pin) != 0)
76 return;
77
78 rt_uint32_t val = _read32(pin);
79 if (ie)
80 val |= IO_CFG_IE_MASK << IO_CFG_IE_OFFSET;
81 else
82 val &= ~(IO_CFG_IE_MASK << IO_CFG_IE_OFFSET);
83 _write32(pin, val);
84 }
85
k230_pinctrl_set_oe(rt_uint32_t pin,rt_uint32_t oe)86 void k230_pinctrl_set_oe(rt_uint32_t pin, rt_uint32_t oe)
87 {
88 if (check_pin(pin) != 0)
89 return;
90
91 rt_uint32_t val = _read32(pin);
92 if (oe)
93 val |= IO_CFG_OE_MASK << IO_CFG_OE_OFFSET;
94 else
95 val &= ~(IO_CFG_OE_MASK << IO_CFG_OE_OFFSET);
96 _write32(pin, val);
97 }
98
k230_pinctrl_set_pu(rt_uint32_t pin,rt_uint32_t pu)99 void k230_pinctrl_set_pu(rt_uint32_t pin, rt_uint32_t pu)
100 {
101 if (check_pin(pin) != 0)
102 return;
103
104 rt_uint32_t val = _read32(pin);
105 if (pu)
106 val |= IO_CFG_PU_MASK << IO_CFG_PU_OFFSET;
107 else
108 val &= ~(IO_CFG_PU_MASK << IO_CFG_PU_OFFSET);
109 _write32(pin, val);
110 }
111
k230_pinctrl_set_pd(rt_uint32_t pin,rt_uint32_t pd)112 void k230_pinctrl_set_pd(rt_uint32_t pin, rt_uint32_t pd)
113 {
114 if (check_pin(pin) != 0)
115 return;
116
117 rt_uint32_t val = _read32(pin);
118 if (pd)
119 val |= IO_CFG_PD_MASK << IO_CFG_PD_OFFSET;
120 else
121 val &= ~(IO_CFG_PD_MASK << IO_CFG_PD_OFFSET);
122 _write32(pin, val);
123 }
124
k230_pinctrl_set_drv(rt_uint32_t pin,rt_uint32_t drv)125 void k230_pinctrl_set_drv(rt_uint32_t pin, rt_uint32_t drv)
126 {
127 if (check_pin(pin) != 0)
128 return;
129 /* FIXME: Unsupported yet */
130 }
131
k230_pinctrl_set_st(rt_uint32_t pin,rt_uint32_t st)132 void k230_pinctrl_set_st(rt_uint32_t pin, rt_uint32_t st)
133 {
134 if (check_pin(pin) != 0)
135 return;
136
137 rt_uint32_t val = _read32(pin);
138 if (st)
139 val |= IO_CFG_ST_MASK << IO_CFG_ST_OFFSET;
140 else
141 val &= ~(IO_CFG_ST_MASK << IO_CFG_ST_OFFSET);
142 _write32(pin, val);
143 }
144
k230_pinctrl_get_regval(rt_uint32_t pin)145 rt_uint32_t k230_pinctrl_get_regval(rt_uint32_t pin)
146 {
147 if (check_pin(pin) != 0)
148 return 0;
149
150 return _read32(pin);
151 }
152
k230_pinctrl_init(void)153 int k230_pinctrl_init(void)
154 {
155 rt_err_t ret;
156
157 pinctrl_base = (rt_ubase_t)rt_ioremap((void *)IOMUX_BASE_ADDR, IOMUX_IO_SIZE);
158
159 return RT_EOK;
160 }
161 INIT_BOARD_EXPORT(k230_pinctrl_init);