/*
 * comedi/drivers/adl_pci8164.c
 *
 * Hardware comedi driver for PCI-8164 Adlink card
 * Copyright (C) 2004 Michel Lachine <mike@mikelachaine.ca>
 *
 * 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.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 */

/*
 * Driver: adl_pci8164
 * Description: Driver for the Adlink PCI-8164 4 Axes Motion Control board
 * Devices: (ADLink) PCI-8164 [adl_pci8164]
 * Author: Michel Lachaine <mike@mikelachaine.ca>
 * Status: experimental
 * Updated: Mon, 14 Apr 2008 15:10:32 +0100
 *
 * Configuration Options: not applicable, uses PCI auto config
 */

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/pci.h>

#include "../comedidev.h"

#define PCI8164_AXIS(x)		((x) * 0x08)
#define PCI8164_CMD_MSTS_REG	0x00
#define PCI8164_OTP_SSTS_REG	0x02
#define PCI8164_BUF0_REG	0x04
#define PCI8164_BUF1_REG	0x06

static int adl_pci8164_insn_read(struct comedi_device *dev,
				 struct comedi_subdevice *s,
				 struct comedi_insn *insn,
				 unsigned int *data)
{
	unsigned long offset = (unsigned long)s->private;
	unsigned int chan = CR_CHAN(insn->chanspec);
	int i;

	for (i = 0; i < insn->n; i++)
		data[i] = inw(dev->iobase + PCI8164_AXIS(chan) + offset);

	return insn->n;
}

static int adl_pci8164_insn_write(struct comedi_device *dev,
				  struct comedi_subdevice *s,
				  struct comedi_insn *insn,
				  unsigned int *data)
{
	unsigned long offset = (unsigned long)s->private;
	unsigned int chan = CR_CHAN(insn->chanspec);
	int i;

	for (i = 0; i < insn->n; i++)
		outw(data[i], dev->iobase + PCI8164_AXIS(chan) + offset);

	return insn->n;
}

static int adl_pci8164_auto_attach(struct comedi_device *dev,
					     unsigned long context_unused)
{
	struct pci_dev *pcidev = comedi_to_pci_dev(dev);
	struct comedi_subdevice *s;
	int ret;

	ret = comedi_pci_enable(dev);
	if (ret)
		return ret;
	dev->iobase = pci_resource_start(pcidev, 2);

	ret = comedi_alloc_subdevices(dev, 4);
	if (ret)
		return ret;

	/* read MSTS register / write CMD register for each axis (channel) */
	s = &dev->subdevices[0];
	s->type		= COMEDI_SUBD_PROC;
	s->subdev_flags	= SDF_READABLE | SDF_WRITABLE;
	s->n_chan	= 4;
	s->maxdata	= 0xffff;
	s->len_chanlist	= 4;
	s->insn_read	= adl_pci8164_insn_read;
	s->insn_write	= adl_pci8164_insn_write;
	s->private	= (void *)PCI8164_CMD_MSTS_REG;

	/* read SSTS register / write OTP register for each axis (channel) */
	s = &dev->subdevices[1];
	s->type		= COMEDI_SUBD_PROC;
	s->subdev_flags	= SDF_READABLE | SDF_WRITABLE;
	s->n_chan	= 4;
	s->maxdata	= 0xffff;
	s->len_chanlist	= 4;
	s->insn_read	= adl_pci8164_insn_read;
	s->insn_write	= adl_pci8164_insn_write;
	s->private	= (void *)PCI8164_OTP_SSTS_REG;

	/* read/write BUF0 register for each axis (channel) */
	s = &dev->subdevices[2];
	s->type		= COMEDI_SUBD_PROC;
	s->subdev_flags	= SDF_READABLE | SDF_WRITABLE;
	s->n_chan	= 4;
	s->maxdata	= 0xffff;
	s->len_chanlist	= 4;
	s->insn_read	= adl_pci8164_insn_read;
	s->insn_write	= adl_pci8164_insn_write;
	s->private	= (void *)PCI8164_BUF0_REG;

	/* read/write BUF1 register for each axis (channel) */
	s = &dev->subdevices[3];
	s->type		= COMEDI_SUBD_PROC;
	s->subdev_flags	= SDF_READABLE | SDF_WRITABLE;
	s->n_chan	= 4;
	s->maxdata	= 0xffff;
	s->len_chanlist	= 4;
	s->insn_read	= adl_pci8164_insn_read;
	s->insn_write	= adl_pci8164_insn_write;
	s->private	= (void *)PCI8164_BUF1_REG;

	return 0;
}

static struct comedi_driver adl_pci8164_driver = {
	.driver_name	= "adl_pci8164",
	.module		= THIS_MODULE,
	.auto_attach	= adl_pci8164_auto_attach,
	.detach		= comedi_pci_disable,
};

static int adl_pci8164_pci_probe(struct pci_dev *dev,
				 const struct pci_device_id *id)
{
	return comedi_pci_auto_config(dev, &adl_pci8164_driver,
				      id->driver_data);
}

static const struct pci_device_id adl_pci8164_pci_table[] = {
	{ PCI_DEVICE(PCI_VENDOR_ID_ADLINK, 0x8164) },
	{ 0 }
};
MODULE_DEVICE_TABLE(pci, adl_pci8164_pci_table);

static struct pci_driver adl_pci8164_pci_driver = {
	.name		= "adl_pci8164",
	.id_table	= adl_pci8164_pci_table,
	.probe		= adl_pci8164_pci_probe,
	.remove		= comedi_pci_auto_unconfig,
};
module_comedi_pci_driver(adl_pci8164_driver, adl_pci8164_pci_driver);

MODULE_AUTHOR("Comedi http://www.comedi.org");
MODULE_DESCRIPTION("Comedi low-level driver");
MODULE_LICENSE("GPL");
