/*
 * GE PIO2 6U VME I/O 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.
 */

#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt

#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/ctype.h>
#include <linux/gpio.h>
#include <linux/slab.h>
#include <linux/vme.h>

#include "vme_pio2.h"


static const char driver_name[] = "pio2";

static int bus[PIO2_CARDS_MAX];
static int bus_num;
static long base[PIO2_CARDS_MAX];
static int base_num;
static int vector[PIO2_CARDS_MAX];
static int vector_num;
static int level[PIO2_CARDS_MAX];
static int level_num;
static char *variant[PIO2_CARDS_MAX];
static int variant_num;

static bool loopback;

static int pio2_match(struct vme_dev *);
static int __devinit pio2_probe(struct vme_dev *);
static int __devexit pio2_remove(struct vme_dev *);

static int pio2_get_led(struct pio2_card *card)
{
	/* Can't read hardware, state saved in structure */
	return card->led;
}

static int pio2_set_led(struct pio2_card *card, int state)
{
	u8 reg;
	int retval;

	reg = card->irq_level;

	/* Register state inverse of led state */
	if (!state)
		reg |= PIO2_LED;

	if (loopback)
		reg |= PIO2_LOOP;

	retval = vme_master_write(card->window, &reg, 1, PIO2_REGS_CTRL);
	if (retval < 0)
		return retval;

	card->led = state ? 1 : 0;

	return 0;
}

static void pio2_int(int level, int vector, void *ptr)
{
	int vec, i, channel, retval;
	u8 reg;
	struct pio2_card *card  = ptr;

	vec = vector & ~PIO2_VME_VECTOR_MASK;

	switch (vec) {
	case 0:
		dev_warn(&card->vdev->dev, "Spurious Interrupt\n");
		break;
	case 1:
	case 2:
	case 3:
	case 4:
		/* Channels 0 to 7 */
		retval = vme_master_read(card->window, &reg, 1,
			PIO2_REGS_INT_STAT[vec - 1]);
		if (retval < 0) {
			dev_err(&card->vdev->dev,
				"Unable to read IRQ status register\n");
			return;
		}
		for (i = 0; i < 8; i++) {
			channel = ((vec - 1) * 8) + i;
			if (reg & PIO2_CHANNEL_BIT[channel])
				dev_info(&card->vdev->dev,
					"Interrupt on I/O channel %d\n",
					channel);
		}
		break;
	case 5:
	case 6:
	case 7:
	case 8:
	case 9:
	case 10:
		/* Counters are dealt with by their own handler */
		dev_err(&card->vdev->dev,
			"Counter interrupt\n");
		break;
	}
}


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

	/* Clear main register*/
	retval = vme_master_write(card->window, &data, 1, PIO2_REGS_CTRL);
	if (retval < 0)
		return retval;

	/* Clear VME vector */
	retval = vme_master_write(card->window, &data, 1, PIO2_REGS_VME_VECTOR);
	if (retval < 0)
		return retval;

	/* Reset GPIO */
	retval = pio2_gpio_reset(card);
	if (retval < 0)
		return retval;

	/* Reset counters */
	retval = pio2_cntr_reset(card);
	if (retval < 0)
		return retval;

	return 0;
}

static struct vme_driver pio2_driver = {
	.name = driver_name,
	.match = pio2_match,
	.probe = pio2_probe,
	.remove = __devexit_p(pio2_remove),
};


static int __init pio2_init(void)
{
	int retval = 0;

	if (bus_num == 0) {
		pr_err("No cards, skipping registration\n");
		goto err_nocard;
	}

	if (bus_num > PIO2_CARDS_MAX) {
		pr_err("Driver only able to handle %d PIO2 Cards\n",
		       PIO2_CARDS_MAX);
		bus_num = PIO2_CARDS_MAX;
	}

	/* Register the PIO2 driver */
	retval = vme_register_driver(&pio2_driver, bus_num);
	if (retval != 0)
		goto err_reg;

	return retval;

err_reg:
err_nocard:
	return retval;
}

static int pio2_match(struct vme_dev *vdev)
{

	if (vdev->num >= bus_num) {
		dev_err(&vdev->dev,
			"The enumeration of the VMEbus to which the board is connected must be specified");
		return 0;
	}

	if (vdev->num >= base_num) {
		dev_err(&vdev->dev,
			"The VME address for the cards registers must be specified");
		return 0;
	}

	if (vdev->num >= vector_num) {
		dev_err(&vdev->dev,
			"The IRQ vector used by the card must be specified");
		return 0;
	}

	if (vdev->num >= level_num) {
		dev_err(&vdev->dev,
			"The IRQ level used by the card must be specified");
		return 0;
	}

	if (vdev->num >= variant_num) {
		dev_err(&vdev->dev, "The variant of the card must be specified");
		return 0;
	}

	return 1;
}

