1 /*
2 * Copyright (c) 2021 Chipsea Technologies (Shenzhen) Corp., 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 *
18 * @file gpio_api.c
19 *
20 * @brief GPIO API functions
21 *
22 ****************************************************************************************
23 */
24
25 /*
26 * INCLUDE FILES
27 ****************************************************************************************
28 */
29 #include <stdint.h>
30 #include "gpio_api.h"
31 #include "reg_gpio.h"
32 #include "reg_iomux.h"
33 #include "arch.h"
34 #if PLF_PMIC
35 #include "pmic_api.h"
36 #endif
37
gpio_init(int gpidx)38 void gpio_init(int gpidx)
39 {
40 unsigned int gpmsk = 0x01UL << gpidx;
41 // iomux
42 if ((gpidx < 2) || ((gpidx > 7) && (gpidx < 10))) {
43 iomux_gpio_config_sel_setf(gpidx, 1);
44 } else if (gpidx < 16) {
45 iomux_gpio_config_sel_setf(gpidx, 0);
46 } else if (gpidx < 32) {
47 iomux_agpio_config_sel_setf((gpidx - 16), 2);
48 }
49 // mask
50 CS_GPIO->MR |= gpmsk;
51 }
52
gpio_deinit(int gpidx)53 void gpio_deinit(int gpidx)
54 {
55 unsigned int gpmsk = 0x01UL << gpidx;
56 // mask
57 CS_GPIO->MR &= ~gpmsk;
58 }
59
gpio_dir_in(int gpidx)60 void gpio_dir_in(int gpidx)
61 {
62 unsigned int gpmsk = 0x01UL << gpidx;
63 CS_GPIO->DR &= ~gpmsk;
64 }
65
gpio_dir_out(int gpidx)66 void gpio_dir_out(int gpidx)
67 {
68 unsigned int gpmsk = 0x01UL << gpidx;
69 CS_GPIO->DR |= gpmsk;
70 }
71
gpio_set(int gpidx)72 void gpio_set(int gpidx)
73 {
74 unsigned int gpmsk = 0x01UL << gpidx;
75 CS_GPIO->VR |= gpmsk;
76 }
77
gpio_clr(int gpidx)78 void gpio_clr(int gpidx)
79 {
80 unsigned int gpmsk = 0x01UL << gpidx;
81 CS_GPIO->VR &= ~gpmsk;
82 }
83
gpio_get(int gpidx)84 int gpio_get(int gpidx)
85 {
86 int val;
87 unsigned int gpmsk = 0x01UL << gpidx;
88 val = (CS_GPIO->VR & gpmsk) ? 1 : 0;
89 return val;
90 }
91
gpio_force_pull_up_enable(int gpidx)92 void gpio_force_pull_up_enable(int gpidx)
93 {
94 if (gpidx < 16) {
95 iomux_gpio_config_pull_dn_setf(gpidx, 0);
96 iomux_gpio_config_pull_up_setf(gpidx, 1);
97 iomux_gpio_config_pull_frc_setf(gpidx, 1);
98 } else if (gpidx < 32) {
99 iomux_agpio_config_pull_dn_setf(gpidx, 0);
100 iomux_agpio_config_pull_up_setf(gpidx, 1);
101 iomux_agpio_config_pull_frc_setf(gpidx, 1);
102 }
103 }
104
gpio_force_pull_dn_enable(int gpidx)105 void gpio_force_pull_dn_enable(int gpidx)
106 {
107 if (gpidx < 16) {
108 iomux_gpio_config_pull_up_setf(gpidx, 0);
109 iomux_gpio_config_pull_dn_setf(gpidx, 1);
110 iomux_gpio_config_pull_frc_setf(gpidx, 1);
111 } else if (gpidx < 32) {
112 iomux_agpio_config_pull_up_setf(gpidx, 0);
113 iomux_agpio_config_pull_dn_setf(gpidx, 1);
114 iomux_agpio_config_pull_frc_setf(gpidx, 1);
115 }
116 }
117
gpio_force_pull_none_enable(int gpidx)118 void gpio_force_pull_none_enable(int gpidx)
119 {
120 if (gpidx < 16) {
121 iomux_gpio_config_pull_dn_setf(gpidx, 0);
122 iomux_gpio_config_pull_up_setf(gpidx, 0);
123 iomux_gpio_config_pull_frc_setf(gpidx, 1);
124 } else if (gpidx < 32) {
125 iomux_agpio_config_pull_dn_setf(gpidx, 0);
126 iomux_agpio_config_pull_up_setf(gpidx, 0);
127 iomux_agpio_config_pull_frc_setf(gpidx, 1);
128 }
129 }
130
gpio_force_pull_up_dn_disable(int gpidx)131 void gpio_force_pull_up_dn_disable(int gpidx)
132 {
133 if (gpidx < 16) {
134 iomux_gpio_config_pull_up_setf(gpidx, 0);
135 iomux_gpio_config_pull_dn_setf(gpidx, 0);
136 iomux_gpio_config_pull_frc_setf(gpidx, 0);
137 } else if (gpidx < 32) {
138 iomux_agpio_config_pull_up_setf(gpidx, 0);
139 iomux_agpio_config_pull_dn_setf(gpidx, 0);
140 iomux_agpio_config_pull_frc_setf(gpidx, 0);
141 }
142 }
143
144 gpio_irq_handler_t gpio_irq_handler[GPIOA_IDX_MAX] = {NULL};
145
gpio_irq_en_set(int gpidx,int enable)146 void gpio_irq_en_set(int gpidx, int enable)
147 {
148 if(enable) {
149 //CS_GPIO->IRR = (0x01UL << gpidx);
150 CS_GPIO->ICR |= (0x01UL << gpidx); // int en
151 } else {
152 CS_GPIO->ICR &= ~(0x01UL << gpidx); // int disable
153 }
154 }
155
gpio_irq_init(int gpidx,int type,gpio_irq_handler_t handler)156 void gpio_irq_init(int gpidx, int type, gpio_irq_handler_t handler)
157 {
158 unsigned int reg_val;
159 gpio_init(gpidx);
160 gpio_dir_in(gpidx);
161 CS_GPIO->TIR |= (0x01UL << gpidx); // input en
162 CS_GPIO->TELR &= ~(0x01UL << gpidx); // edge
163 if (type == GPIOIRQ_TYPE_EDGE_BOTH) {
164 CS_GPIO->TER |= (0x01UL << gpidx); // both edge
165 } else {
166 CS_GPIO->TER &= ~(0x01UL << gpidx); // not both edge
167 if (type == GPIOIRQ_TYPE_EDGE_RISE) {
168 CS_GPIO->TLR |= (0x01UL << gpidx); // rising edge
169 } else {
170 CS_GPIO->TLR &= ~(0x01UL << gpidx); // falling edge
171 }
172 }
173 CS_GPIO->ICR |= (0x01UL << gpidx); // int en
174 reg_val = CS_GPIO->FR & ~(0x07UL << (gpidx & ~0x03UL));
175 CS_GPIO->FR = reg_val | (0x07UL << (gpidx & ~0x03UL)); // filter
176 gpio_irq_handler[gpidx] = handler;
177 if (!NVIC_GetEnableIRQ(GPIO_IRQn)) {
178 NVIC_SetPriority(GPIO_IRQn, __NVIC_PRIO_LOWEST);
179 NVIC_EnableIRQ(GPIO_IRQn);
180 }
181 }
182
GPIO_IRQHandler(void)183 void GPIO_IRQHandler(void)
184 {
185 unsigned int int_status = CS_GPIO->ISR;
186 while (int_status) {
187 int bit = 31 - __CLZ(int_status);
188 if (bit >= GPIOA_IDX_MAX) {
189 // error occors
190 break;
191 }
192 CS_GPIO->IRR = (0x01UL << bit);
193 __ISB();
194 if (gpio_irq_handler[bit]) {
195 int event = GPIOIRQ_EVENT_EDGE_FALL;
196 if (CS_GPIO->TER & (0x01UL << bit)) {
197 event = GPIOIRQ_EVENT_EDGE_BOTH;
198 } else if (CS_GPIO->TLR & (0x01UL << bit)) {
199 event = GPIOIRQ_EVENT_EDGE_RISE;
200 }
201 gpio_irq_handler[bit](GPIOIRQ_CB_PARAM(bit, event)); // pass gpio num to cb func
202 }
203 int_status = CS_GPIO->ISR;
204 }
205 }
206
207 #if PLF_PMIC
208 #if PLF_PMIC_VER_LITE
209 static HWP_CS1000LITE_GPIO_T * const PMIC_GPIOB = cs1000liteGpio;
210 #endif
211 #if PLF_PMIC_VER_AUD
212 static HWP_CS1000AUD_GPIO_T * const PMIC_GPIOB = cs1000audGpio;
213 #endif
214
215 static uint32_t gpiob_irq_history = 0;
216
gpiob_init(int gpidx)217 void gpiob_init(int gpidx)
218 {
219 unsigned int gpmsk = 0x01UL << gpidx;
220 #if PLF_PMIC_VER_LITE
221 // iomux
222 if (gpidx < 2) {
223 PMIC_MEM_MASK_WRITE((unsigned int)(&cs1000liteIomux->GPCFG[gpidx]),
224 (CS1000LITE_IOMUX_PAD_GPIO_SEL(1)),
225 (CS1000LITE_IOMUX_PAD_GPIO_SEL(0xF)));
226 } else if (gpidx < 16) {
227 PMIC_MEM_MASK_WRITE((unsigned int)(&cs1000liteIomux->GPCFG[gpidx]),
228 (CS1000LITE_IOMUX_PAD_GPIO_SEL(0)),
229 (CS1000LITE_IOMUX_PAD_GPIO_SEL(0xF)));
230 if ((gpidx == 14) || (gpidx == 15)) {
231 PMIC_MEM_WRITE((unsigned int)(&cs1000liteSysctrl->MISC_CTRL), CS1000LITE_SYS_CTRL_CFG_USB_IO_USED_FOR_GPIO);
232 }
233 } else {
234 return;
235 }
236 #endif
237 #if PLF_PMIC_VER_AUD
238 // iomux
239 if (gpidx < 2) {
240 PMIC_MEM_MASK_WRITE((unsigned int)(&cs1000audIomux->GPCFG[gpidx]),
241 (CS1000AUD_IOMUX_PAD_GPIO_SEL(1)),
242 (CS1000AUD_IOMUX_PAD_GPIO_SEL(0xF)));
243 } else if (gpidx < 8) {
244 PMIC_MEM_MASK_WRITE((unsigned int)(&cs1000audIomux->GPCFG[gpidx]),
245 (CS1000AUD_IOMUX_PAD_GPIO_SEL(0)),
246 (CS1000AUD_IOMUX_PAD_GPIO_SEL(0xF)));
247 } else {
248 return;
249 }
250 #endif
251 // mask
252 PMIC_MEM_MASK_WRITE((unsigned int)(&PMIC_GPIOB->MR), gpmsk, gpmsk);
253 }
254
gpiob_deinit(int gpidx)255 void gpiob_deinit(int gpidx)
256 {
257 unsigned int gpmsk = 0x01UL << gpidx;
258 // mask
259 PMIC_MEM_MASK_WRITE((unsigned int)(&PMIC_GPIOB->MR), 0, gpmsk);
260 }
261
gpiob_dir_in(int gpidx)262 void gpiob_dir_in(int gpidx)
263 {
264 unsigned int gpmsk = 0x01UL << gpidx;
265 if ((gpidx == 14) || (gpidx == 15)) {
266 gpmsk = ((0x01UL << 14) | (0x01UL << 15));
267 }
268 PMIC_MEM_MASK_WRITE((unsigned int)(&PMIC_GPIOB->DR), 0, gpmsk);
269 }
270
gpiob_dir_out(int gpidx)271 void gpiob_dir_out(int gpidx)
272 {
273 unsigned int gpmsk = 0x01UL << gpidx;
274 if ((gpidx == 14) || (gpidx == 15)) {
275 gpmsk = ((0x01UL << 14) | (0x01UL << 15));
276 }
277 PMIC_MEM_MASK_WRITE((unsigned int)(&PMIC_GPIOB->DR), gpmsk, gpmsk);
278 }
279
gpiob_set(int gpidx)280 void gpiob_set(int gpidx)
281 {
282 unsigned int gpmsk = 0x01UL << gpidx;
283 PMIC_MEM_MASK_WRITE((unsigned int)(&PMIC_GPIOB->VR), gpmsk, gpmsk);
284 }
285
gpiob_clr(int gpidx)286 void gpiob_clr(int gpidx)
287 {
288 unsigned int gpmsk = 0x01UL << gpidx;
289 PMIC_MEM_MASK_WRITE((unsigned int)(&PMIC_GPIOB->VR), 0, gpmsk);
290 }
291
gpiob_get(int gpidx)292 int gpiob_get(int gpidx)
293 {
294 int val;
295 unsigned int gpmsk = 0x01UL << gpidx;
296 val = PMIC_MEM_READ((unsigned int)(&PMIC_GPIOB->VR));
297 val = (val & gpmsk) ? 1 : 0;
298 return val;
299 }
300
gpiob_force_pull_up_enable(int gpidx)301 void gpiob_force_pull_up_enable(int gpidx)
302 {
303 if (gpidx < 16) {
304 #if PLF_PMIC_VER_LITE
305 PMIC_MEM_MASK_WRITE((unsigned int)(&cs1000liteIomux->GPCFG[gpidx]),
306 (CS1000LITE_IOMUX_PAD_GPIO_PULL_FRC |
307 CS1000LITE_IOMUX_PAD_GPIO_PULL_UP |
308 0),
309 (CS1000LITE_IOMUX_PAD_GPIO_PULL_FRC |
310 CS1000LITE_IOMUX_PAD_GPIO_PULL_UP |
311 CS1000LITE_IOMUX_PAD_GPIO_PULL_DN));
312 #endif
313 #if PLF_PMIC_VER_AUD
314 PMIC_MEM_MASK_WRITE((unsigned int)(&cs1000audIomux->GPCFG[gpidx]),
315 (CS1000AUD_IOMUX_PAD_GPIO_PULL_FRC |
316 CS1000AUD_IOMUX_PAD_GPIO_PULL_UP |
317 0),
318 (CS1000AUD_IOMUX_PAD_GPIO_PULL_FRC |
319 CS1000AUD_IOMUX_PAD_GPIO_PULL_UP |
320 CS1000AUD_IOMUX_PAD_GPIO_PULL_DN));
321 #endif
322 } else if (gpidx < 32) {
323 #if PLF_PMIC_VER_LITE
324 PMIC_MEM_MASK_WRITE((unsigned int)(&cs1000liteIomux->AGPCFG[gpidx - 16]),
325 (CS1000LITE_IOMUX_PAD_AGPIO_PULL_FRC |
326 CS1000LITE_IOMUX_PAD_AGPIO_PULL_UP |
327 0),
328 (CS1000LITE_IOMUX_PAD_AGPIO_PULL_FRC |
329 CS1000LITE_IOMUX_PAD_AGPIO_PULL_UP |
330 CS1000LITE_IOMUX_PAD_AGPIO_PULL_DN));
331 #endif
332 #if PLF_PMIC_VER_AUD
333 PMIC_MEM_MASK_WRITE((unsigned int)(&cs1000audIomux->AGPCFG[gpidx - 16]),
334 (CS1000AUD_IOMUX_PAD_AGPIO_PULL_FRC |
335 CS1000AUD_IOMUX_PAD_AGPIO_PULL_UP |
336 0),
337 (CS1000AUD_IOMUX_PAD_AGPIO_PULL_FRC |
338 CS1000AUD_IOMUX_PAD_AGPIO_PULL_UP |
339 CS1000AUD_IOMUX_PAD_AGPIO_PULL_DN));
340 #endif
341 }
342 }
343
gpiob_force_pull_dn_enable(int gpidx)344 void gpiob_force_pull_dn_enable(int gpidx)
345 {
346 if (gpidx < 16) {
347 #if PLF_PMIC_VER_LITE
348 PMIC_MEM_MASK_WRITE((unsigned int)(&cs1000liteIomux->GPCFG[gpidx]),
349 (CS1000LITE_IOMUX_PAD_GPIO_PULL_FRC |
350 0 |
351 CS1000LITE_IOMUX_PAD_GPIO_PULL_DN),
352 (CS1000LITE_IOMUX_PAD_GPIO_PULL_FRC |
353 CS1000LITE_IOMUX_PAD_GPIO_PULL_UP |
354 CS1000LITE_IOMUX_PAD_GPIO_PULL_DN));
355 #endif
356 #if PLF_PMIC_VER_AUD
357 PMIC_MEM_MASK_WRITE((unsigned int)(&cs1000audIomux->GPCFG[gpidx]),
358 (CS1000AUD_IOMUX_PAD_GPIO_PULL_FRC |
359 0 |
360 CS1000AUD_IOMUX_PAD_GPIO_PULL_DN),
361 (CS1000AUD_IOMUX_PAD_GPIO_PULL_FRC |
362 CS1000AUD_IOMUX_PAD_GPIO_PULL_UP |
363 CS1000AUD_IOMUX_PAD_GPIO_PULL_DN));
364 #endif
365 } else if (gpidx < 32) {
366 #if PLF_PMIC_VER_LITE
367 PMIC_MEM_MASK_WRITE((unsigned int)(&cs1000liteIomux->AGPCFG[gpidx - 16]),
368 (CS1000LITE_IOMUX_PAD_AGPIO_PULL_FRC |
369 0 |
370 CS1000LITE_IOMUX_PAD_AGPIO_PULL_DN),
371 (CS1000LITE_IOMUX_PAD_AGPIO_PULL_FRC |
372 CS1000LITE_IOMUX_PAD_AGPIO_PULL_UP |
373 CS1000LITE_IOMUX_PAD_AGPIO_PULL_DN));
374 #endif
375 #if PLF_PMIC_VER_AUD
376 PMIC_MEM_MASK_WRITE((unsigned int)(&cs1000audIomux->AGPCFG[gpidx - 16]),
377 (CS1000AUD_IOMUX_PAD_AGPIO_PULL_FRC |
378 0 |
379 CS1000AUD_IOMUX_PAD_AGPIO_PULL_DN),
380 (CS1000AUD_IOMUX_PAD_AGPIO_PULL_FRC |
381 CS1000AUD_IOMUX_PAD_AGPIO_PULL_UP |
382 CS1000AUD_IOMUX_PAD_AGPIO_PULL_DN));
383 #endif
384 }
385 }
386
gpiob_force_pull_none_enable(int gpidx)387 void gpiob_force_pull_none_enable(int gpidx)
388 {
389 if (gpidx < 16) {
390 #if PLF_PMIC_VER_LITE
391 PMIC_MEM_MASK_WRITE((unsigned int)(&cs1000liteIomux->GPCFG[gpidx]),
392 (CS1000LITE_IOMUX_PAD_GPIO_PULL_FRC |
393 0 |
394 0),
395 (CS1000LITE_IOMUX_PAD_GPIO_PULL_FRC |
396 CS1000LITE_IOMUX_PAD_GPIO_PULL_UP |
397 CS1000LITE_IOMUX_PAD_GPIO_PULL_DN));
398 #endif
399 #if PLF_PMIC_VER_AUD
400 PMIC_MEM_MASK_WRITE((unsigned int)(&cs1000audIomux->GPCFG[gpidx]),
401 (CS1000AUD_IOMUX_PAD_GPIO_PULL_FRC |
402 0 |
403 0),
404 (CS1000AUD_IOMUX_PAD_GPIO_PULL_FRC |
405 CS1000AUD_IOMUX_PAD_GPIO_PULL_UP |
406 CS1000AUD_IOMUX_PAD_GPIO_PULL_DN));
407 #endif
408 } else if (gpidx < 32) {
409 #if PLF_PMIC_VER_LITE
410 PMIC_MEM_MASK_WRITE((unsigned int)(&cs1000liteIomux->AGPCFG[gpidx - 16]),
411 (CS1000LITE_IOMUX_PAD_AGPIO_PULL_FRC |
412 0 |
413 0),
414 (CS1000LITE_IOMUX_PAD_AGPIO_PULL_FRC |
415 CS1000LITE_IOMUX_PAD_AGPIO_PULL_UP |
416 CS1000LITE_IOMUX_PAD_AGPIO_PULL_DN));
417 #endif
418 #if PLF_PMIC_VER_AUD
419 PMIC_MEM_MASK_WRITE((unsigned int)(&cs1000audIomux->AGPCFG[gpidx - 16]),
420 (CS1000AUD_IOMUX_PAD_AGPIO_PULL_FRC |
421 0 |
422 0),
423 (CS1000AUD_IOMUX_PAD_AGPIO_PULL_FRC |
424 CS1000AUD_IOMUX_PAD_AGPIO_PULL_UP |
425 CS1000AUD_IOMUX_PAD_AGPIO_PULL_DN));
426 #endif
427 }
428 }
429
gpiob_force_pull_up_dn_disable(int gpidx)430 void gpiob_force_pull_up_dn_disable(int gpidx)
431 {
432 if (gpidx < 16) {
433 #if PLF_PMIC_VER_LITE
434 PMIC_MEM_MASK_WRITE((unsigned int)(&cs1000liteIomux->GPCFG[gpidx]),
435 (0 |
436 0 |
437 0),
438 (CS1000LITE_IOMUX_PAD_GPIO_PULL_FRC |
439 CS1000LITE_IOMUX_PAD_GPIO_PULL_UP |
440 CS1000LITE_IOMUX_PAD_GPIO_PULL_DN));
441 #endif
442 #if PLF_PMIC_VER_AUD
443 PMIC_MEM_MASK_WRITE((unsigned int)(&cs1000audIomux->GPCFG[gpidx]),
444 (0 |
445 0 |
446 0),
447 (CS1000AUD_IOMUX_PAD_GPIO_PULL_FRC |
448 CS1000AUD_IOMUX_PAD_GPIO_PULL_UP |
449 CS1000AUD_IOMUX_PAD_GPIO_PULL_DN));
450 #endif
451 } else if (gpidx < 32) {
452 #if PLF_PMIC_VER_LITE
453 PMIC_MEM_MASK_WRITE((unsigned int)(&cs1000liteIomux->AGPCFG[gpidx - 16]),
454 (0 |
455 0 |
456 0),
457 (CS1000LITE_IOMUX_PAD_AGPIO_PULL_FRC |
458 CS1000LITE_IOMUX_PAD_AGPIO_PULL_UP |
459 CS1000LITE_IOMUX_PAD_AGPIO_PULL_DN));
460 #endif
461 #if PLF_PMIC_VER_AUD
462 PMIC_MEM_MASK_WRITE((unsigned int)(&cs1000audIomux->AGPCFG[gpidx - 16]),
463 (0 |
464 0 |
465 0),
466 (CS1000AUD_IOMUX_PAD_AGPIO_PULL_FRC |
467 CS1000AUD_IOMUX_PAD_AGPIO_PULL_UP |
468 CS1000AUD_IOMUX_PAD_AGPIO_PULL_DN));
469 #endif
470 }
471 }
472
pmic_clock_set_for_gpiob(void)473 void pmic_clock_set_for_gpiob(void)
474 {
475 #if PLF_PMIC_VER_LITE
476 // hclk divider
477 PMIC_MEM_WRITE((unsigned int)(&cs1000liteSysctrl->hclk_div),
478 (CS1000LITE_SYS_CTRL_CFG_HCLK_DIV_DENOM(0x1) | CS1000LITE_SYS_CTRL_CFG_HCLK_DIV_UPDATE));
479 // hclk sel
480 PMIC_MEM_MASK_WRITE((unsigned int)(&cs1000liteSysctrl->clk_sel),
481 (CS1000LITE_SYS_CTRL_CFG_FAST_HWEN), (CS1000LITE_SYS_CTRL_CFG_FAST_HWEN));
482 #endif
483 }
484
485 gpio_irq_handler_t gpiob_irq_handler[GPIOB_IDX_MAX] = {NULL};
486
GPIOB_IRQHandler(void)487 void GPIOB_IRQHandler(void)
488 {
489 unsigned int int_status = PMIC_MEM_READ((unsigned int)(&PMIC_GPIOB->ISR));
490 while (int_status) {
491 int bit = 31 - __CLZ(int_status);
492 unsigned int bitmsk = (0x01UL << bit);
493 if (bit >= GPIOB_IDX_MAX) {
494 // error occors
495 break;
496 }
497 PMIC_MEM_WRITE((unsigned int)(&PMIC_GPIOB->IRR), bitmsk);
498 __ISB();
499 if (gpiob_irq_handler[bit]) {
500 int event = GPIOIRQ_EVENT_EDGE_FALL;
501 if (PMIC_MEM_READ((unsigned int)(&PMIC_GPIOB->TER)) & bitmsk) {
502 event = GPIOIRQ_EVENT_EDGE_BOTH;
503 } else if (PMIC_MEM_READ((unsigned int)(&PMIC_GPIOB->TLR)) & bitmsk) {
504 event = GPIOIRQ_EVENT_EDGE_RISE;
505 }
506 gpiob_irq_handler[bit](GPIOIRQ_CB_PARAM(bit, event)); // pass gpiob num to cb func
507 } else {
508 gpiob_irq_history_set(0x01UL << bit);
509 }
510 int_status = PMIC_MEM_READ((unsigned int)(&PMIC_GPIOB->ISR));
511 }
512 }
513
gpiob_irq_init(int gpidx,int type,gpio_irq_handler_t handler,int filter)514 void gpiob_irq_init(int gpidx, int type, gpio_irq_handler_t handler, int filter)
515 {
516 unsigned int gpmsk = 0x01UL << gpidx;
517 gpiob_init(gpidx);
518 gpiob_dir_in(gpidx);
519 PMIC_MEM_MASK_WRITE((unsigned int)(&PMIC_GPIOB->TIR), gpmsk, gpmsk); // input en
520 PMIC_MEM_MASK_WRITE((unsigned int)(&PMIC_GPIOB->TELR), 0, gpmsk); // edge
521 if (type == GPIOIRQ_TYPE_EDGE_BOTH) {
522 PMIC_MEM_MASK_WRITE((unsigned int)(&PMIC_GPIOB->TER), gpmsk, gpmsk); // both edge
523 } else {
524 PMIC_MEM_MASK_WRITE((unsigned int)(&PMIC_GPIOB->TER), 0, gpmsk); // not both edge
525 if (type == GPIOIRQ_TYPE_EDGE_RISE) {
526 PMIC_MEM_MASK_WRITE((unsigned int)(&PMIC_GPIOB->TLR), gpmsk, gpmsk); // rising edge
527 } else {
528 PMIC_MEM_MASK_WRITE((unsigned int)(&PMIC_GPIOB->TLR), 0, gpmsk); // falling edge
529 }
530 }
531 PMIC_MEM_MASK_WRITE((unsigned int)(&PMIC_GPIOB->ICR), gpmsk, gpmsk); // int en
532 #if PLF_PMIC_VER_LITE
533 PMIC_MEM_MASK_WRITE((unsigned int)(&PMIC_GPIOB->FR),
534 (0x06UL << (gpidx & ~0x03UL)), (0x07UL << (gpidx & ~0x03UL))); // filter
535 #endif
536 #if PLF_PMIC_VER_AUD
537 if(filter) {
538 unsigned int fltr_div = (filter/7 - 1) & 0xffUL;
539 if(fltr_div) {
540 PMIC_MEM_MASK_WRITE((unsigned int)(&PMIC_GPIOB->FNR),
541 (0x07UL << (gpidx & ~0x03UL)), (0x07UL << (gpidx & ~0x03UL))); // filter num
542 PMIC_MEM_MASK_WRITE((unsigned int)(&PMIC_GPIOB->FDR), fltr_div, 0xffUL); // filter div
543 }
544 }
545 #endif
546 gpiob_irq_handler[gpidx] = handler;
547 pmic_irq_enable(0x01UL << PMIC_GPIO_IRQn);
548 }
549
gpiob_irq_history_set(uint32_t gpidx_bit)550 void gpiob_irq_history_set(uint32_t gpidx_bit)
551 {
552 gpiob_irq_history |= gpidx_bit;
553 }
554
gpiob_irq_history_clear(uint32_t gpidx_bit)555 void gpiob_irq_history_clear(uint32_t gpidx_bit)
556 {
557 gpiob_irq_history &= ~gpidx_bit;
558 }
559
gpiob_irq_history_get(void)560 uint32_t gpiob_irq_history_get(void)
561 {
562 return gpiob_irq_history;
563 }
564
565 #endif
566