/*
 * GE PIO2 GPIO Driver
 *
 * Author: Martyn Welch <martyn.welch@ge.com>
 * Copyright 2009 GE Intelligent Platforms Embedded Systems, Inc.
 *
 * This program is free software; you can redistribute  it and/or modify it
 * under  the terms of  the GNU General  Public License as published by the
 * Free Software Foundation;  either version 2 of the  License, or (at your
 * option) any later version.
 */

#include <linux/version.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/device.h>
#include <linux/platform_device.h>
#include <linux/ctype.h>
#include <linux/gpio.h>
#include <linux/slab.h>

#include "../vme.h"
#include "vme_pio2.h"

static const char driver_name[] = "pio2_gpio";

static struct pio2_card *gpio_to_pio2_card(struct gpio_chip *chip)
{
	return container_of(chip, struct pio2_card, gc);
}

static int pio2_gpio_get(struct gpio_chip *chip, unsigned int offset)
{
	u8 reg;
	int retval;
	struct pio2_card *card = gpio_to_pio2_card(chip);

	if ((card->bank[PIO2_CHANNEL_BANK[offset]].config == OUTPUT) |
		(card->bank[PIO2_CHANNEL_BANK[offset]].config == NOFIT)) {

		dev_err(&card->vdev->dev, "Channel not available as input\n");
		return 0;
	}

	retval = vme_master_read(card->window, &reg, 1,
		PIO2_REGS_DATA[PIO2_CHANNEL_BANK[offset]]);
	if (retval < 0) {
		dev_err(&card->vdev->dev, "Unable to read from GPIO\n");
		return 0;
	}

	/*
	 * Remember, input on channels configured as both input and output
	 * are inverted!
	 */
	if (reg & PIO2_CHANNEL_BIT[offset]) {
		if (card->bank[PIO2_CHANNEL_BANK[offset]].config != BOTH)
			return 0;
		else
			return 1;
	} else {
		if (card->bank[PIO2_CHANNEL_BANK[offset]].config != BOTH)
			return 1;
		else
			return 0;
	}
}

static void pio2_gpio_set(struct gpio_chip *chip, unsigned int offset,
	int value)
{
	u8 reg;
	int retval;
	struct pio2_card *card = gpio_to_pio2_card(chip);

	if ((card->bank[PIO2_CHANNEL_BANK[offset]].config == INPUT) |
		(card->bank[PIO2_CHANNEL_BANK[offset]].config == NOFIT)) {

		dev_err(&card->vdev->dev, "Channel not availabe as output\n");
		return;
	}

	if (value)
		reg = card->bank[PIO2_CHANNEL_BANK[offset]].value |
			PIO2_CHANNEL_BIT[offset];
	else
		reg = card->bank[PIO2_CHANNEL_BANK[offset]].value &
			~PIO2_CHANNEL_BIT[offset];

	retval = vme_master_write(card->window, &reg, 1,
		PIO2_REGS_DATA[PIO2_CHANNEL_BANK[offset]]);
	if (retval < 0) {
		dev_err(&card->vdev->dev, "Unable to write to GPIO\n");
		return;
	}

	card->bank[PIO2_CHANNEL_BANK[offset]].value = reg;
}

/* Directionality configured at board build - send appropriate response */
static int pio2_gpio_dir_in(struct gpio_chip *chip, unsigned offset)
{
	int data;
	struct pio2_card *card = gpio_to_pio2_card(chip);

	if ((card->bank[PIO2_CHANNEL_BANK[offset]].config == OUTPUT) |
		(card->bank[PIO2_CHANNEL_BANK[offset]].config == NOFIT)) {
		dev_err(&card->vdev->dev,
			"Channel directionality not configurable at runtine\n");

		data = -EINVAL;
	} else {
		data = 0;
	}

	return data;
}

/* Directionality configured at board build - send appropriate response */
static int pio2_gpio_dir_out(struct gpio_chip *chip, unsigned offset, int value)
{
	int data;
	struct pio2_card *card = gpio_to_pio2_card(chip);

	if ((card->bank[PIO2_CHANNEL_BANK[offset]].config == INPUT) |
		(card->bank[PIO2_CHANNEL_BANK[offset]].config == NOFIT)) {
		dev_err(&card->vdev->dev,
			"Channel directionality not configurable at runtine\n");

		data = -EINVAL;
	} else {
		data = 0;
	}

	return data;
}

/*
 * We return whether this has been successful - this is used in the probe to
 * ensure we have a valid card.
 */
int pio2_gpio_reset(struct pio2_card *card)
{
	int retval = 0;
	int i, j;

	u8 data = 0;

	/* Zero output registers */
	for (i = 0; i < 4; i++) {
		retval = vme_master_write(card->window, &data, 1,
			PIO2_REGS_DATA[i]);
		if (retval < 0)
			return retval;
		card->bank[i].value = 0;
	}

	/* Set input interrupt masks */
	for (i = 0; i < 4; i++) {
		retval = vme_master_write(card->window, &data, 1,
			PIO2_REGS_INT_MASK[i * 2]);
		if (retval < 0)
			return retval;

		retval = vme_master_write(card->window, &data, 1,
			PIO2_REGS_INT_MASK[(i * 2) + 1]);
		if (retval < 0)
			return retval;

		for (j = 0; j < 8; j++)
			card->bank[i].irq[j] = NONE;
	}

	/* Ensure all I/O interrupts are cleared */
	for (i = 0; i < 4; i++) {
		do {
			retval = vme_master_read(card->window, &data, 1,
				PIO2_REGS_INT_STAT[i]);
			if (retval < 0)
				return retval;
		} while (data != 0);
	}

	return 0;
}

int __devinit pio2_gpio_init(struct pio2_card *card)
{
	int retval = 0;
	char *label;

	label = kmalloc(PIO2_NUM_CHANNELS, GFP_KERNEL);
	if (label == NULL) {
		dev_err(&card->vdev->dev, "Unable to allocate GPIO label\n");
		return -ENOMEM;
	}

	sprintf(label, "%s@%s", driver_name, dev_name(&card->vdev->dev));
	card->gc.label = label;

	card->gc.ngpio = PIO2_NUM_CHANNELS;
	/* Dynamic allocation of base */
	card->gc.base = -1;
	/* Setup pointers to chip functions */
	card->gc.direction_input = pio2_gpio_dir_in;
	card->gc.direction_output = pio2_gpio_dir_out;
	card->gc.get = pio2_gpio_get;
	card->gc.set = pio2_gpio_set;

	/* This function adds a memory mapped GPIO chip */
	retval = gpiochip_add(&(card->gc));
	if (retval) {
		dev_err(&card->vdev->dev, "Unable to register GPIO\n");
		kfree(card->gc.label);
	}

	return retval;
};

void pio2_gpio_exit(struct pio2_card *card)
{
	const char *label = card->gc.label;

	if (gpiochip_remove(&(card->gc)))
		dev_err(&card->vdev->dev, "Failed to remove GPIO");

	kfree(label);
}

