summaryrefslogtreecommitdiff
path: root/drivers/staging/comedi/drivers/me4000.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/staging/comedi/drivers/me4000.c')
-rw-r--r--drivers/staging/comedi/drivers/me4000.c1636
1 files changed, 618 insertions, 1018 deletions
diff --git a/drivers/staging/comedi/drivers/me4000.c b/drivers/staging/comedi/drivers/me4000.c
index 9a8258e6fa45..22db35d091f8 100644
--- a/drivers/staging/comedi/drivers/me4000.c
+++ b/drivers/staging/comedi/drivers/me4000.c
@@ -35,13 +35,7 @@ Supports:
- Digital I/O
- Counter
-Configuration Options:
-
- [0] - PCI bus number (optional)
- [1] - PCI slot number (optional)
-
- If bus/slot is not specified, the first available PCI
- device will be used.
+Configuration Options: not applicable, uses PCI auto config
The firmware required by these boards is available in the
comedi_nonfree_firmware tarball available from
@@ -58,51 +52,306 @@ broken.
#include <linux/list.h>
#include <linux/spinlock.h>
-#include "me4000.h"
+#include "comedi_fc.h"
+#include "8253.h"
+
#if 0
/* file removed due to GPL incompatibility */
#include "me4000_fw.h"
#endif
-static const struct me4000_board me4000_boards[] = {
- {"ME-4650", 0x4650, {0, 0}, {16, 0, 0, 0}, {4}, {0} },
-
- {"ME-4660", 0x4660, {0, 0}, {32, 0, 16, 0}, {4}, {3} },
- {"ME-4660i", 0x4661, {0, 0}, {32, 0, 16, 0}, {4}, {3} },
- {"ME-4660s", 0x4662, {0, 0}, {32, 8, 16, 0}, {4}, {3} },
- {"ME-4660is", 0x4663, {0, 0}, {32, 8, 16, 0}, {4}, {3} },
-
- {"ME-4670", 0x4670, {4, 0}, {32, 0, 16, 1}, {4}, {3} },
- {"ME-4670i", 0x4671, {4, 0}, {32, 0, 16, 1}, {4}, {3} },
- {"ME-4670s", 0x4672, {4, 0}, {32, 8, 16, 1}, {4}, {3} },
- {"ME-4670is", 0x4673, {4, 0}, {32, 8, 16, 1}, {4}, {3} },
+#define PCI_VENDOR_ID_MEILHAUS 0x1402
+
+#define PCI_DEVICE_ID_MEILHAUS_ME4650 0x4650
+#define PCI_DEVICE_ID_MEILHAUS_ME4660 0x4660
+#define PCI_DEVICE_ID_MEILHAUS_ME4660I 0x4661
+#define PCI_DEVICE_ID_MEILHAUS_ME4660S 0x4662
+#define PCI_DEVICE_ID_MEILHAUS_ME4660IS 0x4663
+#define PCI_DEVICE_ID_MEILHAUS_ME4670 0x4670
+#define PCI_DEVICE_ID_MEILHAUS_ME4670I 0x4671
+#define PCI_DEVICE_ID_MEILHAUS_ME4670S 0x4672
+#define PCI_DEVICE_ID_MEILHAUS_ME4670IS 0x4673
+#define PCI_DEVICE_ID_MEILHAUS_ME4680 0x4680
+#define PCI_DEVICE_ID_MEILHAUS_ME4680I 0x4681
+#define PCI_DEVICE_ID_MEILHAUS_ME4680S 0x4682
+#define PCI_DEVICE_ID_MEILHAUS_ME4680IS 0x4683
- {"ME-4680", 0x4680, {4, 4}, {32, 0, 16, 1}, {4}, {3} },
- {"ME-4680i", 0x4681, {4, 4}, {32, 0, 16, 1}, {4}, {3} },
- {"ME-4680s", 0x4682, {4, 4}, {32, 8, 16, 1}, {4}, {3} },
- {"ME-4680is", 0x4683, {4, 4}, {32, 8, 16, 1}, {4}, {3} },
+/*
+ * ME4000 Register map and bit defines
+ */
+#define ME4000_AO_CHAN(x) ((x) * 0x18)
+
+#define ME4000_AO_CTRL_REG(x) (0x00 + ME4000_AO_CHAN(x))
+#define ME4000_AO_CTRL_BIT_MODE_0 (1 << 0)
+#define ME4000_AO_CTRL_BIT_MODE_1 (1 << 1)
+#define ME4000_AO_CTRL_MASK_MODE (3 << 0)
+#define ME4000_AO_CTRL_BIT_STOP (1 << 2)
+#define ME4000_AO_CTRL_BIT_ENABLE_FIFO (1 << 3)
+#define ME4000_AO_CTRL_BIT_ENABLE_EX_TRIG (1 << 4)
+#define ME4000_AO_CTRL_BIT_EX_TRIG_EDGE (1 << 5)
+#define ME4000_AO_CTRL_BIT_IMMEDIATE_STOP (1 << 7)
+#define ME4000_AO_CTRL_BIT_ENABLE_DO (1 << 8)
+#define ME4000_AO_CTRL_BIT_ENABLE_IRQ (1 << 9)
+#define ME4000_AO_CTRL_BIT_RESET_IRQ (1 << 10)
+#define ME4000_AO_STATUS_REG(x) (0x04 + ME4000_AO_CHAN(x))
+#define ME4000_AO_STATUS_BIT_FSM (1 << 0)
+#define ME4000_AO_STATUS_BIT_FF (1 << 1)
+#define ME4000_AO_STATUS_BIT_HF (1 << 2)
+#define ME4000_AO_STATUS_BIT_EF (1 << 3)
+#define ME4000_AO_FIFO_REG(x) (0x08 + ME4000_AO_CHAN(x))
+#define ME4000_AO_SINGLE_REG(x) (0x0c + ME4000_AO_CHAN(x))
+#define ME4000_AO_TIMER_REG(x) (0x10 + ME4000_AO_CHAN(x))
+#define ME4000_AI_CTRL_REG 0x74
+#define ME4000_AI_STATUS_REG 0x74
+#define ME4000_AI_CTRL_BIT_MODE_0 (1 << 0)
+#define ME4000_AI_CTRL_BIT_MODE_1 (1 << 1)
+#define ME4000_AI_CTRL_BIT_MODE_2 (1 << 2)
+#define ME4000_AI_CTRL_BIT_SAMPLE_HOLD (1 << 3)
+#define ME4000_AI_CTRL_BIT_IMMEDIATE_STOP (1 << 4)
+#define ME4000_AI_CTRL_BIT_STOP (1 << 5)
+#define ME4000_AI_CTRL_BIT_CHANNEL_FIFO (1 << 6)
+#define ME4000_AI_CTRL_BIT_DATA_FIFO (1 << 7)
+#define ME4000_AI_CTRL_BIT_FULLSCALE (1 << 8)
+#define ME4000_AI_CTRL_BIT_OFFSET (1 << 9)
+#define ME4000_AI_CTRL_BIT_EX_TRIG_ANALOG (1 << 10)
+#define ME4000_AI_CTRL_BIT_EX_TRIG (1 << 11)
+#define ME4000_AI_CTRL_BIT_EX_TRIG_FALLING (1 << 12)
+#define ME4000_AI_CTRL_BIT_EX_IRQ (1 << 13)
+#define ME4000_AI_CTRL_BIT_EX_IRQ_RESET (1 << 14)
+#define ME4000_AI_CTRL_BIT_LE_IRQ (1 << 15)
+#define ME4000_AI_CTRL_BIT_LE_IRQ_RESET (1 << 16)
+#define ME4000_AI_CTRL_BIT_HF_IRQ (1 << 17)
+#define ME4000_AI_CTRL_BIT_HF_IRQ_RESET (1 << 18)
+#define ME4000_AI_CTRL_BIT_SC_IRQ (1 << 19)
+#define ME4000_AI_CTRL_BIT_SC_IRQ_RESET (1 << 20)
+#define ME4000_AI_CTRL_BIT_SC_RELOAD (1 << 21)
+#define ME4000_AI_STATUS_BIT_EF_CHANNEL (1 << 22)
+#define ME4000_AI_STATUS_BIT_HF_CHANNEL (1 << 23)
+#define ME4000_AI_STATUS_BIT_FF_CHANNEL (1 << 24)
+#define ME4000_AI_STATUS_BIT_EF_DATA (1 << 25)
+#define ME4000_AI_STATUS_BIT_HF_DATA (1 << 26)
+#define ME4000_AI_STATUS_BIT_FF_DATA (1 << 27)
+#define ME4000_AI_STATUS_BIT_LE (1 << 28)
+#define ME4000_AI_STATUS_BIT_FSM (1 << 29)
+#define ME4000_AI_CTRL_BIT_EX_TRIG_BOTH (1 << 31)
+#define ME4000_AI_CHANNEL_LIST_REG 0x78
+#define ME4000_AI_LIST_INPUT_SINGLE_ENDED (0 << 5)
+#define ME4000_AI_LIST_INPUT_DIFFERENTIAL (1 << 5)
+#define ME4000_AI_LIST_RANGE_BIPOLAR_10 (0 << 6)
+#define ME4000_AI_LIST_RANGE_BIPOLAR_2_5 (1 << 6)
+#define ME4000_AI_LIST_RANGE_UNIPOLAR_10 (2 << 6)
+#define ME4000_AI_LIST_RANGE_UNIPOLAR_2_5 (3 << 6)
+#define ME4000_AI_LIST_LAST_ENTRY (1 << 8)
+#define ME4000_AI_DATA_REG 0x7c
+#define ME4000_AI_CHAN_TIMER_REG 0x80
+#define ME4000_AI_CHAN_PRE_TIMER_REG 0x84
+#define ME4000_AI_SCAN_TIMER_LOW_REG 0x88
+#define ME4000_AI_SCAN_TIMER_HIGH_REG 0x8c
+#define ME4000_AI_SCAN_PRE_TIMER_LOW_REG 0x90
+#define ME4000_AI_SCAN_PRE_TIMER_HIGH_REG 0x94
+#define ME4000_AI_START_REG 0x98
+#define ME4000_IRQ_STATUS_REG 0x9c
+#define ME4000_IRQ_STATUS_BIT_EX (1 << 0)
+#define ME4000_IRQ_STATUS_BIT_LE (1 << 1)
+#define ME4000_IRQ_STATUS_BIT_AI_HF (1 << 2)
+#define ME4000_IRQ_STATUS_BIT_AO_0_HF (1 << 3)
+#define ME4000_IRQ_STATUS_BIT_AO_1_HF (1 << 4)
+#define ME4000_IRQ_STATUS_BIT_AO_2_HF (1 << 5)
+#define ME4000_IRQ_STATUS_BIT_AO_3_HF (1 << 6)
+#define ME4000_IRQ_STATUS_BIT_SC (1 << 7)
+#define ME4000_DIO_PORT_0_REG 0xa0
+#define ME4000_DIO_PORT_1_REG 0xa4
+#define ME4000_DIO_PORT_2_REG 0xa8
+#define ME4000_DIO_PORT_3_REG 0xac
+#define ME4000_DIO_DIR_REG 0xb0
+#define ME4000_AO_LOADSETREG_XX 0xb4
+#define ME4000_DIO_CTRL_REG 0xb8
+#define ME4000_DIO_CTRL_BIT_MODE_0 (1 << 0)
+#define ME4000_DIO_CTRL_BIT_MODE_1 (1 << 1)
+#define ME4000_DIO_CTRL_BIT_MODE_2 (1 << 2)
+#define ME4000_DIO_CTRL_BIT_MODE_3 (1 << 3)
+#define ME4000_DIO_CTRL_BIT_MODE_4 (1 << 4)
+#define ME4000_DIO_CTRL_BIT_MODE_5 (1 << 5)
+#define ME4000_DIO_CTRL_BIT_MODE_6 (1 << 6)
+#define ME4000_DIO_CTRL_BIT_MODE_7 (1 << 7)
+#define ME4000_DIO_CTRL_BIT_FUNCTION_0 (1 << 8)
+#define ME4000_DIO_CTRL_BIT_FUNCTION_1 (1 << 9)
+#define ME4000_DIO_CTRL_BIT_FIFO_HIGH_0 (1 << 10)
+#define ME4000_DIO_CTRL_BIT_FIFO_HIGH_1 (1 << 11)
+#define ME4000_DIO_CTRL_BIT_FIFO_HIGH_2 (1 << 12)
+#define ME4000_DIO_CTRL_BIT_FIFO_HIGH_3 (1 << 13)
+#define ME4000_AO_DEMUX_ADJUST_REG 0xbc
+#define ME4000_AO_DEMUX_ADJUST_VALUE 0x4c
+#define ME4000_AI_SAMPLE_COUNTER_REG 0xc0
- {0},
+/*
+ * PLX Register map and bit defines
+ */
+#define PLX_INTCSR 0x4c
+#define PLX_INTCSR_LOCAL_INT1_EN (1 << 0)
+#define PLX_INTCSR_LOCAL_INT1_POL (1 << 1)
+#define PLX_INTCSR_LOCAL_INT1_STATE (1 << 2)
+#define PLX_INTCSR_LOCAL_INT2_EN (1 << 3)
+#define PLX_INTCSR_LOCAL_INT2_POL (1 << 4)
+#define PLX_INTCSR_LOCAL_INT2_STATE (1 << 5)
+#define PLX_INTCSR_PCI_INT_EN (1 << 6)
+#define PLX_INTCSR_SOFT_INT (1 << 7)
+#define PLX_ICR 0x50
+#define PLX_ICR_BIT_EEPROM_CLOCK_SET (1 << 24)
+#define PLX_ICR_BIT_EEPROM_CHIP_SELECT (1 << 25)
+#define PLX_ICR_BIT_EEPROM_WRITE (1 << 26)
+#define PLX_ICR_BIT_EEPROM_READ (1 << 27)
+#define PLX_ICR_BIT_EEPROM_VALID (1 << 28)
+#define PLX_ICR_MASK_EEPROM (0x1f << 24)
+
+#define EEPROM_DELAY 1
+
+#define ME4000_AI_FIFO_COUNT 2048
+
+#define ME4000_AI_MIN_TICKS 66
+#define ME4000_AI_MIN_SAMPLE_TIME 2000
+#define ME4000_AI_BASE_FREQUENCY (unsigned int) 33E6
+
+#define ME4000_AI_CHANNEL_LIST_COUNT 1024
+
+struct me4000_info {
+ unsigned long plx_regbase;
+ unsigned long timer_regbase;
+
+ unsigned int ao_readback[4];
};
-#define ME4000_BOARD_VERSIONS (ARRAY_SIZE(me4000_boards) - 1)
-
-/*-----------------------------------------------------------------------------
- Meilhaus function prototypes
- ---------------------------------------------------------------------------*/
-static int get_registers(struct comedi_device *dev, struct pci_dev *pci_dev_p);
-static int init_board_info(struct comedi_device *dev,
- struct pci_dev *pci_dev_p);
-static int init_ao_context(struct comedi_device *dev);
-static int init_ai_context(struct comedi_device *dev);
-static int init_dio_context(struct comedi_device *dev);
-static int init_cnt_context(struct comedi_device *dev);
-static int xilinx_download(struct comedi_device *dev);
-static int reset_board(struct comedi_device *dev);
+struct me4000_board {
+ const char *name;
+ unsigned short device_id;
+ int ao_nchan;
+ int ao_fifo;
+ int ai_nchan;
+ int ai_diff_nchan;
+ int ai_sh_nchan;
+ int ex_trig_analog;
+ int dio_nchan;
+ int has_counter;
+};
-static int ai_write_chanlist(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_cmd *cmd);
+static const struct me4000_board me4000_boards[] = {
+ {
+ .name = "ME-4650",
+ .device_id = PCI_DEVICE_ID_MEILHAUS_ME4650,
+ .ai_nchan = 16,
+ .dio_nchan = 32,
+ }, {
+ .name = "ME-4660",
+ .device_id = PCI_DEVICE_ID_MEILHAUS_ME4660,
+ .ai_nchan = 32,
+ .ai_diff_nchan = 16,
+ .dio_nchan = 32,
+ .has_counter = 1,
+ }, {
+ .name = "ME-4660i",
+ .device_id = PCI_DEVICE_ID_MEILHAUS_ME4660I,
+ .ai_nchan = 32,
+ .ai_diff_nchan = 16,
+ .dio_nchan = 32,
+ .has_counter = 1,
+ }, {
+ .name = "ME-4660s",
+ .device_id = PCI_DEVICE_ID_MEILHAUS_ME4660S,
+ .ai_nchan = 32,
+ .ai_diff_nchan = 16,
+ .ai_sh_nchan = 8,
+ .dio_nchan = 32,
+ .has_counter = 1,
+ }, {
+ .name = "ME-4660is",
+ .device_id = PCI_DEVICE_ID_MEILHAUS_ME4660IS,
+ .ai_nchan = 32,
+ .ai_diff_nchan = 16,
+ .ai_sh_nchan = 8,
+ .dio_nchan = 32,
+ .has_counter = 1,
+ }, {
+ .name = "ME-4670",
+ .device_id = PCI_DEVICE_ID_MEILHAUS_ME4670,
+ .ao_nchan = 4,
+ .ai_nchan = 32,
+ .ai_diff_nchan = 16,
+ .ex_trig_analog = 1,
+ .dio_nchan = 32,
+ .has_counter = 1,
+ }, {
+ .name = "ME-4670i",
+ .device_id = PCI_DEVICE_ID_MEILHAUS_ME4670I,
+ .ao_nchan = 4,
+ .ai_nchan = 32,
+ .ai_diff_nchan = 16,
+ .ex_trig_analog = 1,
+ .dio_nchan = 32,
+ .has_counter = 1,
+ }, {
+ .name = "ME-4670s",
+ .device_id = PCI_DEVICE_ID_MEILHAUS_ME4670S,
+ .ao_nchan = 4,
+ .ai_nchan = 32,
+ .ai_diff_nchan = 16,
+ .ai_sh_nchan = 8,
+ .ex_trig_analog = 1,
+ .dio_nchan = 32,
+ .has_counter = 1,
+ }, {
+ .name = "ME-4670is",
+ .device_id = PCI_DEVICE_ID_MEILHAUS_ME4670IS,
+ .ao_nchan = 4,
+ .ai_nchan = 32,
+ .ai_diff_nchan = 16,
+ .ai_sh_nchan = 8,
+ .ex_trig_analog = 1,
+ .dio_nchan = 32,
+ .has_counter = 1,
+ }, {
+ .name = "ME-4680",
+ .device_id = PCI_DEVICE_ID_MEILHAUS_ME4680,
+ .ao_nchan = 4,
+ .ao_fifo = 4,
+ .ai_nchan = 32,
+ .ai_diff_nchan = 16,
+ .ex_trig_analog = 1,
+ .dio_nchan = 32,
+ .has_counter = 1,
+ }, {
+ .name = "ME-4680i",
+ .device_id = PCI_DEVICE_ID_MEILHAUS_ME4680I,
+ .ao_nchan = 4,
+ .ao_fifo = 4,
+ .ai_nchan = 32,
+ .ai_diff_nchan = 16,
+ .ex_trig_analog = 1,
+ .dio_nchan = 32,
+ .has_counter = 1,
+ }, {
+ .name = "ME-4680s",
+ .device_id = PCI_DEVICE_ID_MEILHAUS_ME4680S,
+ .ao_nchan = 4,
+ .ao_fifo = 4,
+ .ai_nchan = 32,
+ .ai_diff_nchan = 16,
+ .ai_sh_nchan = 8,
+ .ex_trig_analog = 1,
+ .dio_nchan = 32,
+ .has_counter = 1,
+ }, {
+ .name = "ME-4680is",
+ .device_id = PCI_DEVICE_ID_MEILHAUS_ME4680IS,
+ .ao_nchan = 4,
+ .ao_fifo = 4,
+ .ai_nchan = 32,
+ .ai_diff_nchan = 16,
+ .ai_sh_nchan = 8,
+ .ex_trig_analog = 1,
+ .dio_nchan = 32,
+ .has_counter = 1,
+ },
+};
static const struct comedi_lrange me4000_ai_range = {
4,
@@ -114,380 +363,6 @@ static const struct comedi_lrange me4000_ai_range = {
}
};
-static const struct comedi_lrange me4000_ao_range = {
- 1,
- {
- BIP_RANGE(10),
- }
-};
-
-static int me4000_probe(struct comedi_device *dev, struct comedi_devconfig *it)
-{
- struct pci_dev *pci_device = NULL;
- int result, i;
- struct me4000_board *board;
-
- /* Allocate private memory */
- if (alloc_private(dev, sizeof(struct me4000_info)) < 0)
- return -ENOMEM;
-
- /*
- * Probe the device to determine what device in the series it is.
- */
- for_each_pci_dev(pci_device) {
- if (pci_device->vendor == PCI_VENDOR_ID_MEILHAUS) {
- for (i = 0; i < ME4000_BOARD_VERSIONS; i++) {
- if (me4000_boards[i].device_id ==
- pci_device->device) {
- /*
- * Was a particular
- * bus/slot requested?
- */
- if ((it->options[0] != 0)
- || (it->options[1] != 0)) {
- /*
- * Are we on the wrong
- * bus/slot?
- */
- if (pci_device->bus->number !=
- it->options[0]
- ||
- PCI_SLOT(pci_device->devfn)
- != it->options[1]) {
- continue;
- }
- }
- dev->board_ptr = me4000_boards + i;
- board =
- (struct me4000_board *)
- dev->board_ptr;
- info->pci_dev_p = pci_device;
- goto found;
- }
- }
- }
- }
-
- printk(KERN_ERR
- "comedi%d: me4000: me4000_probe(): "
- "No supported board found (req. bus/slot : %d/%d)\n",
- dev->minor, it->options[0], it->options[1]);
- return -ENODEV;
-
-found:
-
- printk(KERN_INFO
- "comedi%d: me4000: me4000_probe(): "
- "Found %s at PCI bus %d, slot %d\n",
- dev->minor, me4000_boards[i].name, pci_device->bus->number,
- PCI_SLOT(pci_device->devfn));
-
- /* Set data in device structure */
- dev->board_name = board->name;
-
- /* Enable PCI device and request regions */
- result = comedi_pci_enable(pci_device, dev->board_name);
- if (result) {
- printk(KERN_ERR
- "comedi%d: me4000: me4000_probe(): Cannot enable PCI "
- "device and request I/O regions\n", dev->minor);
- return result;
- }
-
- /* Get the PCI base registers */
- result = get_registers(dev, pci_device);
- if (result) {
- printk(KERN_ERR
- "comedi%d: me4000: me4000_probe(): "
- "Cannot get registers\n", dev->minor);
- return result;
- }
- /* Initialize board info */
- result = init_board_info(dev, pci_device);
- if (result) {
- printk(KERN_ERR
- "comedi%d: me4000: me4000_probe(): "
- "Cannot init baord info\n", dev->minor);
- return result;
- }
-
- /* Init analog output context */
- result = init_ao_context(dev);
- if (result) {
- printk(KERN_ERR
- "comedi%d: me4000: me4000_probe(): "
- "Cannot init ao context\n", dev->minor);
- return result;
- }
-
- /* Init analog input context */
- result = init_ai_context(dev);
- if (result) {
- printk(KERN_ERR
- "comedi%d: me4000: me4000_probe(): "
- "Cannot init ai context\n", dev->minor);
- return result;
- }
-
- /* Init digital I/O context */
- result = init_dio_context(dev);
- if (result) {
- printk(KERN_ERR
- "comedi%d: me4000: me4000_probe(): "
- "Cannot init dio context\n", dev->minor);
- return result;
- }
-
- /* Init counter context */
- result = init_cnt_context(dev);
- if (result) {
- printk(KERN_ERR
- "comedi%d: me4000: me4000_probe(): "
- "Cannot init cnt context\n", dev->minor);
- return result;
- }
-
- /* Download the xilinx firmware */
- result = xilinx_download(dev);
- if (result) {
- printk(KERN_ERR
- "comedi%d: me4000: me4000_probe(): "
- "Can't download firmware\n", dev->minor);
- return result;
- }
-
- /* Make a hardware reset */
- result = reset_board(dev);
- if (result) {
- printk(KERN_ERR
- "comedi%d: me4000: me4000_probe(): Can't reset board\n",
- dev->minor);
- return result;
- }
-
- return 0;
-}
-
-static int get_registers(struct comedi_device *dev, struct pci_dev *pci_dev_p)
-{
- /*--------------------------- plx regbase -------------------------------*/
-
- info->plx_regbase = pci_resource_start(pci_dev_p, 1);
- if (info->plx_regbase == 0) {
- printk(KERN_ERR
- "comedi%d: me4000: get_registers(): "
- "PCI base address 1 is not available\n", dev->minor);
- return -ENODEV;
- }
- info->plx_regbase_size = pci_resource_len(pci_dev_p, 1);
-
- /*--------------------------- me4000 regbase ----------------------------*/
-
- info->me4000_regbase = pci_resource_start(pci_dev_p, 2);
- if (info->me4000_regbase == 0) {
- printk(KERN_ERR
- "comedi%d: me4000: get_registers(): "
- "PCI base address 2 is not available\n", dev->minor);
- return -ENODEV;
- }
- info->me4000_regbase_size = pci_resource_len(pci_dev_p, 2);
-
- /*--------------------------- timer regbase ------------------------------*/
-
- info->timer_regbase = pci_resource_start(pci_dev_p, 3);
- if (info->timer_regbase == 0) {
- printk(KERN_ERR
- "comedi%d: me4000: get_registers(): "
- "PCI base address 3 is not available\n", dev->minor);
- return -ENODEV;
- }
- info->timer_regbase_size = pci_resource_len(pci_dev_p, 3);
-
- /*--------------------------- program regbase ----------------------------*/
-
- info->program_regbase = pci_resource_start(pci_dev_p, 5);
- if (info->program_regbase == 0) {
- printk(KERN_ERR
- "comedi%d: me4000: get_registers(): "
- "PCI base address 5 is not available\n", dev->minor);
- return -ENODEV;
- }
- info->program_regbase_size = pci_resource_len(pci_dev_p, 5);
-
- return 0;
-}
-
-static int init_board_info(struct comedi_device *dev, struct pci_dev *pci_dev_p)
-{
- int result;
-
- /* Init spin locks */
- /* spin_lock_init(&info->preload_lock); */
- /* spin_lock_init(&info->ai_ctrl_lock); */
-
- /* Get the serial number */
- result = pci_read_config_dword(pci_dev_p, 0x2C, &info->serial_no);
- if (result != PCIBIOS_SUCCESSFUL)
- return result;
-
- /* Get the hardware revision */
- result = pci_read_config_byte(pci_dev_p, 0x08, &info->hw_revision);
- if (result != PCIBIOS_SUCCESSFUL)
- return result;
-
- /* Get the vendor id */
- info->vendor_id = pci_dev_p->vendor;
-
- /* Get the device id */
- info->device_id = pci_dev_p->device;
-
- /* Get the irq assigned to the board */
- info->irq = pci_dev_p->irq;
-
- return 0;
-}
-
-static int init_ao_context(struct comedi_device *dev)
-{
- int i;
-
- for (i = 0; i < thisboard->ao.count; i++) {
- /* spin_lock_init(&info->ao_context[i].use_lock); */
- info->ao_context[i].irq = info->irq;
-
- switch (i) {
- case 0:
- info->ao_context[i].ctrl_reg =
- info->me4000_regbase + ME4000_AO_00_CTRL_REG;
- info->ao_context[i].status_reg =
- info->me4000_regbase + ME4000_AO_00_STATUS_REG;
- info->ao_context[i].fifo_reg =
- info->me4000_regbase + ME4000_AO_00_FIFO_REG;
- info->ao_context[i].single_reg =
- info->me4000_regbase + ME4000_AO_00_SINGLE_REG;
- info->ao_context[i].timer_reg =
- info->me4000_regbase + ME4000_AO_00_TIMER_REG;
- info->ao_context[i].irq_status_reg =
- info->me4000_regbase + ME4000_IRQ_STATUS_REG;
- info->ao_context[i].preload_reg =
- info->me4000_regbase + ME4000_AO_LOADSETREG_XX;
- break;
- case 1:
- info->ao_context[i].ctrl_reg =
- info->me4000_regbase + ME4000_AO_01_CTRL_REG;
- info->ao_context[i].status_reg =
- info->me4000_regbase + ME4000_AO_01_STATUS_REG;
- info->ao_context[i].fifo_reg =
- info->me4000_regbase + ME4000_AO_01_FIFO_REG;
- info->ao_context[i].single_reg =
- info->me4000_regbase + ME4000_AO_01_SINGLE_REG;
- info->ao_context[i].timer_reg =
- info->me4000_regbase + ME4000_AO_01_TIMER_REG;
- info->ao_context[i].irq_status_reg =
- info->me4000_regbase + ME4000_IRQ_STATUS_REG;
- info->ao_context[i].preload_reg =
- info->me4000_regbase + ME4000_AO_LOADSETREG_XX;
- break;
- case 2:
- info->ao_context[i].ctrl_reg =
- info->me4000_regbase + ME4000_AO_02_CTRL_REG;
- info->ao_context[i].status_reg =
- info->me4000_regbase + ME4000_AO_02_STATUS_REG;
- info->ao_context[i].fifo_reg =
- info->me4000_regbase + ME4000_AO_02_FIFO_REG;
- info->ao_context[i].single_reg =
- info->me4000_regbase + ME4000_AO_02_SINGLE_REG;
- info->ao_context[i].timer_reg =
- info->me4000_regbase + ME4000_AO_02_TIMER_REG;
- info->ao_context[i].irq_status_reg =
- info->me4000_regbase + ME4000_IRQ_STATUS_REG;
- info->ao_context[i].preload_reg =
- info->me4000_regbase + ME4000_AO_LOADSETREG_XX;
- break;
- case 3:
- info->ao_context[i].ctrl_reg =
- info->me4000_regbase + ME4000_AO_03_CTRL_REG;
- info->ao_context[i].status_reg =
- info->me4000_regbase + ME4000_AO_03_STATUS_REG;
- info->ao_context[i].fifo_reg =
- info->me4000_regbase + ME4000_AO_03_FIFO_REG;
- info->ao_context[i].single_reg =
- info->me4000_regbase + ME4000_AO_03_SINGLE_REG;
- info->ao_context[i].timer_reg =
- info->me4000_regbase + ME4000_AO_03_TIMER_REG;
- info->ao_context[i].irq_status_reg =
- info->me4000_regbase + ME4000_IRQ_STATUS_REG;
- info->ao_context[i].preload_reg =
- info->me4000_regbase + ME4000_AO_LOADSETREG_XX;
- break;
- default:
- break;
- }
- }
-
- return 0;
-}
-
-static int init_ai_context(struct comedi_device *dev)
-{
- info->ai_context.irq = info->irq;
-
- info->ai_context.ctrl_reg = info->me4000_regbase + ME4000_AI_CTRL_REG;
- info->ai_context.status_reg =
- info->me4000_regbase + ME4000_AI_STATUS_REG;
- info->ai_context.channel_list_reg =
- info->me4000_regbase + ME4000_AI_CHANNEL_LIST_REG;
- info->ai_context.data_reg = info->me4000_regbase + ME4000_AI_DATA_REG;
- info->ai_context.chan_timer_reg =
- info->me4000_regbase + ME4000_AI_CHAN_TIMER_REG;
- info->ai_context.chan_pre_timer_reg =
- info->me4000_regbase + ME4000_AI_CHAN_PRE_TIMER_REG;
- info->ai_context.scan_timer_low_reg =
- info->me4000_regbase + ME4000_AI_SCAN_TIMER_LOW_REG;
- info->ai_context.scan_timer_high_reg =
- info->me4000_regbase + ME4000_AI_SCAN_TIMER_HIGH_REG;
- info->ai_context.scan_pre_timer_low_reg =
- info->me4000_regbase + ME4000_AI_SCAN_PRE_TIMER_LOW_REG;
- info->ai_context.scan_pre_timer_high_reg =
- info->me4000_regbase + ME4000_AI_SCAN_PRE_TIMER_HIGH_REG;
- info->ai_context.start_reg = info->me4000_regbase + ME4000_AI_START_REG;
- info->ai_context.irq_status_reg =
- info->me4000_regbase + ME4000_IRQ_STATUS_REG;
- info->ai_context.sample_counter_reg =
- info->me4000_regbase + ME4000_AI_SAMPLE_COUNTER_REG;
-
- return 0;
-}
-
-static int init_dio_context(struct comedi_device *dev)
-{
- info->dio_context.dir_reg = info->me4000_regbase + ME4000_DIO_DIR_REG;
- info->dio_context.ctrl_reg = info->me4000_regbase + ME4000_DIO_CTRL_REG;
- info->dio_context.port_0_reg =
- info->me4000_regbase + ME4000_DIO_PORT_0_REG;
- info->dio_context.port_1_reg =
- info->me4000_regbase + ME4000_DIO_PORT_1_REG;
- info->dio_context.port_2_reg =
- info->me4000_regbase + ME4000_DIO_PORT_2_REG;
- info->dio_context.port_3_reg =
- info->me4000_regbase + ME4000_DIO_PORT_3_REG;
-
- return 0;
-}
-
-static int init_cnt_context(struct comedi_device *dev)
-{
- info->cnt_context.ctrl_reg = info->timer_regbase + ME4000_CNT_CTRL_REG;
- info->cnt_context.counter_0_reg =
- info->timer_regbase + ME4000_CNT_COUNTER_0_REG;
- info->cnt_context.counter_1_reg =
- info->timer_regbase + ME4000_CNT_COUNTER_1_REG;
- info->cnt_context.counter_2_reg =
- info->timer_regbase + ME4000_CNT_COUNTER_2_REG;
-
- return 0;
-}
-
#define FIRMWARE_NOT_AVAILABLE 1
#if FIRMWARE_NOT_AVAILABLE
extern unsigned char *xilinx_firm;
@@ -495,11 +370,17 @@ extern unsigned char *xilinx_firm;
static int xilinx_download(struct comedi_device *dev)
{
+ struct pci_dev *pcidev = comedi_to_pci_dev(dev);
+ struct me4000_info *info = dev->private;
+ unsigned long xilinx_iobase = pci_resource_start(pcidev, 5);
u32 value = 0;
wait_queue_head_t queue;
int idx = 0;
int size = 0;
+ if (!xilinx_iobase)
+ return -ENODEV;
+
init_waitqueue_head(&queue);
/*
@@ -514,14 +395,12 @@ static int xilinx_download(struct comedi_device *dev)
outl(value, info->plx_regbase + PLX_ICR);
/* Init Xilinx with CS1 */
- inb(info->program_regbase + 0xC8);
+ inb(xilinx_iobase + 0xC8);
/* Wait until /INIT pin is set */
udelay(20);
if (!(inl(info->plx_regbase + PLX_INTCSR) & 0x20)) {
- printk(KERN_ERR
- "comedi%d: me4000: xilinx_download(): "
- "Can't init Xilinx\n", dev->minor);
+ dev_err(dev->class_dev, "Can't init Xilinx\n");
return -EIO;
}
@@ -530,8 +409,8 @@ static int xilinx_download(struct comedi_device *dev)
value &= ~0x100;
outl(value, info->plx_regbase + PLX_ICR);
if (FIRMWARE_NOT_AVAILABLE) {
- comedi_error(dev, "xilinx firmware unavailable "
- "due to licensing, aborting");
+ dev_err(dev->class_dev,
+ "xilinx firmware unavailable due to licensing, aborting");
return -EIO;
} else {
/* Download Xilinx firmware */
@@ -540,15 +419,14 @@ static int xilinx_download(struct comedi_device *dev)
udelay(10);
for (idx = 0; idx < size; idx++) {
- outb(xilinx_firm[16 + idx], info->program_regbase);
+ outb(xilinx_firm[16 + idx], xilinx_iobase);
udelay(10);
/* Check if BUSY flag is low */
if (inl(info->plx_regbase + PLX_ICR) & 0x20) {
- printk(KERN_ERR
- "comedi%d: me4000: xilinx_download(): "
- "Xilinx is still busy (idx = %d)\n",
- dev->minor, idx);
+ dev_err(dev->class_dev,
+ "Xilinx is still busy (idx = %d)\n",
+ idx);
return -EIO;
}
}
@@ -557,12 +435,8 @@ static int xilinx_download(struct comedi_device *dev)
/* If done flag is high download was successful */
if (inl(info->plx_regbase + PLX_ICR) & 0x4) {
} else {
- printk(KERN_ERR
- "comedi%d: me4000: xilinx_download(): "
- "DONE flag is not set\n", dev->minor);
- printk(KERN_ERR
- "comedi%d: me4000: xilinx_download(): "
- "Download not successful\n", dev->minor);
+ dev_err(dev->class_dev, "DONE flag is not set\n");
+ dev_err(dev->class_dev, "Download not successful\n");
return -EIO;
}
@@ -574,52 +448,45 @@ static int xilinx_download(struct comedi_device *dev)
return 0;
}
-static int reset_board(struct comedi_device *dev)
+static void me4000_reset(struct comedi_device *dev)
{
- unsigned long icr;
+ struct me4000_info *info = dev->private;
+ unsigned long val;
+ int chan;
/* Make a hardware reset */
- icr = inl(info->plx_regbase + PLX_ICR);
- icr |= 0x40000000;
- outl(icr, info->plx_regbase + PLX_ICR);
- icr &= ~0x40000000;
- outl(icr, info->plx_regbase + PLX_ICR);
+ val = inl(info->plx_regbase + PLX_ICR);
+ val |= 0x40000000;
+ outl(val, info->plx_regbase + PLX_ICR);
+ val &= ~0x40000000;
+ outl(val , info->plx_regbase + PLX_ICR);
/* 0x8000 to the DACs means an output voltage of 0V */
- outl(0x8000, info->me4000_regbase + ME4000_AO_00_SINGLE_REG);
- outl(0x8000, info->me4000_regbase + ME4000_AO_01_SINGLE_REG);
- outl(0x8000, info->me4000_regbase + ME4000_AO_02_SINGLE_REG);
- outl(0x8000, info->me4000_regbase + ME4000_AO_03_SINGLE_REG);
+ for (chan = 0; chan < 4; chan++)
+ outl(0x8000, dev->iobase + ME4000_AO_SINGLE_REG(chan));
/* Set both stop bits in the analog input control register */
outl(ME4000_AI_CTRL_BIT_IMMEDIATE_STOP | ME4000_AI_CTRL_BIT_STOP,
- info->me4000_regbase + ME4000_AI_CTRL_REG);
+ dev->iobase + ME4000_AI_CTRL_REG);
/* Set both stop bits in the analog output control register */
- outl(ME4000_AO_CTRL_BIT_IMMEDIATE_STOP | ME4000_AO_CTRL_BIT_STOP,
- info->me4000_regbase + ME4000_AO_00_CTRL_REG);
- outl(ME4000_AO_CTRL_BIT_IMMEDIATE_STOP | ME4000_AO_CTRL_BIT_STOP,
- info->me4000_regbase + ME4000_AO_01_CTRL_REG);
- outl(ME4000_AO_CTRL_BIT_IMMEDIATE_STOP | ME4000_AO_CTRL_BIT_STOP,
- info->me4000_regbase + ME4000_AO_02_CTRL_REG);
- outl(ME4000_AO_CTRL_BIT_IMMEDIATE_STOP | ME4000_AO_CTRL_BIT_STOP,
- info->me4000_regbase + ME4000_AO_03_CTRL_REG);
+ val = ME4000_AO_CTRL_BIT_IMMEDIATE_STOP | ME4000_AO_CTRL_BIT_STOP;
+ for (chan = 0; chan < 4; chan++)
+ outl(val, dev->iobase + ME4000_AO_CTRL_REG(chan));
/* Enable interrupts on the PLX */
outl(0x43, info->plx_regbase + PLX_INTCSR);
/* Set the adustment register for AO demux */
outl(ME4000_AO_DEMUX_ADJUST_VALUE,
- info->me4000_regbase + ME4000_AO_DEMUX_ADJUST_REG);
+ dev->iobase + ME4000_AO_DEMUX_ADJUST_REG);
/*
* Set digital I/O direction for port 0
* to output on isolated versions
*/
- if (!(inl(info->me4000_regbase + ME4000_DIO_DIR_REG) & 0x1))
- outl(0x1, info->me4000_regbase + ME4000_DIO_CTRL_REG);
-
- return 0;
+ if (!(inl(dev->iobase + ME4000_DIO_DIR_REG) & 0x1))
+ outl(0x1, dev->iobase + ME4000_DIO_CTRL_REG);
}
/*=============================================================================
@@ -630,7 +497,7 @@ static int me4000_ai_insn_read(struct comedi_device *dev,
struct comedi_subdevice *subdevice,
struct comedi_insn *insn, unsigned int *data)
{
-
+ const struct me4000_board *thisboard = comedi_board(dev);
int chan = CR_CHAN(insn->chanspec);
int rang = CR_RANGE(insn->chanspec);
int aref = CR_AREF(insn->chanspec);
@@ -642,9 +509,8 @@ static int me4000_ai_insn_read(struct comedi_device *dev,
if (insn->n == 0) {
return 0;
} else if (insn->n > 1) {
- printk(KERN_ERR
- "comedi%d: me4000: me4000_ai_insn_read(): "
- "Invalid instruction length %d\n", dev->minor, insn->n);
+ dev_err(dev->class_dev, "Invalid instruction length %d\n",
+ insn->n);
return -EINVAL;
}
@@ -662,19 +528,16 @@ static int me4000_ai_insn_read(struct comedi_device *dev,
entry |= ME4000_AI_LIST_RANGE_BIPOLAR_10;
break;
default:
- printk(KERN_ERR
- "comedi%d: me4000: me4000_ai_insn_read(): "
- "Invalid range specified\n", dev->minor);
+ dev_err(dev->class_dev, "Invalid range specified\n");
return -EINVAL;
}
switch (aref) {
case AREF_GROUND:
case AREF_COMMON:
- if (chan >= thisboard->ai.count) {
- printk(KERN_ERR
- "comedi%d: me4000: me4000_ai_insn_read(): "
- "Analog input is not available\n", dev->minor);
+ if (chan >= thisboard->ai_nchan) {
+ dev_err(dev->class_dev,
+ "Analog input is not available\n");
return -EINVAL;
}
entry |= ME4000_AI_LIST_INPUT_SINGLE_ENDED | chan;
@@ -682,68 +545,61 @@ static int me4000_ai_insn_read(struct comedi_device *dev,
case AREF_DIFF:
if (rang == 0 || rang == 1) {
- printk(KERN_ERR
- "comedi%d: me4000: me4000_ai_insn_read(): "
- "Range must be bipolar when aref = diff\n",
- dev->minor);
+ dev_err(dev->class_dev,
+ "Range must be bipolar when aref = diff\n");
return -EINVAL;
}
- if (chan >= thisboard->ai.diff_count) {
- printk(KERN_ERR
- "comedi%d: me4000: me4000_ai_insn_read(): "
- "Analog input is not available\n", dev->minor);
+ if (chan >= thisboard->ai_diff_nchan) {
+ dev_err(dev->class_dev,
+ "Analog input is not available\n");
return -EINVAL;
}
entry |= ME4000_AI_LIST_INPUT_DIFFERENTIAL | chan;
break;
default:
- printk(KERN_ERR
- "comedi%d: me4000: me4000_ai_insn_read(): "
- "Invalid aref specified\n", dev->minor);
+ dev_err(dev->class_dev, "Invalid aref specified\n");
return -EINVAL;
}
entry |= ME4000_AI_LIST_LAST_ENTRY;
/* Clear channel list, data fifo and both stop bits */
- tmp = inl(info->ai_context.ctrl_reg);
+ tmp = inl(dev->iobase + ME4000_AI_CTRL_REG);
tmp &= ~(ME4000_AI_CTRL_BIT_CHANNEL_FIFO |
ME4000_AI_CTRL_BIT_DATA_FIFO |
ME4000_AI_CTRL_BIT_STOP | ME4000_AI_CTRL_BIT_IMMEDIATE_STOP);
- outl(tmp, info->ai_context.ctrl_reg);
+ outl(tmp, dev->iobase + ME4000_AI_CTRL_REG);
/* Set the acquisition mode to single */
tmp &= ~(ME4000_AI_CTRL_BIT_MODE_0 | ME4000_AI_CTRL_BIT_MODE_1 |
ME4000_AI_CTRL_BIT_MODE_2);
- outl(tmp, info->ai_context.ctrl_reg);
+ outl(tmp, dev->iobase + ME4000_AI_CTRL_REG);
/* Enable channel list and data fifo */
tmp |= ME4000_AI_CTRL_BIT_CHANNEL_FIFO | ME4000_AI_CTRL_BIT_DATA_FIFO;
- outl(tmp, info->ai_context.ctrl_reg);
+ outl(tmp, dev->iobase + ME4000_AI_CTRL_REG);
/* Generate channel list entry */
- outl(entry, info->ai_context.channel_list_reg);
+ outl(entry, dev->iobase + ME4000_AI_CHANNEL_LIST_REG);
/* Set the timer to maximum sample rate */
- outl(ME4000_AI_MIN_TICKS, info->ai_context.chan_timer_reg);
- outl(ME4000_AI_MIN_TICKS, info->ai_context.chan_pre_timer_reg);
+ outl(ME4000_AI_MIN_TICKS, dev->iobase + ME4000_AI_CHAN_TIMER_REG);
+ outl(ME4000_AI_MIN_TICKS, dev->iobase + ME4000_AI_CHAN_PRE_TIMER_REG);
/* Start conversion by dummy read */
- inl(info->ai_context.start_reg);
+ inl(dev->iobase + ME4000_AI_START_REG);
/* Wait until ready */
udelay(10);
- if (!(inl(info->ai_context.status_reg) &
+ if (!(inl(dev->iobase + ME4000_AI_STATUS_REG) &
ME4000_AI_STATUS_BIT_EF_DATA)) {
- printk(KERN_ERR
- "comedi%d: me4000: me4000_ai_insn_read(): "
- "Value not available after wait\n", dev->minor);
+ dev_err(dev->class_dev, "Value not available after wait\n");
return -EIO;
}
/* Read value from data fifo */
- lval = inl(info->ai_context.data_reg) & 0xFFFF;
+ lval = inl(dev->iobase + ME4000_AI_DATA_REG) & 0xFFFF;
data[0] = lval ^ 0x8000;
return 1;
@@ -755,12 +611,12 @@ static int me4000_ai_cancel(struct comedi_device *dev,
unsigned long tmp;
/* Stop any running conversion */
- tmp = inl(info->ai_context.ctrl_reg);
+ tmp = inl(dev->iobase + ME4000_AI_CTRL_REG);
tmp &= ~(ME4000_AI_CTRL_BIT_STOP | ME4000_AI_CTRL_BIT_IMMEDIATE_STOP);
- outl(tmp, info->ai_context.ctrl_reg);
+ outl(tmp, dev->iobase + ME4000_AI_CTRL_REG);
/* Clear the control register */
- outl(0x0, info->ai_context.ctrl_reg);
+ outl(0x0, dev->iobase + ME4000_AI_CTRL_REG);
return 0;
}
@@ -768,30 +624,25 @@ static int me4000_ai_cancel(struct comedi_device *dev,
static int ai_check_chanlist(struct comedi_device *dev,
struct comedi_subdevice *s, struct comedi_cmd *cmd)
{
+ const struct me4000_board *thisboard = comedi_board(dev);
int aref;
int i;
/* Check whether a channel list is available */
if (!cmd->chanlist_len) {
- printk(KERN_ERR
- "comedi%d: me4000: ai_check_chanlist(): "
- "No channel list available\n", dev->minor);
+ dev_err(dev->class_dev, "No channel list available\n");
return -EINVAL;
}
/* Check the channel list size */
if (cmd->chanlist_len > ME4000_AI_CHANNEL_LIST_COUNT) {
- printk(KERN_ERR
- "comedi%d: me4000: ai_check_chanlist(): "
- "Channel list is to large\n", dev->minor);
+ dev_err(dev->class_dev, "Channel list is to large\n");
return -EINVAL;
}
/* Check the pointer */
if (!cmd->chanlist) {
- printk(KERN_ERR
- "comedi%d: me4000: ai_check_chanlist(): "
- "NULL pointer to channel list\n", dev->minor);
+ dev_err(dev->class_dev, "NULL pointer to channel list\n");
return -EFAULT;
}
@@ -799,10 +650,8 @@ static int ai_check_chanlist(struct comedi_device *dev,
aref = CR_AREF(cmd->chanlist[0]);
for (i = 0; i < cmd->chanlist_len; i++) {
if (CR_AREF(cmd->chanlist[i]) != aref) {
- printk(KERN_ERR
- "comedi%d: me4000: ai_check_chanlist(): "
- "Mode is not equal for all entries\n",
- dev->minor);
+ dev_err(dev->class_dev,
+ "Mode is not equal for all entries\n");
return -EINVAL;
}
}
@@ -811,19 +660,17 @@ static int ai_check_chanlist(struct comedi_device *dev,
if (aref == SDF_DIFF) {
for (i = 0; i < cmd->chanlist_len; i++) {
if (CR_CHAN(cmd->chanlist[i]) >=
- thisboard->ai.diff_count) {
- printk(KERN_ERR
- "comedi%d: me4000: ai_check_chanlist():"
- " Channel number to high\n", dev->minor);
+ thisboard->ai_diff_nchan) {
+ dev_err(dev->class_dev,
+ "Channel number to high\n");
return -EINVAL;
}
}
} else {
for (i = 0; i < cmd->chanlist_len; i++) {
- if (CR_CHAN(cmd->chanlist[i]) >= thisboard->ai.count) {
- printk(KERN_ERR
- "comedi%d: me4000: ai_check_chanlist(): "
- "Channel number to high\n", dev->minor);
+ if (CR_CHAN(cmd->chanlist[i]) >= thisboard->ai_nchan) {
+ dev_err(dev->class_dev,
+ "Channel number to high\n");
return -EINVAL;
}
}
@@ -834,11 +681,8 @@ static int ai_check_chanlist(struct comedi_device *dev,
for (i = 0; i < cmd->chanlist_len; i++) {
if (CR_RANGE(cmd->chanlist[i]) != 1 &&
CR_RANGE(cmd->chanlist[i]) != 2) {
- printk(KERN_ERR
- "comedi%d: me4000: ai_check_chanlist(): "
- "Bipolar is not selected in "
- "differential mode\n",
- dev->minor);
+ dev_err(dev->class_dev,
+ "Bipolar is not selected in differential mode\n");
return -EINVAL;
}
}
@@ -906,16 +750,52 @@ static void ai_write_timer(struct comedi_device *dev,
unsigned int init_ticks,
unsigned int scan_ticks, unsigned int chan_ticks)
{
- outl(init_ticks - 1, info->ai_context.scan_pre_timer_low_reg);
- outl(0x0, info->ai_context.scan_pre_timer_high_reg);
+ outl(init_ticks - 1, dev->iobase + ME4000_AI_SCAN_PRE_TIMER_LOW_REG);
+ outl(0x0, dev->iobase + ME4000_AI_SCAN_PRE_TIMER_HIGH_REG);
if (scan_ticks) {
- outl(scan_ticks - 1, info->ai_context.scan_timer_low_reg);
- outl(0x0, info->ai_context.scan_timer_high_reg);
+ outl(scan_ticks - 1, dev->iobase + ME4000_AI_SCAN_TIMER_LOW_REG);
+ outl(0x0, dev->iobase + ME4000_AI_SCAN_TIMER_HIGH_REG);
}
- outl(chan_ticks - 1, info->ai_context.chan_pre_timer_reg);
- outl(chan_ticks - 1, info->ai_context.chan_timer_reg);
+ outl(chan_ticks - 1, dev->iobase + ME4000_AI_CHAN_PRE_TIMER_REG);
+ outl(chan_ticks - 1, dev->iobase + ME4000_AI_CHAN_TIMER_REG);
+}
+
+static int ai_write_chanlist(struct comedi_device *dev,
+ struct comedi_subdevice *s, struct comedi_cmd *cmd)
+{
+ unsigned int entry;
+ unsigned int chan;
+ unsigned int rang;
+ unsigned int aref;
+ int i;
+
+ for (i = 0; i < cmd->chanlist_len; i++) {
+ chan = CR_CHAN(cmd->chanlist[i]);
+ rang = CR_RANGE(cmd->chanlist[i]);
+ aref = CR_AREF(cmd->chanlist[i]);
+
+ entry = chan;
+
+ if (rang == 0)
+ entry |= ME4000_AI_LIST_RANGE_UNIPOLAR_2_5;
+ else if (rang == 1)
+ entry |= ME4000_AI_LIST_RANGE_UNIPOLAR_10;
+ else if (rang == 2)
+ entry |= ME4000_AI_LIST_RANGE_BIPOLAR_2_5;
+ else
+ entry |= ME4000_AI_LIST_RANGE_BIPOLAR_10;
+
+ if (aref == SDF_DIFF)
+ entry |= ME4000_AI_LIST_INPUT_DIFFERENTIAL;
+ else
+ entry |= ME4000_AI_LIST_INPUT_SINGLE_ENDED;
+
+ outl(entry, dev->iobase + ME4000_AI_CHANNEL_LIST_REG);
+ }
+
+ return 0;
}
static int ai_prepare(struct comedi_device *dev,
@@ -931,7 +811,7 @@ static int ai_prepare(struct comedi_device *dev,
ai_write_timer(dev, init_ticks, scan_ticks, chan_ticks);
/* Reset control register */
- outl(tmp, info->ai_context.ctrl_reg);
+ outl(tmp, dev->iobase + ME4000_AI_CTRL_REG);
/* Start sources */
if ((cmd->start_src == TRIG_EXT &&
@@ -965,19 +845,19 @@ static int ai_prepare(struct comedi_device *dev,
/* Stop triggers */
if (cmd->stop_src == TRIG_COUNT) {
outl(cmd->chanlist_len * cmd->stop_arg,
- info->ai_context.sample_counter_reg);
+ dev->iobase + ME4000_AI_SAMPLE_COUNTER_REG);
tmp |= ME4000_AI_CTRL_BIT_HF_IRQ | ME4000_AI_CTRL_BIT_SC_IRQ;
} else if (cmd->stop_src == TRIG_NONE &&
cmd->scan_end_src == TRIG_COUNT) {
outl(cmd->scan_end_arg,
- info->ai_context.sample_counter_reg);
+ dev->iobase + ME4000_AI_SAMPLE_COUNTER_REG);
tmp |= ME4000_AI_CTRL_BIT_HF_IRQ | ME4000_AI_CTRL_BIT_SC_IRQ;
} else {
tmp |= ME4000_AI_CTRL_BIT_HF_IRQ;
}
/* Write the setup to the control register */
- outl(tmp, info->ai_context.ctrl_reg);
+ outl(tmp, dev->iobase + ME4000_AI_CTRL_REG);
/* Write the channel list */
ai_write_chanlist(dev, s, cmd);
@@ -985,42 +865,6 @@ static int ai_prepare(struct comedi_device *dev,
return 0;
}
-static int ai_write_chanlist(struct comedi_device *dev,
- struct comedi_subdevice *s, struct comedi_cmd *cmd)
-{
- unsigned int entry;
- unsigned int chan;
- unsigned int rang;
- unsigned int aref;
- int i;
-
- for (i = 0; i < cmd->chanlist_len; i++) {
- chan = CR_CHAN(cmd->chanlist[i]);
- rang = CR_RANGE(cmd->chanlist[i]);
- aref = CR_AREF(cmd->chanlist[i]);
-
- entry = chan;
-
- if (rang == 0)
- entry |= ME4000_AI_LIST_RANGE_UNIPOLAR_2_5;
- else if (rang == 1)
- entry |= ME4000_AI_LIST_RANGE_UNIPOLAR_10;
- else if (rang == 2)
- entry |= ME4000_AI_LIST_RANGE_BIPOLAR_2_5;
- else
- entry |= ME4000_AI_LIST_RANGE_BIPOLAR_10;
-
- if (aref == SDF_DIFF)
- entry |= ME4000_AI_LIST_INPUT_DIFFERENTIAL;
- else
- entry |= ME4000_AI_LIST_INPUT_SINGLE_ENDED;
-
- outl(entry, info->ai_context.channel_list_reg);
- }
-
- return 0;
-}
-
static int me4000_ai_do_cmd(struct comedi_device *dev,
struct comedi_subdevice *s)
{
@@ -1047,23 +891,11 @@ static int me4000_ai_do_cmd(struct comedi_device *dev,
return err;
/* Start acquistion by dummy read */
- inl(info->ai_context.start_reg);
+ inl(dev->iobase + ME4000_AI_START_REG);
return 0;
}
-/*
- * me4000_ai_do_cmd_test():
- *
- * The demo cmd.c in ./comedilib/demo specifies 6 return values:
- * - success
- * - invalid source
- * - source conflict
- * - invalid argument
- * - argument conflict
- * - invalid chanlist
- * So I tried to adopt this scheme.
- */
static int me4000_ai_do_cmd_test(struct comedi_device *dev,
struct comedi_subdevice *s,
struct comedi_cmd *cmd)
@@ -1080,91 +912,29 @@ static int me4000_ai_do_cmd_test(struct comedi_device *dev,
/* Round the timer arguments */
ai_round_cmd_args(dev, s, cmd, &init_ticks, &scan_ticks, &chan_ticks);
- /*
- * Stage 1. Check if the trigger sources are generally valid.
- */
- switch (cmd->start_src) {
- case TRIG_NOW:
- case TRIG_EXT:
- break;
- case TRIG_ANY:
- cmd->start_src &= TRIG_NOW | TRIG_EXT;
- err++;
- break;
- default:
- printk(KERN_ERR
- "comedi%d: me4000: me4000_ai_do_cmd_test(): "
- "Invalid start source\n", dev->minor);
- cmd->start_src = TRIG_NOW;
- err++;
- }
- switch (cmd->scan_begin_src) {
- case TRIG_FOLLOW:
- case TRIG_TIMER:
- case TRIG_EXT:
- break;
- case TRIG_ANY:
- cmd->scan_begin_src &= TRIG_FOLLOW | TRIG_TIMER | TRIG_EXT;
- err++;
- break;
- default:
- printk(KERN_ERR
- "comedi%d: me4000: me4000_ai_do_cmd_test(): "
- "Invalid scan begin source\n", dev->minor);
- cmd->scan_begin_src = TRIG_FOLLOW;
- err++;
- }
- switch (cmd->convert_src) {
- case TRIG_TIMER:
- case TRIG_EXT:
- break;
- case TRIG_ANY:
- cmd->convert_src &= TRIG_TIMER | TRIG_EXT;
- err++;
- break;
- default:
- printk(KERN_ERR
- "comedi%d: me4000: me4000_ai_do_cmd_test(): "
- "Invalid convert source\n", dev->minor);
- cmd->convert_src = TRIG_TIMER;
- err++;
- }
- switch (cmd->scan_end_src) {
- case TRIG_NONE:
- case TRIG_COUNT:
- break;
- case TRIG_ANY:
- cmd->scan_end_src &= TRIG_NONE | TRIG_COUNT;
- err++;
- break;
- default:
- printk(KERN_ERR
- "comedi%d: me4000: me4000_ai_do_cmd_test(): "
- "Invalid scan end source\n", dev->minor);
- cmd->scan_end_src = TRIG_NONE;
- err++;
- }
- switch (cmd->stop_src) {
- case TRIG_NONE:
- case TRIG_COUNT:
- break;
- case TRIG_ANY:
- cmd->stop_src &= TRIG_NONE | TRIG_COUNT;
- err++;
- break;
- default:
- printk(KERN_ERR
- "comedi%d: me4000: me4000_ai_do_cmd_test(): "
- "Invalid stop source\n", dev->minor);
- cmd->stop_src = TRIG_NONE;
- err++;
- }
+ /* Step 1 : check if triggers are trivially valid */
+
+ err |= cfc_check_trigger_src(&cmd->start_src, TRIG_NOW | TRIG_EXT);
+ err |= cfc_check_trigger_src(&cmd->scan_begin_src,
+ TRIG_FOLLOW | TRIG_TIMER | TRIG_EXT);
+ err |= cfc_check_trigger_src(&cmd->convert_src, TRIG_TIMER | TRIG_EXT);
+ err |= cfc_check_trigger_src(&cmd->scan_end_src,
+ TRIG_NONE | TRIG_COUNT);
+ err |= cfc_check_trigger_src(&cmd->stop_src, TRIG_NONE | TRIG_COUNT);
+
if (err)
return 1;
- /*
- * Stage 2. Check for trigger source conflicts.
- */
+ /* Step 2a : make sure trigger sources are unique */
+
+ err |= cfc_check_trigger_is_unique(cmd->start_src);
+ err |= cfc_check_trigger_is_unique(cmd->scan_begin_src);
+ err |= cfc_check_trigger_is_unique(cmd->convert_src);
+ err |= cfc_check_trigger_is_unique(cmd->scan_end_src);
+ err |= cfc_check_trigger_is_unique(cmd->stop_src);
+
+ /* Step 2b : and mutually compatible */
+
if (cmd->start_src == TRIG_NOW &&
cmd->scan_begin_src == TRIG_TIMER &&
cmd->convert_src == TRIG_TIMER) {
@@ -1184,13 +954,7 @@ static int me4000_ai_do_cmd_test(struct comedi_device *dev,
cmd->scan_begin_src == TRIG_EXT &&
cmd->convert_src == TRIG_EXT) {
} else {
- printk(KERN_ERR
- "comedi%d: me4000: me4000_ai_do_cmd_test(): "
- "Invalid start trigger combination\n", dev->minor);
- cmd->start_src = TRIG_NOW;
- cmd->scan_begin_src = TRIG_FOLLOW;
- cmd->convert_src = TRIG_TIMER;
- err++;
+ err |= -EINVAL;
}
if (cmd->stop_src == TRIG_NONE && cmd->scan_end_src == TRIG_NONE) {
@@ -1201,13 +965,9 @@ static int me4000_ai_do_cmd_test(struct comedi_device *dev,
} else if (cmd->stop_src == TRIG_COUNT &&
cmd->scan_end_src == TRIG_COUNT) {
} else {
- printk(KERN_ERR
- "comedi%d: me4000: me4000_ai_do_cmd_test(): "
- "Invalid stop trigger combination\n", dev->minor);
- cmd->stop_src = TRIG_NONE;
- cmd->scan_end_src = TRIG_NONE;
- err++;
+ err |= -EINVAL;
}
+
if (err)
return 2;
@@ -1215,30 +975,22 @@ static int me4000_ai_do_cmd_test(struct comedi_device *dev,
* Stage 3. Check if arguments are generally valid.
*/
if (cmd->chanlist_len < 1) {
- printk(KERN_ERR
- "comedi%d: me4000: me4000_ai_do_cmd_test(): "
- "No channel list\n", dev->minor);
+ dev_err(dev->class_dev, "No channel list\n");
cmd->chanlist_len = 1;
err++;
}
if (init_ticks < 66) {
- printk(KERN_ERR
- "comedi%d: me4000: me4000_ai_do_cmd_test(): "
- "Start arg to low\n", dev->minor);
+ dev_err(dev->class_dev, "Start arg to low\n");
cmd->start_arg = 2000;
err++;
}
if (scan_ticks && scan_ticks < 67) {
- printk(KERN_ERR
- "comedi%d: me4000: me4000_ai_do_cmd_test(): "
- "Scan begin arg to low\n", dev->minor);
+ dev_err(dev->class_dev, "Scan begin arg to low\n");
cmd->scan_begin_arg = 2031;
err++;
}
if (chan_ticks < 66) {
- printk(KERN_ERR
- "comedi%d: me4000: me4000_ai_do_cmd_test(): "
- "Convert arg to low\n", dev->minor);
+ dev_err(dev->class_dev, "Convert arg to low\n");
cmd->convert_arg = 2000;
err++;
}
@@ -1255,23 +1007,17 @@ static int me4000_ai_do_cmd_test(struct comedi_device *dev,
/* Check timer arguments */
if (init_ticks < ME4000_AI_MIN_TICKS) {
- printk(KERN_ERR
- "comedi%d: me4000: me4000_ai_do_cmd_test(): "
- "Invalid start arg\n", dev->minor);
+ dev_err(dev->class_dev, "Invalid start arg\n");
cmd->start_arg = 2000; /* 66 ticks at least */
err++;
}
if (chan_ticks < ME4000_AI_MIN_TICKS) {
- printk(KERN_ERR
- "comedi%d: me4000: me4000_ai_do_cmd_test(): "
- "Invalid convert arg\n", dev->minor);
+ dev_err(dev->class_dev, "Invalid convert arg\n");
cmd->convert_arg = 2000; /* 66 ticks at least */
err++;
}
if (scan_ticks <= cmd->chanlist_len * chan_ticks) {
- printk(KERN_ERR
- "comedi%d: me4000: me4000_ai_do_cmd_test(): "
- "Invalid scan end arg\n", dev->minor);
+ dev_err(dev->class_dev, "Invalid scan end arg\n");
/* At least one tick more */
cmd->scan_end_arg = 2000 * cmd->chanlist_len + 31;
@@ -1283,16 +1029,12 @@ static int me4000_ai_do_cmd_test(struct comedi_device *dev,
/* Check timer arguments */
if (init_ticks < ME4000_AI_MIN_TICKS) {
- printk(KERN_ERR
- "comedi%d: me4000: me4000_ai_do_cmd_test(): "
- "Invalid start arg\n", dev->minor);
+ dev_err(dev->class_dev, "Invalid start arg\n");
cmd->start_arg = 2000; /* 66 ticks at least */
err++;
}
if (chan_ticks < ME4000_AI_MIN_TICKS) {
- printk(KERN_ERR
- "comedi%d: me4000: me4000_ai_do_cmd_test(): "
- "Invalid convert arg\n", dev->minor);
+ dev_err(dev->class_dev, "Invalid convert arg\n");
cmd->convert_arg = 2000; /* 66 ticks at least */
err++;
}
@@ -1302,23 +1044,17 @@ static int me4000_ai_do_cmd_test(struct comedi_device *dev,
/* Check timer arguments */
if (init_ticks < ME4000_AI_MIN_TICKS) {
- printk(KERN_ERR
- "comedi%d: me4000: me4000_ai_do_cmd_test(): "
- "Invalid start arg\n", dev->minor);
+ dev_err(dev->class_dev, "Invalid start arg\n");
cmd->start_arg = 2000; /* 66 ticks at least */
err++;
}
if (chan_ticks < ME4000_AI_MIN_TICKS) {
- printk(KERN_ERR
- "comedi%d: me4000: me4000_ai_do_cmd_test(): "
- "Invalid convert arg\n", dev->minor);
+ dev_err(dev->class_dev, "Invalid convert arg\n");
cmd->convert_arg = 2000; /* 66 ticks at least */
err++;
}
if (scan_ticks <= cmd->chanlist_len * chan_ticks) {
- printk(KERN_ERR
- "comedi%d: me4000: me4000_ai_do_cmd_test(): "
- "Invalid scan end arg\n", dev->minor);
+ dev_err(dev->class_dev, "Invalid scan end arg\n");
/* At least one tick more */
cmd->scan_end_arg = 2000 * cmd->chanlist_len + 31;
@@ -1330,16 +1066,12 @@ static int me4000_ai_do_cmd_test(struct comedi_device *dev,
/* Check timer arguments */
if (init_ticks < ME4000_AI_MIN_TICKS) {
- printk(KERN_ERR
- "comedi%d: me4000: me4000_ai_do_cmd_test(): "
- "Invalid start arg\n", dev->minor);
+ dev_err(dev->class_dev, "Invalid start arg\n");
cmd->start_arg = 2000; /* 66 ticks at least */
err++;
}
if (chan_ticks < ME4000_AI_MIN_TICKS) {
- printk(KERN_ERR
- "comedi%d: me4000: me4000_ai_do_cmd_test(): "
- "Invalid convert arg\n", dev->minor);
+ dev_err(dev->class_dev, "Invalid convert arg\n");
cmd->convert_arg = 2000; /* 66 ticks at least */
err++;
}
@@ -1349,16 +1081,12 @@ static int me4000_ai_do_cmd_test(struct comedi_device *dev,
/* Check timer arguments */
if (init_ticks < ME4000_AI_MIN_TICKS) {
- printk(KERN_ERR
- "comedi%d: me4000: me4000_ai_do_cmd_test(): "
- "Invalid start arg\n", dev->minor);
+ dev_err(dev->class_dev, "Invalid start arg\n");
cmd->start_arg = 2000; /* 66 ticks at least */
err++;
}
if (chan_ticks < ME4000_AI_MIN_TICKS) {
- printk(KERN_ERR
- "comedi%d: me4000: me4000_ai_do_cmd_test(): "
- "Invalid convert arg\n", dev->minor);
+ dev_err(dev->class_dev, "Invalid convert arg\n");
cmd->convert_arg = 2000; /* 66 ticks at least */
err++;
}
@@ -1368,27 +1096,21 @@ static int me4000_ai_do_cmd_test(struct comedi_device *dev,
/* Check timer arguments */
if (init_ticks < ME4000_AI_MIN_TICKS) {
- printk(KERN_ERR
- "comedi%d: me4000: me4000_ai_do_cmd_test(): "
- "Invalid start arg\n", dev->minor);
+ dev_err(dev->class_dev, "Invalid start arg\n");
cmd->start_arg = 2000; /* 66 ticks at least */
err++;
}
}
if (cmd->stop_src == TRIG_COUNT) {
if (cmd->stop_arg == 0) {
- printk(KERN_ERR
- "comedi%d: me4000: me4000_ai_do_cmd_test(): "
- "Invalid stop arg\n", dev->minor);
+ dev_err(dev->class_dev, "Invalid stop arg\n");
cmd->stop_arg = 1;
err++;
}
}
if (cmd->scan_end_src == TRIG_COUNT) {
if (cmd->scan_end_arg == 0) {
- printk(KERN_ERR
- "comedi%d: me4000: me4000_ai_do_cmd_test(): "
- "Invalid scan end arg\n", dev->minor);
+ dev_err(dev->class_dev, "Invalid scan end arg\n");
cmd->scan_end_arg = 1;
err++;
}
@@ -1410,8 +1132,7 @@ static irqreturn_t me4000_ai_isr(int irq, void *dev_id)
{
unsigned int tmp;
struct comedi_device *dev = dev_id;
- struct comedi_subdevice *s = dev->subdevices;
- struct me4000_ai_context *ai_context = &info->ai_context;
+ struct comedi_subdevice *s = &dev->subdevices[0];
int i;
int c = 0;
long lval;
@@ -1423,17 +1144,15 @@ static irqreturn_t me4000_ai_isr(int irq, void *dev_id)
s->async->events = 0;
/* Check if irq number is right */
- if (irq != ai_context->irq) {
- printk(KERN_ERR
- "comedi%d: me4000: me4000_ai_isr(): "
- "Incorrect interrupt num: %d\n", dev->minor, irq);
+ if (irq != dev->irq) {
+ dev_err(dev->class_dev, "Incorrect interrupt num: %d\n", irq);
return IRQ_HANDLED;
}
- if (inl(ai_context->irq_status_reg) &
+ if (inl(dev->iobase + ME4000_IRQ_STATUS_REG) &
ME4000_IRQ_STATUS_BIT_AI_HF) {
/* Read status register to find out what happened */
- tmp = inl(ai_context->ctrl_reg);
+ tmp = inl(dev->iobase + ME4000_AI_CTRL_REG);
if (!(tmp & ME4000_AI_STATUS_BIT_FF_DATA) &&
!(tmp & ME4000_AI_STATUS_BIT_HF_DATA) &&
@@ -1447,13 +1166,11 @@ static irqreturn_t me4000_ai_isr(int irq, void *dev_id)
tmp |= ME4000_AI_CTRL_BIT_IMMEDIATE_STOP;
tmp &= ~(ME4000_AI_CTRL_BIT_HF_IRQ |
ME4000_AI_CTRL_BIT_SC_IRQ);
- outl(tmp, ai_context->ctrl_reg);
+ outl(tmp, dev->iobase + ME4000_AI_CTRL_REG);
s->async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
- printk(KERN_ERR
- "comedi%d: me4000: me4000_ai_isr(): "
- "FIFO overflow\n", dev->minor);
+ dev_err(dev->class_dev, "FIFO overflow\n");
} else if ((tmp & ME4000_AI_STATUS_BIT_FF_DATA)
&& !(tmp & ME4000_AI_STATUS_BIT_HF_DATA)
&& (tmp & ME4000_AI_STATUS_BIT_EF_DATA)) {
@@ -1461,9 +1178,8 @@ static irqreturn_t me4000_ai_isr(int irq, void *dev_id)
c = ME4000_AI_FIFO_COUNT / 2;
} else {
- printk(KERN_ERR
- "comedi%d: me4000: me4000_ai_isr(): "
- "Can't determine state of fifo\n", dev->minor);
+ dev_err(dev->class_dev,
+ "Can't determine state of fifo\n");
c = 0;
/*
@@ -1473,18 +1189,16 @@ static irqreturn_t me4000_ai_isr(int irq, void *dev_id)
tmp |= ME4000_AI_CTRL_BIT_IMMEDIATE_STOP;
tmp &= ~(ME4000_AI_CTRL_BIT_HF_IRQ |
ME4000_AI_CTRL_BIT_SC_IRQ);
- outl(tmp, ai_context->ctrl_reg);
+ outl(tmp, dev->iobase + ME4000_AI_CTRL_REG);
s->async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
- printk(KERN_ERR
- "comedi%d: me4000: me4000_ai_isr(): "
- "Undefined FIFO state\n", dev->minor);
+ dev_err(dev->class_dev, "Undefined FIFO state\n");
}
for (i = 0; i < c; i++) {
/* Read value from data fifo */
- lval = inl(ai_context->data_reg) & 0xFFFF;
+ lval = inl(dev->iobase + ME4000_AI_DATA_REG) & 0xFFFF;
lval ^= 0x8000;
if (!comedi_buf_put(s->async, lval)) {
@@ -1495,13 +1209,11 @@ static irqreturn_t me4000_ai_isr(int irq, void *dev_id)
tmp |= ME4000_AI_CTRL_BIT_IMMEDIATE_STOP;
tmp &= ~(ME4000_AI_CTRL_BIT_HF_IRQ |
ME4000_AI_CTRL_BIT_SC_IRQ);
- outl(tmp, ai_context->ctrl_reg);
+ outl(tmp, dev->iobase + ME4000_AI_CTRL_REG);
s->async->events |= COMEDI_CB_OVERFLOW;
- printk(KERN_ERR
- "comedi%d: me4000: me4000_ai_isr(): "
- "Buffer overflow\n", dev->minor);
+ dev_err(dev->class_dev, "Buffer overflow\n");
break;
}
@@ -1509,33 +1221,33 @@ static irqreturn_t me4000_ai_isr(int irq, void *dev_id)
/* Work is done, so reset the interrupt */
tmp |= ME4000_AI_CTRL_BIT_HF_IRQ_RESET;
- outl(tmp, ai_context->ctrl_reg);
+ outl(tmp, dev->iobase + ME4000_AI_CTRL_REG);
tmp &= ~ME4000_AI_CTRL_BIT_HF_IRQ_RESET;
- outl(tmp, ai_context->ctrl_reg);
+ outl(tmp, dev->iobase + ME4000_AI_CTRL_REG);
}
- if (inl(ai_context->irq_status_reg) & ME4000_IRQ_STATUS_BIT_SC) {
+ if (inl(dev->iobase + ME4000_IRQ_STATUS_REG) &
+ ME4000_IRQ_STATUS_BIT_SC) {
s->async->events |= COMEDI_CB_BLOCK | COMEDI_CB_EOA;
/*
* Acquisition is complete, so stop
* conversion and disable all interrupts
*/
- tmp = inl(ai_context->ctrl_reg);
+ tmp = inl(dev->iobase + ME4000_AI_CTRL_REG);
tmp |= ME4000_AI_CTRL_BIT_IMMEDIATE_STOP;
tmp &= ~(ME4000_AI_CTRL_BIT_HF_IRQ | ME4000_AI_CTRL_BIT_SC_IRQ);
- outl(tmp, ai_context->ctrl_reg);
+ outl(tmp, dev->iobase + ME4000_AI_CTRL_REG);
/* Poll data until fifo empty */
- while (inl(ai_context->ctrl_reg) & ME4000_AI_STATUS_BIT_EF_DATA) {
+ while (inl(dev->iobase + ME4000_AI_CTRL_REG) &
+ ME4000_AI_STATUS_BIT_EF_DATA) {
/* Read value from data fifo */
- lval = inl(ai_context->data_reg) & 0xFFFF;
+ lval = inl(dev->iobase + ME4000_AI_DATA_REG) & 0xFFFF;
lval ^= 0x8000;
if (!comedi_buf_put(s->async, lval)) {
- printk(KERN_ERR
- "comedi%d: me4000: me4000_ai_isr(): "
- "Buffer overflow\n", dev->minor);
+ dev_err(dev->class_dev, "Buffer overflow\n");
s->async->events |= COMEDI_CB_OVERFLOW;
break;
}
@@ -1543,9 +1255,9 @@ static irqreturn_t me4000_ai_isr(int irq, void *dev_id)
/* Work is done, so reset the interrupt */
tmp |= ME4000_AI_CTRL_BIT_SC_IRQ_RESET;
- outl(tmp, ai_context->ctrl_reg);
+ outl(tmp, dev->iobase + ME4000_AI_CTRL_REG);
tmp &= ~ME4000_AI_CTRL_BIT_SC_IRQ_RESET;
- outl(tmp, ai_context->ctrl_reg);
+ outl(tmp, dev->iobase + ME4000_AI_CTRL_REG);
}
if (s->async->events)
@@ -1562,7 +1274,8 @@ static int me4000_ao_insn_write(struct comedi_device *dev,
struct comedi_subdevice *s,
struct comedi_insn *insn, unsigned int *data)
{
-
+ const struct me4000_board *thisboard = comedi_board(dev);
+ struct me4000_info *info = dev->private;
int chan = CR_CHAN(insn->chanspec);
int rang = CR_RANGE(insn->chanspec);
int aref = CR_AREF(insn->chanspec);
@@ -1571,46 +1284,39 @@ static int me4000_ao_insn_write(struct comedi_device *dev,
if (insn->n == 0) {
return 0;
} else if (insn->n > 1) {
- printk(KERN_ERR
- "comedi%d: me4000: me4000_ao_insn_write(): "
- "Invalid instruction length %d\n", dev->minor, insn->n);
+ dev_err(dev->class_dev, "Invalid instruction length %d\n",
+ insn->n);
return -EINVAL;
}
- if (chan >= thisboard->ao.count) {
- printk(KERN_ERR
- "comedi%d: me4000: me4000_ao_insn_write(): "
- "Invalid channel %d\n", dev->minor, insn->n);
+ if (chan >= thisboard->ao_nchan) {
+ dev_err(dev->class_dev, "Invalid channel %d\n", insn->n);
return -EINVAL;
}
if (rang != 0) {
- printk(KERN_ERR
- "comedi%d: me4000: me4000_ao_insn_write(): "
- "Invalid range %d\n", dev->minor, insn->n);
+ dev_err(dev->class_dev, "Invalid range %d\n", insn->n);
return -EINVAL;
}
if (aref != AREF_GROUND && aref != AREF_COMMON) {
- printk(KERN_ERR
- "comedi%d: me4000: me4000_ao_insn_write(): "
- "Invalid aref %d\n", dev->minor, insn->n);
+ dev_err(dev->class_dev, "Invalid aref %d\n", insn->n);
return -EINVAL;
}
/* Stop any running conversion */
- tmp = inl(info->ao_context[chan].ctrl_reg);
+ tmp = inl(dev->iobase + ME4000_AO_CTRL_REG(chan));
tmp |= ME4000_AO_CTRL_BIT_IMMEDIATE_STOP;
- outl(tmp, info->ao_context[chan].ctrl_reg);
+ outl(tmp, dev->iobase + ME4000_AO_CTRL_REG(chan));
/* Clear control register and set to single mode */
- outl(0x0, info->ao_context[chan].ctrl_reg);
+ outl(0x0, dev->iobase + ME4000_AO_CTRL_REG(chan));
/* Write data value */
- outl(data[0], info->ao_context[chan].single_reg);
+ outl(data[0], dev->iobase + ME4000_AO_SINGLE_REG(chan));
/* Store in the mirror */
- info->ao_context[chan].mirror = data[0];
+ info->ao_readback[chan] = data[0];
return 1;
}
@@ -1619,18 +1325,17 @@ static int me4000_ao_insn_read(struct comedi_device *dev,
struct comedi_subdevice *s,
struct comedi_insn *insn, unsigned int *data)
{
+ struct me4000_info *info = dev->private;
int chan = CR_CHAN(insn->chanspec);
if (insn->n == 0) {
return 0;
} else if (insn->n > 1) {
- printk
- ("comedi%d: me4000: me4000_ao_insn_read(): "
- "Invalid instruction length\n", dev->minor);
+ dev_err(dev->class_dev, "Invalid instruction length\n");
return -EINVAL;
}
- data[0] = info->ao_context[chan].mirror;
+ data[0] = info->ao_readback[chan];
return 1;
}
@@ -1659,21 +1364,21 @@ static int me4000_dio_insn_bits(struct comedi_device *dev,
/* Write out the new digital output lines */
outl((s->state >> 0) & 0xFF,
- info->dio_context.port_0_reg);
+ dev->iobase + ME4000_DIO_PORT_0_REG);
outl((s->state >> 8) & 0xFF,
- info->dio_context.port_1_reg);
+ dev->iobase + ME4000_DIO_PORT_1_REG);
outl((s->state >> 16) & 0xFF,
- info->dio_context.port_2_reg);
+ dev->iobase + ME4000_DIO_PORT_2_REG);
outl((s->state >> 24) & 0xFF,
- info->dio_context.port_3_reg);
+ dev->iobase + ME4000_DIO_PORT_3_REG);
}
/* On return, data[1] contains the value of
the digital input and output lines. */
- data[1] = ((inl(info->dio_context.port_0_reg) & 0xFF) << 0) |
- ((inl(info->dio_context.port_1_reg) & 0xFF) << 8) |
- ((inl(info->dio_context.port_2_reg) & 0xFF) << 16) |
- ((inl(info->dio_context.port_3_reg) & 0xFF) << 24);
+ data[1] = ((inl(dev->iobase + ME4000_DIO_PORT_0_REG) & 0xFF) << 0) |
+ ((inl(dev->iobase + ME4000_DIO_PORT_1_REG) & 0xFF) << 8) |
+ ((inl(dev->iobase + ME4000_DIO_PORT_2_REG) & 0xFF) << 16) |
+ ((inl(dev->iobase + ME4000_DIO_PORT_3_REG) & 0xFF) << 24);
return insn->n;
}
@@ -1705,7 +1410,7 @@ static int me4000_dio_insn_config(struct comedi_device *dev,
* On the ME-4000 it is only possible to switch port wise (8 bit)
*/
- tmp = inl(info->dio_context.ctrl_reg);
+ tmp = inl(dev->iobase + ME4000_DIO_CTRL_REG);
if (data[0] == INSN_CONFIG_DIO_OUTPUT) {
if (chan < 8) {
@@ -1719,7 +1424,7 @@ static int me4000_dio_insn_config(struct comedi_device *dev,
* If one the first port is a fixed output
* port and the second is a fixed input port.
*/
- if (!inl(info->dio_context.dir_reg))
+ if (!inl(dev->iobase + ME4000_DIO_DIR_REG))
return -ENODEV;
s->io_bits |= 0xFF00;
@@ -1746,7 +1451,7 @@ static int me4000_dio_insn_config(struct comedi_device *dev,
* If one the first port is a fixed output
* port and the second is a fixed input port.
*/
- if (!inl(info->dio_context.dir_reg))
+ if (!inl(dev->iobase + ME4000_DIO_DIR_REG))
return -ENODEV;
s->io_bits &= ~0xFF;
@@ -1769,7 +1474,7 @@ static int me4000_dio_insn_config(struct comedi_device *dev,
}
}
- outl(tmp, info->dio_context.ctrl_reg);
+ outl(tmp, dev->iobase + ME4000_DIO_CTRL_REG);
return 1;
}
@@ -1778,177 +1483,56 @@ static int me4000_dio_insn_config(struct comedi_device *dev,
Counter section
===========================================================================*/
-static int cnt_reset(struct comedi_device *dev, unsigned int channel)
-{
- switch (channel) {
- case 0:
- outb(0x30, info->cnt_context.ctrl_reg);
- outb(0x00, info->cnt_context.counter_0_reg);
- outb(0x00, info->cnt_context.counter_0_reg);
- break;
- case 1:
- outb(0x70, info->cnt_context.ctrl_reg);
- outb(0x00, info->cnt_context.counter_1_reg);
- outb(0x00, info->cnt_context.counter_1_reg);
- break;
- case 2:
- outb(0xB0, info->cnt_context.ctrl_reg);
- outb(0x00, info->cnt_context.counter_2_reg);
- outb(0x00, info->cnt_context.counter_2_reg);
- break;
- default:
- printk(KERN_ERR
- "comedi%d: me4000: cnt_reset(): Invalid channel\n",
- dev->minor);
- return -EINVAL;
- }
-
- return 0;
-}
-
-static int cnt_config(struct comedi_device *dev, unsigned int channel,
- unsigned int mode)
-{
- int tmp = 0;
-
- switch (channel) {
- case 0:
- tmp |= ME4000_CNT_COUNTER_0;
- break;
- case 1:
- tmp |= ME4000_CNT_COUNTER_1;
- break;
- case 2:
- tmp |= ME4000_CNT_COUNTER_2;
- break;
- default:
- printk(KERN_ERR
- "comedi%d: me4000: cnt_config(): Invalid channel\n",
- dev->minor);
- return -EINVAL;
- }
-
- switch (mode) {
- case 0:
- tmp |= ME4000_CNT_MODE_0;
- break;
- case 1:
- tmp |= ME4000_CNT_MODE_1;
- break;
- case 2:
- tmp |= ME4000_CNT_MODE_2;
- break;
- case 3:
- tmp |= ME4000_CNT_MODE_3;
- break;
- case 4:
- tmp |= ME4000_CNT_MODE_4;
- break;
- case 5:
- tmp |= ME4000_CNT_MODE_5;
- break;
- default:
- printk(KERN_ERR
- "comedi%d: me4000: cnt_config(): Invalid counter mode\n",
- dev->minor);
- return -EINVAL;
- }
-
- /* Write the control word */
- tmp |= 0x30;
- outb(tmp, info->cnt_context.ctrl_reg);
-
- return 0;
-}
-
static int me4000_cnt_insn_config(struct comedi_device *dev,
struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data)
+ struct comedi_insn *insn,
+ unsigned int *data)
{
-
+ struct me4000_info *info = dev->private;
int err;
switch (data[0]) {
case GPCT_RESET:
- if (insn->n != 1) {
- printk(KERN_ERR
- "comedi%d: me4000: me4000_cnt_insn_config(): "
- "Invalid instruction length%d\n",
- dev->minor, insn->n);
+ if (insn->n != 1)
return -EINVAL;
- }
- err = cnt_reset(dev, insn->chanspec);
+ err = i8254_load(info->timer_regbase, 0, insn->chanspec, 0,
+ I8254_MODE0 | I8254_BINARY);
if (err)
return err;
break;
case GPCT_SET_OPERATION:
- if (insn->n != 2) {
- printk(KERN_ERR
- "comedi%d: me4000: me4000_cnt_insn_config(): "
- "Invalid instruction length%d\n",
- dev->minor, insn->n);
+ if (insn->n != 2)
return -EINVAL;
- }
- err = cnt_config(dev, insn->chanspec, data[1]);
+ err = i8254_set_mode(info->timer_regbase, 0, insn->chanspec,
+ (data[1] << 1) | I8254_BINARY);
if (err)
return err;
break;
default:
- printk(KERN_ERR
- "comedi%d: me4000: me4000_cnt_insn_config(): "
- "Invalid instruction\n", dev->minor);
return -EINVAL;
}
- return 2;
+ return insn->n;
}
static int me4000_cnt_insn_read(struct comedi_device *dev,
struct comedi_subdevice *s,
struct comedi_insn *insn, unsigned int *data)
{
-
- unsigned short tmp;
+ struct me4000_info *info = dev->private;
if (insn->n == 0)
return 0;
if (insn->n > 1) {
- printk(KERN_ERR
- "comedi%d: me4000: me4000_cnt_insn_read(): "
- "Invalid instruction length %d\n",
- dev->minor, insn->n);
+ dev_err(dev->class_dev, "Invalid instruction length %d\n",
+ insn->n);
return -EINVAL;
}
- switch (insn->chanspec) {
- case 0:
- tmp = inb(info->cnt_context.counter_0_reg);
- data[0] = tmp;
- tmp = inb(info->cnt_context.counter_0_reg);
- data[0] |= tmp << 8;
- break;
- case 1:
- tmp = inb(info->cnt_context.counter_1_reg);
- data[0] = tmp;
- tmp = inb(info->cnt_context.counter_1_reg);
- data[0] |= tmp << 8;
- break;
- case 2:
- tmp = inb(info->cnt_context.counter_2_reg);
- data[0] = tmp;
- tmp = inb(info->cnt_context.counter_2_reg);
- data[0] |= tmp << 8;
- break;
- default:
- printk(KERN_ERR
- "comedi%d: me4000: me4000_cnt_insn_read(): "
- "Invalid channel %d\n",
- dev->minor, insn->chanspec);
- return -EINVAL;
- }
+ data[0] = i8254_read(info->timer_regbase, 0, insn->chanspec);
return 1;
}
@@ -1957,58 +1541,72 @@ static int me4000_cnt_insn_write(struct comedi_device *dev,
struct comedi_subdevice *s,
struct comedi_insn *insn, unsigned int *data)
{
-
- unsigned short tmp;
+ struct me4000_info *info = dev->private;
if (insn->n == 0) {
return 0;
} else if (insn->n > 1) {
- printk(KERN_ERR
- "comedi%d: me4000: me4000_cnt_insn_write(): "
- "Invalid instruction length %d\n",
- dev->minor, insn->n);
+ dev_err(dev->class_dev, "Invalid instruction length %d\n",
+ insn->n);
return -EINVAL;
}
- switch (insn->chanspec) {
- case 0:
- tmp = data[0] & 0xFF;
- outb(tmp, info->cnt_context.counter_0_reg);
- tmp = (data[0] >> 8) & 0xFF;
- outb(tmp, info->cnt_context.counter_0_reg);
- break;
- case 1:
- tmp = data[0] & 0xFF;
- outb(tmp, info->cnt_context.counter_1_reg);
- tmp = (data[0] >> 8) & 0xFF;
- outb(tmp, info->cnt_context.counter_1_reg);
- break;
- case 2:
- tmp = data[0] & 0xFF;
- outb(tmp, info->cnt_context.counter_2_reg);
- tmp = (data[0] >> 8) & 0xFF;
- outb(tmp, info->cnt_context.counter_2_reg);
- break;
- default:
- printk(KERN_ERR
- "comedi%d: me4000: me4000_cnt_insn_write(): "
- "Invalid channel %d\n",
- dev->minor, insn->chanspec);
- return -EINVAL;
- }
+ i8254_write(info->timer_regbase, 0, insn->chanspec, data[0]);
return 1;
}
-static int me4000_attach(struct comedi_device *dev, struct comedi_devconfig *it)
+static const void *me4000_find_boardinfo(struct comedi_device *dev,
+ struct pci_dev *pcidev)
{
+ const struct me4000_board *thisboard;
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(me4000_boards); i++) {
+ thisboard = &me4000_boards[i];
+ if (thisboard->device_id == pcidev->device)
+ return thisboard;
+ }
+ return NULL;
+}
+
+static int me4000_attach_pci(struct comedi_device *dev,
+ struct pci_dev *pcidev)
+{
+ const struct me4000_board *thisboard;
+ struct me4000_info *info;
struct comedi_subdevice *s;
int result;
- result = me4000_probe(dev, it);
+ comedi_set_hw_dev(dev, &pcidev->dev);
+
+ thisboard = me4000_find_boardinfo(dev, pcidev);
+ if (!thisboard)
+ return -ENODEV;
+ dev->board_ptr = thisboard;
+ dev->board_name = thisboard->name;
+
+ result = alloc_private(dev, sizeof(*info));
+ if (result)
+ return result;
+ info = dev->private;
+
+ result = comedi_pci_enable(pcidev, dev->board_name);
+ if (result)
+ return result;
+
+ info->plx_regbase = pci_resource_start(pcidev, 1);
+ dev->iobase = pci_resource_start(pcidev, 2);
+ info->timer_regbase = pci_resource_start(pcidev, 3);
+ if (!info->plx_regbase || !dev->iobase || !info->timer_regbase)
+ return -ENODEV;
+
+ result = xilinx_download(dev);
if (result)
return result;
+ me4000_reset(dev);
+
result = comedi_alloc_subdevices(dev, 4);
if (result)
return result;
@@ -2017,35 +1615,34 @@ static int me4000_attach(struct comedi_device *dev, struct comedi_devconfig *it)
Analog input subdevice
========================================================================*/
- s = dev->subdevices + 0;
+ s = &dev->subdevices[0];
- if (thisboard->ai.count) {
+ if (thisboard->ai_nchan) {
s->type = COMEDI_SUBD_AI;
s->subdev_flags =
SDF_READABLE | SDF_COMMON | SDF_GROUND | SDF_DIFF;
- s->n_chan = thisboard->ai.count;
+ s->n_chan = thisboard->ai_nchan;
s->maxdata = 0xFFFF; /* 16 bit ADC */
s->len_chanlist = ME4000_AI_CHANNEL_LIST_COUNT;
s->range_table = &me4000_ai_range;
s->insn_read = me4000_ai_insn_read;
- if (info->irq > 0) {
- if (request_irq(info->irq, me4000_ai_isr,
- IRQF_SHARED, "ME-4000", dev)) {
- printk
- ("comedi%d: me4000: me4000_attach(): "
- "Unable to allocate irq\n", dev->minor);
+ if (pcidev->irq > 0) {
+ if (request_irq(pcidev->irq, me4000_ai_isr,
+ IRQF_SHARED, dev->board_name, dev)) {
+ dev_warn(dev->class_dev,
+ "request_irq failed\n");
} else {
dev->read_subdev = s;
s->subdev_flags |= SDF_CMD_READ;
s->cancel = me4000_ai_cancel;
s->do_cmdtest = me4000_ai_do_cmd_test;
s->do_cmd = me4000_ai_do_cmd;
+
+ dev->irq = pcidev->irq;
}
} else {
- printk(KERN_WARNING
- "comedi%d: me4000: me4000_attach(): "
- "No interrupt available\n", dev->minor);
+ dev_warn(dev->class_dev, "No interrupt available\n");
}
} else {
s->type = COMEDI_SUBD_UNUSED;
@@ -2055,14 +1652,14 @@ static int me4000_attach(struct comedi_device *dev, struct comedi_devconfig *it)
Analog output subdevice
========================================================================*/
- s = dev->subdevices + 1;
+ s = &dev->subdevices[1];
- if (thisboard->ao.count) {
+ if (thisboard->ao_nchan) {
s->type = COMEDI_SUBD_AO;
s->subdev_flags = SDF_WRITEABLE | SDF_COMMON | SDF_GROUND;
- s->n_chan = thisboard->ao.count;
+ s->n_chan = thisboard->ao_nchan;
s->maxdata = 0xFFFF; /* 16 bit DAC */
- s->range_table = &me4000_ao_range;
+ s->range_table = &range_bipolar10;
s->insn_write = me4000_ao_insn_write;
s->insn_read = me4000_ao_insn_read;
} else {
@@ -2073,12 +1670,12 @@ static int me4000_attach(struct comedi_device *dev, struct comedi_devconfig *it)
Digital I/O subdevice
========================================================================*/
- s = dev->subdevices + 2;
+ s = &dev->subdevices[2];
- if (thisboard->dio.count) {
+ if (thisboard->dio_nchan) {
s->type = COMEDI_SUBD_DIO;
s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
- s->n_chan = thisboard->dio.count * 8;
+ s->n_chan = thisboard->dio_nchan;
s->maxdata = 1;
s->range_table = &range_digital;
s->insn_bits = me4000_dio_insn_bits;
@@ -2091,21 +1688,22 @@ static int me4000_attach(struct comedi_device *dev, struct comedi_devconfig *it)
* Check for optoisolated ME-4000 version. If one the first
* port is a fixed output port and the second is a fixed input port.
*/
- if (!inl(info->dio_context.dir_reg)) {
+ if (!inl(dev->iobase + ME4000_DIO_DIR_REG)) {
s->io_bits |= 0xFF;
- outl(ME4000_DIO_CTRL_BIT_MODE_0, info->dio_context.dir_reg);
+ outl(ME4000_DIO_CTRL_BIT_MODE_0,
+ dev->iobase + ME4000_DIO_DIR_REG);
}
/*=========================================================================
Counter subdevice
========================================================================*/
- s = dev->subdevices + 3;
+ s = &dev->subdevices[3];
- if (thisboard->cnt.count) {
+ if (thisboard->has_counter) {
s->type = COMEDI_SUBD_COUNTER;
s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
- s->n_chan = thisboard->cnt.count;
+ s->n_chan = 3;
s->maxdata = 0xFFFF; /* 16 bit counters */
s->insn_read = me4000_cnt_insn_read;
s->insn_write = me4000_cnt_insn_write;
@@ -2119,12 +1717,14 @@ static int me4000_attach(struct comedi_device *dev, struct comedi_devconfig *it)
static void me4000_detach(struct comedi_device *dev)
{
- if (info) {
- if (info->pci_dev_p) {
- reset_board(dev);
- if (info->plx_regbase)
- comedi_pci_disable(info->pci_dev_p);
- pci_dev_put(info->pci_dev_p);
+ struct pci_dev *pcidev = comedi_to_pci_dev(dev);
+
+ if (dev->irq)
+ free_irq(dev->irq, dev);
+ if (pcidev) {
+ if (dev->iobase) {
+ me4000_reset(dev);
+ comedi_pci_disable(pcidev);
}
}
}
@@ -2132,7 +1732,7 @@ static void me4000_detach(struct comedi_device *dev)
static struct comedi_driver me4000_driver = {
.driver_name = "me4000",
.module = THIS_MODULE,
- .attach = me4000_attach,
+ .attach_pci = me4000_attach_pci,
.detach = me4000_detach,
};
@@ -2148,20 +1748,20 @@ static void __devexit me4000_pci_remove(struct pci_dev *dev)
}
static DEFINE_PCI_DEVICE_TABLE(me4000_pci_table) = {
- { PCI_DEVICE(PCI_VENDOR_ID_MEILHAUS, 0x4650) },
- { PCI_DEVICE(PCI_VENDOR_ID_MEILHAUS, 0x4660) },
- { PCI_DEVICE(PCI_VENDOR_ID_MEILHAUS, 0x4661) },
- { PCI_DEVICE(PCI_VENDOR_ID_MEILHAUS, 0x4662) },
- { PCI_DEVICE(PCI_VENDOR_ID_MEILHAUS, 0x4663) },
- { PCI_DEVICE(PCI_VENDOR_ID_MEILHAUS, 0x4670) },
- { PCI_DEVICE(PCI_VENDOR_ID_MEILHAUS, 0x4671) },
- { PCI_DEVICE(PCI_VENDOR_ID_MEILHAUS, 0x4672) },
- { PCI_DEVICE(PCI_VENDOR_ID_MEILHAUS, 0x4673) },
- { PCI_DEVICE(PCI_VENDOR_ID_MEILHAUS, 0x4680) },
- { PCI_DEVICE(PCI_VENDOR_ID_MEILHAUS, 0x4681) },
- { PCI_DEVICE(PCI_VENDOR_ID_MEILHAUS, 0x4682) },
- { PCI_DEVICE(PCI_VENDOR_ID_MEILHAUS, 0x4683) },
- { 0 }
+ {PCI_DEVICE(PCI_VENDOR_ID_MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME4650)},
+ {PCI_DEVICE(PCI_VENDOR_ID_MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME4660)},
+ {PCI_DEVICE(PCI_VENDOR_ID_MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME4660I)},
+ {PCI_DEVICE(PCI_VENDOR_ID_MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME4660S)},
+ {PCI_DEVICE(PCI_VENDOR_ID_MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME4660IS)},
+ {PCI_DEVICE(PCI_VENDOR_ID_MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME4670)},
+ {PCI_DEVICE(PCI_VENDOR_ID_MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME4670I)},
+ {PCI_DEVICE(PCI_VENDOR_ID_MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME4670S)},
+ {PCI_DEVICE(PCI_VENDOR_ID_MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME4670IS)},
+ {PCI_DEVICE(PCI_VENDOR_ID_MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME4680)},
+ {PCI_DEVICE(PCI_VENDOR_ID_MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME4680I)},
+ {PCI_DEVICE(PCI_VENDOR_ID_MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME4680S)},
+ {PCI_DEVICE(PCI_VENDOR_ID_MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME4680IS)},
+ {0}
};
MODULE_DEVICE_TABLE(pci, me4000_pci_table);