Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 951fd40b authored by H Hartley Sweeten's avatar H Hartley Sweeten Committed by Greg Kroah-Hartman
Browse files

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: default avatarH Hartley Sweeten <hsweeten@visionengravers.com>
Reviewed-by: default avatarIan Abbott <abbotti@mev.co.uk>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 4484a239
Loading
Loading
Loading
Loading
+51 −3
Original line number Original line Diff line number Diff line
@@ -30,7 +30,44 @@
#include "comedi_fc.h"
#include "comedi_fc.h"
#include "addi_watchdog.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 {
struct apci1564_private {
	unsigned long eeprom;		/* base address of EEPROM register */
	unsigned long counters;		/* base address of 32-bit counters */
	unsigned long counters;		/* base address of 32-bit counters */
	unsigned int mode1;		/* riding-edge/high level channels */
	unsigned int mode1;		/* riding-edge/high level channels */
	unsigned int mode2;		/* falling-edge/low 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 pci_dev *pcidev = comedi_to_pci_dev(dev);
	struct apci1564_private *devpriv;
	struct apci1564_private *devpriv;
	struct comedi_subdevice *s;
	struct comedi_subdevice *s;
	unsigned int val;
	int ret;
	int ret;


	devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
	devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
@@ -362,9 +400,19 @@ static int apci1564_auto_attach(struct comedi_device *dev,
	if (ret)
	if (ret)
		return ret;
		return ret;


	/* 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 */
		/* PLD Revision 2.x I/O Mapping */
	dev->iobase = pci_resource_start(pcidev, 0);
		dev->iobase = devpriv->eeprom;
		devpriv->counters = pci_resource_start(pcidev, 1);
		devpriv->counters = pci_resource_start(pcidev, 1);
	}


	apci1564_reset(dev);
	apci1564_reset(dev);