static int __devinit pio2_probe(struct vme_dev *vdev)
{
	struct pio2_card *card;
	int retval;
	int i;
	u8 reg;
	int vec;

	card = kzalloc(sizeof(struct pio2_card), GFP_KERNEL);
	if (card == NULL) {
		dev_err(&vdev->dev, "Unable to allocate card structure\n");
		retval = -ENOMEM;
		goto err_struct;
	}

	card->id = vdev->num;
	card->bus = bus[card->id];
	card->base = base[card->id];
	card->irq_vector = vector[card->id];
	card->irq_level = level[card->id] & PIO2_VME_INT_MASK;
	strncpy(card->variant, variant[card->id], PIO2_VARIANT_LENGTH);
	card->vdev = vdev;

	for (i = 0; i < PIO2_VARIANT_LENGTH; i++) {

		if (isdigit(card->variant[i]) == 0) {
			dev_err(&card->vdev->dev, "Variant invalid\n");
			retval = -EINVAL;
			goto err_variant;
		}
	}

	/*
	 * Bottom 4 bits of VME interrupt vector used to determine source,
	 * provided vector should only use upper 4 bits.
	 */
	if (card->irq_vector & ~PIO2_VME_VECTOR_MASK) {
		dev_err(&card->vdev->dev,
			"Invalid VME IRQ Vector, vector must not use lower 4 bits\n");
		retval = -EINVAL;
		goto err_vector;
	}

	/*
	 * There is no way to determine the build variant or whether each bank
	 * is input, output or both at run time. The inputs are also inverted
	 * if configured as both.
	 *
	 * We pass in the board variant and use that to determine the
	 * configuration of the banks.
	 */
	for (i = 1; i < PIO2_VARIANT_LENGTH; i++) {
		switch (card->variant[i]) {
		case '0':
			card->bank[i-1].config = NOFIT;
			break;
		case '1':
		case '2':
		case '3':
		case '4':
			card->bank[i-1].config = INPUT;
			break;
		case '5':
			card->bank[i-1].config = OUTPUT;
			break;
		case '6':
		case '7':
		case '8':
		case '9':
			card->bank[i-1].config = BOTH;
			break;
		}
	}

	/* Get a master window and position over regs */
	card->window = vme_master_request(vdev, VME_A24, VME_SCT, VME_D16);
	if (card->window == NULL) {
		dev_err(&card->vdev->dev,
			"Unable to assign VME master resource\n");
		retval = -EIO;
		goto err_window;
	}

	retval = vme_master_set(card->window, 1, card->base, 0x10000, VME_A24,
		(VME_SCT | VME_USER | VME_DATA), VME_D16);
	if (retval) {
		dev_err(&card->vdev->dev,
			"Unable to configure VME master resource\n");
		goto err_set;
	}

	/*
	 * There is also no obvious register which we can probe to determine
	 * whether the provided base is valid. If we can read the "ID Register"
	 * offset and the reset function doesn't error, assume we have a valid
	 * location.
	 */
	retval = vme_master_read(card->window, &reg, 1, PIO2_REGS_ID);
	if (retval < 0) {
		dev_err(&card->vdev->dev, "Unable to read from device\n");
		goto err_read;
	}

	dev_dbg(&card->vdev->dev, "ID Register:%x\n", reg);

	/*
	 * Ensure all the I/O is cleared. We can't read back the states, so
	 * this is the only method we have to ensure that the I/O is in a known
	 * state.
	 */
	retval = pio2_reset_card(card);
	if (retval) {
		dev_err(&card->vdev->dev,
			"Failed to reset card, is location valid?");
		retval = -ENODEV;
		goto err_reset;
	}

	/* Configure VME Interrupts */
	reg = card->irq_level;
	if (pio2_get_led(card))
		reg |= PIO2_LED;
	if (loopback)
		reg |= PIO2_LOOP;
	retval = vme_master_write(card->window, &reg, 1, PIO2_REGS_CTRL);
	if (retval < 0)
		return retval;

	/* Set VME vector */
	retval = vme_master_write(card->window, &card->irq_vector, 1,
		PIO2_REGS_VME_VECTOR);
	if (retval < 0)
		return retval;

	/* Attach spurious interrupt handler. */
	vec = card->irq_vector | PIO2_VME_VECTOR_SPUR;

	retval = vme_irq_request(vdev, card->irq_level, vec,
		&pio2_int, (void *)card);
	if (retval < 0) {
		dev_err(&card->vdev->dev,
			"Unable to attach VME interrupt vector0x%x, level 0x%x\n",
			 vec, card->irq_level);
		goto err_irq;
	}

	/* Attach GPIO interrupt handlers. */
	for (i = 0; i < 4; i++) {
		vec = card->irq_vector | PIO2_VECTOR_BANK[i];

		retval = vme_irq_request(vdev, card->irq_level, vec,
			&pio2_int, (void *)card);
		if (retval < 0) {
			dev_err(&card->vdev->dev,
				"Unable to attach VME interrupt vector0x%x, level 0x%x\n",
				 vec, card->irq_level);
			goto err_gpio_irq;
		}
	}

	/* Attach counter interrupt handlers. */
	for (i = 0; i < 6; i++) {
		vec = card->irq_vector | PIO2_VECTOR_CNTR[i];

		retval = vme_irq_request(vdev, card->irq_level, vec,
			&pio2_int, (void *)card);
		if (retval < 0) {
			dev_err(&card->vdev->dev,
				"Unable to attach VME interrupt vector0x%x, level 0x%x\n",
				vec, card->irq_level);
			goto err_cntr_irq;
		}
	}

	/* Register IO */
	retval = pio2_gpio_init(card);
	if (retval < 0) {
		dev_err(&card->vdev->dev,
			"Unable to register with GPIO framework\n");
		goto err_gpio;
	}

	/* Set LED - This also sets interrupt level */
	retval = pio2_set_led(card, 0);
	if (retval < 0) {
		dev_err(&card->vdev->dev, "Unable to set LED\n");
		goto err_led;
	}

	dev_set_drvdata(&card->vdev->dev, card);

	dev_info(&card->vdev->dev,
		"PIO2 (variant %s) configured at 0x%lx\n", card->variant,
		card->base);

	return 0;

err_led:
	pio2_gpio_exit(card);
err_gpio:
	i = 6;
err_cntr_irq:
	while (i > 0) {
		i--;
		vec = card->irq_vector | PIO2_VECTOR_CNTR[i];
		vme_irq_free(vdev, card->irq_level, vec);
	}

	i = 4;
err_gpio_irq:
	while (i > 0) {
		i--;
		vec = card->irq_vector | PIO2_VECTOR_BANK[i];
		vme_irq_free(vdev, card->irq_level, vec);
	}

	vec = (card->irq_vector & PIO2_VME_VECTOR_MASK) | PIO2_VME_VECTOR_SPUR;
	vme_irq_free(vdev, card->irq_level, vec);
err_irq:
	 pio2_reset_card(card);
err_reset:
err_read:
	vme_master_set(card->window, 0, 0, 0, VME_A16, 0, VME_D16);
err_set:
	vme_master_free(card->window);
err_window:
err_vector:
err_variant:
	kfree(card);
err_struct:
	return retval;
}

static int __devexit pio2_remove(struct vme_dev *vdev)
{
	int vec;
	int i;

	struct pio2_card *card = dev_get_drvdata(&vdev->dev);

	pio2_gpio_exit(card);

	for (i = 0; i < 6; i++) {
		vec = card->irq_vector | PIO2_VECTOR_CNTR[i];
		vme_irq_free(vdev, card->irq_level, vec);
	}

	for (i = 0; i < 4; i++) {
		vec = card->irq_vector | PIO2_VECTOR_BANK[i];
		vme_irq_free(vdev, card->irq_level, vec);
	}

	vec = (card->irq_vector & PIO2_VME_VECTOR_MASK) | PIO2_VME_VECTOR_SPUR;
	vme_irq_free(vdev, card->irq_level, vec);

	pio2_reset_card(card);

	vme_master_set(card->window, 0, 0, 0, VME_A16, 0, VME_D16);

	vme_master_free(card->window);

	kfree(card);

	return 0;
}

static void __exit pio2_exit(void)
{
	vme_unregister_driver(&pio2_driver);
}


/* These are required for each board */
MODULE_PARM_DESC(bus, "Enumeration of VMEbus to which the board is connected");
module_param_array(bus, int, &bus_num, S_IRUGO);

MODULE_PARM_DESC(base, "Base VME address for PIO2 Registers");
module_param_array(base, long, &base_num, S_IRUGO);

MODULE_PARM_DESC(vector, "VME IRQ Vector (Lower 4 bits masked)");
module_param_array(vector, int, &vector_num, S_IRUGO);

MODULE_PARM_DESC(level, "VME IRQ Level");
module_param_array(level, int, &level_num, S_IRUGO);

MODULE_PARM_DESC(variant, "Last 4 characters of PIO2 board variant");
module_param_array(variant, charp, &variant_num, S_IRUGO);

/* This is for debugging */
MODULE_PARM_DESC(loopback, "Enable loopback mode on all cards");
module_param(loopback, bool, S_IRUGO);

MODULE_DESCRIPTION("GE PIO2 6U VME I/O Driver");
MODULE_AUTHOR("Martyn Welch <martyn.welch@ge.com");
MODULE_LICENSE("GPL");

module_init(pio2_init);
module_exit(pio2_exit);

