/*
    comedi/drivers/ke_counter.c
    Comedi driver for Kolter-Electronic PCI Counter 1 Card

    COMEDI - Linux Control and Measurement Device Interface
    Copyright (C) 2000 David A. Schleef <ds@schleef.org>

    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: ke_counter
Description: Driver for Kolter Electronic Counter Card
Devices: [Kolter Electronic] PCI Counter Card (ke_counter)
Author: Michael Hillmann
Updated: Mon, 14 Apr 2008 15:42:42 +0100
Status: tested

Configuration Options:
  [0] - PCI bus of device (optional)
  [1] - PCI slot of device (optional)
  If bus/slot is not specified, the first supported
  PCI device found will be used.

This driver is a simple driver to read the counter values from
Kolter Electronic PCI Counter Card.
*/

#include "../comedidev.h"

#include "comedi_pci.h"

#define CNT_DRIVER_NAME         "ke_counter"
#define PCI_VENDOR_ID_KOLTER    0x1001
#define CNT_CARD_DEVICE_ID      0x0014

/*-- function prototypes ----------------------------------------------------*/

static int cnt_attach(struct comedi_device *dev, struct comedi_devconfig *it);
static int cnt_detach(struct comedi_device *dev);

static DEFINE_PCI_DEVICE_TABLE(cnt_pci_table) = {
	{
	PCI_VENDOR_ID_KOLTER, CNT_CARD_DEVICE_ID, PCI_ANY_ID,
		    PCI_ANY_ID, 0, 0, 0}, {
	0}
};

MODULE_DEVICE_TABLE(pci, cnt_pci_table);

/*-- board specification structure ------------------------------------------*/

struct cnt_board_struct {

	const char *name;
	int device_id;
	int cnt_channel_nbr;
	int cnt_bits;
};

static const struct cnt_board_struct cnt_boards[] = {
	{
	 .name = CNT_DRIVER_NAME,
	 .device_id = CNT_CARD_DEVICE_ID,
	 .cnt_channel_nbr = 3,
	 .cnt_bits = 24}
};

#define cnt_board_nbr (sizeof(cnt_boards)/sizeof(struct cnt_board_struct))

/*-- device private structure -----------------------------------------------*/

struct cnt_device_private {

	struct pci_dev *pcidev;
};

#define devpriv ((struct cnt_device_private *)dev->private)

static struct comedi_driver cnt_driver = {
	.driver_name = CNT_DRIVER_NAME,
	.module = THIS_MODULE,
	.attach = cnt_attach,
	.detach = cnt_detach,
};

COMEDI_PCI_INITCLEANUP(cnt_driver, cnt_pci_table);

/*-- counter write ----------------------------------------------------------*/

/* This should be used only for resetting the counters; maybe it is better
   to make a special command 'reset'. */
static int cnt_winsn(struct comedi_device *dev,
		     struct comedi_subdevice *s, struct comedi_insn *insn,
		     unsigned int *data)
{
	int chan = CR_CHAN(insn->chanspec);

	outb((unsigned char)((data[0] >> 24) & 0xff),
	     dev->iobase + chan * 0x20 + 0x10);
	outb((unsigned char)((data[0] >> 16) & 0xff),
	     dev->iobase + chan * 0x20 + 0x0c);
	outb((unsigned char)((data[0] >> 8) & 0xff),
	     dev->iobase + chan * 0x20 + 0x08);
	outb((unsigned char)((data[0] >> 0) & 0xff),
	     dev->iobase + chan * 0x20 + 0x04);

	/* return the number of samples written */
	return 1;
}

/*-- counter read -----------------------------------------------------------*/

