/*
 * 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.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */

/*
 * 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/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 DEFINE_PCI_DEVICE_TABLE(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");
