/*
 * Support for the VMIVME-7805 board access to the Universe II bridge.
 *
 * Author: Arthur Benilov <arthur.benilov@iba-group.com>
 * Copyright 2010 Ion Beam Application, 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/module.h>
#include <linux/types.h>
#include <linux/errno.h>
#include <linux/pci.h>
#include <linux/poll.h>
#include <linux/io.h>

#include "vme_vmivme7805.h"

static int __init vmic_init(void);
static int vmic_probe(struct pci_dev *, const struct pci_device_id *);
static void vmic_remove(struct pci_dev *);
static void __exit vmic_exit(void);

/** Base address to access FPGA register */
static void *vmic_base;

static const char driver_name[] = "vmivme_7805";

static DEFINE_PCI_DEVICE_TABLE(vmic_ids) = {
	{ PCI_DEVICE(PCI_VENDOR_ID_VMIC, PCI_DEVICE_ID_VTIMR) },
	{ },
};

static struct pci_driver vmic_driver = {
	.name = driver_name,
	.id_table = vmic_ids,
	.probe = vmic_probe,
	.remove = vmic_remove,
};

static int __init vmic_init(void)
{
	return pci_register_driver(&vmic_driver);
}

static int vmic_probe(struct pci_dev *pdev, const struct pci_device_id *id)
{
	int retval;
	u32 data;

	/* Enable the device */
	retval = pci_enable_device(pdev);
	if (retval) {
		dev_err(&pdev->dev, "Unable to enable device\n");
		goto err;
	}

	/* Map Registers */
	retval = pci_request_regions(pdev, driver_name);
	if (retval) {
		dev_err(&pdev->dev, "Unable to reserve resources\n");
		goto err_resource;
	}

	/* Map registers in BAR 0 */
	vmic_base = ioremap_nocache(pci_resource_start(pdev, 0), 16);
	if (!vmic_base) {
		dev_err(&pdev->dev, "Unable to remap CRG region\n");
		retval = -EIO;
		goto err_remap;
	}

	/* Clear the FPGA VME IF contents */
	iowrite32(0, vmic_base + VME_CONTROL);

	/* Clear any initial BERR  */
	data = ioread32(vmic_base + VME_CONTROL) & 0x00000FFF;
	data |= BM_VME_CONTROL_BERRST;
	iowrite32(data, vmic_base + VME_CONTROL);

	/* Enable the vme interface and byte swapping */
	data = ioread32(vmic_base + VME_CONTROL) & 0x00000FFF;
	data = data | BM_VME_CONTROL_MASTER_ENDIAN |
			BM_VME_CONTROL_SLAVE_ENDIAN |
			BM_VME_CONTROL_ABLE |
			BM_VME_CONTROL_BERRI |
			BM_VME_CONTROL_BPENA |
			BM_VME_CONTROL_VBENA;
	iowrite32(data, vmic_base + VME_CONTROL);

	return 0;

err_remap:
	pci_release_regions(pdev);
err_resource:
	pci_disable_device(pdev);
err:
	return retval;
}

static void vmic_remove(struct pci_dev *pdev)
{
	iounmap(vmic_base);
	pci_release_regions(pdev);
	pci_disable_device(pdev);

}

static void __exit vmic_exit(void)
{
	pci_unregister_driver(&vmic_driver);
}

MODULE_DESCRIPTION("VMIVME-7805 board support driver");
MODULE_AUTHOR("Arthur Benilov <arthur.benilov@iba-group.com>");
MODULE_LICENSE("GPL");

module_init(vmic_init);
module_exit(vmic_exit);

