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);