1 /*
2 * Copyright (c) 2022 Winner Microelectronics Co., Ltd. All rights reserved.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 /**
17 * @file wm_io.c
18 *
19 * @brief IO Driver Module
20 *
21 * @author lilm
22 *
23 * Copyright (c) 2015 Winner Microelectronics Co., Ltd.
24 */
25
26 #include "wm_regs.h"
27 #include "wm_osal.h"
28 #include "wm_dbg.h"
29 #include "tls_common.h"
30 #include "wm_io.h"
31
io_cfg_option1(enum tls_io_name name)32 static void io_cfg_option1(enum tls_io_name name)
33 {
34 u8 pin;
35 u16 offset;
36
37 if (name >= WM_IO_PB_00) {
38 pin = name - WM_IO_PB_00;
39 offset = TLS_IO_AB_OFFSET;
40 } else {
41 pin = name;
42 offset = 0;
43 }
44
45 tls_reg_write32(HR_GPIO_AF_SEL + offset, tls_reg_read32(HR_GPIO_AF_SEL + offset) | BIT(pin)); /* gpio function */
46 tls_reg_write32(HR_GPIO_AF_S1 + offset, tls_reg_read32(HR_GPIO_AF_S1 + offset) & (~BIT(pin)));
47 tls_reg_write32(HR_GPIO_AF_S0 + offset, tls_reg_read32(HR_GPIO_AF_S0 + offset) & (~BIT(pin)));
48 }
49
io_cfg_option2(enum tls_io_name name)50 static void io_cfg_option2(enum tls_io_name name)
51 {
52 u8 pin;
53 u16 offset;
54
55 if (name >= WM_IO_PB_00) {
56 pin = name - WM_IO_PB_00;
57 offset = TLS_IO_AB_OFFSET;
58 } else {
59 pin = name;
60 offset = 0;
61 }
62
63 tls_reg_write32(HR_GPIO_AF_SEL + offset, tls_reg_read32(HR_GPIO_AF_SEL + offset) | BIT(pin)); /* gpio function */
64 tls_reg_write32(HR_GPIO_AF_S1 + offset, tls_reg_read32(HR_GPIO_AF_S1 + offset) & (~BIT(pin)));
65 tls_reg_write32(HR_GPIO_AF_S0 + offset, tls_reg_read32(HR_GPIO_AF_S0 + offset) | BIT(pin));
66 }
67
io_cfg_option3(enum tls_io_name name)68 static void io_cfg_option3(enum tls_io_name name)
69 {
70 u8 pin;
71 u16 offset;
72
73 if (name >= WM_IO_PB_00) {
74 pin = name - WM_IO_PB_00;
75 offset = TLS_IO_AB_OFFSET;
76 } else {
77 pin = name;
78 offset = 0;
79 }
80
81 tls_reg_write32(HR_GPIO_AF_SEL + offset, tls_reg_read32(HR_GPIO_AF_SEL + offset) | BIT(pin)); /* gpio function */
82 tls_reg_write32(HR_GPIO_AF_S1 + offset, tls_reg_read32(HR_GPIO_AF_S1 + offset) | BIT(pin));
83 tls_reg_write32(HR_GPIO_AF_S0 + offset, tls_reg_read32(HR_GPIO_AF_S0 + offset) & (~BIT(pin)));
84 }
85
io_cfg_option4(enum tls_io_name name)86 static void io_cfg_option4(enum tls_io_name name)
87 {
88 u8 pin;
89 u16 offset;
90
91 if (name >= WM_IO_PB_00) {
92 pin = name - WM_IO_PB_00;
93 offset = TLS_IO_AB_OFFSET;
94 } else {
95 pin = name;
96 offset = 0;
97 }
98
99 tls_reg_write32(HR_GPIO_AF_SEL + offset, tls_reg_read32(HR_GPIO_AF_SEL + offset) | BIT(pin)); /* gpio function */
100 tls_reg_write32(HR_GPIO_AF_S1 + offset, tls_reg_read32(HR_GPIO_AF_S1 + offset) | BIT(pin));
101 tls_reg_write32(HR_GPIO_AF_S0 + offset, tls_reg_read32(HR_GPIO_AF_S0 + offset) | BIT(pin));
102 }
103
io_cfg_option5(enum tls_io_name name)104 static void io_cfg_option5(enum tls_io_name name)
105 {
106 u8 pin;
107 u16 offset;
108
109 if (name >= WM_IO_PB_00) {
110 pin = name - WM_IO_PB_00;
111 offset = TLS_IO_AB_OFFSET;
112 } else {
113 pin = name;
114 offset = 0;
115 }
116
117 /* disable gpio function */
118 tls_reg_write32(HR_GPIO_AF_SEL + offset, tls_reg_read32(HR_GPIO_AF_SEL + offset) & (~BIT(pin)));
119 }
120
121 static u32 io_pa_option67 = 0;
122 static u32 io_pb_option67 = 0;
io_cfg_option6(enum tls_io_name name)123 static void io_cfg_option6(enum tls_io_name name)
124 {
125 u8 pin;
126 u16 offset;
127
128 if (name >= WM_IO_PB_00) {
129 pin = name - WM_IO_PB_00;
130 offset = TLS_IO_AB_OFFSET;
131 io_pb_option67 |= BIT(pin);
132 } else {
133 pin = name;
134 offset = 0;
135 io_pa_option67 |= BIT(pin);
136 }
137
138 /* disable gpio function */
139 tls_reg_write32(HR_GPIO_AF_SEL + offset, tls_reg_read32(HR_GPIO_AF_SEL + offset) & (~BIT(pin)));
140 tls_reg_write32(HR_GPIO_DIR + offset, tls_reg_read32(HR_GPIO_DIR + offset) & (~BIT(pin)));
141 tls_reg_write32(HR_GPIO_PULLUP_EN + offset, tls_reg_read32(HR_GPIO_PULLUP_EN + offset) | (BIT(pin)));
142 tls_reg_write32(HR_GPIO_PULLDOWN_EN + offset, tls_reg_read32(HR_GPIO_PULLDOWN_EN + offset) & (~BIT(pin)));
143 }
144
io_cfg_option7(enum tls_io_name name)145 static void io_cfg_option7(enum tls_io_name name)
146 {
147 u8 pin;
148 u16 offset;
149
150 if (name >= WM_IO_PB_00) {
151 pin = name - WM_IO_PB_00;
152 offset = TLS_IO_AB_OFFSET;
153 io_pb_option67 &= BIT(pin);
154 } else {
155 pin = name;
156 offset = 0;
157 io_pa_option67 &= BIT(pin);
158 }
159 /* enable gpio function */
160 tls_reg_write32(HR_GPIO_AF_SEL + offset, tls_reg_read32(HR_GPIO_AF_SEL + offset) & (~BIT(pin)));
161 /* set input */
162 tls_reg_write32(HR_GPIO_DIR + offset, tls_reg_read32(HR_GPIO_DIR + offset) & (~BIT(pin)));
163 /* disable pull up */
164 tls_reg_write32(HR_GPIO_PULLUP_EN + offset, tls_reg_read32(HR_GPIO_PULLUP_EN + offset) | (BIT(pin)));
165 /* disable pull down */
166 tls_reg_write32(HR_GPIO_PULLDOWN_EN + offset, tls_reg_read32(HR_GPIO_PULLDOWN_EN + offset) & (~BIT(pin)));
167 }
168
169 /**
170 * @brief This function is used to config io function
171 *
172 * @param[in] name io name
173 * @param[in] option io function option, value is WM_IO_OPT*_*, also is WM_IO_OPTION1-6
174 *
175 * @return None
176 *
177 * @note None
178 */
tls_io_cfg_set(enum tls_io_name name,u8 option)179 void tls_io_cfg_set(enum tls_io_name name, u8 option)
180 {
181 if (WM_IO_OPTION1 == option)
182 io_cfg_option1(name);
183 else if (WM_IO_OPTION2 == option)
184 io_cfg_option2(name);
185 else if (WM_IO_OPTION3 == option)
186 io_cfg_option3(name);
187 else if (WM_IO_OPTION4 == option)
188 io_cfg_option4(name);
189 else if (WM_IO_OPTION5 == option)
190 io_cfg_option5(name);
191 else if (WM_IO_OPTION6 == option)
192 io_cfg_option6(name);
193 else if (WM_IO_OPTION7 == option)
194 io_cfg_option7(name);
195 else
196 TLS_DBGPRT_IO_ERR("invalid io option.\r\n");
197 }
198
199 /**
200 * @brief This function is used to get io function config
201 *
202 * @param[in] name io name
203 *
204 * @retval WM_IO_OPTION1~6 Mapping io function
205 *
206 * @note None
207 */
tls_io_cfg_get(enum tls_io_name name)208 int tls_io_cfg_get(enum tls_io_name name)
209 {
210 u8 pin;
211 u16 offset;
212 u32 afsel, afs1, afs0, dir, pullupen, pulldownen;
213
214 if (name >= WM_IO_PB_00) {
215 pin = name - WM_IO_PB_00;
216 offset = TLS_IO_AB_OFFSET;
217 } else {
218 pin = name;
219 offset = 0;
220 }
221
222 afsel = tls_reg_read32(HR_GPIO_AF_SEL + offset);
223 afs1 = tls_reg_read32(HR_GPIO_AF_S1 + offset);
224 afs0 = tls_reg_read32(HR_GPIO_AF_S0 + offset);
225 dir = tls_reg_read32(HR_GPIO_DIR + offset);
226 pullupen = tls_reg_read32(HR_GPIO_PULLUP_EN + offset);
227 pulldownen = tls_reg_read32(HR_GPIO_PULLDOWN_EN + offset);
228
229 if (afsel&BIT(pin)) {
230 if (((afs1&BIT(pin)) == 0) && ((afs0&BIT(pin)) == 0))
231 return WM_IO_OPTION1;
232 else if (((afs1&BIT(pin)) == 0) && (afs0&BIT(pin)))
233 return WM_IO_OPTION2;
234 else if ((afs1&BIT(pin)) && ((afs0&BIT(pin)) == 0))
235 return WM_IO_OPTION3;
236 else if ((afs1&BIT(pin)) && (afs0&BIT(pin)))
237 return WM_IO_OPTION4;
238 } else {
239 if ((!(dir&BIT(pin))) && (pullupen&BIT(pin)) && (!(pulldownen&BIT(pin)))) {
240 if (offset) {
241 if (io_pb_option67 & BIT(pin)) {
242 return WM_IO_OPTION6;
243 } else {
244 return WM_IO_OPTION7;
245 }
246 } else {
247 if (io_pa_option67 & BIT(pin)) {
248 return WM_IO_OPTION6;
249 } else {
250 return WM_IO_OPTION7;
251 }
252 }
253 } else
254 return WM_IO_OPTION5;
255 }
256
257 return 0;
258 }
259
260