/*
 *  linux/arch/arm/mach-pxa/gpio.c
 *
 *  Generic PXA GPIO handling
 *
 *  Author:	Nicolas Pitre
 *  Created:	Jun 15, 2001
 *  Copyright:	MontaVista Software Inc.
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License version 2 as
 *  published by the Free Software Foundation.
 */

#include <linux/init.h>
#include <linux/module.h>
#include <linux/irq.h>
#include <linux/sysdev.h>
#include <linux/io.h>

#include <asm/gpio.h>
#include <mach/hardware.h>
#include <mach/pxa-regs.h>
#include <mach/pxa2xx-gpio.h>

#include "generic.h"

#define GPIO0_BASE	((void __iomem *)io_p2v(0x40E00000))
#define GPIO1_BASE	((void __iomem *)io_p2v(0x40E00004))
#define GPIO2_BASE	((void __iomem *)io_p2v(0x40E00008))
#define GPIO3_BASE	((void __iomem *)io_p2v(0x40E00100))

#define GPLR_OFFSET	0x00
#define GPDR_OFFSET	0x0C
#define GPSR_OFFSET	0x18
#define GPCR_OFFSET	0x24
#define GRER_OFFSET	0x30
#define GFER_OFFSET	0x3C
#define GEDR_OFFSET	0x48

struct pxa_gpio_chip {
	struct gpio_chip chip;
	void __iomem     *regbase;
};

int pxa_last_gpio;

#ifdef CONFIG_CPU_PXA26x
/* GPIO86/87/88/89 on PXA26x have their direction bits in GPDR2 inverted,
 * as well as their Alternate Function value being '1' for GPIO in GAFRx.
 */
static int __gpio_is_inverted(unsigned gpio)
{
	return cpu_is_pxa25x() && gpio > 85;
}
#else
#define __gpio_is_inverted(gpio)	(0)
#endif

/*
 * Configure pins for GPIO or other functions
 */
int pxa_gpio_mode(int gpio_mode)
{
	unsigned long flags;
	int gpio = gpio_mode & GPIO_MD_MASK_NR;
	int fn = (gpio_mode & GPIO_MD_MASK_FN) >> 8;
	int gafr;

	if (gpio > pxa_last_gpio)
		return -EINVAL;

	local_irq_save(flags);
	if (gpio_mode & GPIO_DFLT_LOW)
		GPCR(gpio) = GPIO_bit(gpio);
	else if (gpio_mode & GPIO_DFLT_HIGH)
		GPSR(gpio) = GPIO_bit(gpio);
	if (gpio_mode & GPIO_MD_MASK_DIR)
		GPDR(gpio) |= GPIO_bit(gpio);
	else
		GPDR(gpio) &= ~GPIO_bit(gpio);
	gafr = GAFR(gpio) & ~(0x3 << (((gpio) & 0xf)*2));
	GAFR(gpio) = gafr |  (fn  << (((gpio) & 0xf)*2));
	local_irq_restore(flags);

	return 0;
}
EXPORT_SYMBOL(pxa_gpio_mode);

static int pxa_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
{
	unsigned long        flags;
	u32                  mask = 1 << offset;
	u32                  value;
	struct pxa_gpio_chip *pxa;
	void __iomem         *gpdr;

	pxa = container_of(chip, struct pxa_gpio_chip, chip);
	gpdr = pxa->regbase + GPDR_OFFSET;
	local_irq_save(flags);
	value = __raw_readl(gpdr);
	if (__gpio_is_inverted(chip->base + offset))
		value |= mask;
	else
		value &= ~mask;
	__raw_writel(value, gpdr);
	local_irq_restore(flags);

	return 0;
}

static int pxa_gpio_direction_output(struct gpio_chip *chip,
					unsigned offset, int value)
{
	unsigned long        flags;
	u32                  mask = 1 << offset;
	u32                  tmp;
	struct pxa_gpio_chip *pxa;
	void __iomem         *gpdr;

	pxa = container_of(chip, struct pxa_gpio_chip, chip);
	__raw_writel(mask,
			pxa->regbase + (value ? GPSR_OFFSET : GPCR_OFFSET));
	gpdr = pxa->regbase + GPDR_OFFSET;
	local_irq_save(flags);
	tmp = __raw_readl(gpdr);
	if (__gpio_is_inverted(chip->base + offset))
		tmp &= ~mask;
	else
		tmp |= mask;
	__raw_writel(tmp, gpdr);
	local_irq_restore(flags);

	return 0;
}

/*
 * Return GPIO level
 */
static int pxa_gpio_get(struct gpio_chip *chip, unsigned offset)
{
	u32                  mask = 1 << offset;
	struct pxa_gpio_chip *pxa;

	pxa = container_of(chip, struct pxa_gpio_chip, chip);
	return __raw_readl(pxa->regbase + GPLR_OFFSET) & mask;
}

/*
 * Set output GPIO level
 */
static void pxa_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
{
	u32                  mask = 1 << offset;
	struct pxa_gpio_chip *pxa;

	pxa = container_of(chip, struct pxa_gpio_chip, chip);

	if (value)
		__raw_writel(mask, pxa->regbase + GPSR_OFFSET);
	else
		__raw_writel(mask, pxa->regbase + GPCR_OFFSET);
}

#define GPIO_CHIP(_n)							\
	[_n] = {							\
		.regbase = GPIO##_n##_BASE,				\
		.chip = {						\
			.label		  = "gpio-" #_n,		\
			.direction_input  = pxa_gpio_direction_input,	\
			.direction_output = pxa_gpio_direction_output,	\
			.get		  = pxa_gpio_get,		\
			.set		  = pxa_gpio_set,		\
			.base		  = (_n) * 32,			\
			.ngpio		  = 32,				\
		},							\
	}

static struct pxa_gpio_chip pxa_gpio_chip[] = {
	GPIO_CHIP(0),
	GPIO_CHIP(1),
	GPIO_CHIP(2),
#if defined(CONFIG_PXA27x) || defined(CONFIG_PXA3xx)
	GPIO_CHIP(3),
#endif
};

/*
 * PXA GPIO edge detection for IRQs:
 * IRQs are generated on Falling-Edge, Rising-Edge, or both.
 * Use this instead of directly setting GRER/GFER.
 */

static unsigned long GPIO_IRQ_rising_edge[4];
static unsigned long GPIO_IRQ_falling_edge[4];
static unsigned long GPIO_IRQ_mask[4];

/*
 * On PXA25x and PXA27x, GAFRx and GPDRx together decide the alternate
 * function of a GPIO, and GPDRx cannot be altered once configured. It
 * is attributed as "occupied" here (I know this terminology isn't
 * accurate, you are welcome to propose a better one :-)
 */
static int __gpio_is_occupied(unsigned gpio)
{
	if (cpu_is_pxa27x() || cpu_is_pxa25x()) {
		int af = (GAFR(gpio) >> ((gpio & 0xf) * 2)) & 0x3;
		int dir = GPDR(gpio) & GPIO_bit(gpio);

		if (__gpio_is_inverted(gpio))
			return af != 1 || dir == 0;
		else
			return af != 0 || dir != 0;
	}

	return 0;
}

static int pxa_gpio_irq_type(unsigned int irq, unsigned int type)
{
	int gpio, idx;

	gpio = IRQ_TO_GPIO(irq);
	idx = gpio >> 5;

	if (type == IRQ_TYPE_PROBE) {
		/* Don't mess with enabled GPIOs using preconfigured edges or
		 * GPIOs set to alternate function or to output during probe
		 */
		if ((GPIO_IRQ_rising_edge[idx] & GPIO_bit(gpio)) ||
		    (GPIO_IRQ_falling_edge[idx] & GPIO_bit(gpio)))
			return 0;

		if (__gpio_is_occupied(gpio))
			return 0;

		type = IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING;
	}

	if (__gpio_is_inverted(gpio))
		GPDR(gpio) |= GPIO_bit(gpio);
	else
		GPDR(gpio) &= ~GPIO_bit(gpio);

	if (type & IRQ_TYPE_EDGE_RISING)
		__set_bit(gpio, GPIO_IRQ_rising_edge);
	else
		__clear_bit(gpio, GPIO_IRQ_rising_edge);

	if (type & IRQ_TYPE_EDGE_FALLING)
		__set_bit(gpio, GPIO_IRQ_falling_edge);
	else
		__clear_bit(gpio, GPIO_IRQ_falling_edge);

	GRER(gpio) = GPIO_IRQ_rising_edge[idx] & GPIO_IRQ_mask[idx];
	GFER(gpio) = GPIO_IRQ_falling_edge[idx] & GPIO_IRQ_mask[idx];

	pr_debug("%s: IRQ%d (GPIO%d) - edge%s%s\n", __func__, irq, gpio,
		((type & IRQ_TYPE_EDGE_RISING)  ? " rising"  : ""),
		((type & IRQ_TYPE_EDGE_FALLING) ? " falling" : ""));
	return 0;
}

/*
 * GPIO IRQs must be acknowledged.  This is for GPIO 0 and 1.
 */

static void pxa_ack_low_gpio(unsigned int irq)
{
	GEDR0 = (1 << (irq - IRQ_GPIO0));
}

static void pxa_mask_low_gpio(unsigned int irq)
{
	ICMR &= ~(1 << (irq - PXA_IRQ(0)));
}

static void pxa_unmask_low_gpio(unsigned int irq)
{
	ICMR |= 1 << (irq - PXA_IRQ(0));
}

static struct irq_chip pxa_low_gpio_chip = {
	.name		= "GPIO-l",
	.ack		= pxa_ack_low_gpio,
	.mask		= pxa_mask_low_gpio,
	.unmask		= pxa_unmask_low_gpio,
	.set_type	= pxa_gpio_irq_type,
};

/*
 * Demux handler for GPIO>=2 edge detect interrupts
 */

#define GEDR_BITS	(sizeof(gedr) * BITS_PER_BYTE)

static void pxa_gpio_demux_handler(unsigned int irq, struct irq_desc *desc)
{
	int loop, bit, n;
	unsigned long gedr[4];

	do {
		gedr[0] = GEDR0 & GPIO_IRQ_mask[0] & ~3;
		gedr[1] = GEDR1 & GPIO_IRQ_mask[1];
		gedr[2] = GEDR2 & GPIO_IRQ_mask[2];
		gedr[3] = GEDR3 & GPIO_IRQ_mask[3];

		GEDR0 = gedr[0]; GEDR1 = gedr[1];
		GEDR2 = gedr[2]; GEDR3 = gedr[3];

		loop = 0;
		bit = find_first_bit(gedr, GEDR_BITS);
		while (bit < GEDR_BITS) {
			loop = 1;

			n = PXA_GPIO_IRQ_BASE + bit;
			generic_handle_irq(n);

			bit = find_next_bit(gedr, GEDR_BITS, bit + 1);
		}
	} while (loop);
}

static void pxa_ack_muxed_gpio(unsigned int irq)
{
	int gpio = irq - IRQ_GPIO(2) + 2;
	GEDR(gpio) = GPIO_bit(gpio);
}

static void pxa_mask_muxed_gpio(unsigned int irq)
{
	int gpio = irq - IRQ_GPIO(2) + 2;
	__clear_bit(gpio, GPIO_IRQ_mask);
	GRER(gpio) &= ~GPIO_bit(gpio);
	GFER(gpio) &= ~GPIO_bit(gpio);
}

static void pxa_unmask_muxed_gpio(unsigned int irq)
{
	int gpio = irq - IRQ_GPIO(2) + 2;
	int idx = gpio >> 5;
	__set_bit(gpio, GPIO_IRQ_mask);
	GRER(gpio) = GPIO_IRQ_rising_edge[idx] & GPIO_IRQ_mask[idx];
	GFER(gpio) = GPIO_IRQ_falling_edge[idx] & GPIO_IRQ_mask[idx];
}

