/*
 * arch/arm/mach-pnx4008/gpio.c
 *
 * PNX4008 GPIO driver
 *
 * Author: Dmitry Chigirev <source@mvista.com>
 *
 * Based on reference code by Iwo Mergler and Z.Tabaaloute from Philips:
 * Copyright (c) 2005 Koninklijke Philips Electronics N.V.
 *
 * 2005 (c) MontaVista Software, Inc. This file is licensed under
 * the terms of the GNU General Public License version 2. This program
 * is licensed "as is" without any warranty of any kind, whether express
 * or implied.
 */

#include <linux/config.h>
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <asm/semaphore.h>
#include <asm/io.h>
#include <asm/arch/platform.h>
#include <asm/arch/gpio.h>

/* register definitions */
#define PIO_VA_BASE	IO_ADDRESS(PNX4008_PIO_BASE)

#define PIO_INP_STATE	(0x00U)
#define PIO_OUTP_SET	(0x04U)
#define PIO_OUTP_CLR	(0x08U)
#define PIO_OUTP_STATE	(0x0CU)
#define PIO_DRV_SET	(0x10U)
#define PIO_DRV_CLR	(0x14U)
#define PIO_DRV_STATE	(0x18U)
#define PIO_SDINP_STATE	(0x1CU)
#define PIO_SDOUTP_SET	(0x20U)
#define PIO_SDOUTP_CLR	(0x24U)
#define PIO_MUX_SET	(0x28U)
#define PIO_MUX_CLR	(0x2CU)
#define PIO_MUX_STATE	(0x30U)

static inline void gpio_lock(void)
{
	local_irq_disable();
}

static inline void gpio_unlock(void)
{
	local_irq_enable();
}

/* Inline functions */
static inline int gpio_read_bit(u32 reg, int gpio)
{
	u32 bit, val;
	int ret = -EFAULT;

	if (gpio < 0)
		goto out;

	bit = GPIO_BIT(gpio);
	if (bit) {
		val = __raw_readl(PIO_VA_BASE + reg);
		ret = (val & bit) ? 1 : 0;
	}
out:
	return ret;
}

static inline int gpio_set_bit(u32 reg, int gpio)
{
	u32 bit, val;
	int ret = -EFAULT;

	if (gpio < 0)
		goto out;

	bit = GPIO_BIT(gpio);
	if (bit) {
		val = __raw_readl(PIO_VA_BASE + reg);
		val |= bit;
		__raw_writel(val, PIO_VA_BASE + reg);
		ret = 0;
	}
out:
	return ret;
}

/* Very simple access control, bitmap for allocated/free */
static unsigned long access_map[4];
#define INP_INDEX	0
#define OUTP_INDEX	1
#define GPIO_INDEX	2
#define MUX_INDEX	3

/*GPIO to Input Mapping */
static short gpio_to_inp_map[32] = {
	-1, -1, -1, -1, -1, -1, -1, -1,
	-1, -1, -1, -1, -1, -1, -1, -1,
	-1, -1, -1, -1, -1, -1, -1, -1,
	-1, 10, 11, 12, 13, 14, 24, -1
};

/*GPIO to Mux Mapping */
static short gpio_to_mux_map[32] = {
	-1, -1, -1, -1, -1, -1, -1, -1,
	-1, -1, -1, -1, -1, -1, -1, -1,
	-1, -1, -1, -1, -1, -1, -1, -1,
	-1, -1, -1, 0, 1, 4, 5, -1
};

/*Output to Mux Mapping */
static short outp_to_mux_map[32] = {
	-1, -1, -1, 6, -1, -1, -1, -1,
	-1, -1, -1, -1, -1, -1, -1, -1,
	-1, -1, -1, -1, -1, 2, -1, -1,
	-1, -1, -1, -1, -1, -1, -1, -1
};

