/*******************************************************************************
** Document: w747_gpio_function.c
** Copyright (c) 2004 R&D Center, Tailyn Communication Company, Ltd.  
** Created by: Chien Chung Lo
** Date: Dec. 6, 2004
** Description: Wintegra GPIO device function.
** Version: 0.1
*******************************************************************************/
#include <asm/io.h>

#include "w747_gpio_function.h"
#include "w747_host_bus.h"

//----------------------------------------------------------------------
//
//----------------------------------------------------------------------
int gpio_read(unsigned int gpio_pin)
{
	unsigned int value;
	
	if(gpio_pin < GPIO_C_BASE)
	{
		value = inl_p(W747_GPIO_GPVR_A_REG);
		value = (value >> gpio_pin) & 0x1;
		return value;
	}
	else if(gpio_pin >= GPIO_C_BASE && gpio_pin < GPIO_E_BASE)
	{
		value = inl_p(W747_GPIO_GPVR_C_REG);
		value = (value >> (gpio_pin - GPIO_C_BASE)) & 0x1;
		return value;
	}
	else if(gpio_pin >= GPIO_E_BASE && gpio_pin < MAX_GPIO_NUM)
	{
		value = inl_p(W747_GPIO_GPVR_E_REG);
		value = (value >> (gpio_pin - GPIO_E_BASE)) & 0x1;
		return value;
	}
	
	return -EINVAL;
}

//----------------------------------------------------------------------
//
//----------------------------------------------------------------------
int gpio_set(unsigned int gpio_pin)
{
	unsigned int value;
	
	if(gpio_pin >= GPIO_C_BASE && gpio_pin < GPIO_E_BASE)
	{
		value = inl_p(W747_GPIO_GPVR_C_REG);
		value = value | (unsigned int)(1 << (gpio_pin - GPIO_C_BASE));
		outl_p(value, W747_GPIO_GPVR_C_REG);
		return 0;
	}
	else if(gpio_pin >= GPIO_E_BASE && gpio_pin < MAX_GPIO_NUM)
	{
		value = inl_p(W747_GPIO_GPVR_E_REG);
		value = value | (unsigned int)(1 << (gpio_pin - GPIO_E_BASE));
		outl_p(value, W747_GPIO_GPVR_E_REG);
		return 0;	
	}
	
	return -EINVAL;	
}

//----------------------------------------------------------------------
//
//----------------------------------------------------------------------
int gpio_clr(unsigned int gpio_pin)
{
	unsigned int value;
	
	if(gpio_pin >= GPIO_C_BASE && gpio_pin < GPIO_E_BASE)
	{
		value = inl_p(W747_GPIO_GPVR_C_REG);
		value = value & (unsigned int)(~(1 << (gpio_pin - GPIO_C_BASE)));
		outl_p(value, W747_GPIO_GPVR_C_REG);
		return 0;
	}
	
	else if(gpio_pin >= GPIO_E_BASE && gpio_pin < MAX_GPIO_NUM)
	{
		value = inl_p(W747_GPIO_GPVR_E_REG);
		value = value & (unsigned int)(~(1 << (gpio_pin - GPIO_E_BASE)));
		outl_p(value, W747_GPIO_GPVR_E_REG);
		return 0;
	}
	
	return -EINVAL; // fail !!
}

