• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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