int pnx4008_gpio_register_pin(unsigned short pin)
{
	unsigned long bit = GPIO_BIT(pin);
	int ret = -EBUSY;	/* Already in use */

	gpio_lock();

	if (GPIO_ISBID(pin)) {
		if (access_map[GPIO_INDEX] & bit)
			goto out;
		access_map[GPIO_INDEX] |= bit;

	} else if (GPIO_ISRAM(pin)) {
		if (access_map[GPIO_INDEX] & bit)
			goto out;
		access_map[GPIO_INDEX] |= bit;

	} else if (GPIO_ISMUX(pin)) {
		if (access_map[MUX_INDEX] & bit)
			goto out;
		access_map[MUX_INDEX] |= bit;

	} else if (GPIO_ISOUT(pin)) {
		if (access_map[OUTP_INDEX] & bit)
			goto out;
		access_map[OUTP_INDEX] |= bit;

	} else if (GPIO_ISIN(pin)) {
		if (access_map[INP_INDEX] & bit)
			goto out;
		access_map[INP_INDEX] |= bit;
	} else
		goto out;
	ret = 0;

out:
	gpio_unlock();
	return ret;
}

EXPORT_SYMBOL(pnx4008_gpio_register_pin);

int pnx4008_gpio_unregister_pin(unsigned short pin)
{
	unsigned long bit = GPIO_BIT(pin);
	int ret = -EFAULT;	/* Not registered */

	gpio_lock();

	if (GPIO_ISBID(pin)) {
		if (~access_map[GPIO_INDEX] & bit)
			goto out;
		access_map[GPIO_INDEX] &= ~bit;
	} else if (GPIO_ISRAM(pin)) {
		if (~access_map[GPIO_INDEX] & bit)
			goto out;
		access_map[GPIO_INDEX] &= ~bit;
	} else if (GPIO_ISMUX(pin)) {
		if (~access_map[MUX_INDEX] & bit)
			goto out;
		access_map[MUX_INDEX] &= ~bit;
	} else if (GPIO_ISOUT(pin)) {
		if (~access_map[OUTP_INDEX] & bit)
			goto out;
		access_map[OUTP_INDEX] &= ~bit;
	} else if (GPIO_ISIN(pin)) {
		if (~access_map[INP_INDEX] & bit)
			goto out;
		access_map[INP_INDEX] &= ~bit;
	} else
		goto out;
	ret = 0;

out:
	gpio_unlock();
	return ret;
}

EXPORT_SYMBOL(pnx4008_gpio_unregister_pin);

unsigned long pnx4008_gpio_read_pin(unsigned short pin)
{
	unsigned long ret = -EFAULT;
	int gpio = GPIO_BIT_MASK(pin);
	gpio_lock();
	if (GPIO_ISOUT(pin)) {
		ret = gpio_read_bit(PIO_OUTP_STATE, gpio);
	} else if (GPIO_ISRAM(pin)) {
		if (gpio_read_bit(PIO_DRV_STATE, gpio) == 0) {
			ret = gpio_read_bit(PIO_SDINP_STATE, gpio);
		}
	} else if (GPIO_ISBID(pin)) {
		ret = gpio_read_bit(PIO_DRV_STATE, gpio);
		if (ret > 0)
			ret = gpio_read_bit(PIO_OUTP_STATE, gpio);
		else if (ret == 0)
			ret =
			    gpio_read_bit(PIO_INP_STATE, gpio_to_inp_map[gpio]);
	} else if (GPIO_ISIN(pin)) {
		ret = gpio_read_bit(PIO_INP_STATE, gpio);
	}
	gpio_unlock();
	return ret;
}

EXPORT_SYMBOL(pnx4008_gpio_read_pin);

