#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <termios.h>
#include <errno.h>
#include <fcntl.h>
#include <sys/ioctl.h>


#include "pcie_rst.h"

static GPIO_ATTR_ST gpios[] = {
	/*{"IMX_GPIO5_4", IMX_GPIO5_4}, */
	{"IMX_GPIO5_6",IMX_GPIO5_6},
	{"IMX_GPIO5_1",IMX_GPIO5_1},
	{"IMX_GPIO5_2",IMX_GPIO5_2},
	{"IMX_GPIO5_7",IMX_GPIO5_7},
};

static char *get_gpio_name(int gpio_index)
{
    int i;
    
    for (i = 0; i < ARRAY_SIZE(gpios); i++) 
    {
        if (gpio_index == gpios[i].gpio_index) 
        {
            return gpios[i].gpio_name;
        }
    }

    return NULL;
}

static int gpio_set_level(int fd, 	IOCTL_GPIO_ARG_ST *parg)
{
    int i;
    int ret = RET_SUCCESS;

    if (NULL == parg)
	{
        DEBUG_ERROR("Invalid argument!\n"); 
        return RET_FAILED;
	}

	if (NULL == get_gpio_name(parg->gpio_index))
	{
        DEBUG_ERROR("Invalid argument!\n"); 
        return RET_FAILED;
	}

	if ((GPIO_LEVEL_LOW != parg->gpio_level) &&
	    (GPIO_LEVEL_HIGHT != parg->gpio_level))
    {
        DEBUG_ERROR("Invalid argument!\n"); 
        return RET_FAILED;
	}
	
    ret = ioctl(fd, IOCTL_GPIO_LEVEL_SET, parg);
    if (0 != ret)
    {
        //ret = RET_FAILED;
    	DEBUG_ERROR("gpio '%s' 'IOCTL_GPIO_LEVEL_SET' '%d' error!errno = %d\n", 
    	            get_gpio_name(parg->gpio_index), parg->gpio_level, ret);
    }
    else
    {
        DEBUG_INFO("set gpio '%s' level '%d'\n", get_gpio_name(parg->gpio_index), parg->gpio_level);
    }

   return ret;
}

static void pcie_reset(int fd)
{
	IOCTL_GPIO_ARG_ST arg;
	
    memset (&arg, 0, sizeof(arg));	
	arg.gpio_index = IMX_GPIO5_6; 
    arg.gpio_level = GPIO_LEVEL_LOW;
	gpio_set_level(fd, &arg); 
	usleep(200000);
	
	arg.gpio_level = GPIO_LEVEL_HIGHT;
	gpio_set_level(fd, &arg); 
	usleep(500000);
}

int main(int argc, char *argv[])
{
	int i;
	int index;
	int fd_gpio = -1;

	fd_gpio = open(DEV_GPIO, O_RDWR);
	if (fd_gpio < 0) 
    {
		DEBUG_ERROR("open gpio device %s error!\n", DEV_GPIO);
		return RET_FAILED;
	}
	
	pcie_reset(fd_gpio);
	close(fd_gpio);

	return 0;
}

