#include <net/rtl/rtl_types.h> #include <net/rtl/rtl_glue.h> #include "../AsicDriver/asicRegs.h" #include "gpio_8198.h" #define RTL_GPIO_PABDIR PABCD_DIR #define RTL_GPIO_PABDATA PABCD_DAT #define RTL_GPIO_PABCNR PABCD_CNR /* * 0 -- less debug information * 5 -- more debug information */ #define _GPIO_DEBUG_ 0 enum GPIO_FUNC { GPIO_FUNC_DEDICATE, GPIO_FUNC_DEDICATE_PERIPHERAL_TYPE, GPIO_FUNC_DIRECTION, GPIO_FUNC_DATA, GPIO_FUNC_INTERRUPT_STATUS, GPIO_FUNC_INTERRUPT_ENABLE, GPIO_FUNC_MAX, }; #define PABCCNR PABCD_CNR #define PDEPTCR PEFGH_CNR #define PFGHICNR PEFGH_CNR static uint32 regGpioControl[] = { PABCD_CNR, /* Port A */ PABCD_CNR, /* Port B */ PABCD_CNR, /* Port C */ PABCD_CNR, /* Port D */ PEFGH_CNR, /* Port E */ PEFGH_CNR,/* Port F */ PEFGH_CNR,/* Port G */ PEFGH_CNR,/* Port H */ }; static uint32 bitStartGpioControl[] = { 0, /* Port A */ 8, /* Port B */ 16, /* Port C */ 24, /* Port D */ 0, /* Port E */ 8, /* Port F */ 16, /* Port G */ 24, /* Port H */ 0, /* Port I */ }; static uint32 regGpioDedicatePeripheralType[] = { PABCD_PTYPE, /* Port A */ PABCD_PTYPE, /* Port B */ PABCD_PTYPE, /* Port C */ PABCD_PTYPE, /* Port D */ PEFGH_PTYPE, /* Port E */ PEFGH_PTYPE, /* Port F */ PEFGH_PTYPE, /* Port G */ PEFGH_PTYPE, /* Port H */ 0, /* Port I */ }; static uint32 bitStartGpioDedicatePeripheralType[] = { 0, /* Port A */ 8, /* Port B */ 16, /* Port C */ 24, /* Port D */ 0, /* Port E */ 8, /* Port F */ 16, /* Port G */ 24, /* Port H */ 0, /* Port I */ }; static uint32 regGpioDirection[] = { PABCD_DIR, /* Port A */ PABCD_DIR, /* Port B */ PABCD_DIR, /* Port C */ PABCD_DIR, /* Port D */ PEFGH_DIR, /* Port E */ PEFGH_DIR,/* Port F */ PEFGH_DIR,/* Port G */ PEFGH_DIR,/* Port H */ 0,/* Port I */ }; static uint32 bitStartGpioDirection[] = { 0, /* Port A */ 8, /* Port B */ 16, /* Port C */ 24, /* Port D */ 0, /* Port E */ 8, /* Port F */ 16, /* Port G */ 24, /* Port H */ 0, /* Port I */ }; static uint32 regGpioData[] = { PABCD_DAT, /* Port A */ PABCD_DAT, /* Port B */ PABCD_DAT, /* Port C */ PABCD_DAT, /* Port D */ PEFGH_DAT, /* Port E */ PEFGH_DAT,/* Port F */ PEFGH_DAT,/* Port G */ PEFGH_DAT,/* Port H */ 0,/* Port I */ }; static uint32 bitStartGpioData[] = { 0, /* Port A */ 8, /* Port B */ 16, /* Port C */ 24, /* Port D */ 0, /* Port E */ 8, /* Port F */ 16, /* Port G */ 24, /* Port H */ 0, /* Port I */ }; static uint32 regGpioInterruptStatus[] = { PABCD_ISR, /* Port A */ PABCD_ISR, /* Port B */ PABCD_ISR, /* Port C */ PABCD_ISR, /* Port D */ PEFGH_ISR, /* Port E */ PEFGH_ISR,/* Port F */ PEFGH_ISR,/* Port G */ PEFGH_ISR,/* Port H */ 0,/* Port I */ }; static uint32 bitStartGpioInterruptStatus[] = { 0, /* Port A */ 8, /* Port B */ 16, /* Port C */ 24, /* Port D */ 0, /* Port E */ 8, /* Port F */ 16, /* Port G */ 24, /* Port H */ 0, /* Port I */ }; static uint32 regGpioInterruptEnable[] = { PAB_IMR,/* Port A */ PAB_IMR,/* Port B */ PCD_IMR, /* Port C */ PCD_IMR,/* Port D */ PEF_IMR,/* Port E */ PEF_IMR,/* Port F */ PGH_IMR,/* Port G */ PGH_IMR,/* Port H */ 0,/* Port I */ }; static uint32 bitStartGpioInterruptEnable[] = { 16, /* Port A */ 0, /* Port B */ 16, /* Port C */ 16, /* Port D */ 0, /* Port E */ 16, /* Port F */ 0, /* Port G */ 16, /* Port H */ 0, /* Port I */ }; /* @func int32 | _getGpio | abstract GPIO registers @parm enum GPIO_FUNC | func | control/data/interrupt register @parm enum GPIO_PORT | port | GPIO port @parm uint32 | pin | pin number @rvalue uint32 | value @comm This function is for internal use only. You don't need to care what register address of GPIO is. This function abstracts these information. */ static uint32 _getGpio( enum GPIO_FUNC func, enum GPIO_PORT port, uint32 pin ) { assert( port < GPIO_PORT_MAX ); assert( func < GPIO_FUNC_MAX ); assert( pin < 8 ); #if _GPIO_DEBUG_ >= 4 rtlglue_printf("[%s():%d] func=%d port=%d pin=%d\n", __FUNCTION__, __LINE__, func, port, pin ); #endif switch( func ) { case GPIO_FUNC_DEDICATE: #if _GPIO_DEBUG_ >= 5 rtlglue_printf("[%s():%d] regGpioControl[port]=0x%08x bitStartGpioControl[port]=%d\n", __FUNCTION__, __LINE__, regGpioControl[port], bitStartGpioControl[port] ); #endif if ( REG32(regGpioControl[port]) & ( (uint32)1 << (pin+bitStartGpioControl[port]) ) ) return 1; else return 0; break; case GPIO_FUNC_DEDICATE_PERIPHERAL_TYPE: assert( port <= GPIO_PORT_E ); #if _GPIO_DEBUG_ >= 5 rtlglue_printf("[%s():%d] regGpioDedicatePeripheralType[port]=0x%08x bitStartGpioDedicatePeripheralType[port]=%d\n", __FUNCTION__, __LINE__, regGpioDedicatePeripheralType[port], bitStartGpioDedicatePeripheralType[port] ); #endif if ( REG32(regGpioDedicatePeripheralType[port]) & ( (uint32)1 << (pin+bitStartGpioDedicatePeripheralType[port]) ) ) return 1; else return 0; break; case GPIO_FUNC_DIRECTION: #if _GPIO_DEBUG_ >= 5 rtlglue_printf("[%s():%d] regGpioDirection[port]=0x%08x bitStartGpioDirection[port]=%d\n", __FUNCTION__, __LINE__, regGpioDirection[port], bitStartGpioDirection[port] ); #endif if ( REG32(regGpioDirection[port]) & ( (uint32)1 << (pin+bitStartGpioDirection[port]) ) ) return 1; else return 0; break; case GPIO_FUNC_DATA: #if _GPIO_DEBUG_ >= 5 rtlglue_printf("[%s():%d] regGpioData[port]=0x%08x bitStartGpioData[port]=%d\n", __FUNCTION__, __LINE__, regGpioData[port], bitStartGpioData[port] ); #endif if ( REG32(regGpioData[port]) & ( (uint32)1 << (pin+bitStartGpioData[port]) ) ) return 1; else return 0; break; case GPIO_FUNC_INTERRUPT_ENABLE: #if _GPIO_DEBUG_ >= 5 rtlglue_printf("[%s():%d] regGpioInterruptEnable[port]=0x%08x bitStartGpioInterruptEnable[port]=%d\n", __FUNCTION__, __LINE__, regGpioInterruptEnable[port], bitStartGpioInterruptEnable[port] ); #endif return ( REG32(regGpioInterruptEnable[port]) >> (pin*2+bitStartGpioInterruptEnable[port]) ) & (uint32)0x3; break; case GPIO_FUNC_INTERRUPT_STATUS: #if _GPIO_DEBUG_ >= 5 rtlglue_printf("[%s():%d] regGpioInterruptStatus[port]=0x%08x bitStartGpioInterruptEnable[port]=%d\n", __FUNCTION__, __LINE__, regGpioInterruptStatus[port], bitStartGpioInterruptStatus[port] ); #endif if ( REG32(regGpioInterruptStatus[port]) & ( (uint32)1 << (pin+bitStartGpioInterruptStatus[port]) ) ) return 1; else return 0; break; case GPIO_FUNC_MAX: assert( 0 ); break; } return 0xffffffff; } /* @func int32 | _setGpio | abstract GPIO registers @parm enum GPIO_FUNC | func | control/data/interrupt register @parm enum GPIO_PORT | port | GPIO port @parm uint32 | pin | pin number @parm uint32 | data | value @rvalue NONE @comm This function is for internal use only. You don't need to care what register address of GPIO is. This function abstracts these information. */ static void _setGpio( enum GPIO_FUNC func, enum GPIO_PORT port, uint32 pin, uint32 data ) { assert( port < GPIO_PORT_MAX ); assert( func < GPIO_FUNC_MAX ); assert( pin < 8 ); #if _GPIO_DEBUG_ >= 4 rtlglue_printf("[%s():%d] func=%d port=%d pin=%d data=%d\n", __FUNCTION__, __LINE__, func, port, pin, data ); #endif switch( func ) { case GPIO_FUNC_DEDICATE: #if _GPIO_DEBUG_ >= 5 rtlglue_printf("[%s():%d] regGpioControl[port]=0x%08x bitStartGpioControl[port]=%d\n", __FUNCTION__, __LINE__, regGpioControl[port], bitStartGpioControl[port] ); #endif if ( data ) REG32(regGpioControl[port]) |= (uint32)1 << (pin+bitStartGpioControl[port]); else REG32(regGpioControl[port]) &= ~((uint32)1 << (pin+bitStartGpioControl[port])); break; case GPIO_FUNC_DEDICATE_PERIPHERAL_TYPE: #if _GPIO_DEBUG_ >= 5 rtlglue_printf("[%s():%d] regGpioDedicatePeripheralType[port]=0x%08x bitStartGpioDedicatePeripheralType[port]=%d\n", __FUNCTION__, __LINE__, regGpioDedicatePeripheralType[port], bitStartGpioDedicatePeripheralType[port] ); #endif assert( port <= GPIO_PORT_E ); if ( data ) REG32(regGpioDedicatePeripheralType[port]) |= (uint32)1 << (pin+bitStartGpioDedicatePeripheralType[port]); else REG32(regGpioDedicatePeripheralType[port]) &= ~((uint32)1 << (pin+bitStartGpioDedicatePeripheralType[port])); break; case GPIO_FUNC_DIRECTION: #if _GPIO_DEBUG_ >= 5 rtlglue_printf("[%s():%d] regGpioDirection[port]=0x%08x bitStartGpioDirection[port]=%d\n", __FUNCTION__, __LINE__, regGpioDirection[port], bitStartGpioDirection[port] ); #endif if ( data ) REG32(regGpioDirection[port]) |= (uint32)1 << (pin+bitStartGpioDirection[port]); else REG32(regGpioDirection[port]) &= ~((uint32)1 << (pin+bitStartGpioDirection[port])); break; case GPIO_FUNC_DATA: #if _GPIO_DEBUG_ >= 5 rtlglue_printf("[%s():%d] regGpioData[port]=0x%08x bitStartGpioData[port]=%d\n", __FUNCTION__, __LINE__, regGpioData[port], bitStartGpioData[port] ); #endif if ( data ) REG32(regGpioData[port]) |= (uint32)1 << (pin+bitStartGpioData[port]); else REG32(regGpioData[port]) &= ~((uint32)1 << (pin+bitStartGpioData[port])); break; case GPIO_FUNC_INTERRUPT_ENABLE: #if _GPIO_DEBUG_ >= 5 rtlglue_printf("[%s():%d] regGpioInterruptEnable[port]=0x%08x bitStartGpioInterruptEnable[port]=%d\n", __FUNCTION__, __LINE__, regGpioInterruptEnable[port], bitStartGpioInterruptEnable[port] ); #endif REG32(regGpioInterruptEnable[port]) &= ~((uint32)0x3 << (pin*2+bitStartGpioInterruptEnable[port])); REG32(regGpioInterruptEnable[port]) |= (uint32)data << (pin*2+bitStartGpioInterruptEnable[port]); break; case GPIO_FUNC_INTERRUPT_STATUS: #if _GPIO_DEBUG_ >= 5 rtlglue_printf("[%s():%d] regGpioInterruptStatus[port]=0x%08x bitStartGpioInterruptStatus[port]=%d\n", __FUNCTION__, __LINE__, regGpioInterruptStatus[port], bitStartGpioInterruptStatus[port] ); #endif if ( data ) REG32(regGpioInterruptStatus[port]) |= (uint32)1 << (pin+bitStartGpioInterruptStatus[port]); else REG32(regGpioInterruptStatus[port]) &= ~((uint32)1 << (pin+bitStartGpioInterruptStatus[port])); break; case GPIO_FUNC_MAX: assert( 0 ); break; } } /* @func int32 | _rtl865x_initGpioPin | Initiate a specifed GPIO port. @parm uint32 | gpioId | The GPIO port that will be configured @parm enum GPIO_PERIPHERAL | dedicate | Dedicated peripheral type @parm enum GPIO_DIRECTION | direction | Data direction, in or out @parm enum GPIO_INTERRUPT_TYPE | interruptEnable | Interrupt mode @rvalue SUCCESS | success. @rvalue FAILED | failed. Parameter error. @comm This function is used to initialize GPIO port. */ int32 _rtl865x_initGpioPin( gpioID gpioId, enum GPIO_PERIPHERAL dedicate, enum GPIO_DIRECTION direction, enum GPIO_INTERRUPT_TYPE interruptEnable ) { uint32 port = GPIO_PORT( gpioId ); uint32 pin = GPIO_PIN( gpioId ); if ( port >= GPIO_PORT_MAX ) return FAILED; if ( pin >= 8 ) return FAILED; switch( dedicate ) { case GPIO_PERI_GPIO: _setGpio( GPIO_FUNC_DEDICATE, port, pin, 0 ); //if ( port == GPIO_PORT_D || port == GPIO_PORT_E ) /*change Mii interface IO as GPIO pins*/ // REG32( MISCCR ) |= P5_LINK_PCMCIA << P5_LINK_OFFSET; break; case GPIO_PERI_TYPE0: if( port > GPIO_PORT_E ) return FAILED; _setGpio( GPIO_FUNC_DEDICATE, port, pin, 1 ); _setGpio( GPIO_FUNC_DEDICATE_PERIPHERAL_TYPE, port, pin, 0 ); break; case GPIO_PERI_TYPE1: if( port > GPIO_PORT_E ) return FAILED; _setGpio( GPIO_FUNC_DEDICATE, port, pin, 1 ); _setGpio( GPIO_FUNC_DEDICATE_PERIPHERAL_TYPE, port, pin, 1 ); break; } _setGpio( GPIO_FUNC_DIRECTION, port, pin, direction ); _setGpio( GPIO_FUNC_INTERRUPT_ENABLE, port, pin, interruptEnable ); return SUCCESS; } /* @func int32 | _rtl865x_getGpioDataBit | Get the bit value of a specified GPIO ID. @parm uint32 | gpioId | GPIO ID @parm uint32* | data | Pointer to store return value @rvalue SUCCESS | success. @rvalue FAILED | failed. Parameter error. @comm */ int32 _rtl865x_getGpioDataBit( uint32 gpioId, uint32* pData ) { uint32 port = GPIO_PORT( gpioId ); uint32 pin = GPIO_PIN( gpioId ); if ( port >= GPIO_PORT_MAX ) return FAILED; if ( pin >= 8 ) return FAILED; if ( pData == NULL ) return FAILED; *pData = _getGpio( GPIO_FUNC_DATA, port, pin ); #if _GPIO_DEBUG_ >= 3 rtlglue_printf("[%s():%d] (port=%d,pin=%d)=%d\n", __FUNCTION__, __LINE__, port, pin, *pData ); #endif return SUCCESS; } /* @func int32 | _rtl865x_setGpioDataBit | Set the bit value of a specified GPIO ID. @parm uint32 | gpioId | GPIO ID @parm uint32 | data | Data to write @rvalue SUCCESS | success. @rvalue FAILED | failed. Parameter error. @comm */ int32 _rtl865x_setGpioDataBit( uint32 gpioId, uint32 data ) { uint32 port = GPIO_PORT( gpioId ); uint32 pin = GPIO_PIN( gpioId ); if ( port >= GPIO_PORT_MAX ) return FAILED; if ( pin >= 8 ) return FAILED; #if 0 if ( _getGpio( GPIO_FUNC_DIRECTION, port, pin ) == GPIO_DIR_IN ) return FAILED; /* read only */ #endif #if _GPIO_DEBUG_ >= 3 rtlglue_printf("[%s():%d] (port=%d,pin=%d)=%d\n", __FUNCTION__, __LINE__, port, pin, data ); #endif _setGpio( GPIO_FUNC_DATA, port, pin, data ); return SUCCESS; }