/*
 * arch/arm/mach-orion5x/gpio.c
 *
 * GPIO functions for Marvell Orion System On Chip
 *
 * Maintainer: Tzachi Perelstein <tzachi@marvell.com>
 *
 * 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/kernel.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/spinlock.h>
#include <linux/bitops.h>
#include <asm/gpio.h>
#include <asm/io.h>
#include <mach/orion5x.h>
#include "common.h"

static DEFINE_SPINLOCK(gpio_lock);
static unsigned long gpio_valid[BITS_TO_LONGS(GPIO_MAX)];
static const char *gpio_label[GPIO_MAX];  /* non null for allocated GPIOs */

void __init orion5x_gpio_set_valid(unsigned pin, int valid)
{
	if (valid)
		__set_bit(pin, gpio_valid);
	else
		__clear_bit(pin, gpio_valid);
}

/*
 * GENERIC_GPIO primitives
 */
int gpio_direction_input(unsigned pin)
{
	unsigned long flags;

	if (pin >= GPIO_MAX || !test_bit(pin, gpio_valid)) {
		pr_debug("%s: invalid GPIO %d\n", __func__, pin);
		return -EINVAL;
	}

	spin_lock_irqsave(&gpio_lock, flags);

	/*
	 * Some callers might have not used the gpio_request(),
	 * so flag this pin as requested now.
	 */
	if (!gpio_label[pin])
		gpio_label[pin] = "?";

	orion5x_setbits(GPIO_IO_CONF, 1 << pin);

	spin_unlock_irqrestore(&gpio_lock, flags);
	return 0;
}
EXPORT_SYMBOL(gpio_direction_input);

int gpio_direction_output(unsigned pin, int value)
{
	unsigned long flags;
	int mask;

	if (pin >= GPIO_MAX || !test_bit(pin, gpio_valid)) {
		pr_debug("%s: invalid GPIO %d\n", __func__, pin);
		return -EINVAL;
	}

	spin_lock_irqsave(&gpio_lock, flags);

	/*
	 * Some callers might have not used the gpio_request(),
	 * so flag this pin as requested now.
	 */
	if (!gpio_label[pin])
		gpio_label[pin] = "?";

	mask = 1 << pin;
	orion5x_clrbits(GPIO_BLINK_EN, mask);
	if (value)
		orion5x_setbits(GPIO_OUT, mask);
	else
		orion5x_clrbits(GPIO_OUT, mask);
	orion5x_clrbits(GPIO_IO_CONF, mask);

	spin_unlock_irqrestore(&gpio_lock, flags);
	return 0;
}
EXPORT_SYMBOL(gpio_direction_output);

int gpio_get_value(unsigned pin)
{
	int val, mask = 1 << pin;

	if (readl(GPIO_IO_CONF) & mask)
		val = readl(GPIO_DATA_IN) ^ readl(GPIO_IN_POL);
	else
		val = readl(GPIO_OUT);

	return val & mask;
}
EXPORT_SYMBOL(gpio_get_value);

void gpio_set_value(unsigned pin, int value)
{
	unsigned long flags;
	int mask = 1 << pin;

	spin_lock_irqsave(&gpio_lock, flags);

	orion5x_clrbits(GPIO_BLINK_EN, mask);
	if (value)
		orion5x_setbits(GPIO_OUT, mask);
	else
		orion5x_clrbits(GPIO_OUT, mask);

	spin_unlock_irqrestore(&gpio_lock, flags);
}
EXPORT_SYMBOL(gpio_set_value);

void orion5x_gpio_set_blink(unsigned pin, int blink)
{
	unsigned long flags;
	int mask = 1 << pin;

	spin_lock_irqsave(&gpio_lock, flags);

	orion5x_clrbits(GPIO_OUT, mask);
	if (blink)
		orion5x_setbits(GPIO_BLINK_EN, mask);
	else
		orion5x_clrbits(GPIO_BLINK_EN, mask);

	spin_unlock_irqrestore(&gpio_lock, flags);
}
EXPORT_SYMBOL(orion5x_gpio_set_blink);

int gpio_request(unsigned pin, const char *label)
{
	int ret = 0;
	unsigned long flags;

	if (pin >= GPIO_MAX || !test_bit(pin, gpio_valid)) {
		pr_debug("%s: invalid GPIO %d\n", __func__, pin);
		return -EINVAL;
	}

	spin_lock_irqsave(&gpio_lock, flags);

	if (gpio_label[pin]) {
		pr_debug("%s: GPIO %d already used as %s\n",
			 __func__, pin, gpio_label[pin]);
		ret = -EBUSY;
	} else
		gpio_label[pin] = label ? label : "?";

	spin_unlock_irqrestore(&gpio_lock, flags);
	return ret;
}
EXPORT_SYMBOL(gpio_request);

void gpio_free(unsigned pin)
{
	if (pin >= GPIO_MAX || !test_bit(pin, gpio_valid)) {
		pr_debug("%s: invalid GPIO %d\n", __func__, pin);
		return;
	}

	if (!gpio_label[pin])
		pr_warning("%s: GPIO %d already freed\n", __func__, pin);
	else
		gpio_label[pin] = NULL;
}
EXPORT_SYMBOL(gpio_free);

/* Debug helper */
void gpio_display(void)
{
	int i;

	for (i = 0; i < GPIO_MAX; i++) {
		printk(KERN_DEBUG "Pin-%d: ", i);

		if (!test_bit(i, gpio_valid)) {
			printk("non-GPIO\n");
		} else if (!gpio_label[i]) {
			printk("GPIO, free\n");
		} else {
			printk("GPIO, used by %s, ", gpio_label[i]);
			if (readl(GPIO_IO_CONF) & (1 << i)) {
				printk("input, active %s, level %s, edge %s\n",
				((readl(GPIO_IN_POL) >> i) & 1) ? "low" : "high",
				((readl(GPIO_LEVEL_MASK) >> i) & 1) ? "enabled" : "masked",
				((readl(GPIO_EDGE_MASK) >> i) & 1) ? "enabled" : "masked");
			} else {
				printk("output, val=%d\n", (readl(GPIO_OUT) >> i) & 1);
			}
		}
	}

	printk(KERN_DEBUG "MPP_0_7_CTRL (0x%08x) = 0x%08x\n",
				MPP_0_7_CTRL, readl(MPP_0_7_CTRL));
	printk(KERN_DEBUG "MPP_8_15_CTRL (0x%08x) = 0x%08x\n",
				MPP_8_15_CTRL, readl(MPP_8_15_CTRL));
	printk(KERN_DEBUG "MPP_16_19_CTRL (0x%08x) = 0x%08x\n",
				MPP_16_19_CTRL, readl(MPP_16_19_CTRL));
	printk(KERN_DEBUG "MPP_DEV_CTRL (0x%08x) = 0x%08x\n",
				MPP_DEV_CTRL, readl(MPP_DEV_CTRL));
	printk(KERN_DEBUG "GPIO_OUT (0x%08x) = 0x%08x\n",
				GPIO_OUT, readl(GPIO_OUT));
	printk(KERN_DEBUG "GPIO_IO_CONF (0x%08x) = 0x%08x\n",
				GPIO_IO_CONF, readl(GPIO_IO_CONF));
	printk(KERN_DEBUG "GPIO_BLINK_EN (0x%08x) = 0x%08x\n",
				GPIO_BLINK_EN, readl(GPIO_BLINK_EN));
	printk(KERN_DEBUG "GPIO_IN_POL (0x%08x) = 0x%08x\n",
				GPIO_IN_POL, readl(GPIO_IN_POL));
	printk(KERN_DEBUG "GPIO_DATA_IN (0x%08x) = 0x%08x\n",
				GPIO_DATA_IN, readl(GPIO_DATA_IN));
	printk(KERN_DEBUG "GPIO_LEVEL_MASK (0x%08x) = 0x%08x\n",
				GPIO_LEVEL_MASK, readl(GPIO_LEVEL_MASK));
	printk(KERN_DEBUG "GPIO_EDGE_CAUSE (0x%08x) = 0x%08x\n",
				GPIO_EDGE_CAUSE, readl(GPIO_EDGE_CAUSE));
	printk(KERN_DEBUG "GPIO_EDGE_MASK (0x%08x) = 0x%08x\n",
				GPIO_EDGE_MASK, readl(GPIO_EDGE_MASK));
}
