blob: 82d1e829ef85b65d0dd5aa4b73f8da4a2011a82a [file] [log] [blame]
/***********************************************************************
* Copyright (C) 2016, ZIXC Corporation.
*
* File Name: hal_gpio.c
* File Mark:
* Description:
* Others:
* Version: v1.0
* Author: zhangdongdong
* Date: 2015-07-31
*
* History 1:
* Date:
* Version:
* Author:
* Modification:
*
* History 2:
**********************************************************************/
/*************************************************************************
* Include files *
*************************************************************************/
#include <config.h>
#include "hal_gpio_v3.h"
#include <drvs_gpio.h>
/*GPIO*/
#define GPIO0_REG_BASE 0x0013D000
#define GPIO1_REG_BASE 0x0013E000
#define PINMUX_REG_BASE 0x01303000
#define PADCTRL_REG_BASE 0x0013c000
#define IO_CFG_REG_BASE (PADCTRL_REG_BASE+0x800)
#define EX_GPIO_INT_TOP_AP_CLEAR_REG (0x13a000+0x128)
#define EX_GPIO_INT_TOP_CP_CLEAR_REG (0x13a000+0x118)
#define EX_8INT1_CLEAR_REG (0x13a000+0x064)
/*************************************************************************
* Macro *
*************************************************************************/
#define GPIO0_MODULE_NUM 128
#define GPIO1_MODULE_NUM 28
#define GPIOPDD_REG0(gpio) (GPIO0_REG_BASE + ((gpio>>4) * 16) * 4)
#define RECV_REG0(gpio) (GPIO0_REG_BASE + ((gpio>>4) * 16 + 5) * 4)
#define SET1_SEND_REG0(gpio) (GPIO0_REG_BASE + ((gpio>>4) * 16 + 6) * 4)
#define SET0_SEND_REG0(gpio) (GPIO0_REG_BASE + ((gpio>>4) * 16 + 7) * 4)
#define SEND_REG0(gpio) (GPIO0_REG_BASE + ((gpio>>4) * 16 + 8) * 4)
#define GPIOPDD_REG1(gpio) (GPIO1_REG_BASE + (((gpio)>>4) * 16) * 4)
#define RECV_REG1(gpio) (GPIO1_REG_BASE + (((gpio)>>4) * 16 + 5) * 4)
#define SET1_SEND_REG1(gpio) (GPIO1_REG_BASE + (((gpio)>>4) * 16 + 6) * 4)
#define SET0_SEND_REG1(gpio) (GPIO1_REG_BASE + (((gpio)>>4) * 16 + 7) * 4)
#define SEND_REG1(gpio) (GPIO1_REG_BASE + (((gpio)>>4) * 16 + 8) * 4)
#define TOP_SEL_AON 0
#define TOP_SEL_PD 1
/**************************************************************************
* Types *
**************************************************************************/
/**************************************************************************
* Global Variable *
**************************************************************************/
extern UINT32 gGpioNumMax;
extern T_Gpio gGpioInfoTable[];
/**************************************************************************
* Function Prototypes *
**************************************************************************/
/**************************************************************************
* Function Defines *
**************************************************************************/
/**************************************************************************
* Functin: zDrvGpio_SetFunc
* Description: set the pin use ,used as GPIO or other module,when use for GPIO
* Parameters:
* Input:
* gpio_id: gpio id
* func_sel: sel pd or aon func
* val: pd or aon func val
* Output:
* NONE
* Returns:
* success or parameter fault
* Others:
* None.
**************************************************************************/
SINT32 zDrvGpio_SetFunc(UINT32 gpio_id, T_ZDrvGpio_FuncSel func_sel)
{
#if 1//ndef _FPGA_TEST
UINT32 i = 0;
UINT32 topFunc = (func_sel>>12)&0x1;
UINT32 l2Func = func_sel&0x3ff;
if((gpio_id != (func_sel>>24))||(MAX_GPIO_NUM < gpio_id)){
return -1;
}
for(i=0; i<gGpioNumMax; i++)
{
if(gpio_id == gGpioInfoTable[i].gpio)
break;
}
if(INVLID_ADDR != gGpioInfoTable[i].topFuncSel.regBase)
{
set_reg_bits(gGpioInfoTable[i].topFuncSel.regBase,
gGpioInfoTable[i].topFuncSel.offset,
gGpioInfoTable[i].topFuncSel.size,
topFunc);
}
if(TOP_SEL_AON == topFunc)
{
if(INVLID_ADDR != gGpioInfoTable[i].aonFuncSel.regBase)
{
set_reg_bits(gGpioInfoTable[i].aonFuncSel.regBase,
gGpioInfoTable[i].aonFuncSel.offset,
gGpioInfoTable[i].aonFuncSel.size,
l2Func);
}
}
else
{
if(INVLID_ADDR != gGpioInfoTable[i].pdFuncSel.regBase)
{
set_reg_bits(gGpioInfoTable[i].pdFuncSel.regBase,
gGpioInfoTable[i].pdFuncSel.offset,
gGpioInfoTable[i].pdFuncSel.size,
l2Func);
}
}
#endif
return 0;
}
/**************************************************************************
* Functin: zDrvGpio_PullUpDown
* Description: internal pull up or pull down
* Parameters:
* Input:
* gpio_id: gpio id
* value: pull up or down val
* Output:
* NONE
* Returns:
* success or parameter fault
* Others:
* None.
**************************************************************************/
SINT32 zDrvGpio_PullUpDown(UINT32 gpio_id, UINT32 val)
{
UINT32 i = 0;
if(MAX_GPIO_NUM < gpio_id){
return -1;
}
for(i=0; i<gGpioNumMax; i++)
{
if(gpio_id == gGpioInfoTable[i].gpio)
break;
}
if(INVLID_ADDR != gGpioInfoTable[i].ioCfg.regBase)
{
set_reg_bits(gGpioInfoTable[i].ioCfg.regBase,
gGpioInfoTable[i].ioCfg.offset,
gGpioInfoTable[i].ioCfg.size,
val);
}
else
return -1;
return 0;
}
/**************************************************************************
* Functin: zDrvGpio_SetDirection
* Description: set direction of gpio, in or out
* Parameters:
* Input:
* gpio_id: gpio id
* value: in or out.
* Output:
* NONE
* Returns:
* NONE
* Others:
* None.
**************************************************************************/
void zDrvGpio_SetDirection(UINT32 gpio_id, T_ZDrvGpio_IoDirection value)
{
UINT32 gpio_addr = 0;
UINT32 tmp = 0;
if(GPIO0_MODULE_NUM > gpio_id)
gpio_addr = GPIOPDD_REG0(gpio_id);
else
gpio_addr = GPIOPDD_REG1(gpio_id-GPIO0_MODULE_NUM);
tmp = get_reg_val(gpio_addr);
if(GPIO_IN == value)
tmp &= ~(0x1<<(gpio_id % 16));
else
tmp |= (0x1<<(gpio_id % 16));
set_reg_val(gpio_addr, tmp);
;
}
/**************************************************************************
* Functin: zDrvGpio_GetDirection
* Description: get direction
* Parameters:
* Input:
* gpio_id: gpio id
* Output:
* gpio input or output
* Returns:
*
* Others:
* None.
**************************************************************************/
T_ZDrvGpio_IoDirection zDrvGpio_GetDirection(UINT32 gpio_id)
{
UINT32 gpio_addr = 0;
UINT32 tmp = 0;
if(GPIO0_MODULE_NUM > gpio_id)
gpio_addr = GPIOPDD_REG0(gpio_id);
else
gpio_addr = GPIOPDD_REG1(gpio_id-GPIO0_MODULE_NUM);
tmp = get_reg_val(gpio_addr);
if((tmp >> (gpio_id % 16)) & 0x1)
return GPIO_OUT;
else
return GPIO_IN;
}
/**************************************************************************
* Functin: zDrvGpio_SetOutputValue
* Description: set output value
* Parameters:
* Input:
* gpio_id: gpio id
* value: high or low.
* Output:
* NONE
* Returns:
* success or parameter fault
* Others:
* None.
**************************************************************************/
void zDrvGpio_SetOutputValue(UINT32 gpio_id, T_ZDrvGpio_IoVal value)
{
UINT32 gpio_addr = 0;
UINT32 tmp = 0;
if(GPIO_LOW == value)
{
if(GPIO0_MODULE_NUM > gpio_id)
gpio_addr = SET0_SEND_REG0(gpio_id);
else
gpio_addr = SET0_SEND_REG1(gpio_id-GPIO0_MODULE_NUM);
tmp = (0x1<<(gpio_id % 16));
set_reg_val(gpio_addr, tmp);
}
if(GPIO_HIGH == value)
{
if(GPIO0_MODULE_NUM > gpio_id)
gpio_addr = SET1_SEND_REG0(gpio_id);
else
gpio_addr = SET1_SEND_REG1(gpio_id-GPIO0_MODULE_NUM);
tmp = (0x1<<(gpio_id % 16));
set_reg_val(gpio_addr, tmp);
}
}
/**************************************************************************
* Functin: zDrvGpio_GetOutputValue
* Description: get output value
* Parameters:
* Input:
* gpio_id: gpio id
* Output:
* output high or low
* Returns:
* NONE
* Others:
* None.
**************************************************************************/
T_ZDrvGpio_IoVal zDrvGpio_GetOutputValue(UINT32 gpio_id)
{
UINT32 gpio_addr = 0;
UINT32 tmp = 0;
if(GPIO0_MODULE_NUM > gpio_id)
gpio_addr = SEND_REG0(gpio_id);
else
gpio_addr = SEND_REG1(gpio_id-GPIO0_MODULE_NUM);
tmp = get_reg_val(gpio_addr);
if((tmp >> (gpio_id % 16)) & 0x1)
return GPIO_HIGH;
else
return GPIO_LOW;
}
/**************************************************************************
* Functin: zDrvGpio_GetInputValue
* Description: get input value
* Parameters:
* Input:
* gpio_id: gpio id
* Output:
* input high or low
* Returns:
* NONE
* Others:
* None.
**************************************************************************/
T_ZDrvGpio_IoVal zDrvGpio_GetInputValue(UINT32 gpio_id)
{
UINT32 gpio_addr = 0;
UINT32 tmp = 0;
if(GPIO0_MODULE_NUM > gpio_id)
gpio_addr = RECV_REG0(gpio_id);
else
gpio_addr = RECV_REG1(gpio_id-GPIO0_MODULE_NUM);
tmp = get_reg_val(gpio_addr);
if((tmp >> (gpio_id % 16)) & 0x1)
return GPIO_HIGH;
else
return GPIO_LOW;
}
void gpio_reset(void)
{
unsigned int i=0;
//gpio0~1
for(i=0;i<8;i++)
{
if(i == 1) { //v3 pshold1: gpio24
reg32(GPIO0_REG_BASE + 0x40 *i + 0x00) &=0x0100;
reg32(GPIO0_REG_BASE + 0x40 *i + 0x18) &=0x0100;
reg32(GPIO0_REG_BASE + 0x40 *i + 0x1c) &=0x0100;
reg32(GPIO0_REG_BASE + 0x40 *i + 0x20) &=0x0100;
reg32(GPIO0_REG_BASE + 0x40 *i + 0x24) &=0x0100;
reg32(GPIO1_REG_BASE + 0x40 *i + 0x00)=0;
reg32(GPIO1_REG_BASE + 0x40 *i + 0x18)=0;
reg32(GPIO1_REG_BASE + 0x40 *i + 0x1c)=0;
reg32(GPIO1_REG_BASE + 0x40 *i + 0x20)=0;
reg32(GPIO1_REG_BASE + 0x40 *i + 0x24)=0;
}
else {
reg32(GPIO0_REG_BASE + 0x40 *i + 0x00)=0;
reg32(GPIO0_REG_BASE + 0x40 *i + 0x18)=0;
reg32(GPIO0_REG_BASE + 0x40 *i + 0x1c)=0;
reg32(GPIO0_REG_BASE + 0x40 *i + 0x20)=0;
reg32(GPIO0_REG_BASE + 0x40 *i + 0x24)=0;
reg32(GPIO1_REG_BASE + 0x40 *i + 0x00)=0;
reg32(GPIO1_REG_BASE + 0x40 *i + 0x18)=0;
reg32(GPIO1_REG_BASE + 0x40 *i + 0x1c)=0;
reg32(GPIO1_REG_BASE + 0x40 *i + 0x20)=0;
reg32(GPIO1_REG_BASE + 0x40 *i + 0x24)=0;
}
}
}
void pinmux_reset(void)
{
unsigned int i=0;
unsigned int tmp=0;
//pinmux
reg32(PINMUX_REG_BASE + 0x00)=0;
reg32(PINMUX_REG_BASE + 0x04)=0;
reg32(PINMUX_REG_BASE + 0x08)=0;
reg32(PINMUX_REG_BASE + 0x0c)=0x7ff;
for(i=4;i<14;i++) {
reg32(PINMUX_REG_BASE + 0x4* i)=0;
}
//padctrl fun_sel
reg32(PADCTRL_REG_BASE + 0x00)=0x00000500;
reg32(PADCTRL_REG_BASE + 0x04)=0x00000000;
reg32(PADCTRL_REG_BASE + 0x08)=0x00000000;
reg32(PADCTRL_REG_BASE + 0x0c)=0x00015400;
reg32(PADCTRL_REG_BASE + 0x10)=0x00000000;
reg32(PADCTRL_REG_BASE + 0x14)=0x00000000;
reg32(PADCTRL_REG_BASE + 0x18)=0x00000000;
reg32(PADCTRL_REG_BASE + 0x1c)=0x00007fff;
reg32(PADCTRL_REG_BASE + 0x20)=0x0000c030;
reg32(PADCTRL_REG_BASE + 0x24)=0x000003ff;
reg32(PADCTRL_REG_BASE + 0x28)=0x00007fc0;
reg32(PADCTRL_REG_BASE + 0x2c)=0x00000000;
reg32(PADCTRL_REG_BASE + 0x30)=0x00000000;
//padctrl io_cfg
tmp=reg32(IO_CFG_REG_BASE + 0x04); //pshold1-gpio24:bit[29:28]
tmp &= 0x30000000;
tmp |= 0x00d40000;
reg32(IO_CFG_REG_BASE + 0x04)=tmp;
reg32(IO_CFG_REG_BASE + 0x00)=0x00fffd4f;
//reg32(IO_CFG_REG_BASE+0x04)=0x10d40000;
reg32(IO_CFG_REG_BASE + 0x08)=0x557fff57;
reg32(IO_CFG_REG_BASE + 0x0c)=0x15554015;
reg32(IO_CFG_REG_BASE + 0x10)=0x38383858;
reg32(IO_CFG_REG_BASE + 0x14)=0x38583838;
reg32(IO_CFG_REG_BASE + 0x18)=0x38383838;
reg32(IO_CFG_REG_BASE + 0x1c)=0x155fd5ff;
reg32(IO_CFG_REG_BASE + 0x20)=0x00154ff7;
reg32(IO_CFG_REG_BASE + 0x24)=0x00555555;
reg32(IO_CFG_REG_BASE + 0x28)=0x00003858;
reg32(IO_CFG_REG_BASE + 0x2c)=0x05555555;
reg32(IO_CFG_REG_BASE + 0x30)=0x000000ad;
reg32(IO_CFG_REG_BASE + 0x34)=0x00000048;
reg32(IO_CFG_REG_BASE + 0x38)=0x00000001;
reg32(IO_CFG_REG_BASE + 0x3c)=0x00000058;
reg32(IO_CFG_REG_BASE + 0x40)=0x00585858;
}
void pcu_clear_8in1_Int(void)
{
reg32(EX_8INT1_CLEAR_REG) = 0xff<<8;//clear External_Gpio_Int_Top_Clear_Reg
reg32(EX_GPIO_INT_TOP_AP_CLEAR_REG) = 0x1;//clear External_Gpio_Int_Top_Clear_Reg
reg32(EX_GPIO_INT_TOP_CP_CLEAR_REG) = 0x1;//clear External_Gpio_Int_Top_Clear_Reg
}
int gpio_pad_init2rst(void)
{
gpio_reset();
pinmux_reset();
pcu_clear_8in1_Int();
return 0;
}