/* Write Value to output */
int pnx4008_gpio_write_pin(unsigned short pin, int output)
{
	int gpio = GPIO_BIT_MASK(pin);
	int ret = -EFAULT;

	gpio_lock();
	if (GPIO_ISOUT(pin)) {
		printk( "writing '%x' to '%x'\n",
				gpio, output ? PIO_OUTP_SET : PIO_OUTP_CLR );
		ret = gpio_set_bit(output ? PIO_OUTP_SET : PIO_OUTP_CLR, gpio);
	} else if (GPIO_ISRAM(pin)) {
		if (gpio_read_bit(PIO_DRV_STATE, gpio) > 0)
			ret = gpio_set_bit(output ? PIO_SDOUTP_SET :
					   PIO_SDOUTP_CLR, gpio);
	} else if (GPIO_ISBID(pin)) {
		if (gpio_read_bit(PIO_DRV_STATE, gpio) > 0)
			ret = gpio_set_bit(output ? PIO_OUTP_SET :
					   PIO_OUTP_CLR, gpio);
	}
	gpio_unlock();
	return ret;
}

EXPORT_SYMBOL(pnx4008_gpio_write_pin);

/* Value = 1 : Set GPIO pin as output */
/* Value = 0 : Set GPIO pin as input */
int pnx4008_gpio_set_pin_direction(unsigned short pin, int output)
{
	int gpio = GPIO_BIT_MASK(pin);
	int ret = -EFAULT;

	gpio_lock();
	if (GPIO_ISBID(pin) || GPIO_ISRAM(pin)) {
		ret = gpio_set_bit(output ? PIO_DRV_SET : PIO_DRV_CLR, gpio);
	}
	gpio_unlock();
	return ret;
}

EXPORT_SYMBOL(pnx4008_gpio_set_pin_direction);

/* Read GPIO pin direction: 0= pin used as input, 1= pin used as output*/
int pnx4008_gpio_read_pin_direction(unsigned short pin)
{
	int gpio = GPIO_BIT_MASK(pin);
	int ret = -EFAULT;

	gpio_lock();
	if (GPIO_ISBID(pin) || GPIO_ISRAM(pin)) {
		ret = gpio_read_bit(PIO_DRV_STATE, gpio);
	}
	gpio_unlock();
	return ret;
}

EXPORT_SYMBOL(pnx4008_gpio_read_pin_direction);

/* Value = 1 : Set pin to muxed function  */
/* Value = 0 : Set pin as GPIO */
int pnx4008_gpio_set_pin_mux(unsigned short pin, int output)
{
	int gpio = GPIO_BIT_MASK(pin);
	int ret = -EFAULT;

	gpio_lock();
	if (GPIO_ISBID(pin)) {
		ret =
		    gpio_set_bit(output ? PIO_MUX_SET : PIO_MUX_CLR,
				 gpio_to_mux_map[gpio]);
	} else if (GPIO_ISOUT(pin)) {
		ret =
		    gpio_set_bit(output ? PIO_MUX_SET : PIO_MUX_CLR,
				 outp_to_mux_map[gpio]);
	} else if (GPIO_ISMUX(pin)) {
		ret = gpio_set_bit(output ? PIO_MUX_SET : PIO_MUX_CLR, gpio);
	}
	gpio_unlock();
	return ret;
}

EXPORT_SYMBOL(pnx4008_gpio_set_pin_mux);

/* Read pin mux function: 0= pin used as GPIO, 1= pin used for muxed function*/
int pnx4008_gpio_read_pin_mux(unsigned short pin)
{
	int gpio = GPIO_BIT_MASK(pin);
	int ret = -EFAULT;

	gpio_lock();
	if (GPIO_ISBID(pin)) {
		ret = gpio_read_bit(PIO_MUX_STATE, gpio_to_mux_map[gpio]);
	} else if (GPIO_ISOUT(pin)) {
		ret = gpio_read_bit(PIO_MUX_STATE, outp_to_mux_map[gpio]);
	} else if (GPIO_ISMUX(pin)) {
		ret = gpio_read_bit(PIO_MUX_STATE, gpio);
	}
	gpio_unlock();
	return ret;
}

EXPORT_SYMBOL(pnx4008_gpio_read_pin_mux);
