summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorH Hartley Sweeten <hsweeten@visionengravers.com>2014-11-10 16:20:11 -0700
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2014-11-26 15:31:33 -0800
commit951fd40b28444e273404c2fb0b28d8e3cf5660b2 (patch)
tree6a4809ad7aaac0005863e62b2a062373ade000f6 /drivers
parent4484a23907724ad524d41e11dafa2a6be993420a (diff)
staging: comedi: addi_apci_1564: detect PLD revision for I/O mapping
The APCI-1564 has different I/O mapping depending on if the PLD revision is Rev 1.0 or Rev 2.x. The revision can be determined by reading the EEPROM register at offset 0x00 of PCI BAR 0 and checking the value of bits 7 to 4. Add this check to apci1564_auto_attach(). Currently this driver is coded to work with the Rev 2.x I/O mapping. For now, fail the attach if a Rev 1.0 PLD is detected. Document the I/O mapping for both revisions. Signed-off-by: H Hartley Sweeten <hsweeten@visionengravers.com> Reviewed-by: Ian Abbott <abbotti@mev.co.uk> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/staging/comedi/drivers/addi_apci_1564.c54
1 files changed, 51 insertions, 3 deletions
diff --git a/drivers/staging/comedi/drivers/addi_apci_1564.c b/drivers/staging/comedi/drivers/addi_apci_1564.c
index 4252054e86ea..f75803a39449 100644
--- a/drivers/staging/comedi/drivers/addi_apci_1564.c
+++ b/drivers/staging/comedi/drivers/addi_apci_1564.c
@@ -30,7 +30,44 @@
#include "comedi_fc.h"
#include "addi_watchdog.h"
+/*
+ * PCI BAR 0
+ *
+ * PLD Revision 1.0 I/O Mapping
+ * 0x00 93C76 EEPROM
+ * 0x04 - 0x18 Timer 12-Bit
+ *
+ * PLD Revision 2.x I/O Mapping
+ * 0x00 93C76 EEPROM
+ * 0x04 - 0x14 Digital Input
+ * 0x18 - 0x25 Digital Output
+ * 0x28 - 0x44 Watchdog 8-Bit
+ * 0x48 - 0x64 Timer 12-Bit
+ */
+#define APCI1564_EEPROM_REG 0x00
+#define APCI1564_EEPROM_VCC_STATUS (1 << 8)
+#define APCI1564_EEPROM_TO_REV(x) (((x) >> 4) & 0xf)
+#define APCI1564_EEPROM_DI (1 << 3)
+#define APCI1564_EEPROM_DO (1 << 2)
+#define APCI1564_EEPROM_CS (1 << 1)
+#define APCI1564_EEPROM_CLK (1 << 0)
+
+/*
+ * PCI BAR 1
+ *
+ * PLD Revision 1.0 I/O Mapping
+ * 0x00 - 0x10 Digital Input
+ * 0x14 - 0x20 Digital Output
+ * 0x24 - 0x3c Watchdog 8-Bit
+ *
+ * PLD Revision 2.x I/O Mapping
+ * 0x00 Counter_0
+ * 0x20 Counter_1
+ * 0x30 Counter_3
+ */
+
struct apci1564_private {
+ unsigned long eeprom; /* base address of EEPROM register */
unsigned long counters; /* base address of 32-bit counters */
unsigned int mode1; /* riding-edge/high level channels */
unsigned int mode2; /* falling-edge/low level channels */
@@ -352,6 +389,7 @@ static int apci1564_auto_attach(struct comedi_device *dev,
struct pci_dev *pcidev = comedi_to_pci_dev(dev);
struct apci1564_private *devpriv;
struct comedi_subdevice *s;
+ unsigned int val;
int ret;
devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
@@ -362,9 +400,19 @@ static int apci1564_auto_attach(struct comedi_device *dev,
if (ret)
return ret;
- /* PLD Revision 2.x I/O Mapping */
- dev->iobase = pci_resource_start(pcidev, 0);
- devpriv->counters = pci_resource_start(pcidev, 1);
+ /* read the EEPROM register and check the I/O map revision */
+ devpriv->eeprom = pci_resource_start(pcidev, 0);
+ val = inl(devpriv->eeprom + APCI1564_EEPROM_REG);
+ if (APCI1564_EEPROM_TO_REV(val) == 0) {
+ /* PLD Revision 1.0 I/O Mapping */
+ dev_err(dev->class_dev,
+ "PLD Revision 1.0 detected, not yet supported\n");
+ return -ENXIO;
+ } else {
+ /* PLD Revision 2.x I/O Mapping */
+ dev->iobase = devpriv->eeprom;
+ devpriv->counters = pci_resource_start(pcidev, 1);
+ }
apci1564_reset(dev);