static struct irq_chip pxa_muxed_gpio_chip = {
	.name		= "GPIO",
	.ack		= pxa_ack_muxed_gpio,
	.mask		= pxa_mask_muxed_gpio,
	.unmask		= pxa_unmask_muxed_gpio,
	.set_type	= pxa_gpio_irq_type,
};

void __init pxa_init_gpio(int gpio_nr, set_wake_t fn)
{
	int irq, i, gpio;

	pxa_last_gpio = gpio_nr - 1;

	/* clear all GPIO edge detects */
	for (i = 0; i < gpio_nr; i += 32) {
		GFER(i) = 0;
		GRER(i) = 0;
		GEDR(i) = GEDR(i);
	}

	/* GPIO 0 and 1 must have their mask bit always set */
	GPIO_IRQ_mask[0] = 3;

	for (irq = IRQ_GPIO0; irq <= IRQ_GPIO1; irq++) {
		set_irq_chip(irq, &pxa_low_gpio_chip);
		set_irq_handler(irq, handle_edge_irq);
		set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
	}

	for (irq = IRQ_GPIO(2); irq < IRQ_GPIO(gpio_nr); irq++) {
		set_irq_chip(irq, &pxa_muxed_gpio_chip);
		set_irq_handler(irq, handle_edge_irq);
		set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
	}

	/* Install handler for GPIO>=2 edge detect interrupts */
	set_irq_chained_handler(IRQ_GPIO_2_x, pxa_gpio_demux_handler);

	pxa_low_gpio_chip.set_wake = fn;
	pxa_muxed_gpio_chip.set_wake = fn;

	/* add a GPIO chip for each register bank.
	 * the last PXA25x register only contains 21 GPIOs
	 */
	for (gpio = 0, i = 0; gpio < gpio_nr; gpio += 32, i++) {
		if (gpio + 32 > gpio_nr)
			pxa_gpio_chip[i].chip.ngpio = gpio_nr - gpio;
		gpiochip_add(&pxa_gpio_chip[i].chip);
	}
}

#ifdef CONFIG_PM

static unsigned long saved_gplr[4];
static unsigned long saved_gpdr[4];
static unsigned long saved_grer[4];
static unsigned long saved_gfer[4];

static int pxa_gpio_suspend(struct sys_device *dev, pm_message_t state)
{
	int i, gpio;

	for (gpio = 0, i = 0; gpio < pxa_last_gpio; gpio += 32, i++) {
		saved_gplr[i] = GPLR(gpio);
		saved_gpdr[i] = GPDR(gpio);
		saved_grer[i] = GRER(gpio);
		saved_gfer[i] = GFER(gpio);

		/* Clear GPIO transition detect bits */
		GEDR(gpio) = GEDR(gpio);
	}
	return 0;
}

static int pxa_gpio_resume(struct sys_device *dev)
{
	int i, gpio;

	for (gpio = 0, i = 0; gpio < pxa_last_gpio; gpio += 32, i++) {
		/* restore level with set/clear */
		GPSR(gpio) = saved_gplr[i];
		GPCR(gpio) = ~saved_gplr[i];

		GRER(gpio) = saved_grer[i];
		GFER(gpio) = saved_gfer[i];
		GPDR(gpio) = saved_gpdr[i];
	}
	return 0;
}
#else
#define pxa_gpio_suspend	NULL
#define pxa_gpio_resume		NULL
#endif

struct sysdev_class pxa_gpio_sysclass = {
	.name		= "gpio",
	.suspend	= pxa_gpio_suspend,
	.resume		= pxa_gpio_resume,
};

static int __init pxa_gpio_init(void)
{
	return sysdev_class_register(&pxa_gpio_sysclass);
}

core_initcall(pxa_gpio_init);