static int cnt_rinsn(struct comedi_device *dev,
		     struct comedi_subdevice *s, struct comedi_insn *insn,
		     unsigned int *data)
{
	unsigned char a0, a1, a2, a3, a4;
	int chan = CR_CHAN(insn->chanspec);
	int result;

	a0 = inb(dev->iobase + chan * 0x20);
	a1 = inb(dev->iobase + chan * 0x20 + 0x04);
	a2 = inb(dev->iobase + chan * 0x20 + 0x08);
	a3 = inb(dev->iobase + chan * 0x20 + 0x0c);
	a4 = inb(dev->iobase + chan * 0x20 + 0x10);

	result = (a1 + (a2 * 256) + (a3 * 65536));
	if (a4 > 0)
		result = result - s->maxdata;

	*data = (unsigned int)result;

	/* return the number of samples read */
	return 1;
}

/*-- attach -----------------------------------------------------------------*/

static int cnt_attach(struct comedi_device *dev, struct comedi_devconfig *it)
{
	struct comedi_subdevice *subdevice;
	struct pci_dev *pci_device;
	struct cnt_board_struct *board;
	unsigned long io_base;
	int error, i;

	/* allocate device private structure */
	error = alloc_private(dev, sizeof(struct cnt_device_private));
	if (error < 0)
		return error;

	/* Probe the device to determine what device in the series it is. */
	for (pci_device = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, NULL);
	     pci_device != NULL;
	     pci_device = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pci_device)) {
		if (pci_device->vendor == PCI_VENDOR_ID_KOLTER) {
			for (i = 0; i < cnt_board_nbr; i++) {
				if (cnt_boards[i].device_id ==
				    pci_device->device) {
					/* was a particular bus/slot requested? */
					if ((it->options[0] != 0)
					    || (it->options[1] != 0)) {
						/* are we on the wrong bus/slot? */
						if (pci_device->bus->number !=
						    it->options[0]
						    ||
						    PCI_SLOT(pci_device->devfn)
						    != it->options[1]) {
							continue;
						}
					}

					dev->board_ptr = cnt_boards + i;
					board =
					    (struct cnt_board_struct *)
					    dev->board_ptr;
					goto found;
				}
			}
		}
	}
	printk("comedi%d: no supported board found! (req. bus/slot: %d/%d)\n",
	       dev->minor, it->options[0], it->options[1]);
	return -EIO;

found:
	printk("comedi%d: found %s at PCI bus %d, slot %d\n", dev->minor,
	       board->name, pci_device->bus->number,
	       PCI_SLOT(pci_device->devfn));
	devpriv->pcidev = pci_device;
	dev->board_name = board->name;

	/* enable PCI device and request regions */
	error = comedi_pci_enable(pci_device, CNT_DRIVER_NAME);
	if (error < 0) {
		printk
		    ("comedi%d: failed to enable PCI device and request regions!\n",
		     dev->minor);
		return error;
	}

	/* read register base address [PCI_BASE_ADDRESS #0] */
	io_base = pci_resource_start(pci_device, 0);
	dev->iobase = io_base;

	/* allocate the subdevice structures */
	error = alloc_subdevices(dev, 1);
	if (error < 0)
		return error;

	subdevice = dev->subdevices + 0;
	dev->read_subdev = subdevice;

	subdevice->type = COMEDI_SUBD_COUNTER;
	subdevice->subdev_flags = SDF_READABLE /* | SDF_COMMON */ ;
	subdevice->n_chan = board->cnt_channel_nbr;
	subdevice->maxdata = (1 << board->cnt_bits) - 1;
	subdevice->insn_read = cnt_rinsn;
	subdevice->insn_write = cnt_winsn;

	/*  select 20MHz clock */
	outb(3, dev->iobase + 248);

	/*  reset all counters */
	outb(0, dev->iobase);
	outb(0, dev->iobase + 0x20);
	outb(0, dev->iobase + 0x40);

	printk("comedi%d: " CNT_DRIVER_NAME " attached.\n", dev->minor);
	return 0;
}

/*-- detach -----------------------------------------------------------------*/

static int cnt_detach(struct comedi_device *dev)
{
	if (devpriv && devpriv->pcidev) {
		if (dev->iobase) {
			comedi_pci_disable(devpriv->pcidev);
		}
		pci_dev_put(devpriv->pcidev);
	}
	printk("comedi%d: " CNT_DRIVER_NAME " remove\n", dev->minor);
	return 0;
}
