]> git.sur5r.net Git - freertos/blob
fce9c7d8a3540d803d4792890b3e4facb2d2c2af
[freertos] /
1 /******************************************************************************
2 *
3 * (c) Copyright 2010-14 Xilinx, Inc. All rights reserved.
4 *
5 * This file contains confidential and proprietary information of Xilinx, Inc.
6 * and is protected under U.S. and international copyright and other
7 * intellectual property laws.
8 *
9 * DISCLAIMER
10 * This disclaimer is not a license and does not grant any rights to the
11 * materials distributed herewith. Except as otherwise provided in a valid
12 * license issued to you by Xilinx, and to the maximum extent permitted by
13 * applicable law: (1) THESE MATERIALS ARE MADE AVAILABLE "AS IS" AND WITH ALL
14 * FAULTS, AND XILINX HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS,
15 * IMPLIED, OR STATUTORY, INCLUDING BUT NOT LIMITED TO WARRANTIES OF
16 * MERCHANTABILITY, NON-INFRINGEMENT, OR FITNESS FOR ANY PARTICULAR PURPOSE;
17 * and (2) Xilinx shall not be liable (whether in contract or tort, including
18 * negligence, or under any other theory of liability) for any loss or damage
19 * of any kind or nature related to, arising under or in connection with these
20 * materials, including for any direct, or any indirect, special, incidental,
21 * or consequential loss or damage (including loss of data, profits, goodwill,
22 * or any type of loss or damage suffered as a result of any action brought by
23 * a third party) even if such damage or loss was reasonably foreseeable or
24 * Xilinx had been advised of the possibility of the same.
25 *
26 * CRITICAL APPLICATIONS
27 * Xilinx products are not designed or intended to be fail-safe, or for use in
28 * any application requiring fail-safe performance, such as life-support or
29 * safety devices or systems, Class III medical devices, nuclear facilities,
30 * applications related to the deployment of airbags, or any other applications
31 * that could lead to death, personal injury, or severe property or
32 * environmental damage (individually and collectively, "Critical
33 * Applications"). Customer assumes the sole risk and liability of any use of
34 * Xilinx products in Critical Applications, subject only to applicable laws
35 * and regulations governing limitations on product liability.
36 *
37 * THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS PART OF THIS FILE
38 * AT ALL TIMES.
39 *
40 ******************************************************************************/
41 /*****************************************************************************/
42 /**
43 *
44 * @file xgpiops_intr.c
45 *
46 * This file contains functions related to GPIO interrupt handling.
47 *
48 * <pre>
49 * MODIFICATION HISTORY:
50 *
51 * Ver   Who  Date     Changes
52 * ----- ---- -------- -----------------------------------------------
53 * 1.00a sv   01/18/10 First Release
54 * </pre>
55 *
56 ******************************************************************************/
57
58 /***************************** Include Files *********************************/
59
60 #include "xgpiops.h"
61
62 /************************** Constant Definitions *****************************/
63
64 /**************************** Type Definitions *******************************/
65
66 /***************** Macros (Inline Functions) Definitions *********************/
67
68 /************************** Variable Definitions *****************************/
69
70 /************************** Function Prototypes ******************************/
71
72 void StubHandler(void *CallBackRef, int Bank, u32 Status);
73
74 /****************************************************************************/
75 /**
76 *
77 * This function enables the interrupts for the specified pins in the specified
78 * bank.
79 *
80 * @param        InstancePtr is a pointer to the XGpioPs instance.
81 * @param        Bank is the bank number of the GPIO to operate on.
82 *               Valid values are 0 to XGPIOPS_MAX_BANKS - 1.
83 * @param        Mask is the bit mask of the pins for which interrupts are to
84 *               be enabled. Bit positions of 1 will be enabled. Bit positions
85 *               of 0 will keep the previous setting.
86 *
87 * @return       None.
88 *
89 * @note         None.
90 *
91 *****************************************************************************/
92 void XGpioPs_IntrEnable(XGpioPs *InstancePtr, u8 Bank, u32 Mask)
93 {
94         Xil_AssertVoid(InstancePtr != NULL);
95         Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
96         Xil_AssertVoid(Bank < XGPIOPS_MAX_BANKS);
97
98         XGpioPs_WriteReg(InstancePtr->GpioConfig.BaseAddr,
99                           ((Bank) * XGPIOPS_REG_MASK_OFFSET) +
100                           XGPIOPS_INTEN_OFFSET, Mask);
101 }
102
103 /****************************************************************************/
104 /**
105 *
106 * This function enables the interrupt for the specified pin.
107 *
108 * @param        InstancePtr is a pointer to the XGpioPs instance.
109 * @param        Pin is the pin number for which the interrupt is to be enabled.
110 *               Valid values are 0 to XGPIOPS_DEVICE_MAX_PIN_NUM - 1.
111 *
112 * @return       None.
113 *
114 * @note         None.
115 *
116 *****************************************************************************/
117 void XGpioPs_IntrEnablePin(XGpioPs *InstancePtr, int Pin)
118 {
119         u8 Bank;
120         u8 PinNumber;
121         u32 IntrReg = 0;
122
123         Xil_AssertVoid(InstancePtr != NULL);
124         Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
125         Xil_AssertVoid(Pin < XGPIOPS_DEVICE_MAX_PIN_NUM);
126
127         /*
128          * Get the Bank number and Pin number within the bank.
129          */
130         XGpioPs_GetBankPin(Pin, &Bank, &PinNumber);
131
132         IntrReg = 1 << PinNumber;
133         XGpioPs_WriteReg(InstancePtr->GpioConfig.BaseAddr,
134                           ((Bank) * XGPIOPS_REG_MASK_OFFSET) +
135                           XGPIOPS_INTEN_OFFSET, IntrReg);
136 }
137
138 /****************************************************************************/
139 /**
140 *
141 * This function disables the interrupts for the specified pins in the specified
142 * bank.
143 *
144 * @param        InstancePtr is a pointer to the XGpioPs instance.
145 * @param        Bank is the bank number of the GPIO to operate on.
146 *               Valid values are 0 to XGPIOPS_MAX_BANKS - 1.
147 * @param        Mask is the bit mask of the pins for which interrupts are
148 *               to be disabled. Bit positions of 1 will be disabled. Bit
149 *               positions of 0 will keep the previous setting.
150 *
151 * @return       None.
152 *
153 * @note         None.
154 *
155 *****************************************************************************/
156 void XGpioPs_IntrDisable(XGpioPs *InstancePtr, u8 Bank, u32 Mask)
157 {
158         Xil_AssertVoid(InstancePtr != NULL);
159         Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
160         Xil_AssertVoid(Bank < XGPIOPS_MAX_BANKS);
161
162         XGpioPs_WriteReg(InstancePtr->GpioConfig.BaseAddr,
163                           ((Bank) * XGPIOPS_REG_MASK_OFFSET) +
164                           XGPIOPS_INTDIS_OFFSET, Mask);
165 }
166
167 /****************************************************************************/
168 /**
169 *
170 * This function disables the interrupts for the specified pin.
171 *
172 * @param        InstancePtr is a pointer to the XGpioPs instance.
173 * @param        Pin is the pin number for which the interrupt is to be disabled.
174 *               Valid values are 0 to XGPIOPS_DEVICE_MAX_PIN_NUM - 1.
175 *
176 * @return       None.
177 *
178 * @note         None.
179 *
180 *****************************************************************************/
181 void XGpioPs_IntrDisablePin(XGpioPs *InstancePtr, int Pin)
182 {
183         u8 Bank;
184         u8 PinNumber;
185         u32 IntrReg = 0;
186
187         Xil_AssertVoid(InstancePtr != NULL);
188         Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
189         Xil_AssertVoid(Pin < XGPIOPS_DEVICE_MAX_PIN_NUM);
190
191         /*
192          * Get the Bank number and Pin number within the bank.
193          */
194         XGpioPs_GetBankPin(Pin, &Bank, &PinNumber);
195
196         IntrReg =  1 << PinNumber;
197         XGpioPs_WriteReg(InstancePtr->GpioConfig.BaseAddr,
198                           ((Bank) * XGPIOPS_REG_MASK_OFFSET) +
199                           XGPIOPS_INTDIS_OFFSET, IntrReg);
200 }
201
202 /****************************************************************************/
203 /**
204 *
205 * This function returns the interrupt enable status for a bank.
206 *
207 * @param        InstancePtr is a pointer to the XGpioPs instance.
208 * @param        Bank is the bank number of the GPIO to operate on.
209 *               Valid values are 0 to XGPIOPS_MAX_BANKS - 1.
210 *
211 * @return       Enabled interrupt(s) in a 32-bit format. Bit positions with 1
212 *               indicate that the interrupt for that pin is enabled, bit
213 *               positions with 0 indicate that the interrupt for that pin is
214 *               disabled.
215 *
216 * @note         None.
217 *
218 *****************************************************************************/
219 u32 XGpioPs_IntrGetEnabled(XGpioPs *InstancePtr, u8 Bank)
220 {
221         u32 IntrMask;
222
223         Xil_AssertNonvoid(InstancePtr != NULL);
224         Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
225         Xil_AssertNonvoid(Bank < XGPIOPS_MAX_BANKS);
226
227         IntrMask = XGpioPs_ReadReg(InstancePtr->GpioConfig.BaseAddr,
228                                     ((Bank) * XGPIOPS_REG_MASK_OFFSET) +
229                                     XGPIOPS_INTMASK_OFFSET);
230         return ~IntrMask;
231 }
232
233 /****************************************************************************/
234 /**
235 *
236 * This function returns whether interrupts are enabled for the specified pin.
237 *
238 * @param        InstancePtr is a pointer to the XGpioPs instance.
239 * @param        Pin is the pin number for which the interrupt enable status
240 *               is to be known.
241 *               Valid values are 0 to XGPIOPS_DEVICE_MAX_PIN_NUM - 1.
242 *
243 * @return
244 *               - TRUE if the interrupt is enabled.
245 *               - FALSE if the interrupt is disabled.
246 *
247 * @note         None.
248 *
249 *****************************************************************************/
250 int XGpioPs_IntrGetEnabledPin(XGpioPs *InstancePtr, int Pin)
251 {
252         u8 Bank;
253         u8 PinNumber;
254         u32 IntrReg;
255
256         Xil_AssertNonvoid(InstancePtr != NULL);
257         Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
258         Xil_AssertNonvoid(Pin < XGPIOPS_DEVICE_MAX_PIN_NUM);
259
260         /*
261          * Get the Bank number and Pin number within the bank.
262          */
263         XGpioPs_GetBankPin(Pin, &Bank, &PinNumber);
264
265         IntrReg  = XGpioPs_ReadReg(InstancePtr->GpioConfig.BaseAddr,
266                                     ((Bank) * XGPIOPS_REG_MASK_OFFSET) +
267                                     XGPIOPS_INTMASK_OFFSET);
268
269         return (IntrReg & (1 << Pin)) ? TRUE : FALSE;
270 }
271
272 /****************************************************************************/
273 /**
274 *
275 * This function returns interrupt status read from Interrupt Status Register.
276 *
277 * @param        InstancePtr is a pointer to the XGpioPs instance.
278 * @param        Bank is the bank number of the GPIO to operate on.
279 *               Valid values are 0 to XGPIOPS_MAX_BANKS - 1.
280 *
281 * @return       The value read from Interrupt Status Register.
282 *
283 * @note         None.
284 *
285 *****************************************************************************/
286 u32 XGpioPs_IntrGetStatus(XGpioPs *InstancePtr, u8 Bank)
287 {
288         Xil_AssertNonvoid(InstancePtr != NULL);
289         Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
290         Xil_AssertNonvoid(Bank < XGPIOPS_MAX_BANKS);
291
292         return XGpioPs_ReadReg(InstancePtr->GpioConfig.BaseAddr,
293                                 ((Bank) * XGPIOPS_REG_MASK_OFFSET) +
294                                 XGPIOPS_INTSTS_OFFSET);
295 }
296
297 /****************************************************************************/
298 /**
299 *
300 * This function returns interrupt enable status of the specified pin.
301 *
302 * @param        InstancePtr is a pointer to the XGpioPs instance.
303 * @param        Pin is the pin number for which the interrupt enable status
304 *               is to be known.
305 *               Valid values are 0 to XGPIOPS_DEVICE_MAX_PIN_NUM - 1.
306 *
307 * @return
308 *               - TRUE if the interrupt has occurred.
309 *               - FALSE if the interrupt has not occurred.
310 *
311 * @note         None.
312 *
313 *****************************************************************************/
314 int XGpioPs_IntrGetStatusPin(XGpioPs *InstancePtr, int Pin)
315 {
316         u8 Bank;
317         u8 PinNumber;
318         u32 IntrReg;
319
320         Xil_AssertNonvoid(InstancePtr != NULL);
321         Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
322         Xil_AssertNonvoid(Pin < XGPIOPS_DEVICE_MAX_PIN_NUM);
323
324         /*
325          * Get the Bank number and Pin number within the bank.
326          */
327         XGpioPs_GetBankPin(Pin, &Bank, &PinNumber);
328
329         IntrReg = XGpioPs_ReadReg(InstancePtr->GpioConfig.BaseAddr,
330                                    ((Bank) * XGPIOPS_REG_MASK_OFFSET) +
331                                    XGPIOPS_INTSTS_OFFSET);
332
333         return (IntrReg & (1 << Pin)) ? TRUE : FALSE;
334 }
335
336 /****************************************************************************/
337 /**
338 *
339 * This function clears pending interrupt(s) with the provided mask. This
340 * function should be called after the software has serviced the interrupts
341 * that are pending.
342 *
343 * @param        InstancePtr is a pointer to the XGpioPs instance.
344 * @param        Bank is the bank number of the GPIO to operate on.
345 *               Valid values are 0 to XGPIOPS_MAX_BANKS - 1.
346 * @param        Mask is the mask of the interrupts to be cleared. Bit positions
347 *               of 1 will be cleared. Bit positions of 0 will not change the
348 *               previous interrupt status.
349 *
350 * @note         None.
351 *
352 *****************************************************************************/
353 void XGpioPs_IntrClear(XGpioPs *InstancePtr, u8 Bank, u32 Mask)
354 {
355         Xil_AssertVoid(InstancePtr != NULL);
356         Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
357         Xil_AssertVoid(Bank < XGPIOPS_MAX_BANKS);
358
359         /*
360          * Clear the currently pending interrupts.
361          */
362         XGpioPs_WriteReg(InstancePtr->GpioConfig.BaseAddr,
363                           ((Bank) * XGPIOPS_REG_MASK_OFFSET) +
364                           XGPIOPS_INTSTS_OFFSET, Mask);
365 }
366
367 /****************************************************************************/
368 /**
369 *
370 * This function clears the specified pending interrupt. This function should be
371 * called after the software has serviced the interrupts that are pending.
372 *
373 * @param        InstancePtr is a pointer to the XGpioPs instance.
374 * @param        Pin is the pin number for which the interrupt status is to be
375 *               cleared. Valid values are 0 to XGPIOPS_DEVICE_MAX_PIN_NUM - 1.
376 *
377 * @note         None.
378 *
379 *****************************************************************************/
380 void XGpioPs_IntrClearPin(XGpioPs *InstancePtr, int Pin)
381 {
382         u8 Bank;
383         u8 PinNumber;
384         u32 IntrReg;
385
386         Xil_AssertVoid(InstancePtr != NULL);
387         Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
388         Xil_AssertVoid(Pin < XGPIOPS_DEVICE_MAX_PIN_NUM);
389
390         /*
391          * Get the Bank number and Pin number within the bank.
392          */
393         XGpioPs_GetBankPin(Pin, &Bank, &PinNumber);
394
395         /*
396          * Clear the specified pending interrupts.
397          */
398         IntrReg = XGpioPs_ReadReg(InstancePtr->GpioConfig.BaseAddr,
399                                    ((Bank) * XGPIOPS_REG_MASK_OFFSET) +
400                                    XGPIOPS_INTSTS_OFFSET);
401
402         IntrReg &= (1 << Pin);
403         XGpioPs_WriteReg(InstancePtr->GpioConfig.BaseAddr,
404                           ((Bank) * XGPIOPS_REG_MASK_OFFSET) +
405                           XGPIOPS_INTSTS_OFFSET, IntrReg);
406 }
407
408 /****************************************************************************/
409 /**
410 *
411 * This function is used for setting the Interrupt Type, Interrupt Polarity and
412 * Interrupt On Any for the specified GPIO Bank pins.
413 *
414 * @param        InstancePtr is a pointer to an XGpioPs instance.
415 * @param        Bank is the bank number of the GPIO to operate on.
416 *               Valid values are 0 to XGPIOPS_MAX_BANKS - 1.
417 * @param        IntrType is the 32 bit mask of the interrupt type.
418 *               0 means Level Sensitive and 1 means Edge Sensitive.
419 * @param        IntrPolarity is the 32 bit mask of the interrupt polarity.
420 *               0 means Active Low or Falling Edge and 1 means Active High or
421 *               Rising Edge.
422 * @param        IntrOnAny is the 32 bit mask of the interrupt trigger for
423 *               edge triggered interrupts. 0 means trigger on single edge using
424 *               the configured interrupt polarity and 1 means  trigger on both
425 *               edges.
426 *
427 * @return       None.
428 *
429 * @note         This function is used for setting the interrupt related
430 *               properties of all the pins in the specified bank. The previous
431 *               state of the pins is not maintained.
432 *               To change the Interrupt properties of a single GPIO pin, use the
433 *               function XGpioPs_SetPinIntrType().
434 *
435 *****************************************************************************/
436 void XGpioPs_SetIntrType(XGpioPs *InstancePtr, u8 Bank, u32 IntrType,
437                           u32 IntrPolarity, u32 IntrOnAny)
438 {
439         Xil_AssertVoid(InstancePtr != NULL);
440         Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
441         Xil_AssertVoid(Bank < XGPIOPS_MAX_BANKS);
442
443         XGpioPs_WriteReg(InstancePtr->GpioConfig.BaseAddr,
444                           ((Bank) * XGPIOPS_REG_MASK_OFFSET) +
445                           XGPIOPS_INTTYPE_OFFSET, IntrType);
446
447         XGpioPs_WriteReg(InstancePtr->GpioConfig.BaseAddr,
448                           ((Bank) * XGPIOPS_REG_MASK_OFFSET) +
449                           XGPIOPS_INTPOL_OFFSET, IntrPolarity);
450
451         XGpioPs_WriteReg(InstancePtr->GpioConfig.BaseAddr,
452                           ((Bank) * XGPIOPS_REG_MASK_OFFSET) +
453                           XGPIOPS_INTANY_OFFSET, IntrOnAny);
454 }
455
456 /****************************************************************************/
457 /**
458 *
459 * This function is used for getting the Interrupt Type, Interrupt Polarity and
460 * Interrupt On Any for the specified GPIO Bank pins.
461 *
462 * @param        InstancePtr is a pointer to an XGpioPs instance.
463 * @param        Bank is the bank number of the GPIO to operate on.
464 *               Valid values are 0 to XGPIOPS_MAX_BANKS - 1.
465 * @param        IntrType returns the 32 bit mask of the interrupt type.
466 *               0 means Level Sensitive and 1 means Edge Sensitive.
467 * @param        IntrPolarity returns the 32 bit mask of the interrupt
468 *               polarity. 0 means Active Low or Falling Edge and 1 means
469 *               Active High or Rising Edge.
470 * @param        IntrOnAny returns the 32 bit mask of the interrupt trigger for
471 *               edge triggered interrupts. 0 means trigger on single edge using
472 *               the configured interrupt polarity and 1 means trigger on both
473 *               edges.
474 *
475 * @return       None.
476 *
477 * @note         None.
478 *
479 *****************************************************************************/
480 void XGpioPs_GetIntrType(XGpioPs *InstancePtr, u8 Bank, u32 *IntrType,
481                           u32 *IntrPolarity, u32 *IntrOnAny)
482
483 {
484         Xil_AssertVoid(InstancePtr != NULL);
485         Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
486         Xil_AssertVoid(Bank < XGPIOPS_MAX_BANKS);
487
488         *IntrType = XGpioPs_ReadReg(InstancePtr->GpioConfig.BaseAddr,
489                                      ((Bank) * XGPIOPS_REG_MASK_OFFSET) +
490                                      XGPIOPS_INTTYPE_OFFSET);
491
492         *IntrPolarity = XGpioPs_ReadReg(InstancePtr->GpioConfig.BaseAddr,
493                                          ((Bank) * XGPIOPS_REG_MASK_OFFSET) +
494                                          XGPIOPS_INTPOL_OFFSET);
495
496         *IntrOnAny = XGpioPs_ReadReg(InstancePtr->GpioConfig.BaseAddr,
497                                       ((Bank) * XGPIOPS_REG_MASK_OFFSET) +
498                                       XGPIOPS_INTANY_OFFSET);
499 }
500
501 /****************************************************************************/
502 /**
503 *
504 * This function is used for setting the IRQ Type of a single GPIO pin.
505 *
506 * @param        InstancePtr is a pointer to an XGpioPs instance.
507 * @param        Pin is the pin number whose IRQ type is to be set.
508 *               Valid values are 0 to XGPIOPS_DEVICE_MAX_PIN_NUM - 1.
509 * @param        IrqType is the IRQ type for GPIO Pin. Use XGPIOPS_IRQ_TYPE_*
510 *               defined in xgpiops.h to specify the IRQ type.
511 *
512 * @return       None.
513 *
514 * @note         None.
515 *
516 *****************************************************************************/
517 void XGpioPs_SetIntrTypePin(XGpioPs *InstancePtr, int Pin, u8 IrqType)
518 {
519         u32 IntrTypeReg;
520         u32 IntrPolReg;
521         u32 IntrOnAnyReg;
522         u8 Bank;
523         u8 PinNumber;
524
525         Xil_AssertVoid(InstancePtr != NULL);
526         Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
527         Xil_AssertVoid(Pin < XGPIOPS_DEVICE_MAX_PIN_NUM);
528         Xil_AssertVoid(IrqType <= XGPIOPS_IRQ_TYPE_LEVEL_LOW);
529
530         /*
531          * Get the Bank number and Pin number within the bank.
532          */
533         XGpioPs_GetBankPin(Pin, &Bank, &PinNumber);
534
535         IntrTypeReg = XGpioPs_ReadReg(InstancePtr->GpioConfig.BaseAddr,
536                                        ((Bank) * XGPIOPS_REG_MASK_OFFSET) +
537                                        XGPIOPS_INTTYPE_OFFSET);
538
539         IntrPolReg = XGpioPs_ReadReg(InstancePtr->GpioConfig.BaseAddr,
540                                       ((Bank) * XGPIOPS_REG_MASK_OFFSET) +
541                                       XGPIOPS_INTPOL_OFFSET);
542
543         IntrOnAnyReg = XGpioPs_ReadReg(InstancePtr->GpioConfig.BaseAddr,
544                                         ((Bank) * XGPIOPS_REG_MASK_OFFSET) +
545                                         XGPIOPS_INTANY_OFFSET);
546
547         switch (IrqType) {
548                 case XGPIOPS_IRQ_TYPE_EDGE_RISING:
549                         IntrTypeReg |= (1 << PinNumber);
550                         IntrPolReg |= (1 << PinNumber);
551                         IntrOnAnyReg &= ~(1 << PinNumber);
552                         break;
553                 case XGPIOPS_IRQ_TYPE_EDGE_FALLING:
554                         IntrTypeReg |= (1 << PinNumber);
555                         IntrPolReg &= ~(1 << PinNumber);
556                         IntrOnAnyReg &= ~(1 << PinNumber);
557                         break;
558                 case XGPIOPS_IRQ_TYPE_EDGE_BOTH:
559                         IntrTypeReg |= (1 << PinNumber);
560                         IntrOnAnyReg |= (1 << PinNumber);
561                         break;
562                 case XGPIOPS_IRQ_TYPE_LEVEL_HIGH:
563                         IntrTypeReg &= ~(1 << PinNumber);
564                         IntrPolReg |= (1 << PinNumber);
565                         break;
566                 case XGPIOPS_IRQ_TYPE_LEVEL_LOW:
567                         IntrTypeReg &= ~(1 << PinNumber);
568                         IntrPolReg &= ~(1 << PinNumber);
569                         break;
570         }
571
572         XGpioPs_WriteReg(InstancePtr->GpioConfig.BaseAddr,
573                           ((Bank) * XGPIOPS_REG_MASK_OFFSET) +
574                           XGPIOPS_INTTYPE_OFFSET, IntrTypeReg);
575
576         XGpioPs_WriteReg(InstancePtr->GpioConfig.BaseAddr,
577                           ((Bank) * XGPIOPS_REG_MASK_OFFSET) +
578                           XGPIOPS_INTPOL_OFFSET, IntrPolReg);
579
580         XGpioPs_WriteReg(InstancePtr->GpioConfig.BaseAddr,
581                           ((Bank) * XGPIOPS_REG_MASK_OFFSET) +
582                           XGPIOPS_INTANY_OFFSET, IntrOnAnyReg);
583 }
584
585 /****************************************************************************/
586 /**
587 *
588 * This function returns the IRQ Type of a given GPIO pin.
589 *
590 * @param        InstancePtr is a pointer to an XGpioPs instance.
591 * @param        Pin is the pin number whose IRQ type is to be obtained.
592 *               Valid values are 0 to XGPIOPS_DEVICE_MAX_PIN_NUM - 1.
593 *
594 * @return       None.
595 *
596 * @note         Use XGPIOPS_IRQ_TYPE_* defined in xgpiops.h for the IRQ type
597 *               returned by this function.
598 *
599 *****************************************************************************/
600 u8 XGpioPs_GetIntrTypePin(XGpioPs *InstancePtr, int Pin)
601 {
602         u32 IntrType;
603         u32 IntrPol;
604         u32 IntrOnAny;
605         u8 Bank;
606         u8 PinNumber;
607         u8 IrqType;
608
609         Xil_AssertNonvoid(InstancePtr != NULL);
610         Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
611         Xil_AssertNonvoid(Pin < XGPIOPS_DEVICE_MAX_PIN_NUM);
612
613         /*
614          * Get the Bank number and Pin number within the bank.
615          */
616         XGpioPs_GetBankPin(Pin, &Bank, &PinNumber);
617
618         IntrType = XGpioPs_ReadReg(InstancePtr->GpioConfig.BaseAddr,
619                                     ((Bank) * XGPIOPS_REG_MASK_OFFSET) +
620                                     XGPIOPS_INTTYPE_OFFSET) & PinNumber;
621
622         IntrPol = XGpioPs_ReadReg(InstancePtr->GpioConfig.BaseAddr,
623                                    ((Bank) * XGPIOPS_REG_MASK_OFFSET) +
624                                    XGPIOPS_INTPOL_OFFSET) & PinNumber;
625
626         IntrOnAny = XGpioPs_ReadReg(InstancePtr->GpioConfig.BaseAddr,
627                                      ((Bank) * XGPIOPS_REG_MASK_OFFSET) +
628                                      XGPIOPS_INTANY_OFFSET) & PinNumber;
629
630         if (IntrType == 1) {
631                 if (IntrOnAny == 1) {
632                         IrqType = XGPIOPS_IRQ_TYPE_EDGE_BOTH;
633                 } else if (IntrPol == 1) {
634                         IrqType = XGPIOPS_IRQ_TYPE_EDGE_RISING;
635                 } else {
636                         IrqType = XGPIOPS_IRQ_TYPE_EDGE_FALLING;
637                 }
638         } else {
639                 if (IntrPol == 1) {
640                         IrqType = XGPIOPS_IRQ_TYPE_LEVEL_HIGH;
641                 } else {
642                         IrqType = XGPIOPS_IRQ_TYPE_LEVEL_LOW;
643                 }
644         }
645
646         return IrqType;
647 }
648
649 /*****************************************************************************/
650 /**
651 *
652 * This function sets the status callback function. The callback function is
653 * called by the  XGpioPs_IntrHandler when an interrupt occurs.
654 *
655 * @param        InstancePtr is a pointer to the XGpioPs instance.
656 * @param        CallBackRef is the upper layer callback reference passed back
657 *               when the callback function is invoked.
658 * @param        FuncPtr is the pointer to the callback function.
659 *
660 *
661 * @return       None.
662 *
663 * @note         The handler is called within interrupt context, so it should do
664 *               its work quickly and queue potentially time-consuming work to a
665 *               task-level thread.
666 *
667 ******************************************************************************/
668 void XGpioPs_SetCallbackHandler(XGpioPs *InstancePtr, void *CallBackRef,
669                                  XGpioPs_Handler FuncPtr)
670 {
671         Xil_AssertVoid(InstancePtr != NULL);
672         Xil_AssertVoid(FuncPtr != NULL);
673         Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
674
675         InstancePtr->Handler = FuncPtr;
676         InstancePtr->CallBackRef = CallBackRef;
677 }
678
679 /*****************************************************************************/
680 /**
681 *
682 * This function is the interrupt handler for GPIO interrupts.It checks the
683 * interrupt status registers of all the banks to determine the actual bank in
684 * which an interrupt has been triggered. It then calls the upper layer callback
685 * handler set by the function XGpioPs_SetBankHandler(). The callback is called
686 * when an interrupt
687 *
688 * @param        InstancePtr is a pointer to the XGpioPs instance.
689 *
690 * @return       None.
691 *
692 * @note         This function does not save and restore the processor context
693 *               such that the user must provide this processing.
694 *
695 ******************************************************************************/
696 void XGpioPs_IntrHandler(XGpioPs *InstancePtr)
697 {
698         u8 Bank;
699         u32 IntrStatus;
700         u32 IntrEnabled;
701
702         Xil_AssertVoid(InstancePtr != NULL);
703         Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
704
705         for (Bank = 0; Bank < XGPIOPS_MAX_BANKS; Bank++) {
706                 IntrStatus = XGpioPs_IntrGetStatus(InstancePtr, Bank);
707                 if (IntrStatus != 0) {
708                         IntrEnabled = XGpioPs_IntrGetEnabled(InstancePtr,
709                                                               Bank);
710                         XGpioPs_IntrClear(InstancePtr, Bank,
711                                            IntrStatus & IntrEnabled);
712                         InstancePtr->Handler((void *)InstancePtr->
713                                              CallBackRef, Bank,
714                                              (IntrStatus & IntrEnabled));
715                 }
716         }
717 }
718
719 /*****************************************************************************/
720 /**
721 *
722 * This is a stub for the status callback. The stub is here in case the upper
723 * layers do not set the handler.
724 *
725 * @param        CallBackRef is a pointer to the upper layer callback reference
726 * @param        Bank is the GPIO Bank in which an interrupt occurred.
727 * @param        Status is the Interrupt status of the GPIO bank.
728 *
729 * @return       None.
730 *
731 * @note         None.
732 *
733 ******************************************************************************/
734 void StubHandler(void *CallBackRef, int Bank, u32 Status)
735 {
736         (void) CallBackRef;
737         (void) Bank;
738         (void) Status;
739
740         Xil_AssertVoidAlways();
741 }