⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gpio.c

📁 linux下的SPI总线驱动程序
💻 C
字号:
#include <linux/autoconf.h>#include <asicRegs.h>#include <rtl8651_tblAsicDrv.h>#include "rtl_glue.h"#include "rtl_types.h"#include "rtl_errno.h"#include "assert.h"#include "spi.h"#include "gpio.h"/* * 0 -- less debug information * 5 -- more debug information */#define _GPIO_DEBUG_ 0enum 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,};static uint32 regGpioControl[] = {	PABCCNR, /* Port A */	PABCCNR, /* Port B */	PABCCNR, /* Port C */	PDEPTCR, /* Port D */	PDEPTCR, /* Port E */	PFGHICNR,/* Port F */	PFGHICNR,/* Port G */	PFGHICNR,/* Port H */	PFGHICNR,/* Port I */};static uint32 bitStartGpioControl[] ={	24, /* Port A */	16, /* Port B */	8,  /* Port C */	24, /* Port D */	16, /* Port E */	24, /* Port F */	16, /* Port G */	8,  /* Port H */	0,  /* Port I */};static uint32 regGpioDedicatePeripheralType[] = {	PABCPTCR, /* Port A */	PABCPTCR, /* Port B */	PABCPTCR, /* Port C */	PDEPTCR,  /* Port D */	PDEPTCR,  /* Port E */	0,        /* Port F */	0,        /* Port G */	0,        /* Port H */	0,        /* Port I */};static uint32 bitStartGpioDedicatePeripheralType[] ={	24, /* Port A */	16, /* Port B */	8,  /* Port C */	24, /* Port D */	16, /* Port E */	0,  /* Port F */	0,  /* Port G */	0,  /* Port H */	0,  /* Port I */};static uint32 regGpioDirection[] ={	PABCDIR, /* Port A */	PABCDIR, /* Port B */	PABCDIR, /* Port C */	PDEDIR,  /* Port D */	PDEDIR,  /* Port E */	PFGHIDIR,/* Port F */	PFGHIDIR,/* Port G */	PFGHIDIR,/* Port H */	PFGHIDIR,/* Port I */};static uint32 bitStartGpioDirection[] ={	24, /* Port A */	16, /* Port B */	8,  /* Port C */	24, /* Port D */	16, /* Port E */	24, /* Port F */	16, /* Port G */	8,  /* Port H */	0,  /* Port I */};static uint32 regGpioData[] ={	PABCDAT, /* Port A */	PABCDAT, /* Port B */	PABCDAT, /* Port C */	PDEDAT,  /* Port D */	PDEDAT,  /* Port E */	PFGHIDAT,/* Port F */	PFGHIDAT,/* Port G */	PFGHIDAT,/* Port H */	PFGHIDAT,/* Port I */};static uint32 bitStartGpioData[] ={	24, /* Port A */	16, /* Port B */	8,  /* Port C */	24, /* Port D */	16, /* Port E */	24, /* Port F */	16, /* Port G */	8,  /* Port H */	0,  /* Port I */};static uint32 regGpioInterruptStatus[] ={	PABCISR, /* Port A */	PABCISR, /* Port B */	PABCISR, /* Port C */	PDEISR,  /* Port D */	PDEISR,  /* Port E */	PFGHIISR,/* Port F */	PFGHIISR,/* Port G */	PFGHIISR,/* Port H */	PFGHIISR,/* Port I */};static uint32 bitStartGpioInterruptStatus[] ={	24, /* Port A */	16, /* Port B */	8,  /* Port C */	24, /* Port D */	16, /* Port E */	24, /* Port F */	16, /* Port G */	8,  /* Port H */	0,  /* Port I */};static uint32 regGpioInterruptEnable[] ={	PABIMR,/* Port A */	PABIMR,/* Port B */	PCIMR, /* Port C */	PDEIMR,/* Port D */	PDEIMR,/* Port E */	PFGIMR,/* Port F */	PFGIMR,/* Port G */	PHIIMR,/* Port H */	PHIIMR,/* 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@commThis 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@commThis 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.@commThis 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;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -