[PATCH] staging: comedi: adv_pci_dio: separate out PCI-1760 support

H Hartley Sweeten hsweeten at visionengravers.com
Thu Nov 12 22:28:08 UTC 2015


The PCI-1760 board unique. It uses a outgoing/incoming mailbox programming
sequence to access the hardware. The other boards supported by this driver
use simple register mapping. Including support for the PCI-1760 in this
driver just makes it harder to understand.

Separate out the PCI-1760 support into a new driver, adv_pci1760.

Clean up the new driver. The original code had a bunch of CamelCase and
other checkpatch.pl issues.

The code used to access the outgoing/incoming mailboxes was also a bit
awkward with the passing of the arrays for the outgoing and incoming
mailbox bytes. Replace them with two new functions that send a command
and return the feedback data from the command based on the programming
flow chart in the datasheet for the PCI-1760.

The new adv_pci1760 driver also fixes the incomplete timer subdevice.
This subdevice is actually the 2 PWM outputs so the subdevice type
has been changed to COMEDI_SUBD_PWM.

The counter subdevice support was not complete in the original code.
For now that subdevice has been disabled (COMEDI_SUBD_UNUSED).

Signed-off-by: H Hartley Sweeten <hsweeten at visionengravers.com>
Cc: Ian Abbott <abbotti at mev.co.uk>
Cc: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
---
 drivers/staging/comedi/Kconfig               |  12 +-
 drivers/staging/comedi/drivers/Makefile      |   1 +
 drivers/staging/comedi/drivers/adv_pci1760.c | 432 +++++++++++++++++++++++++++
 drivers/staging/comedi/drivers/adv_pci_dio.c | 417 +-------------------------
 4 files changed, 445 insertions(+), 417 deletions(-)
 create mode 100644 drivers/staging/comedi/drivers/adv_pci1760.c

diff --git a/drivers/staging/comedi/Kconfig b/drivers/staging/comedi/Kconfig
index 945c85a..e7255f8 100644
--- a/drivers/staging/comedi/Kconfig
+++ b/drivers/staging/comedi/Kconfig
@@ -772,6 +772,14 @@ config COMEDI_ADV_PCI1724
 	  To compile this driver as a module, choose M here: the module will be
 	  called adv_pci1724.
 
+config COMEDI_ADV_PCI1760
+	tristate "Advantech PCI-1760 support"
+	---help---
+	  Enable support for Advantech PCI-1760 board.
+
+	  To compile this driver as a module, choose M here: the module will be
+	  called adv_pci1760.
+
 config COMEDI_ADV_PCI_DIO
 	tristate "Advantech PCI DIO card support"
 	select COMEDI_8254
@@ -779,8 +787,8 @@ config COMEDI_ADV_PCI_DIO
 	---help---
 	  Enable support for Advantech PCI DIO cards
 	  PCI-1730, PCI-1733, PCI-1734, PCI-1735U, PCI-1736UP, PCI-1739U,
-	  PCI-1750, PCI-1751, PCI-1752, PCI-1753/E, PCI-1754, PCI-1756,
-	  PCI-1760 and PCI-1762
+	  PCI-1750, PCI-1751, PCI-1752, PCI-1753/E, PCI-1754, PCI-1756 and
+	  PCI-1762
 
 	  To compile this driver as a module, choose M here: the module will be
 	  called adv_pci_dio.
diff --git a/drivers/staging/comedi/drivers/Makefile b/drivers/staging/comedi/drivers/Makefile
index 94c179b..0c8cfa7 100644
--- a/drivers/staging/comedi/drivers/Makefile
+++ b/drivers/staging/comedi/drivers/Makefile
@@ -81,6 +81,7 @@ obj-$(CONFIG_COMEDI_ADV_PCI1710)	+= adv_pci1710.o
 obj-$(CONFIG_COMEDI_ADV_PCI1720)	+= adv_pci1720.o
 obj-$(CONFIG_COMEDI_ADV_PCI1723)	+= adv_pci1723.o
 obj-$(CONFIG_COMEDI_ADV_PCI1724)	+= adv_pci1724.o
+obj-$(CONFIG_COMEDI_ADV_PCI1760)	+= adv_pci1760.o
 obj-$(CONFIG_COMEDI_ADV_PCI_DIO)	+= adv_pci_dio.o
 obj-$(CONFIG_COMEDI_AMPLC_DIO200_PCI)	+= amplc_dio200_pci.o
 obj-$(CONFIG_COMEDI_AMPLC_PC236_PCI)	+= amplc_pci236.o
diff --git a/drivers/staging/comedi/drivers/adv_pci1760.c b/drivers/staging/comedi/drivers/adv_pci1760.c
new file mode 100644
index 0000000..8d71165
--- /dev/null
+++ b/drivers/staging/comedi/drivers/adv_pci1760.c
@@ -0,0 +1,432 @@
+/*
+ * COMEDI driver for the Advantech PCI-1760
+ * Copyright (C) 2015 H Hartley Sweeten <hsweeten at visionengravers.com>
+ *
+ * Based on the pci1760 support in the adv_pci_dio driver written by:
+ *	Michal Dobes <dobes at tesnet.cz>
+ *
+ * COMEDI - Linux Control and Measurement Device Interface
+ * Copyright (C) 2000 David A. Schleef <ds at 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.
+ */
+
+/*
+ * Driver: adv_pci1760
+ * Description: Advantech PCI-1760 Relay & Isolated Digital Input Card
+ * Devices: [Advantech] PCI-1760 (adv_pci1760)
+ * Author: H Hartley Sweeten <hsweeten at visionengravers.com>
+ * Updated: Mon, 09 Jan 2012 12:40:46 +0000
+ * Status: untested
+ *
+ * Configuration Options: not applicable, uses PCI auto config
+ */
+
+#include <linux/module.h>
+
+#include "../comedi_pci.h"
+
+/*
+ * PCI-760 Register Map
+ *
+ * Outgoing Mailbox Bytes
+ * OMB3: Not used (must be 0)
+ * OMB2: The command code to the PCI-1760
+ * OMB1: The hi byte of the parameter for the command in OMB2
+ * OMB0: The lo byte of the parameter for the command in OMB2
+ *
+ * Incoming Mailbox Bytes
+ * IMB3: The Isolated Digital Input status (updated every 100us)
+ * IMB2: The current command (matches OMB2 when command is successful)
+ * IMB1: The hi byte of the feedback data for the command in OMB2
+ * IMB0: The lo byte of the feedback data for the command in OMB2
+ *
+ * Interrupt Control/Status
+ * INTCSR3: Not used (must be 0)
+ * INTCSR2: The interrupt status (read only)
+ * INTCSR1: Interrupt enable/disable
+ * INTCSR0: Not used (must be 0)
+ */
+#define PCI1760_OMB_REG(x)		(0x0c + (x))
+#define PCI1760_IMB_REG(x)		(0x1c + (x))
+#define PCI1760_INTCSR_REG(x)		(0x38 + (x))
+#define PCI1760_INTCSR1_IRQ_ENA		BIT(5)
+#define PCI1760_INTCSR2_OMB_IRQ		BIT(0)
+#define PCI1760_INTCSR2_IMB_IRQ		BIT(1)
+#define PCI1760_INTCSR2_IRQ_STATUS	BIT(6)
+#define PCI1760_INTCSR2_IRQ_ASSERTED	BIT(7)
+
+/* PCI-1760 command codes */
+#define PCI1760_CMD_CLR_IMB2		0x00	/* Clears IMB2 */
+#define PCI1760_CMD_SET_DO		0x01	/* Set output state */
+#define PCI1760_CMD_GET_DO		0x02	/* Read output status */
+#define PCI1760_CMD_GET_STATUS		0x03	/* Read current status */
+#define PCI1760_CMD_GET_FW_VER		0x0e	/* Read firware version */
+#define PCI1760_CMD_GET_HW_VER		0x0f	/* Read hardware version */
+#define PCI1760_CMD_SET_PWM_HI(x)	(0x10 + (x) * 2) /* Set "hi" period */
+#define PCI1760_CMD_SET_PWM_LO(x)	(0x11 + (x) * 2) /* Set "lo" period */
+#define PCI1760_CMD_SET_PWM_CNT(x)	(0x14 + (x)) /* Set burst count */
+#define PCI1760_CMD_ENA_PWM		0x1f	/* Enable PWM outputs */
+#define PCI1760_CMD_ENA_FILT		0x20	/* Enable input filter */
+#define PCI1760_CMD_ENA_PAT_MATCH	0x21	/* Enable input pattern match */
+#define PCI1760_CMD_SET_PAT_MATCH	0x22	/* Set input pattern match */
+#define PCI1760_CMD_ENA_RISE_EDGE	0x23	/* Enable input rising edge */
+#define PCI1760_CMD_ENA_FALL_EDGE	0x24	/* Enable input falling edge */
+#define PCI1760_CMD_ENA_CNT		0x28	/* Enable counter */
+#define PCI1760_CMD_RST_CNT		0x29	/* Reset counter */
+#define PCI1760_CMD_ENA_CNT_OFLOW	0x2a	/* Enable counter overflow */
+#define PCI1760_CMD_ENA_CNT_MATCH	0x2b	/* Enable counter match */
+#define PCI1760_CMD_SET_CNT_EDGE	0x2c	/* Set counter edge */
+#define PCI1760_CMD_GET_CNT		0x2f	/* Reads counter value */
+#define PCI1760_CMD_SET_HI_SAMP(x)	(0x30 + (x)) /* Set "hi" sample time */
+#define PCI1760_CMD_SET_LO_SAMP(x)	(0x38 + (x)) /* Set "lo" sample time */
+#define PCI1760_CMD_SET_CNT(x)		(0x40 + (x)) /* Set counter reset val */
+#define PCI1760_CMD_SET_CNT_MATCH(x)	(0x48 + (x)) /* Set counter match val */
+#define PCI1760_CMD_GET_INT_FLAGS	0x60	/* Read interrupt flags */
+#define PCI1760_CMD_GET_INT_FLAGS_MATCH	BIT(0)
+#define PCI1760_CMD_GET_INT_FLAGS_COS	BIT(1)
+#define PCI1760_CMD_GET_INT_FLAGS_OFLOW	BIT(2)
+#define PCI1760_CMD_GET_OS		0x61	/* Read edge change flags */
+#define PCI1760_CMD_GET_CNT_STATUS	0x62	/* Read counter oflow/match */
+
+#define PCI1760_CMD_TIMEOUT		250	/* 250 usec timeout */
+#define PCI1760_CMD_RETRIES		3	/* limit number of retries */
+
+#define PCI1760_PWM_TIMEBASE		100000	/* 1 unit = 100 usec */
+
+static int pci1760_send_cmd(struct comedi_device *dev,
+			    unsigned char cmd, unsigned short val)
+{
+	unsigned long timeout;
+
+	/* send the command and parameter */
+	outb(val & 0xff, dev->iobase + PCI1760_OMB_REG(0));
+	outb((val >> 8) & 0xff, dev->iobase + PCI1760_OMB_REG(1));
+	outb(cmd, dev->iobase + PCI1760_OMB_REG(2));
+	outb(0, dev->iobase + PCI1760_OMB_REG(3));
+
+	/* datasheet says to allow up to 250 usec for the command to complete */
+	timeout = jiffies + usecs_to_jiffies(PCI1760_CMD_TIMEOUT);
+	do {
+		if (inb(dev->iobase + PCI1760_IMB_REG(2)) == cmd) {
+			/* command success; return the feedback data */
+			return inb(dev->iobase + PCI1760_IMB_REG(0)) |
+			       (inb(dev->iobase + PCI1760_IMB_REG(1)) << 8);
+		}
+		cpu_relax();
+	} while (time_before(jiffies, timeout));
+
+	return -EBUSY;
+}
+
+static int pci1760_cmd(struct comedi_device *dev,
+		       unsigned char cmd, unsigned short val)
+{
+	int repeats;
+	int ret;
+
+	/* send PCI1760_CMD_CLR_IMB2 between identical commands */
+	if (inb(dev->iobase + PCI1760_IMB_REG(2)) == cmd) {
+		ret = pci1760_send_cmd(dev, PCI1760_CMD_CLR_IMB2, 0);
+		if (ret < 0) {
+			/* timeout? try it once more */
+			ret = pci1760_send_cmd(dev, PCI1760_CMD_CLR_IMB2, 0);
+			if (ret < 0)
+				return -ETIMEDOUT;
+		}
+	}
+
+	/* datasheet says to keep retrying the command */
+	for (repeats = 0; repeats < PCI1760_CMD_RETRIES; repeats++) {
+		ret = pci1760_send_cmd(dev, cmd, val);
+		if (ret >= 0)
+			return ret;
+	}
+
+	/* command failed! */
+	return -ETIMEDOUT;
+}
+
+static int pci1760_di_insn_bits(struct comedi_device *dev,
+				struct comedi_subdevice *s,
+				struct comedi_insn *insn,
+				unsigned int *data)
+{
+	data[1] = inb(dev->iobase + PCI1760_IMB_REG(3));
+
+	return insn->n;
+}
+
+static int pci1760_do_insn_bits(struct comedi_device *dev,
+				struct comedi_subdevice *s,
+				struct comedi_insn *insn,
+				unsigned int *data)
+{
+	int ret;
+
+	if (comedi_dio_update_state(s, data)) {
+		ret = pci1760_cmd(dev, PCI1760_CMD_SET_DO, s->state);
+		if (ret < 0)
+			return ret;
+	}
+
+	data[1] = s->state;
+
+	return insn->n;
+}
+
+static int pci1760_pwm_ns_to_div(unsigned int flags, unsigned int ns)
+{
+	unsigned int divisor;
+
+	switch (flags) {
+	case CMDF_ROUND_NEAREST:
+		divisor = DIV_ROUND_CLOSEST(ns, PCI1760_PWM_TIMEBASE);
+		break;
+	case CMDF_ROUND_UP:
+		divisor = DIV_ROUND_UP(ns, PCI1760_PWM_TIMEBASE);
+		break;
+	case CMDF_ROUND_DOWN:
+		divisor = ns / PCI1760_PWM_TIMEBASE;
+	default:
+		return -EINVAL;
+	}
+
+	if (divisor < 1)
+		divisor = 1;
+	if (divisor > 0xffff)
+		divisor = 0xffff;
+
+	return divisor;
+}
+
+static int pci1760_pwm_enable(struct comedi_device *dev,
+			      unsigned int chan, bool enable)
+{
+	int ret;
+
+	ret = pci1760_cmd(dev, PCI1760_CMD_GET_STATUS, PCI1760_CMD_ENA_PWM);
+	if (ret < 0)
+		return ret;
+
+	if (enable)
+		ret |= BIT(chan);
+	else
+		ret &= ~BIT(chan);
+
+	return pci1760_cmd(dev, PCI1760_CMD_ENA_PWM, ret);
+}
+
+static int pci1760_pwm_insn_config(struct comedi_device *dev,
+				   struct comedi_subdevice *s,
+				   struct comedi_insn *insn,
+				   unsigned int *data)
+{
+	unsigned int chan = CR_CHAN(insn->chanspec);
+	int hi_div;
+	int lo_div;
+	int ret;
+
+	switch (data[0]) {
+	case INSN_CONFIG_ARM:
+		ret = pci1760_pwm_enable(dev, chan, false);
+		if (ret < 0)
+			return ret;
+
+		if (data[1] > 0xffff)
+			return -EINVAL;
+		ret = pci1760_cmd(dev, PCI1760_CMD_SET_PWM_CNT(chan), data[1]);
+		if (ret < 0)
+			return ret;
+
+		ret = pci1760_pwm_enable(dev, chan, true);
+		if (ret < 0)
+			return ret;
+		break;
+	case INSN_CONFIG_DISARM:
+		ret = pci1760_pwm_enable(dev, chan, false);
+		if (ret < 0)
+			return ret;
+		break;
+	case INSN_CONFIG_PWM_OUTPUT:
+		ret = pci1760_pwm_enable(dev, chan, false);
+		if (ret < 0)
+			return ret;
+
+		hi_div = pci1760_pwm_ns_to_div(data[1], data[2]);
+		lo_div = pci1760_pwm_ns_to_div(data[3], data[4]);
+		if (hi_div < 0 || lo_div < 0)
+			return -EINVAL;
+		if ((hi_div * PCI1760_PWM_TIMEBASE) != data[2] ||
+		    (lo_div * PCI1760_PWM_TIMEBASE) != data[4]) {
+			data[2] = hi_div * PCI1760_PWM_TIMEBASE;
+			data[4] = lo_div * PCI1760_PWM_TIMEBASE;
+			return -EAGAIN;
+		}
+		ret = pci1760_cmd(dev, PCI1760_CMD_SET_PWM_HI(chan), hi_div);
+		if (ret < 0)
+			return ret;
+		ret = pci1760_cmd(dev, PCI1760_CMD_SET_PWM_LO(chan), lo_div);
+		if (ret < 0)
+			return ret;
+		break;
+	case INSN_CONFIG_GET_PWM_OUTPUT:
+		hi_div = pci1760_cmd(dev, PCI1760_CMD_GET_STATUS,
+				     PCI1760_CMD_SET_PWM_HI(chan));
+		lo_div = pci1760_cmd(dev, PCI1760_CMD_GET_STATUS,
+				     PCI1760_CMD_SET_PWM_LO(chan));
+		if (hi_div < 0 || lo_div < 0)
+			return -ETIMEDOUT;
+
+		data[1] = hi_div * PCI1760_PWM_TIMEBASE;
+		data[2] = lo_div * PCI1760_PWM_TIMEBASE;
+		break;
+	case INSN_CONFIG_GET_PWM_STATUS:
+		ret = pci1760_cmd(dev, PCI1760_CMD_GET_STATUS,
+				  PCI1760_CMD_ENA_PWM);
+		if (ret < 0)
+			return ret;
+
+		data[1] = (ret & BIT(chan)) ? 1 : 0;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return insn->n;
+}
+
+static void pci1760_reset(struct comedi_device *dev)
+{
+	int i;
+
+	/* disable interrupts (intcsr2 is read-only) */
+	outb(0, dev->iobase + PCI1760_INTCSR_REG(0));
+	outb(0, dev->iobase + PCI1760_INTCSR_REG(1));
+	outb(0, dev->iobase + PCI1760_INTCSR_REG(3));
+
+	/* disable counters */
+	pci1760_cmd(dev, PCI1760_CMD_ENA_CNT, 0);
+
+	/* disable overflow interrupts */
+	pci1760_cmd(dev, PCI1760_CMD_ENA_CNT_OFLOW, 0);
+
+	/* disable match */
+	pci1760_cmd(dev, PCI1760_CMD_ENA_CNT_MATCH, 0);
+
+	/* set match and counter reset values */
+	for (i = 0; i < 8; i++) {
+		pci1760_cmd(dev, PCI1760_CMD_SET_CNT_MATCH(i), 0x8000);
+		pci1760_cmd(dev, PCI1760_CMD_SET_CNT(i), 0x0000);
+	}
+
+	/* reset counters to reset values */
+	pci1760_cmd(dev, PCI1760_CMD_RST_CNT, 0xff);
+
+	/* set counter count edges */
+	pci1760_cmd(dev, PCI1760_CMD_SET_CNT_EDGE, 0);
+
+	/* disable input filters */
+	pci1760_cmd(dev, PCI1760_CMD_ENA_FILT, 0);
+
+	/* disable pattern matching */
+	pci1760_cmd(dev, PCI1760_CMD_ENA_PAT_MATCH, 0);
+
+	/* set pattern match value */
+	pci1760_cmd(dev, PCI1760_CMD_SET_PAT_MATCH, 0);
+}
+
+static int pci1760_auto_attach(struct comedi_device *dev,
+			       unsigned long context)
+{
+	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, 0);
+
+	pci1760_reset(dev);
+
+	ret = comedi_alloc_subdevices(dev, 4);
+	if (ret)
+		return ret;
+
+	/* Digital Input subdevice */
+	s = &dev->subdevices[0];
+	s->type		= COMEDI_SUBD_DI;
+	s->subdev_flags	= SDF_READABLE;
+	s->n_chan	= 8;
+	s->maxdata	= 1;
+	s->range_table	= &range_digital;
+	s->insn_bits	= pci1760_di_insn_bits;
+
+	/* Digital Output subdevice */
+	s = &dev->subdevices[1];
+	s->type		= COMEDI_SUBD_DO;
+	s->subdev_flags	= SDF_WRITABLE;
+	s->n_chan	= 8;
+	s->maxdata	= 1;
+	s->range_table	= &range_digital;
+	s->insn_bits	= pci1760_do_insn_bits;
+
+	/* get the current state of the outputs */
+	ret = pci1760_cmd(dev, PCI1760_CMD_GET_DO, 0);
+	if (ret < 0)
+		return ret;
+	s->state	= ret;
+
+	/* PWM subdevice */
+	s = &dev->subdevices[2];
+	s->type		= COMEDI_SUBD_PWM;
+	s->subdev_flags	= SDF_PWM_COUNTER;
+	s->n_chan	= 2;
+	s->insn_config	= pci1760_pwm_insn_config;
+
+	/* Counter subdevice */
+	s = &dev->subdevices[3];
+	s->type		= COMEDI_SUBD_UNUSED;
+
+	return 0;
+}
+
+static struct comedi_driver pci1760_driver = {
+	.driver_name	= "adv_pci1760",
+	.module		= THIS_MODULE,
+	.auto_attach	= pci1760_auto_attach,
+	.detach		= comedi_pci_detach,
+};
+
+static int pci1760_pci_probe(struct pci_dev *dev,
+			     const struct pci_device_id *id)
+{
+	return comedi_pci_auto_config(dev, &pci1760_driver, id->driver_data);
+}
+
+static const struct pci_device_id pci1760_pci_table[] = {
+	{ PCI_DEVICE(PCI_VENDOR_ID_ADVANTECH, 0x1760) },
+	{ 0 }
+};
+MODULE_DEVICE_TABLE(pci, pci1760_pci_table);
+
+static struct pci_driver pci1760_pci_driver = {
+	.name		= "adv_pci1760",
+	.id_table	= pci1760_pci_table,
+	.probe		= pci1760_pci_probe,
+	.remove		= comedi_pci_auto_unconfig,
+};
+module_comedi_pci_driver(pci1760_driver, pci1760_pci_driver);
+
+MODULE_AUTHOR("Comedi http://www.comedi.org");
+MODULE_DESCRIPTION("Comedi driver for Advantech PCI-1760");
+MODULE_LICENSE("GPL");
diff --git a/drivers/staging/comedi/drivers/adv_pci_dio.c b/drivers/staging/comedi/drivers/adv_pci_dio.c
index f1b3c5a..05df1ec 100644
--- a/drivers/staging/comedi/drivers/adv_pci_dio.c
+++ b/drivers/staging/comedi/drivers/adv_pci_dio.c
@@ -9,13 +9,13 @@
 Driver: adv_pci_dio
 Description: Advantech PCI-1730, PCI-1733, PCI-1734, PCI-1735U,
 	PCI-1736UP, PCI-1739U, PCI-1750, PCI-1751, PCI-1752,
-	PCI-1753/E, PCI-1754, PCI-1756, PCI-1760, PCI-1762
+	PCI-1753/E, PCI-1754, PCI-1756, PCI-1762
 Author: Michal Dobes <dobes at tesnet.cz>
 Devices: [Advantech] PCI-1730 (adv_pci_dio), PCI-1733,
   PCI-1734, PCI-1735U, PCI-1736UP, PCI-1739U, PCI-1750,
   PCI-1751, PCI-1752, PCI-1753,
   PCI-1753+PCI-1753E, PCI-1754, PCI-1756,
-  PCI-1760, PCI-1762
+  PCI-1762
 Status: untested
 Updated: Mon, 09 Jan 2012 12:40:46 +0000
 
@@ -46,7 +46,6 @@ enum hw_cards_id {
 	TYPE_PCI1752,
 	TYPE_PCI1753, TYPE_PCI1753E,
 	TYPE_PCI1754, TYPE_PCI1756,
-	TYPE_PCI1760,
 	TYPE_PCI1762
 };
 
@@ -141,84 +140,6 @@ enum hw_io_access {
 #define PCI1762_ICR	   6	/* W:   Interrupt control register */
 #define PCI1762_ISR	   6	/* R:   Interrupt status register */
 
-/*  Advantech PCI-1760 registers */
-#define OMB0		0x0c	/* W:   Mailbox outgoing registers */
-#define OMB1		0x0d
-#define OMB2		0x0e
-#define OMB3		0x0f
-#define IMB0		0x1c	/* R:   Mailbox incoming registers */
-#define IMB1		0x1d
-#define IMB2		0x1e
-#define IMB3		0x1f
-#define INTCSR0		0x38	/* R/W: Interrupt control registers */
-#define INTCSR1		0x39
-#define INTCSR2		0x3a
-#define INTCSR3		0x3b
-
-/*  PCI-1760 mailbox commands */
-#define CMD_ClearIMB2		0x00	/* Clear IMB2 status and return actual
-					 * DI status in IMB3 */
-#define CMD_SetRelaysOutput	0x01	/* Set relay output from OMB0 */
-#define CMD_GetRelaysStatus	0x02	/* Get relay status to IMB0 */
-#define CMD_ReadCurrentStatus	0x07	/* Read the current status of the
-					 * register in OMB0, result in IMB0 */
-#define CMD_ReadFirmwareVersion	0x0e	/* Read the firmware ver., result in
-					 * IMB1.IMB0 */
-#define CMD_ReadHardwareVersion	0x0f	/* Read the hardware ver., result in
-					 * IMB1.IMB0 */
-#define CMD_EnableIDIFilters	0x20	/* Enable IDI filters based on bits in
-					 * OMB0 */
-#define CMD_EnableIDIPatternMatch 0x21	/* Enable IDI pattern match based on
-					 * bits in OMB0 */
-#define CMD_SetIDIPatternMatch	0x22	/* Enable IDI pattern match based on
-					 * bits in OMB0 */
-#define CMD_EnableIDICounters	0x28	/* Enable IDI counters based on bits in
-					 * OMB0 */
-#define CMD_ResetIDICounters	0x29	/* Reset IDI counters based on bits in
-					 * OMB0 to its reset values */
-#define CMD_OverflowIDICounters	0x2a	/* Enable IDI counters overflow
-					 * interrupts  based on bits in OMB0 */
-#define CMD_MatchIntIDICounters	0x2b	/* Enable IDI counters match value
-					 * interrupts  based on bits in OMB0 */
-#define CMD_EdgeIDICounters	0x2c	/* Set IDI up counters count edge (bit=0
-					 * - rising, =1 - falling) */
-#define CMD_GetIDICntCurValue	0x2f	/* Read IDI{OMB0} up counter current
-					 * value */
-#define CMD_SetIDI0CntResetValue 0x40	/* Set IDI0 Counter Reset Value
-					 * 256*OMB1+OMB0 */
-#define CMD_SetIDI1CntResetValue 0x41	/* Set IDI1 Counter Reset Value
-					 * 256*OMB1+OMB0 */
-#define CMD_SetIDI2CntResetValue 0x42	/* Set IDI2 Counter Reset Value
-					 * 256*OMB1+OMB0 */
-#define CMD_SetIDI3CntResetValue 0x43	/* Set IDI3 Counter Reset Value
-					 * 256*OMB1+OMB0 */
-#define CMD_SetIDI4CntResetValue 0x44	/* Set IDI4 Counter Reset Value
-					 * 256*OMB1+OMB0 */
-#define CMD_SetIDI5CntResetValue 0x45	/* Set IDI5 Counter Reset Value
-					 * 256*OMB1+OMB0 */
-#define CMD_SetIDI6CntResetValue 0x46	/* Set IDI6 Counter Reset Value
-					 * 256*OMB1+OMB0 */
-#define CMD_SetIDI7CntResetValue 0x47	/* Set IDI7 Counter Reset Value
-					 * 256*OMB1+OMB0 */
-#define CMD_SetIDI0CntMatchValue 0x48	/* Set IDI0 Counter Match Value
-					 * 256*OMB1+OMB0 */
-#define CMD_SetIDI1CntMatchValue 0x49	/* Set IDI1 Counter Match Value
-					 * 256*OMB1+OMB0 */
-#define CMD_SetIDI2CntMatchValue 0x4a	/* Set IDI2 Counter Match Value
-					 * 256*OMB1+OMB0 */
-#define CMD_SetIDI3CntMatchValue 0x4b	/* Set IDI3 Counter Match Value
-					 * 256*OMB1+OMB0 */
-#define CMD_SetIDI4CntMatchValue 0x4c	/* Set IDI4 Counter Match Value
-					 * 256*OMB1+OMB0 */
-#define CMD_SetIDI5CntMatchValue 0x4d	/* Set IDI5 Counter Match Value
-					 * 256*OMB1+OMB0 */
-#define CMD_SetIDI6CntMatchValue 0x4e	/* Set IDI6 Counter Match Value
-					 * 256*OMB1+OMB0 */
-#define CMD_SetIDI7CntMatchValue 0x4f	/* Set IDI7 Counter Match Value
-					 * 256*OMB1+OMB0 */
-
-#define OMBCMD_RETRY	0x03	/* 3 times try request before error */
-
 struct diosubd_data {
 	int chans;		/*  num of chans */
 	int addr;		/*  PCI address ofset */
@@ -365,14 +286,6 @@ static const struct dio_boardtype boardtypes[] = {
 		.boardid	= { 4, PCI175x_BOARDID, 1, SDF_INTERNAL, },
 		.io_access	= IO_16b,
 	},
-	[TYPE_PCI1760] = {
-		/* This card has its own 'attach' */
-		.name		= "pci1760",
-		.main_pci_region = 0,
-		.cardtype	= TYPE_PCI1760,
-		.nsubdevs	= 4,
-		.io_access	= IO_8b,
-	},
 	[TYPE_PCI1762] = {
 		.name		= "pci1762",
 		.main_pci_region = PCIDIO_MAINREG,
@@ -387,21 +300,6 @@ static const struct dio_boardtype boardtypes[] = {
 
 struct pci_dio_private {
 	char GlobalIrqEnabled;	/*  1= any IRQ source is enabled */
-	/*  PCI-1760 specific data */
-	unsigned char IDICntEnable;	/* counter's counting enable status */
-	unsigned char IDICntOverEnable;	/* counter's overflow interrupts enable
-					 * status */
-	unsigned char IDICntMatchEnable;	/* counter's match interrupts
-						 * enable status */
-	unsigned char IDICntEdge;	/* counter's count edge value
-					 * (bit=0 - rising, =1 - falling) */
-	unsigned short CntResValue[8];	/*  counters' reset value */
-	unsigned short CntMatchValue[8]; /*  counters' match interrupt value */
-	unsigned char IDIFiltersEn; /*  IDI's digital filters enable status */
-	unsigned char IDIPatMatchEn;	/*  IDI's pattern match enable status */
-	unsigned char IDIPatMatchValue;	/*  IDI's pattern match value */
-	unsigned short IDIFiltrLow[8];	/*  IDI's filter value low signal */
-	unsigned short IDIFiltrHigh[8];	/*  IDI's filter value high signal */
 };
 
 /*
@@ -476,260 +374,6 @@ static int pci_dio_insn_bits_do_w(struct comedi_device *dev,
 	return insn->n;
 }
 
-/*
-==============================================================================
-*/
-static int pci1760_unchecked_mbxrequest(struct comedi_device *dev,
-					unsigned char *omb, unsigned char *imb,
-					int repeats)
-{
-	int cnt, tout, ok = 0;
-
-	for (cnt = 0; cnt < repeats; cnt++) {
-		outb(omb[0], dev->iobase + OMB0);
-		outb(omb[1], dev->iobase + OMB1);
-		outb(omb[2], dev->iobase + OMB2);
-		outb(omb[3], dev->iobase + OMB3);
-		for (tout = 0; tout < 251; tout++) {
-			imb[2] = inb(dev->iobase + IMB2);
-			if (imb[2] == omb[2]) {
-				imb[0] = inb(dev->iobase + IMB0);
-				imb[1] = inb(dev->iobase + IMB1);
-				imb[3] = inb(dev->iobase + IMB3);
-				ok = 1;
-				break;
-			}
-			udelay(1);
-		}
-		if (ok)
-			return 0;
-	}
-
-	dev_err(dev->class_dev, "PCI-1760 mailbox request timeout!\n");
-	return -ETIME;
-}
-
-static int pci1760_clear_imb2(struct comedi_device *dev)
-{
-	unsigned char omb[4] = { 0x0, 0x0, CMD_ClearIMB2, 0x0 };
-	unsigned char imb[4];
-	/* check if imb2 is already clear */
-	if (inb(dev->iobase + IMB2) == CMD_ClearIMB2)
-		return 0;
-	return pci1760_unchecked_mbxrequest(dev, omb, imb, OMBCMD_RETRY);
-}
-
-static int pci1760_mbxrequest(struct comedi_device *dev,
-			      unsigned char *omb, unsigned char *imb)
-{
-	if (omb[2] == CMD_ClearIMB2) {
-		dev_err(dev->class_dev,
-			"bug! this function should not be used for CMD_ClearIMB2 command\n");
-		return -EINVAL;
-	}
-	if (inb(dev->iobase + IMB2) == omb[2]) {
-		int retval;
-
-		retval = pci1760_clear_imb2(dev);
-		if (retval < 0)
-			return retval;
-	}
-	return pci1760_unchecked_mbxrequest(dev, omb, imb, OMBCMD_RETRY);
-}
-
-/*
-==============================================================================
-*/
-static int pci1760_insn_bits_di(struct comedi_device *dev,
-				struct comedi_subdevice *s,
-				struct comedi_insn *insn, unsigned int *data)
-{
-	data[1] = inb(dev->iobase + IMB3);
-
-	return insn->n;
-}
-
-static int pci1760_insn_bits_do(struct comedi_device *dev,
-				struct comedi_subdevice *s,
-				struct comedi_insn *insn,
-				unsigned int *data)
-{
-	int ret;
-	unsigned char omb[4] = {
-		0x00,
-		0x00,
-		CMD_SetRelaysOutput,
-		0x00
-	};
-	unsigned char imb[4];
-
-	if (comedi_dio_update_state(s, data)) {
-		omb[0] = s->state;
-		ret = pci1760_mbxrequest(dev, omb, imb);
-		if (!ret)
-			return ret;
-	}
-
-	data[1] = s->state;
-
-	return insn->n;
-}
-
-/*
-==============================================================================
-*/
-static int pci1760_insn_cnt_read(struct comedi_device *dev,
-				 struct comedi_subdevice *s,
-				 struct comedi_insn *insn, unsigned int *data)
-{
-	int ret, n;
-	unsigned char omb[4] = {
-		CR_CHAN(insn->chanspec) & 0x07,
-		0x00,
-		CMD_GetIDICntCurValue,
-		0x00
-	};
-	unsigned char imb[4];
-
-	for (n = 0; n < insn->n; n++) {
-		ret = pci1760_mbxrequest(dev, omb, imb);
-		if (!ret)
-			return ret;
-		data[n] = (imb[1] << 8) + imb[0];
-	}
-
-	return n;
-}
-
-/*
-==============================================================================
-*/
-static int pci1760_insn_cnt_write(struct comedi_device *dev,
-				  struct comedi_subdevice *s,
-				  struct comedi_insn *insn, unsigned int *data)
-{
-	struct pci_dio_private *devpriv = dev->private;
-	int ret;
-	unsigned char chan = CR_CHAN(insn->chanspec) & 0x07;
-	unsigned char bitmask = 1 << chan;
-	unsigned char omb[4] = {
-		data[0] & 0xff,
-		(data[0] >> 8) & 0xff,
-		CMD_SetIDI0CntResetValue + chan,
-		0x00
-	};
-	unsigned char imb[4];
-
-	/* Set reset value if different */
-	if (devpriv->CntResValue[chan] != (data[0] & 0xffff)) {
-		ret = pci1760_mbxrequest(dev, omb, imb);
-		if (!ret)
-			return ret;
-		devpriv->CntResValue[chan] = data[0] & 0xffff;
-	}
-
-	omb[0] = bitmask;	/*  reset counter to it reset value */
-	omb[2] = CMD_ResetIDICounters;
-	ret = pci1760_mbxrequest(dev, omb, imb);
-	if (!ret)
-		return ret;
-
-	/*  start counter if it don't run */
-	if (!(bitmask & devpriv->IDICntEnable)) {
-		omb[0] = bitmask;
-		omb[2] = CMD_EnableIDICounters;
-		ret = pci1760_mbxrequest(dev, omb, imb);
-		if (!ret)
-			return ret;
-		devpriv->IDICntEnable |= bitmask;
-	}
-	return 1;
-}
-
-/*
-==============================================================================
-*/
-static int pci1760_reset(struct comedi_device *dev)
-{
-	struct pci_dio_private *devpriv = dev->private;
-	int i;
-	unsigned char omb[4] = { 0x00, 0x00, 0x00, 0x00 };
-	unsigned char imb[4];
-
-	outb(0, dev->iobase + INTCSR0);	/*  disable IRQ */
-	outb(0, dev->iobase + INTCSR1);
-	outb(0, dev->iobase + INTCSR2);
-	outb(0, dev->iobase + INTCSR3);
-	devpriv->GlobalIrqEnabled = 0;
-
-	omb[0] = 0x00;
-	omb[2] = CMD_SetRelaysOutput;	/*  reset relay outputs */
-	pci1760_mbxrequest(dev, omb, imb);
-
-	omb[0] = 0x00;
-	omb[2] = CMD_EnableIDICounters;	/*  disable IDI up counters */
-	pci1760_mbxrequest(dev, omb, imb);
-	devpriv->IDICntEnable = 0;
-
-	omb[0] = 0x00;
-	omb[2] = CMD_OverflowIDICounters; /* disable counters overflow
-					   * interrupts */
-	pci1760_mbxrequest(dev, omb, imb);
-	devpriv->IDICntOverEnable = 0;
-
-	omb[0] = 0x00;
-	omb[2] = CMD_MatchIntIDICounters; /* disable counters match value
-					   * interrupts */
-	pci1760_mbxrequest(dev, omb, imb);
-	devpriv->IDICntMatchEnable = 0;
-
-	omb[0] = 0x00;
-	omb[1] = 0x80;
-	for (i = 0; i < 8; i++) {	/*  set IDI up counters match value */
-		omb[2] = CMD_SetIDI0CntMatchValue + i;
-		pci1760_mbxrequest(dev, omb, imb);
-		devpriv->CntMatchValue[i] = 0x8000;
-	}
-
-	omb[0] = 0x00;
-	omb[1] = 0x00;
-	for (i = 0; i < 8; i++) {	/*  set IDI up counters reset value */
-		omb[2] = CMD_SetIDI0CntResetValue + i;
-		pci1760_mbxrequest(dev, omb, imb);
-		devpriv->CntResValue[i] = 0x0000;
-	}
-
-	omb[0] = 0xff;
-	omb[2] = CMD_ResetIDICounters; /* reset IDI up counters to reset
-					* values */
-	pci1760_mbxrequest(dev, omb, imb);
-
-	omb[0] = 0x00;
-	omb[2] = CMD_EdgeIDICounters;	/*  set IDI up counters count edge */
-	pci1760_mbxrequest(dev, omb, imb);
-	devpriv->IDICntEdge = 0x00;
-
-	omb[0] = 0x00;
-	omb[2] = CMD_EnableIDIFilters;	/*  disable all digital in filters */
-	pci1760_mbxrequest(dev, omb, imb);
-	devpriv->IDIFiltersEn = 0x00;
-
-	omb[0] = 0x00;
-	omb[2] = CMD_EnableIDIPatternMatch;	/*  disable pattern matching */
-	pci1760_mbxrequest(dev, omb, imb);
-	devpriv->IDIPatMatchEn = 0x00;
-
-	omb[0] = 0x00;
-	omb[2] = CMD_SetIDIPatternMatch;	/*  set pattern match value */
-	pci1760_mbxrequest(dev, omb, imb);
-	devpriv->IDIPatMatchValue = 0x00;
-
-	return 0;
-}
-
-/*
-==============================================================================
-*/
 static int pci_dio_reset(struct comedi_device *dev)
 {
 	const struct dio_boardtype *board = dev->board_ptr;
@@ -821,9 +465,6 @@ static int pci_dio_reset(struct comedi_device *dev)
 		outw(0, dev->iobase + PCI1756_IDO);	/*  clear outputs */
 		outw(0, dev->iobase + PCI1756_IDO + 2);
 		break;
-	case TYPE_PCI1760:
-		pci1760_reset(dev);
-		break;
 	case TYPE_PCI1762:
 		outw(0x0101, dev->iobase + PCI1762_ICR); /* disable & clear
 							  * interrupts */
@@ -833,56 +474,6 @@ static int pci_dio_reset(struct comedi_device *dev)
 	return 0;
 }
 
-/*
-==============================================================================
-*/
-static int pci1760_attach(struct comedi_device *dev)
-{
-	struct comedi_subdevice *s;
-
-	s = &dev->subdevices[0];
-	s->type = COMEDI_SUBD_DI;
-	s->subdev_flags = SDF_READABLE;
-	s->n_chan = 8;
-	s->maxdata = 1;
-	s->len_chanlist = 8;
-	s->range_table = &range_digital;
-	s->insn_bits = pci1760_insn_bits_di;
-
-	s = &dev->subdevices[1];
-	s->type = COMEDI_SUBD_DO;
-	s->subdev_flags = SDF_WRITABLE;
-	s->n_chan = 8;
-	s->maxdata = 1;
-	s->len_chanlist = 8;
-	s->range_table = &range_digital;
-	s->state = 0;
-	s->insn_bits = pci1760_insn_bits_do;
-
-	s = &dev->subdevices[2];
-	s->type = COMEDI_SUBD_TIMER;
-	s->subdev_flags = SDF_WRITABLE | SDF_LSAMPL;
-	s->n_chan = 2;
-	s->maxdata = 0xffffffff;
-	s->len_chanlist = 2;
-/*       s->insn_config=pci1760_insn_pwm_cfg; */
-
-	s = &dev->subdevices[3];
-	s->type = COMEDI_SUBD_COUNTER;
-	s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
-	s->n_chan = 8;
-	s->maxdata = 0xffff;
-	s->len_chanlist = 8;
-	s->insn_read = pci1760_insn_cnt_read;
-	s->insn_write = pci1760_insn_cnt_write;
-/*       s->insn_config=pci1760_insn_cnt_cfg; */
-
-	return 0;
-}
-
-/*
-==============================================================================
-*/
 static int pci_dio_add_di(struct comedi_device *dev,
 			  struct comedi_subdevice *s,
 			  const struct diosubd_data *d)
@@ -1050,9 +641,6 @@ static int pci_dio_auto_attach(struct comedi_device *dev,
 		subdev++;
 	}
 
-	if (board->cardtype == TYPE_PCI1760)
-		pci1760_attach(dev);
-
 	pci_dio_reset(dev);
 
 	return 0;
@@ -1094,7 +682,6 @@ static const struct pci_device_id adv_pci_dio_pci_table[] = {
 	{ PCI_VDEVICE(ADVANTECH, 0x1753), TYPE_PCI1753 },
 	{ PCI_VDEVICE(ADVANTECH, 0x1754), TYPE_PCI1754 },
 	{ PCI_VDEVICE(ADVANTECH, 0x1756), TYPE_PCI1756 },
-	{ PCI_VDEVICE(ADVANTECH, 0x1760), TYPE_PCI1760 },
 	{ PCI_VDEVICE(ADVANTECH, 0x1762), TYPE_PCI1762 },
 	{ 0 }
 };
-- 
2.5.1



More information about the devel mailing list