1 // Copyright (C) 2022 Beken Corporation
2 //
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 #include <common/bk_include.h>
16 #include "gpio_hal.h"
17 #include <driver/gpio_types.h>
18 #include "icu_driver.h"
19
20 //move out from function, which uses too much STACK.
21 static const gpio_map_t gpio_map_table[] = GPIO_DEV_MAP;
gpio_hal_init(gpio_hal_t * hal)22 bk_err_t gpio_hal_init(gpio_hal_t *hal)
23 {
24 hal->hw = (gpio_hw_t *)GPIO_LL_REG_BASE;
25 gpio_ll_init(hal->hw);
26 return BK_OK;
27 }
28
gpio_hal_disable_jtag_mode(gpio_hal_t * hal)29 bk_err_t gpio_hal_disable_jtag_mode(gpio_hal_t *hal)
30 {
31 return BK_OK;
32 }
33
gpio_hal_output_enable(gpio_hal_t * hal,gpio_id_t gpio_id,uint32 enable)34 bk_err_t gpio_hal_output_enable(gpio_hal_t *hal, gpio_id_t gpio_id, uint32 enable)
35 {
36 gpio_ll_output_enable(hal->hw, gpio_id, enable);
37
38 return BK_OK;
39 }
40
gpio_hal_input_enable(gpio_hal_t * hal,gpio_id_t gpio_id,uint32 enable)41 bk_err_t gpio_hal_input_enable(gpio_hal_t *hal, gpio_id_t gpio_id, uint32 enable)
42 {
43 gpio_ll_input_enable(hal->hw, gpio_id, enable);
44
45 return BK_OK;
46 }
47
48
gpio_hal_pull_up_enable(gpio_hal_t * hal,gpio_id_t gpio_id,uint32 enable)49 bk_err_t gpio_hal_pull_up_enable(gpio_hal_t *hal, gpio_id_t gpio_id, uint32 enable)
50 {
51 gpio_ll_pull_up_enable(hal->hw, gpio_id, enable);
52
53 return BK_OK;
54 }
55
56
gpio_hal_pull_enable(gpio_hal_t * hal,gpio_id_t gpio_id,uint32 enable)57 bk_err_t gpio_hal_pull_enable(gpio_hal_t *hal, gpio_id_t gpio_id, uint32 enable)
58 {
59 gpio_ll_pull_enable(hal->hw, gpio_id, enable);
60
61 return BK_OK;
62 }
63
gpio_hal_sencond_function_enable(gpio_hal_t * hal,gpio_id_t gpio_id,uint32 enable)64 bk_err_t gpio_hal_sencond_function_enable(gpio_hal_t *hal, gpio_id_t gpio_id, uint32 enable)
65 {
66 gpio_ll_second_function_enable(hal->hw, gpio_id, enable);
67
68 return BK_OK;
69 }
70
71
gpio_hal_monitor_input_enable(gpio_hal_t * hal,gpio_id_t gpio_id,uint32 enable)72 bk_err_t gpio_hal_monitor_input_enable(gpio_hal_t *hal, gpio_id_t gpio_id, uint32 enable)
73 {
74 gpio_ll_monitor_input_value_enable(hal->hw, gpio_id, enable);
75
76 return BK_OK;
77 }
78
79
gpio_hal_set_capacity(gpio_hal_t * hal,gpio_id_t gpio_id,uint32 capacity)80 bk_err_t gpio_hal_set_capacity(gpio_hal_t *hal, gpio_id_t gpio_id, uint32 capacity)
81 {
82 gpio_ll_set_capacity(hal->hw, gpio_id, capacity);
83
84 return BK_OK;
85 }
86
87
gpio_hal_set_output_value(gpio_hal_t * hal,gpio_id_t gpio_id,uint32 output_value)88 bk_err_t gpio_hal_set_output_value(gpio_hal_t *hal, gpio_id_t gpio_id, uint32 output_value)
89 {
90 if(gpio_ll_check_output_enable(hal->hw, gpio_id))
91 gpio_ll_set_gpio_output_value(hal->hw, gpio_id, output_value);
92 else
93 return BK_ERR_GPIO_NOT_OUTPUT_MODE;
94
95 return BK_OK;
96 }
97
gpio_hal_get_input(gpio_hal_t * hal,gpio_id_t gpio_id)98 bk_err_t gpio_hal_get_input(gpio_hal_t *hal, gpio_id_t gpio_id)
99 {
100 if(gpio_ll_check_input_enable(hal->hw, gpio_id))
101 return (gpio_ll_get_gpio_input_value(hal->hw, gpio_id));
102 else
103 return BK_ERR_GPIO_NOT_INPUT_MODE;
104 }
105
106
gpio_hal_set_int_type(gpio_hal_t * hal,gpio_id_t gpio_id,gpio_int_type_t type)107 bk_err_t gpio_hal_set_int_type(gpio_hal_t *hal, gpio_id_t gpio_id, gpio_int_type_t type)
108 {
109 gpio_ll_set_interrupt_type(hal->hw, gpio_id, type);
110
111 return BK_OK;
112 }
113
gpio_hal_enable_interrupt(gpio_hal_t * hal,gpio_id_t gpio_id)114 bk_err_t gpio_hal_enable_interrupt(gpio_hal_t *hal, gpio_id_t gpio_id)
115 {
116 if(gpio_ll_check_input_enable(hal->hw, gpio_id)) {
117 gpio_ll_enable_interrupt(hal->hw, gpio_id);
118 return BK_OK;
119 } else
120 return BK_ERR_GPIO_NOT_INPUT_MODE;
121 }
122
gpio_hal_map_check(gpio_hal_t * hal,gpio_id_t gpio_id)123 static bk_err_t gpio_hal_map_check(gpio_hal_t *hal, gpio_id_t gpio_id)
124 {
125 const gpio_map_t *gpio_map = NULL;
126
127 //special for BK7235:the GPIO ID isn't from 0~47, some of the GPIO are not exist.
128 for(int i = 0; i < sizeof(gpio_map_table)/sizeof(gpio_map_t); i++)
129 {
130 if(gpio_map_table[i].id == gpio_id)
131 {
132 gpio_map = &gpio_map_table[i];
133 break;
134 }
135 }
136 if(gpio_map == NULL)
137 {
138 HAL_LOGE("gpio id=%d is not exist\r\n", gpio_id);
139 return BK_ERR_GPIO_INVALID_ID;
140 }
141
142 //TODO check gpio is busy
143 if(gpio_ll_check_func_mode_enable(hal->hw, gpio_id)) {
144 uint32 func_mode = gpio_ll_get_gpio_perial_mode((hal)->hw, gpio_id);
145 uint32 dev_use = gpio_map->dev[func_mode];
146
147 HAL_LOGW("[gpio_log]:gpio:%d was busy: device num:0x%x!\r\n", gpio_id, dev_use);
148
149 return BK_ERR_GPIO_INTERNAL_USED;
150 }
151
152 return BK_OK;
153 }
154
155
gpio_hal_func_map(gpio_hal_t * hal,gpio_id_t gpio_id,gpio_dev_t dev)156 bk_err_t gpio_hal_func_map(gpio_hal_t *hal, gpio_id_t gpio_id, gpio_dev_t dev)
157 {
158 const gpio_map_t *gpio_map = NULL;
159
160 //special for BK7235:the GPIO ID isn't from 0~47, some of the GPIO are not exist.
161 for(int i = 0; i < sizeof(gpio_map_table)/sizeof(gpio_map_t); i++)
162 {
163 if(gpio_map_table[i].id == gpio_id)
164 {
165 gpio_map = &gpio_map_table[i];
166 break;
167 }
168 }
169 if(gpio_map == NULL)
170 {
171 HAL_LOGE("gpio id=%d is not exist\r\n", gpio_id);
172 return BK_ERR_GPIO_INVALID_ID;
173 }
174
175 if(gpio_hal_map_check(hal, gpio_id)) {
176 return BK_ERR_GPIO_INTERNAL_USED;
177 }
178
179 //get peri mode of id
180 if (dev == GPIO_DEV_NONE) {
181 HAL_LOGE("gpio device is none, id=%d dev=%d\r\n", gpio_id, dev);
182 return BK_ERR_GPIOS_MAP_NONE;
183 } else {
184 for (int peri_func = 0; peri_func < GPIO_PERI_FUNC_NUM; peri_func ++) {
185 if (dev == gpio_map->dev[peri_func])
186 gpio_ll_set_gpio_perial_mode((hal)->hw, gpio_id, peri_func);
187 }
188 }
189
190 // set gpio as second function mode
191 gpio_hal_output_enable(hal, gpio_id, 0);
192 gpio_hal_input_enable(hal, gpio_id, 0);
193 gpio_hal_pull_enable(hal, gpio_id, 0);
194 gpio_hal_sencond_function_enable(hal, gpio_id, 1);
195
196 return BK_OK;
197 }
198
gpio_hal_func_unmap(gpio_hal_t * hal,gpio_id_t gpio_id)199 bk_err_t gpio_hal_func_unmap(gpio_hal_t *hal, gpio_id_t gpio_id)
200 {
201 gpio_hal_sencond_function_enable(hal, gpio_id, 0);
202 return BK_OK;
203 }
204
gpio_hal_devs_map(gpio_hal_t * hal,uint64 gpios,gpio_dev_t * devs,uint8 dev_num)205 bk_err_t gpio_hal_devs_map(gpio_hal_t *hal, uint64 gpios, gpio_dev_t *devs, uint8 dev_num)
206 {
207 int gpio_index = 0;
208 int dev_id = 0;
209
210 //check dev is null
211 if(!devs) {
212 HAL_LOGE("gpio devs is null \r\n");
213 return BK_ERR_NULL_PARAM;
214 }
215
216 for(gpio_index = 0; gpio_index < GPIO_NUM; gpio_index++)
217 {
218 if (gpios & BIT64(gpio_index)) {
219 HAL_LOGD("gpio_index = %d\r\n", gpio_index);
220 gpio_hal_func_map(hal, gpio_index, devs[dev_id++]);
221 }
222 }
223
224 if(dev_id != dev_num) {
225 HAL_LOGE("dev_num expected %d actual is %d \r\n", dev_num, dev_id);
226
227 return BK_ERR_GPIO_BITS_NUM;
228 }
229
230 return BK_OK;
231 }
232
gpio_hal_set_config(gpio_hal_t * hal,gpio_id_t gpio_id,const gpio_config_t * config)233 bk_err_t gpio_hal_set_config(gpio_hal_t *hal, gpio_id_t gpio_id, const gpio_config_t *config)
234 {
235 if(gpio_hal_map_check(hal, gpio_id)) {
236 HAL_LOGE("gpio has map\r\n");
237 return BK_ERR_GPIO_INTERNAL_USED;
238 }
239
240 gpio_ll_set_mode(hal->hw, gpio_id, config);
241
242 return BK_OK;
243 }
244
245 #if CONFIG_GPIO_WAKEUP_SUPPORT
gpio_hal_bak_configs(uint16_t * gpio_cfg,uint32_t count)246 bk_err_t gpio_hal_bak_configs(uint16_t *gpio_cfg, uint32_t count)
247 {
248 gpio_ll_bak_configs(gpio_cfg, count);
249 return BK_OK;
250 }
251
gpio_hal_restore_configs(uint16_t * gpio_cfg,uint32_t count)252 bk_err_t gpio_hal_restore_configs(uint16_t *gpio_cfg, uint32_t count)
253 {
254 gpio_ll_restore_configs(gpio_cfg, count);
255 return BK_OK;
256 }
257
gpio_hal_bak_int_type_configs(uint32_t * gpio_int_type_cfg,uint32_t count)258 bk_err_t gpio_hal_bak_int_type_configs(uint32_t *gpio_int_type_cfg, uint32_t count)
259 {
260 gpio_ll_bak_int_type_configs(gpio_int_type_cfg, count);
261
262 return BK_OK;
263 }
264
gpio_hal_restore_int_type_configs(uint32_t * gpio_int_type_cfg,uint32_t count)265 bk_err_t gpio_hal_restore_int_type_configs(uint32_t *gpio_int_type_cfg, uint32_t count)
266 {
267 gpio_ll_restore_int_type_configs(gpio_int_type_cfg, count);
268 return BK_OK;
269 }
270
gpio_hal_bak_int_enable_configs(uint32_t * gpio_int_enable_cfg,uint32_t count)271 bk_err_t gpio_hal_bak_int_enable_configs(uint32_t *gpio_int_enable_cfg, uint32_t count)
272 {
273 gpio_ll_bak_int_enable_configs(gpio_int_enable_cfg, count);
274
275 return BK_OK;
276 }
277
gpio_hal_restore_int_enable_configs(uint32_t * gpio_int_enable_cfg,uint32_t count)278 bk_err_t gpio_hal_restore_int_enable_configs(uint32_t *gpio_int_enable_cfg, uint32_t count)
279 {
280 gpio_ll_restore_int_enable_configs(gpio_int_enable_cfg, count);
281 return BK_OK;
282 }
283
284 /* gpio switch to low power status:set all gpios to input mode to avoid power leakage */
gpio_hal_switch_to_low_power_status(void)285 bk_err_t gpio_hal_switch_to_low_power_status(void)
286 {
287 gpio_ll_switch_to_low_power_status();
288 return BK_OK;
289 }
290 #else
gpio_hal_reg_save(uint32_t * gpio_cfg)291 bk_err_t gpio_hal_reg_save(uint32_t* gpio_cfg)
292 {
293 gpio_ll_reg_save(gpio_cfg);
294 return BK_OK;
295 }
gpio_hal_reg_restore(uint32_t * gpio_cfg)296 bk_err_t gpio_hal_reg_restore(uint32_t* gpio_cfg)
297 {
298 gpio_ll_reg_restore(gpio_cfg);
299 return BK_OK;
300 }
gpio_hal_wakeup_enable(int64_t index,uint64_t type_l,uint64_t type_h)301 bk_err_t gpio_hal_wakeup_enable(int64_t index, uint64_t type_l, uint64_t type_h)
302 {
303 gpio_ll_wakeup_enable(index, type_l, type_h);
304 return BK_OK;
305 }
gpio_hal_wakeup_interrupt_clear()306 bk_err_t gpio_hal_wakeup_interrupt_clear()
307 {
308 gpio_ll_wakeup_interrupt_clear();
309 return BK_OK;
310 }
311 #endif
312
313