From 951fd40b28444e273404c2fb0b28d8e3cf5660b2 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 10 Nov 2014 16:20:11 -0700 Subject: [PATCH] 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 Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- .../staging/comedi/drivers/addi_apci_1564.c | 54 +++++++++++++++++-- 1 file 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); -- 2.34.1