1 /******************************************************************************
2 ** File Name: gpio_phy_v0.c *
3 ** Author: Steve.Zhan *
5 ** Copyright: 2010 Spreatrum, Incoporated. All Rights Reserved. *
6 ** Description: This file define the physical layer of I2C device. *
7 ******************************************************************************
9 ******************************************************************************
11 ** ------------------------------------------------------------------------- *
12 ** DATE NAME DESCRIPTION *
13 ** 07/28/2010 Steve.Zhan Create. *
14 ******************************************************************************/
16 /**---------------------------------------------------------------------------*
18 **---------------------------------------------------------------------------*/
19 #include "sci_types.h"
21 #include "chip_plf_export.h"
22 #include "gpio_drvapi.h"
23 #include "../gpio_phy.h"
24 #ifdef PLATFORM_SC6800H
25 #include "gpio_reg_v0.h"
27 /*lint -e30 -e502 -e26 -e63 */
28 /**---------------------------------------------------------------------------*
30 **---------------------------------------------------------------------------*/
32 #define GPI_DATA 0xFFFF
36 #define GPO_DATA 0xFFFF
40 #define GPIO_DATA 0xFFFF
44 #define GPI_DMSK 0xFFFF
48 #define GPO_TRI 0xFFFF
52 #define GPIO_DMSK 0xFFFF
60 #define GPIO_IE 0xFFFF
64 #define GPIO_DIR 0xFFFF
68 #define GPI_MIS 0xFFFF
72 #define GPIO_MIS 0xFFFF
80 #define GPIO_IC 0xFFFF
84 #define GPI_IEV 0xFFFF
88 #define GPIO_IS 0xFFFF
92 #define GPIO_IC 0xFFFF
96 #define GPIO_IBE 0xFFFF
100 #define GPI_0CTRL 0xFFFF
104 #define GPI_TRIG 0xFFFF
107 #ifndef GPI_DEBOUNCE_BIT
108 #define GPI_DEBOUNCE_BIT 255
112 #define GPIO_REG_SET CHIP_REG_SET
116 #define GPIO_REG32 REG32
120 #define GPIO_REG_AND CHIP_REG_AND
124 #define GPIO_REG_OR CHIP_REG_OR
127 /*****************************************************************************/
128 // Description: This function get gpio module base info.
129 // Dependency: Gpio_GetCfgSectionTable(uint32 *table)
130 // Author: Steve.Zhan
132 /*****************************************************************************/
133 /*lint -e{681} -e{737}*/
134 PUBLIC void GPIO_PHY_GetBaseInfo (uint32 gpio_id, GPIO_INFO_T *pGpio_info)
137 uint32 table_size = 0;
139 GPIO_SECTION_T *p_gpio_section_table = (GPIO_SECTION_T *) Gpio_GetCfgSectionTable (&table_size);
141 SCI_ASSERT (gpio_id < GPIO_MAX_PIN_NUM && table_size > 0);
144 pGpio_info->baseAddr = GpioCfg_GetBaseAddr (gpio_id);//lint !e527 eliminate pclint "e533" by steve.zhan
145 pGpio_info->bit_num = GpioCfg_GetBitNum (gpio_id);
147 for (i = 0; i < table_size; ++i)
149 if (p_gpio_section_table[i].gpxx_pagex_base == pGpio_info->baseAddr)
151 if (p_gpio_section_table[i].gpxx_pagex_size > pGpio_info->bit_num)
153 pGpio_info->gpio_type = p_gpio_section_table[i].gpxx_section_type;
161 pGpio_info->gpio_type = GPIO_SECTION_INVALID;
166 /*****************************************************************************/
167 // Description: This function get gpio data register addr.
171 /*****************************************************************************/
172 LOCAL BOOLEAN _GPIO_GetGpioDataRegAddr (GPIO_INFO_T *pGpio_info, uint32 *pOffsetAddr)
174 switch (pGpio_info->gpio_type)
176 case GPIO_SECTION_GPI:
177 *pOffsetAddr = GPI_DATA;
179 case GPIO_SECTION_GPO:
180 *pOffsetAddr = GPO_DATA;
182 case GPIO_SECTION_GPIO:
183 *pOffsetAddr = GPIO_DATA;
185 case GPIO_SECTION_INVALID:
186 GPIO_PRINT ( ("[GPIO_DRV]the GPIO_ID is Invalid in this chip"));
187 GPIO_SECTION_ASSERT (0);
198 /*****************************************************************************/
199 // Description: This function used to get the state of a gpio gpi gpo pin
200 // Author: Zhemin.Lin
201 // retread by: Steve.Zhan
203 /*****************************************************************************/
204 PUBLIC BOOLEAN GPIO_PHY_GetPinData (GPIO_INFO_T *pGpio_info)
206 uint32 offsetAddr = 0;
209 reg_addr = pGpio_info->baseAddr;
211 if (_GPIO_GetGpioDataRegAddr (pGpio_info, &offsetAddr))
213 reg_addr += offsetAddr;
214 return ( (GPIO_REG32 (reg_addr) & (1<<pGpio_info->bit_num)) ? SCI_TRUE : SCI_FALSE);
220 /*****************************************************************************/
221 // Description: This function used to get the state of a gpio pin
224 /*****************************************************************************/
225 PUBLIC void GPIO_PHY_SetPinData (GPIO_INFO_T *pGpio_info ,BOOLEAN b_on)
227 uint32 offsetAddr = 0;
229 BOOLEAN value = (b_on ? SCI_TRUE : SCI_FALSE);
231 reg_addr = pGpio_info->baseAddr;
233 _GPIO_GetGpioDataRegAddr (pGpio_info, &offsetAddr);
234 reg_addr += offsetAddr;
236 GPIO_REG_SET (reg_addr, ( (GPIO_REG32 (reg_addr) & ~ (1<<pGpio_info->bit_num)) |
237 (value<<pGpio_info->bit_num)));
241 /*****************************************************************************/
242 // Description: This function get gpio data Mask register addr.
246 /*****************************************************************************/
247 LOCAL BOOLEAN _GPIO_GetGpioDataMaskRegAddr (GPIO_INFO_T *pGpio_info, uint32 *pOffsetAddr)
249 switch (pGpio_info->gpio_type)
251 case GPIO_SECTION_GPI:
252 *pOffsetAddr = GPI_DMSK;
254 case GPIO_SECTION_GPO:
255 *pOffsetAddr = GPO_TRI;
257 case GPIO_SECTION_GPIO:
258 *pOffsetAddr = GPIO_DMSK;
260 case GPIO_SECTION_INVALID:
261 GPIO_PRINT ( ("[GPIO_DRV]the GPIO_ID is Invalid in this chip"));
262 GPIO_SECTION_ASSERT (0);
265 GPIO_PRINT ( ("[GPIO_DRV]the GPIO_ID is Invalid in this chip"));
267 return SCI_FALSE;//lint !e527, by steve.zhan
274 /*****************************************************************************/
275 // Description: This function used to know whether the gpio port is enabled.
277 /*****************************************************************************/
278 PUBLIC BOOLEAN GPIO_PHY_GetDataMask (GPIO_INFO_T *pGpio_info)
280 uint32 offsetAddr = 0;
283 reg_addr = pGpio_info->baseAddr;
285 if (_GPIO_GetGpioDataMaskRegAddr (pGpio_info, &offsetAddr))
287 reg_addr += offsetAddr;
288 return ( (GPIO_REG32 (reg_addr) & (1<<pGpio_info->bit_num)) ? SCI_TRUE : SCI_FALSE);
294 /*****************************************************************************/
295 // Description: This function used to know whether the gpio port is enabled.
298 /*****************************************************************************/
299 PUBLIC void GPIO_PHY_SetDataMask (GPIO_INFO_T *pGpio_info, BOOLEAN b_on)
301 BOOLEAN value = (b_on ? SCI_TRUE : SCI_FALSE);
303 uint32 offsetAddr = 0;
305 reg_addr = pGpio_info->baseAddr;
307 if (_GPIO_GetGpioDataMaskRegAddr (pGpio_info, &offsetAddr))
309 reg_addr += offsetAddr;
310 GPIO_REG_SET ( (reg_addr), ( (GPIO_REG32 (reg_addr) & ~ (1<<pGpio_info->bit_num)) |
311 (value<<pGpio_info->bit_num)));
317 LOCAL BOOLEAN _GPIO_GetGpioIntMaskAddr (GPIO_INFO_T *pGpio_info, uint32 *pOffsetAddr)
319 switch (pGpio_info->gpio_type)
321 case GPIO_SECTION_GPI:
322 *pOffsetAddr = GPI_IE;
324 case GPIO_SECTION_GPO:
325 GPIO_PRINT ( ("[GPIO_DRV]this opretion can not belong to GPO"));
328 case GPIO_SECTION_GPIO:
329 *pOffsetAddr = GPIO_IE;
332 case GPIO_SECTION_INVALID:
333 GPIO_PRINT ( ("[GPIO_DRV]the GPIO_ID is Invalid in this chip"));
334 // GPIO_SECTION_ASSERT (0);
346 /*****************************************************************************/
347 // Description: This function used to know whether the gpio int mask is enabled.
348 // Interrupt mask register, "1" corresponding pin is not masked.
349 // "0" corresponding pin interrupt is masked
350 // Author: Benjamin.Wang
351 // Retreat by: Steve.Zhan
352 // Note: SCI_FALSE - disable
354 /*****************************************************************************/
355 PUBLIC BOOLEAN GPIO_PHY_GetIntIsMask (GPIO_INFO_T *pGpio_info)
358 uint32 offsetAddr = 0;
360 reg_addr = pGpio_info->baseAddr;
362 if (_GPIO_GetGpioIntMaskAddr (pGpio_info, &offsetAddr))
364 reg_addr += offsetAddr;
365 return ( (GPIO_REG32 (reg_addr) & (1<<pGpio_info->bit_num)) ? SCI_TRUE : SCI_FALSE);
371 /*****************************************************************************/
372 // Description: This function used to Set GPIO IE. enable interrupt.
375 /*****************************************************************************/
376 PUBLIC void GPIO_PHY_SetIntMask (GPIO_INFO_T *pGpio_info)
378 BOOLEAN value = SCI_TRUE;
380 uint32 offsetAddr = 0;
382 reg_addr = pGpio_info->baseAddr;
384 if (_GPIO_GetGpioIntMaskAddr (pGpio_info, &offsetAddr))
386 reg_addr += offsetAddr;
387 GPIO_REG_SET (reg_addr, ( (GPIO_REG32 (reg_addr) & ~ (1<<pGpio_info->bit_num)) |
388 (value<<pGpio_info->bit_num)));
394 /*****************************************************************************/
395 // Description: This function used to Set GPIO IE. disable interrupt.
398 /*****************************************************************************/
399 PUBLIC void GPIO_PHY_CleanIntMask (GPIO_INFO_T *pGpio_info)
401 BOOLEAN value = SCI_FALSE;
403 uint32 offsetAddr = 0;
405 reg_addr = pGpio_info->baseAddr;
407 if (_GPIO_GetGpioIntMaskAddr (pGpio_info, &offsetAddr))
409 reg_addr += offsetAddr;
410 GPIO_REG_SET (reg_addr, ( (GPIO_REG32 (reg_addr) & ~ (1<<pGpio_info->bit_num)) |
411 (value<<pGpio_info->bit_num)));
418 /*****************************************************************************/
419 // Description: This function used to get the direction of a gpio pin
422 /*****************************************************************************/
423 PUBLIC BOOLEAN GPIO_PHY_GetDirection (GPIO_INFO_T *pGpio_info)
426 reg_addr = pGpio_info->baseAddr;
428 switch (pGpio_info->gpio_type)
430 case GPIO_SECTION_GPI:
433 case GPIO_SECTION_GPO:
436 case GPIO_SECTION_GPIO:
437 reg_addr += GPIO_DIR;
440 case GPIO_SECTION_INVALID:
441 GPIO_PRINT ( ("[GPIO_DRV]the GPIO_ID is Invalid in this chip"));
442 GPIO_SECTION_ASSERT (0);
450 return ( (GPIO_REG32 (reg_addr) & (1<<pGpio_info->bit_num)) ? SCI_TRUE : SCI_FALSE);
453 /*****************************************************************************/
454 // Description: This function used to set the direction of a gpio pin
457 /*****************************************************************************/
458 PUBLIC void GPIO_PHY_SetDirection (GPIO_INFO_T *pGpio_info, BOOLEAN directions)
460 BOOLEAN value = (directions ? SCI_TRUE : SCI_FALSE);
462 reg_addr = pGpio_info->baseAddr;
464 switch (pGpio_info->gpio_type)
466 case GPIO_SECTION_GPI:
470 GPIO_PRINT ( ("[GPIO_DRV]GPIO_SetDirection error"));
471 GPIO_SECTION_ASSERT (0);
476 case GPIO_SECTION_GPO:
480 GPIO_PRINT ( ("[GPIO_DRV]GPIO_SetDirection error"));
481 GPIO_SECTION_ASSERT (0);
486 case GPIO_SECTION_GPIO:
487 reg_addr += GPIO_DIR;
489 case GPIO_SECTION_INVALID:
490 GPIO_PRINT ( ("[GPIO_DRV]the GPIO_ID is Invalid in this chip"));
491 GPIO_SECTION_ASSERT (0);
499 GPIO_REG_SET (reg_addr, ( (GPIO_REG32 (reg_addr) & ~ (1<<pGpio_info->bit_num)) | (value<<pGpio_info->bit_num)));
504 /*****************************************************************************/
505 // Description: This function used to get the intr state of a gpio pin
506 // Author: Zhemin.Lin
507 // retread by: Yiyue.He
508 // Retreat by: Steve.Zhan
510 /*****************************************************************************/
511 PUBLIC BOOLEAN GPIO_PHY_GetIntState (GPIO_INFO_T *pGpio_info)
515 reg_addr = pGpio_info->baseAddr;
517 switch (pGpio_info->gpio_type)
519 case GPIO_SECTION_GPI:
522 case GPIO_SECTION_GPO:
523 GPIO_PRINT ( ("[GPIO_DRV]The corresponding reg of this GPIO_ID is a GPO! No Intr!"));
526 case GPIO_SECTION_GPIO:
527 reg_addr += GPIO_MIS;
529 case GPIO_SECTION_INVALID:
530 GPIO_PRINT ( ("[GPIO_DRV]the GPIO_ID is Invalid in this chip"));
531 GPIO_SECTION_ASSERT (0);
539 return ( (GPIO_REG32 (reg_addr) & (1<<pGpio_info->bit_num)) ? SCI_TRUE : SCI_FALSE);
542 /*****************************************************************************/
543 // Description: This function used to clear the given interrupt status bit.
544 // Author: Benjamin.Wang
545 // retread by: Yiyue.He
546 // Retreat by: Steve.Zhan
548 /*****************************************************************************/
549 PUBLIC void GPIO_PHY_ClearIntStatus (GPIO_INFO_T *pGpio_info)
551 BOOLEAN value = SCI_TRUE;
554 reg_addr = pGpio_info->baseAddr;
556 switch (pGpio_info->gpio_type)
558 case GPIO_SECTION_GPI:
561 case GPIO_SECTION_GPO:
562 GPIO_PRINT ( ("[GPIO_DRV]this opretion can not belong to GPO"));
564 case GPIO_SECTION_GPIO:
567 case GPIO_SECTION_INVALID:
568 GPIO_PRINT ( ("[GPIO_DRV]the GPIO_ID is Invalid in this chip"));
569 GPIO_SECTION_ASSERT (0);
577 GPIO_REG_SET (reg_addr, ( (GPIO_REG32 (reg_addr) & ~ (1<<pGpio_info->bit_num)) | (value <<pGpio_info->bit_num)));
580 /*****************************************************************************/
581 // Description: This function used to set gpio Interrupt sense type.
582 // Author: Benjamin.Wang
583 // Retreat by: Steve.Zhan
585 /*****************************************************************************/
587 PUBLIC void GPIO_PHY_SetInterruptSense (GPIO_INFO_T *pGpio_info, GPIO_INT_TYPE sensetype)
589 switch (pGpio_info->gpio_type)
591 case GPIO_SECTION_GPI:
595 case GPIO_INT_LEVEL_HIGH: // detect high level.
596 GPIO_REG_OR ( (pGpio_info->baseAddr + GPI_IEV), (0x1 << pGpio_info->bit_num));
599 case GPIO_INT_LEVEL_LOW: // detect low level.
600 GPIO_REG_AND ( (pGpio_info->baseAddr + GPI_IEV), ~ (0x1 << pGpio_info->bit_num));
603 case GPIO_INT_EDGES_BOTH: // detect the rising edges and falling edges.
604 case GPIO_INT_EDGES_RISING: // detect the rising edges.
605 case GPIO_INT_EDGES_FALLING:
608 GPIO_PRINT ( ("This Intr sense type is invalid for GPI. \n"));
615 case GPIO_SECTION_GPO:
616 GPIO_PRINT ( ("[GPIO_DRV]this opretion can not belong to GPO"));
617 GPIO_SECTION_ASSERT (0);
620 case GPIO_SECTION_GPIO:
624 case GPIO_INT_LEVEL_HIGH: // detect high level.
625 GPIO_REG_OR ( (pGpio_info->baseAddr + GPIO_IS), (0x1 << pGpio_info->bit_num));
626 GPIO_REG_AND ( (pGpio_info->baseAddr + GPIO_IBE), ~ (0x1 << pGpio_info->bit_num));
627 GPIO_REG_OR ( (pGpio_info->baseAddr + GPIO_IEV), (0x1 << pGpio_info->bit_num));
630 case GPIO_INT_LEVEL_LOW: // detect low level.
631 GPIO_REG_OR ( (pGpio_info->baseAddr + GPIO_IS), (0x1 << pGpio_info->bit_num));
632 GPIO_REG_AND ( (pGpio_info->baseAddr + GPIO_IBE), ~ (0x1 <<pGpio_info->bit_num));
633 GPIO_REG_AND ( (pGpio_info->baseAddr + GPIO_IEV), ~ (0x1 <<pGpio_info->bit_num));
636 case GPIO_INT_EDGES_BOTH: // detect the rising edges and falling edges.
637 GPIO_REG_AND ( (pGpio_info->baseAddr + GPIO_IS), ~ (0x1 << pGpio_info->bit_num));
638 GPIO_REG_OR ( (pGpio_info->baseAddr + GPIO_IBE), (0x1 << pGpio_info->bit_num));
639 GPIO_REG_AND ( (pGpio_info->baseAddr + GPIO_IEV), ~ (0x1 << pGpio_info->bit_num));
642 case GPIO_INT_EDGES_RISING: // detect the rising edges.
643 GPIO_REG_AND ( (pGpio_info->baseAddr + GPIO_IS), ~ (0x1 << pGpio_info->bit_num));
644 GPIO_REG_AND ( (pGpio_info->baseAddr + GPIO_IBE), ~ (0x1 << pGpio_info->bit_num));
645 GPIO_REG_OR ( (pGpio_info->baseAddr + GPIO_IEV), (0x1 << pGpio_info->bit_num));
648 case GPIO_INT_EDGES_FALLING:
649 GPIO_REG_AND ( (pGpio_info->baseAddr + GPIO_IS), ~ (0x1 << pGpio_info->bit_num));
650 GPIO_REG_AND ( (pGpio_info->baseAddr + GPIO_IBE), ~ (0x1 << pGpio_info->bit_num));
651 GPIO_REG_AND ( (pGpio_info->baseAddr + GPIO_IEV), ~ (0x1 << pGpio_info->bit_num));
655 GPIO_PRINT ( ("This operation is invalid. \n"));
659 case GPIO_SECTION_INVALID:
660 GPIO_PRINT ( ("[GPIO_DRV]the GPIO_ID is Invalid in this chip"));
661 GPIO_SECTION_ASSERT (0);
670 /*****************************************************************************/
671 // Description: This function used to set gpin Debounce time.
672 // Author: Steve.Zhan
674 /*****************************************************************************/
675 /*lint -e{737} -e{718}*/
676 PUBLIC void GPIO_PHY_SetGPIDebounce (GPIO_INFO_T *pGpio_info, uint8 debounce_period)
681 GPIO_SECTION_E *gpio_type = NULL;
683 gpio_type = Gpio_GetCfgDebounceGpioTable (&size);
685 for (i = 0; i< size ; ++i)
687 if ( (int) pGpio_info->gpio_type != (int) gpio_type[i])
699 GPIO_PRINT ( ("[GPIO_DRV]this opretion can not belong to SetGPIDebounce"));
703 reg_addr = pGpio_info->baseAddr;
705 reg_addr += (GPI_0CTRL+ (pGpio_info->bit_num<<2));
707 if (debounce_period >= 1)
709 GPIO_REG_OR (reg_addr, GPI_DEBOUNCE_BIT);
710 GPIO_REG_SET (reg_addr, (GPIO_REG32 (reg_addr) & 0xFF00) +debounce_period);
714 GPIO_REG_AND (reg_addr, ~GPI_DEBOUNCE_BIT); //bypass mode
719 /*****************************************************************************/
720 // Description: This function used to set gpi Interrupt Trigering
721 // Author: Steve.Zhan
723 /*****************************************************************************/
724 PUBLIC void GPIO_PHY_TrigGPIDetect (GPIO_INFO_T *pGpio_info)
726 BOOLEAN value=SCI_TRUE;
729 reg_addr = pGpio_info->baseAddr;
731 switch (pGpio_info->gpio_type)
733 case GPIO_SECTION_GPI:
734 reg_addr += GPI_TRIG;
737 case GPIO_SECTION_GPO:
738 case GPIO_SECTION_GPIO:
739 GPIO_PRINT ( ("[GPIO_DRV]this opretion can not belong to GPO/GPIO"));
742 case GPIO_SECTION_INVALID:
743 GPIO_PRINT ( ("[GPIO_DRV]the GPIO_ID is Invalid in this chip"));
744 GPIO_SECTION_ASSERT (0);
752 GPIO_REG_SET (reg_addr, ( (GPIO_REG32 (reg_addr) & ~ (1<<pGpio_info->bit_num)) | (value<<pGpio_info->bit_num)));
756 /*****************************************************************************/
757 // Description: This function used to Enable gpi Detect function
758 // Author: Steve.Zhan
760 /*****************************************************************************/
761 PUBLIC void GPIO_PHY_EnableGPIDetect (GPIO_INFO_T *pGpio_info)
763 switch (pGpio_info->gpio_type)
765 case GPIO_SECTION_GPI:
766 GPIO_PHY_SetIntMask (pGpio_info);
767 GPIO_PHY_TrigGPIDetect (pGpio_info);
769 case GPIO_SECTION_GPO:
770 case GPIO_SECTION_GPIO: