staging: comedi: addi_apci_1564: store PCI BAR 1 base address in private data
According to ADDI-DATA, only the PLD Revision 2.x versions of the APCI-1564 have the 3 counters. The base address for these counters is found in PCI BAR 1. For aesthetics, save this base address in the private data. The dev->iobase can then be used for the main registers of the board. 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>
This commit is contained in:
parent
950a6f8714
commit
63f9c51a52
|
@ -47,7 +47,7 @@
|
|||
#define APCI1564_TIMER_WARN_TIMEBASE_REG 0x64
|
||||
|
||||
/*
|
||||
* dev->iobase Register Map
|
||||
* devpriv->counters Register Map
|
||||
*/
|
||||
#define APCI1564_COUNTER_REG(x) (0x00 + ((x) * 0x20))
|
||||
#define APCI1564_COUNTER_RELOAD_REG(x) (0x04 + ((x) * 0x20))
|
||||
|
@ -93,12 +93,12 @@ static int apci1564_timer_config(struct comedi_device *dev,
|
|||
outl(0x0, devpriv->amcc_iobase + APCI1564_DI_IRQ_REG);
|
||||
outl(0x0, devpriv->amcc_iobase + APCI1564_DO_IRQ_REG);
|
||||
outl(0x0, devpriv->amcc_iobase + APCI1564_WDOG_IRQ_REG);
|
||||
outl(0x0, dev->iobase +
|
||||
APCI1564_COUNTER_IRQ_REG(0));
|
||||
outl(0x0, dev->iobase +
|
||||
APCI1564_COUNTER_IRQ_REG(1));
|
||||
outl(0x0, dev->iobase +
|
||||
APCI1564_COUNTER_IRQ_REG(2));
|
||||
outl(0x0,
|
||||
devpriv->counters + APCI1564_COUNTER_IRQ_REG(0));
|
||||
outl(0x0,
|
||||
devpriv->counters + APCI1564_COUNTER_IRQ_REG(1));
|
||||
outl(0x0,
|
||||
devpriv->counters + APCI1564_COUNTER_IRQ_REG(2));
|
||||
} else {
|
||||
/* disable Timer interrupt */
|
||||
outl(0x0, devpriv->amcc_iobase + APCI1564_TIMER_CTRL_REG);
|
||||
|
@ -118,16 +118,16 @@ static int apci1564_timer_config(struct comedi_device *dev,
|
|||
devpriv->timer_select_mode = ADDIDATA_COUNTER;
|
||||
|
||||
/* First Stop The Counter */
|
||||
ul_Command1 = inl(dev->iobase +
|
||||
APCI1564_COUNTER_CTRL_REG(chan));
|
||||
ul_Command1 = inl(devpriv->counters +
|
||||
APCI1564_COUNTER_CTRL_REG(chan));
|
||||
ul_Command1 = ul_Command1 & 0xFFFFF9FEUL;
|
||||
/* Stop The Timer */
|
||||
outl(ul_Command1, dev->iobase +
|
||||
APCI1564_COUNTER_CTRL_REG(chan));
|
||||
outl(ul_Command1,
|
||||
devpriv->counters + APCI1564_COUNTER_CTRL_REG(chan));
|
||||
|
||||
/* Set the reload value */
|
||||
outl(data[3], dev->iobase +
|
||||
APCI1564_COUNTER_RELOAD_REG(chan));
|
||||
outl(data[3],
|
||||
devpriv->counters + APCI1564_COUNTER_RELOAD_REG(chan));
|
||||
|
||||
/* Set the mode : */
|
||||
/* - Disable the hardware */
|
||||
|
@ -140,18 +140,18 @@ static int apci1564_timer_config(struct comedi_device *dev,
|
|||
ul_Command1 =
|
||||
(ul_Command1 & 0xFFFC19E2UL) | 0x80000UL |
|
||||
(unsigned int) ((unsigned int) data[4] << 16UL);
|
||||
outl(ul_Command1, dev->iobase +
|
||||
APCI1564_COUNTER_CTRL_REG(chan));
|
||||
outl(ul_Command1,
|
||||
devpriv->counters + APCI1564_COUNTER_CTRL_REG(chan));
|
||||
|
||||
/* Enable or Disable Interrupt */
|
||||
ul_Command1 = (ul_Command1 & 0xFFFFF9FD) | (data[1] << 1);
|
||||
outl(ul_Command1, dev->iobase +
|
||||
APCI1564_COUNTER_CTRL_REG(chan));
|
||||
outl(ul_Command1,
|
||||
devpriv->counters + APCI1564_COUNTER_CTRL_REG(chan));
|
||||
|
||||
/* Set the Up/Down selection */
|
||||
ul_Command1 = (ul_Command1 & 0xFFFBF9FFUL) | (data[6] << 18);
|
||||
outl(ul_Command1, dev->iobase +
|
||||
APCI1564_COUNTER_CTRL_REG(chan));
|
||||
outl(ul_Command1,
|
||||
devpriv->counters + APCI1564_COUNTER_CTRL_REG(chan));
|
||||
} else {
|
||||
dev_err(dev->class_dev, "Invalid subdevice.\n");
|
||||
}
|
||||
|
@ -188,9 +188,8 @@ static int apci1564_timer_write(struct comedi_device *dev,
|
|||
outl(ul_Command1, devpriv->amcc_iobase + APCI1564_TIMER_CTRL_REG);
|
||||
}
|
||||
} else if (devpriv->timer_select_mode == ADDIDATA_COUNTER) {
|
||||
ul_Command1 =
|
||||
inl(dev->iobase +
|
||||
APCI1564_COUNTER_CTRL_REG(chan));
|
||||
ul_Command1 = inl(devpriv->counters +
|
||||
APCI1564_COUNTER_CTRL_REG(chan));
|
||||
if (data[1] == 1) {
|
||||
/* Start the Counter subdevice */
|
||||
ul_Command1 = (ul_Command1 & 0xFFFFF9FFUL) | 0x1UL;
|
||||
|
@ -202,8 +201,8 @@ static int apci1564_timer_write(struct comedi_device *dev,
|
|||
/* Clears the Counter subdevice */
|
||||
ul_Command1 = (ul_Command1 & 0xFFFFF9FFUL) | 0x400;
|
||||
}
|
||||
outl(ul_Command1, dev->iobase +
|
||||
APCI1564_COUNTER_CTRL_REG(chan));
|
||||
outl(ul_Command1,
|
||||
devpriv->counters + APCI1564_COUNTER_CTRL_REG(chan));
|
||||
} else {
|
||||
dev_err(dev->class_dev, "Invalid subdevice.\n");
|
||||
}
|
||||
|
@ -230,12 +229,10 @@ static int apci1564_timer_read(struct comedi_device *dev,
|
|||
data[1] = inl(devpriv->amcc_iobase + APCI1564_TIMER_REG);
|
||||
} else if (devpriv->timer_select_mode == ADDIDATA_COUNTER) {
|
||||
/* Read the Counter Actual Value. */
|
||||
data[0] =
|
||||
inl(dev->iobase +
|
||||
APCI1564_COUNTER_REG(chan));
|
||||
ul_Command1 =
|
||||
inl(dev->iobase +
|
||||
APCI1564_COUNTER_STATUS_REG(chan));
|
||||
data[0] = inl(devpriv->counters +
|
||||
APCI1564_COUNTER_REG(chan));
|
||||
ul_Command1 = inl(devpriv->counters +
|
||||
APCI1564_COUNTER_STATUS_REG(chan));
|
||||
|
||||
/* Get the software trigger status */
|
||||
data[1] = (unsigned char) ((ul_Command1 >> 1) & 1);
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
#include "addi_watchdog.h"
|
||||
|
||||
struct apci1564_private {
|
||||
unsigned long counters; /* base address of 32-bit counters */
|
||||
unsigned int amcc_iobase; /* base of AMCC I/O registers */
|
||||
unsigned int mode1; /* riding-edge/high level channels */
|
||||
unsigned int mode2; /* falling-edge/low level channels */
|
||||
|
@ -63,9 +64,9 @@ static int apci1564_reset(struct comedi_device *dev)
|
|||
outl(0x0, devpriv->amcc_iobase + APCI1564_TIMER_RELOAD_REG);
|
||||
|
||||
/* Reset the counter registers */
|
||||
outl(0x0, dev->iobase + APCI1564_COUNTER_CTRL_REG(0));
|
||||
outl(0x0, dev->iobase + APCI1564_COUNTER_CTRL_REG(1));
|
||||
outl(0x0, dev->iobase + APCI1564_COUNTER_CTRL_REG(2));
|
||||
outl(0x0, devpriv->counters + APCI1564_COUNTER_CTRL_REG(0));
|
||||
outl(0x0, devpriv->counters + APCI1564_COUNTER_CTRL_REG(1));
|
||||
outl(0x0, devpriv->counters + APCI1564_COUNTER_CTRL_REG(2));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -108,20 +109,21 @@ static irqreturn_t apci1564_interrupt(int irq, void *d)
|
|||
}
|
||||
|
||||
for (chan = 0; chan < 4; chan++) {
|
||||
status = inl(dev->iobase + APCI1564_COUNTER_IRQ_REG(chan));
|
||||
status = inl(devpriv->counters +
|
||||
APCI1564_COUNTER_IRQ_REG(chan));
|
||||
if (status & 0x01) {
|
||||
/* Disable Counter Interrupt */
|
||||
ctrl = inl(dev->iobase +
|
||||
APCI1564_COUNTER_CTRL_REG(chan));
|
||||
outl(0x0, dev->iobase +
|
||||
APCI1564_COUNTER_CTRL_REG(chan));
|
||||
ctrl = inl(devpriv->counters +
|
||||
APCI1564_COUNTER_CTRL_REG(chan));
|
||||
outl(0x0, devpriv->counters +
|
||||
APCI1564_COUNTER_CTRL_REG(chan));
|
||||
|
||||
/* Send a signal to from kernel to user space */
|
||||
send_sig(SIGIO, devpriv->tsk_current, 0);
|
||||
|
||||
/* Enable Counter Interrupt */
|
||||
outl(ctrl, dev->iobase +
|
||||
APCI1564_COUNTER_CTRL_REG(chan));
|
||||
outl(ctrl, devpriv->counters +
|
||||
APCI1564_COUNTER_CTRL_REG(chan));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -369,8 +371,9 @@ static int apci1564_auto_attach(struct comedi_device *dev,
|
|||
if (ret)
|
||||
return ret;
|
||||
|
||||
dev->iobase = pci_resource_start(pcidev, 1);
|
||||
/* PLD Revision 2.x I/O Mapping */
|
||||
devpriv->amcc_iobase = pci_resource_start(pcidev, 0);
|
||||
devpriv->counters = pci_resource_start(pcidev, 1);
|
||||
|
||||
apci1564_reset(dev);
|
||||
|
||||
|
|
Loading…
Reference in New Issue