/*
 * Driver for GE FPGA based GPIO
 *
 * Author: Martyn Welch <martyn.welch@ge.com>
 *
 * 2008 (c) GE Intelligent Platforms Embedded Systems, 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.
 */

/* TODO
 *
 * Configuration of output modes (totem-pole/open-drain)
 * Interrupt configuration - interrupts are always generated the FPGA relies on
 * the I/O interrupt controllers mask to stop them propergating
 */

#include <linux/kernel.h>
#include <linux/compiler.h>
#include <linux/init.h>
#include <linux/io.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/of_platform.h>
#include <linux/of_gpio.h>
#include <linux/gpio.h>
#include <linux/slab.h>
#include <linux/module.h>

#define GEF_GPIO_DIRECT		0x00
#define GEF_GPIO_IN		0x04
#define GEF_GPIO_OUT		0x08
#define GEF_GPIO_TRIG		0x0C
#define GEF_GPIO_POLAR_A	0x10
#define GEF_GPIO_POLAR_B	0x14
#define GEF_GPIO_INT_STAT	0x18
#define GEF_GPIO_OVERRUN	0x1C
#define GEF_GPIO_MODE		0x20

static void _gef_gpio_set(void __iomem *reg, unsigned int offset, int value)
{
	unsigned int data;

	data = ioread32be(reg);
	/* value: 0=low; 1=high */
	if (value & 0x1)
		data = data | (0x1 << offset);
	else
		data = data & ~(0x1 << offset);

	iowrite32be(data, reg);
}


static int gef_gpio_dir_in(struct gpio_chip *chip, unsigned offset)
{
	unsigned int data;
	struct of_mm_gpio_chip *mmchip = to_of_mm_gpio_chip(chip);

	data = ioread32be(mmchip->regs + GEF_GPIO_DIRECT);
	data = data | (0x1 << offset);
	iowrite32be(data, mmchip->regs + GEF_GPIO_DIRECT);

	return 0;
}

static int gef_gpio_dir_out(struct gpio_chip *chip, unsigned offset, int value)
{
	unsigned int data;
	struct of_mm_gpio_chip *mmchip = to_of_mm_gpio_chip(chip);

	/* Set direction before switching to input */
	_gef_gpio_set(mmchip->regs + GEF_GPIO_OUT, offset, value);

	data = ioread32be(mmchip->regs + GEF_GPIO_DIRECT);
	data = data & ~(0x1 << offset);
	iowrite32be(data, mmchip->regs + GEF_GPIO_DIRECT);

	return 0;
}

static int gef_gpio_get(struct gpio_chip *chip, unsigned offset)
{
	unsigned int data;
	int state = 0;
	struct of_mm_gpio_chip *mmchip = to_of_mm_gpio_chip(chip);

	data = ioread32be(mmchip->regs + GEF_GPIO_IN);
	state = (int)((data >> offset) & 0x1);

	return state;
}

static void gef_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
{
	struct of_mm_gpio_chip *mmchip = to_of_mm_gpio_chip(chip);

	_gef_gpio_set(mmchip->regs + GEF_GPIO_OUT, offset, value);
}

static int __init gef_gpio_init(void)
{
	struct device_node *np;
	int retval;
	struct of_mm_gpio_chip *gef_gpio_chip;

	for_each_compatible_node(np, NULL, "gef,sbc610-gpio") {

		pr_debug("%s: Initialising GEF GPIO\n", np->full_name);

		/* Allocate chip structure */
		gef_gpio_chip = kzalloc(sizeof(*gef_gpio_chip), GFP_KERNEL);
		if (!gef_gpio_chip) {
			pr_err("%s: Unable to allocate structure\n",
				np->full_name);
			continue;
		}

		/* Setup pointers to chip functions */
		gef_gpio_chip->gc.of_gpio_n_cells = 2;
		gef_gpio_chip->gc.ngpio = 19;
		gef_gpio_chip->gc.direction_input = gef_gpio_dir_in;
		gef_gpio_chip->gc.direction_output = gef_gpio_dir_out;
		gef_gpio_chip->gc.get = gef_gpio_get;
		gef_gpio_chip->gc.set = gef_gpio_set;

		/* This function adds a memory mapped GPIO chip */
		retval = of_mm_gpiochip_add(np, gef_gpio_chip);
		if (retval) {
			kfree(gef_gpio_chip);
			pr_err("%s: Unable to add GPIO\n", np->full_name);
		}
	}

	for_each_compatible_node(np, NULL, "gef,sbc310-gpio") {

		pr_debug("%s: Initialising GEF GPIO\n", np->full_name);

		/* Allocate chip structure */
		gef_gpio_chip = kzalloc(sizeof(*gef_gpio_chip), GFP_KERNEL);
		if (!gef_gpio_chip) {
			pr_err("%s: Unable to allocate structure\n",
				np->full_name);
			continue;
		}

		/* Setup pointers to chip functions */
		gef_gpio_chip->gc.of_gpio_n_cells = 2;
		gef_gpio_chip->gc.ngpio = 6;
		gef_gpio_chip->gc.direction_input = gef_gpio_dir_in;
		gef_gpio_chip->gc.direction_output = gef_gpio_dir_out;
		gef_gpio_chip->gc.get = gef_gpio_get;
		gef_gpio_chip->gc.set = gef_gpio_set;

		/* This function adds a memory mapped GPIO chip */
		retval = of_mm_gpiochip_add(np, gef_gpio_chip);
		if (retval) {
			kfree(gef_gpio_chip);
			pr_err("%s: Unable to add GPIO\n", np->full_name);
		}
	}

	for_each_compatible_node(np, NULL, "ge,imp3a-gpio") {

		pr_debug("%s: Initialising GE GPIO\n", np->full_name);

		/* Allocate chip structure */
		gef_gpio_chip = kzalloc(sizeof(*gef_gpio_chip), GFP_KERNEL);
		if (!gef_gpio_chip) {
			pr_err("%s: Unable to allocate structure\n",
				np->full_name);
			continue;
		}

		/* Setup pointers to chip functions */
		gef_gpio_chip->gc.of_gpio_n_cells = 2;
		gef_gpio_chip->gc.ngpio = 16;
		gef_gpio_chip->gc.direction_input = gef_gpio_dir_in;
		gef_gpio_chip->gc.direction_output = gef_gpio_dir_out;
		gef_gpio_chip->gc.get = gef_gpio_get;
		gef_gpio_chip->gc.set = gef_gpio_set;

		/* This function adds a memory mapped GPIO chip */
		retval = of_mm_gpiochip_add(np, gef_gpio_chip);
		if (retval) {
			kfree(gef_gpio_chip);
			pr_err("%s: Unable to add GPIO\n", np->full_name);
		}
	}

	return 0;
};
arch_initcall(gef_gpio_init);

MODULE_DESCRIPTION("GE I/O FPGA GPIO driver");
MODULE_AUTHOR("Martyn Welch <martyn.welch@ge.com");
MODULE_LICENSE("GPL");
