blob: 3b84532d87d8ce9a8653cb4cb2015bb814deb5a3 [file] [log] [blame]
#include <stdio.h>
#include <errno.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <string.h>
#include <fcntl.h>
#include "mbtk_log.h"
#include "ql/ql_gpio.h"
static int gpio_export(int gpio)
{
int index=0;
int file=-1;
int result =-1;
char pin_index_buffer[5]= {0};
char buffer[50];
memset(buffer,0,50);
sprintf(buffer,"/sys/class/gpio/gpio%d/direction", gpio);
if(access(buffer , F_OK) == 0)
{
LOGD("%d has export.", gpio);
return 0;
}
file = open("/sys/class/gpio/export",O_WRONLY);
if(file == -1)
{
LOGE("Open gpio export file fail.");
return -1;
}
memset(pin_index_buffer,0,5);
sprintf(pin_index_buffer,"%d", gpio);
result = write(file,pin_index_buffer,strlen(pin_index_buffer));
if(result < 0)
{
LOGE("Gpio[%d] export fail.", gpio);
close(file);
return -1;
}
close(file);
return 0;
}
static int gpio_unexport(int gpio)
{
int index=0;
int file=-1;
int result =-1;
char pin_index_buffer[5]= {0};
char buffer[50];
memset(buffer,0,50);
sprintf(buffer,"/sys/class/gpio/gpio%d/direction", gpio);
if(access(buffer , F_OK) == -1)
{
LOGD("%d not export.", gpio);
return 0;
}
file = open("/sys/class/gpio/unexport",O_WRONLY);
if(file == -1)
{
LOGE("Open gpio unexport file fail.");
return -1;
}
memset(pin_index_buffer,0,5);
sprintf(pin_index_buffer,"%d", gpio);
result=write(file,pin_index_buffer,strlen(pin_index_buffer));
if(result < 0)
{
close(file);
LOGE("Gpio[%d] unexport fail.", gpio);
return -1;
}
close(file);
return 0;
}
static int gpio_direct_get(int gpio, char *value, int value_size)
{
char buffer[50]= {0};
int file =-1;
int result =-1;
memset(buffer,0,50);
sprintf(buffer,"/sys/class/gpio/gpio%d/direction", gpio);
file = open(buffer, O_RDONLY);
if(file == -1)
{
LOGE("Open gpio[%d] direct fail.", gpio);
return -1;
}
memset(value, 0x0, value_size);
result = read(file,value,value_size);
if(result <= 0)
{
LOGE("Get gpio[%d] direct fail.", gpio);
close(file);
return -1;
}
close(file);
return 0;
}
static int gpio_direct_set(int gpio, char *value)
{
char buffer[50]= {0};
int file =-1;
int result =-1;
memset(buffer,0,50);
sprintf(buffer,"/sys/class/gpio/gpio%d/direction", gpio);
file = open(buffer, O_WRONLY);
if(file == -1)
{
LOGE("Open gpio[%d] direct fail.", gpio);
return -1;
}
result = write(file,value,strlen(value));
if(result != strlen(value))
{
LOGE("Set gpio[%d] direct fail.", gpio);
close(file);
return -1;
}
close(file);
return 0;
}
static int gpio_value_get(int gpio)
{
char buffer[50];
char path[10];
int file =-1;
int result =-1;
int value;
memset(path,0,50);
memset(buffer,0,10);
sprintf(path,"/sys/class/gpio/gpio%d/value", gpio);
file = open(path,O_RDONLY);
if(file == -1)
{
LOGE("Open gpio[%d] fail.", gpio);
return -1;
}
result = read(file,buffer,5);
if(result <= 0)
{
LOGE("Get gpio[%d] value fail", gpio);
close(file);
return -1;
}
close(file);
value = atoi(buffer);
return value;
}
static int gpio_value_set(int gpio, int value)
{
char buffer[50]= {0};
int file =-1;
int result =-1;
memset(buffer,0,50);
sprintf(buffer,"/sys/class/gpio/gpio%d/value", gpio);
file = open(buffer,O_WRONLY);
if(file == -1)
{
LOGE("Open gpio[%d] value fail.", gpio);
return -1;
}
if(value == 0) {
result = write(file,"0",1);
} else {
result = write(file,"1",1);
}
if(result != 1)
{
LOGE("Set gpio[%d] value fail.", gpio);
close(file);
return -1;
}
close(file);
return 0;
}
/*****************************************************************
* Function: Ql_GPIO_Init
*
* Description:
* This function enables the GPIO function of the specified pin,
* and initialize the configurations, including direction,
* level and pull selection.
*
* Parameters:
* pin_name:
* Pin name, one value of Enum_PinName.
* dir:
* The initial direction of GPIO, one value of Enum_PinDirection.
* level:
* The initial level of GPIO, one value of Enum_PinLevel.
* pull_sel:
* Pull selection, one value of Enum_PinPullSel.
* Return:
* RES_OK, this function succeeds.
* RES_IO_NOT_SUPPORT, the input GPIO is invalid.
* RES_IO_ERR, the function failed
* other place. For example this GPIO has been using as EINT.
*****************************************************************/
int Ql_GPIO_Init(Enum_PinName pin_name,
Enum_PinDirection dir,
Enum_PinLevel level,
Enum_PinPullSel pull_sel
)
{
if(gpio_export(pin_name))
{
LOGE("gpio_export() fail.");
return RES_IO_ERROR;
}
if(gpio_direct_set(pin_name, dir == PINDIRECTION_IN ? "in" : "out"))
{
LOGE("gpio_direct_set() fail.");
return RES_IO_ERROR;
}
if(gpio_value_set(pin_name, level))
{
LOGE("gpio_value_set() fail.");
return RES_IO_ERROR;
}
// No support pull mode now.
return RES_OK;
}
/*****************************************************************
* Function: Ql_GPIO_Base_Init
*
* Description:
* This function enables the GPIO function of the specified pin.
*
* Parameters:
* pin_name:
* Pin name, one value of Enum_PinName.
*
* Return:
* RES_OK, this function succeeds.
* RES_IO_NOT_SUPPORT, the input GPIO is invalid.
* RES_IO_ERR, the function failed
*****************************************************************/
int Ql_GPIO_Base_Init(Enum_PinName pin_name );
/*****************************************************************
* Function: Ql_GPIO_SetLevel
*
* Description:
* This function sets the level of the specified GPIO.
*
* Parameters:
* pin_name:
* Pin name, one value of Enum_PinName.
* level:
* The initial level of GPIO, one value of Enum_PinLevel.
* Return:
* RES_OK, this function succeeds.
* RES_IO_NOT_SUPPORT, the input GPIO is invalid.
* RES_IO_ERR, the function failed
* other place. For example this GPIO has been using as EINT.
*****************************************************************/
int Ql_GPIO_SetLevel(Enum_PinName pin_name, Enum_PinLevel level)
{
if(gpio_value_set(pin_name, level)) {
LOGE("gpio_value_set() fail.");
return RES_IO_ERROR;
} else {
return RES_OK;
}
}
/*****************************************************************
* Function: Ql_GPIO_GetLevel
*
* Description:
* This function gets the level of the specified GPIO.
*
* Parameters:
* pin_name:
* Pin name, one value of Enum_PinName.
* Return:
* The level value of the specified GPIO, which is
* nonnegative integer.
* RES_IO_NOT_SUPPORT, the input GPIO is invalid.
*****************************************************************/
int Ql_GPIO_GetLevel(Enum_PinName pin_name)
{
return gpio_value_get(pin_name);
}
/*****************************************************************
* Function: Ql_GPIO_SetDirection
*
* Description:
* This function sets the direction of the specified GPIO.
*
* Parameters:
* pin_name:
* Pin name, one value of Enum_PinName.
* dir:
* The initial direction of GPIO, one value of Enum_PinDirection.
* Return:
* RES_OK, this function succeeds.
* RES_IO_NOT_SUPPORT, the input GPIO is invalid.
* RES_IO_ERR, the function failed
* other place. For example this GPIO has been using as EINT.
*****************************************************************/
int Ql_GPIO_SetDirection(Enum_PinName pin_name, Enum_PinDirection dir)
{
if(gpio_direct_set(pin_name, dir == PINDIRECTION_IN ? "in" : "out")) {
LOGE("gpio_direct_set() fail.");
return RES_IO_ERROR;
} else {
return RES_OK;
}
}
/*****************************************************************
* Function: Ql_GPIO_GetDirection
*
* Description:
* This function gets the direction of the specified GPIO.
*
* Parameters:
* pin_name:
* Pin name, one value of Enum_PinName.
* Return:
* 0 INPUT
* 1 OUTPUT
* RES_IO_NOT_SUPPORT, the input GPIO is invalid.
* other place. For example this GPIO has been using as EINT.
*****************************************************************/
int Ql_GPIO_GetDirection(Enum_PinName pin_name)
{
char buff[10];
if(gpio_direct_get(pin_name, buff, 10)) {
LOGE("gpio_direct_get() fail.");
return RES_IO_NOT_SUPPORT;
} else {
if(strcmp(buff, "in") == 0) {
return PINDIRECTION_IN;
} else if(strcmp(buff, "out") == 0) {
return PINDIRECTION_OUT;
} else {
return RES_IO_NOT_SUPPORT;
}
}
}
/*****************************************************************
* Function: Ql_GPIO_SetPullSelection
*
* Description:
* This function sets the pull selection of the specified GPIO.
*
* Parameters:
* pin_name:
* Pin name, one value of Enum_PinName.
* Enum_PinPullSel:
* Pull selection, one value of Enum_PinPullSel.
* Return:
* RES_OK, this function succeeds.
* RES_IO_NOT_SUPPORT, the input GPIO is invalid.
* RES_IO_ERR, the function failed
* other place. For example this GPIO has been using as EINT.
*****************************************************************/
int Ql_GPIO_SetPullSelection(Enum_PinName pin_name, Enum_PinPullSel pull_sel);
/*****************************************************************
* Function: ql_gpio_get_pull_selection
*
* Description:
* This function gets the pull selection of the specified GPIO.
*
* Parameters:
* pin_name:
* Pin name, one value of Enum_PinName.
* Return:
* 0<<13 no pull
* 5<<13 pull down
* 6<<13 pull up
*****************************************************************/
int Ql_GPIO_GetPullSelection(Enum_PinName pin_name);
/*****************************************************************
* Function: Ql_GPIO_Uninit
*
* Description:
* This function releases the specified GPIO that was
* initialized by calling Ql_GPIO_Init() previously.
* After releasing, the GPIO can be used for other purpose.
* Parameters:
* pin_name:
* Pin name, one value of Enum_PinName.
* Return:
* RES_OK, this function succeeds.
* RES_IO_NOT_SUPPORT, the input GPIO is invalid.
* RES_IO_ERR, the function failed
* other place. For example this GPIO has been using as EINT.
*****************************************************************/
int Ql_GPIO_Uninit(Enum_PinName pin_name)
{
if(gpio_unexport(pin_name))
{
LOGE("gpio_unexport() fail.");
return RES_IO_ERROR;
}
return RES_OK;
}
//------------------------------------------------------------------------------
/*
* Function: Ql_EINT_Enable
*
* Description:
* Set the interrupt sense mode, and enable interrupt.
*
* Parameters:
* eint_pin_name:
* EINT pin name, one value of Enum_PinName that has
* the interrupt function.
*
* eint_type:
* Interrupt type, level-triggered or edge-triggered.
* Now, only edge-triggered interrupt is supported.
*
* eint_callback:
* call back function
*
* Return:
* RES_OK, this function succeeds.
* else failed to execute the function.
*/
//------------------------------------------------------------------------------
int Ql_EINT_Enable(Enum_PinName eint_pin_name, Enum_EintType eint_type, Ql_EINT_Callback eint_callback);
//------------------------------------------------------------------------------
/*
* Function: Ql_EINT_Disable
*
* Description:
* Disable the interrupt sense.
*
* Parameters:
* eint_pin_name:
* EINT pin name, one value of Enum_PinName that has
* the interrupt function.
*
* Return:
* RES_OK, this function succeeds.
* else failed to execute the function.
*/
//------------------------------------------------------------------------------
int Ql_EINT_Disable(Enum_PinName eint_pin_name);