diff options
Diffstat (limited to 'drivers/staging/comedi/drivers/me4000.c')
-rw-r--r-- | drivers/staging/comedi/drivers/me4000.c | 213 |
1 files changed, 89 insertions, 124 deletions
diff --git a/drivers/staging/comedi/drivers/me4000.c b/drivers/staging/comedi/drivers/me4000.c index b766bb93efd..641e693d5d0 100644 --- a/drivers/staging/comedi/drivers/me4000.c +++ b/drivers/staging/comedi/drivers/me4000.c @@ -55,26 +55,13 @@ broken. #include "comedi_fc.h" #include "8253.h" +#include "plx9052.h" #if 0 /* file removed due to GPL incompatibility */ #include "me4000_fw.h" #endif -#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 - /* * ME4000 Register map and bit defines */ @@ -183,28 +170,6 @@ broken. #define ME4000_AO_DEMUX_ADJUST_VALUE 0x4c #define ME4000_AI_SAMPLE_COUNTER_REG 0xc0 -/* - * 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 @@ -220,9 +185,24 @@ struct me4000_info { unsigned int ao_readback[4]; }; +enum me4000_boardid { + BOARD_ME4650, + BOARD_ME4660, + BOARD_ME4660I, + BOARD_ME4660S, + BOARD_ME4660IS, + BOARD_ME4670, + BOARD_ME4670I, + BOARD_ME4670S, + BOARD_ME4670IS, + BOARD_ME4680, + BOARD_ME4680I, + BOARD_ME4680S, + BOARD_ME4680IS, +}; + struct me4000_board { const char *name; - unsigned short device_id; int ao_nchan; int ao_fifo; int ai_nchan; @@ -234,62 +214,61 @@ struct me4000_board { }; static const struct me4000_board me4000_boards[] = { - { + [BOARD_ME4650] = { .name = "ME-4650", - .device_id = PCI_DEVICE_ID_MEILHAUS_ME4650, .ai_nchan = 16, .dio_nchan = 32, - }, { + }, + [BOARD_ME4660] = { .name = "ME-4660", - .device_id = PCI_DEVICE_ID_MEILHAUS_ME4660, .ai_nchan = 32, .ai_diff_nchan = 16, .dio_nchan = 32, .has_counter = 1, - }, { + }, + [BOARD_ME4660I] = { .name = "ME-4660i", - .device_id = PCI_DEVICE_ID_MEILHAUS_ME4660I, .ai_nchan = 32, .ai_diff_nchan = 16, .dio_nchan = 32, .has_counter = 1, - }, { + }, + [BOARD_ME4660S] = { .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, - }, { + }, + [BOARD_ME4660IS] = { .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, - }, { + }, + [BOARD_ME4670] = { .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, - }, { + }, + [BOARD_ME4670I] = { .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, - }, { + }, + [BOARD_ME4670S] = { .name = "ME-4670s", - .device_id = PCI_DEVICE_ID_MEILHAUS_ME4670S, .ao_nchan = 4, .ai_nchan = 32, .ai_diff_nchan = 16, @@ -297,9 +276,9 @@ static const struct me4000_board me4000_boards[] = { .ex_trig_analog = 1, .dio_nchan = 32, .has_counter = 1, - }, { + }, + [BOARD_ME4670IS] = { .name = "ME-4670is", - .device_id = PCI_DEVICE_ID_MEILHAUS_ME4670IS, .ao_nchan = 4, .ai_nchan = 32, .ai_diff_nchan = 16, @@ -307,9 +286,9 @@ static const struct me4000_board me4000_boards[] = { .ex_trig_analog = 1, .dio_nchan = 32, .has_counter = 1, - }, { + }, + [BOARD_ME4680] = { .name = "ME-4680", - .device_id = PCI_DEVICE_ID_MEILHAUS_ME4680, .ao_nchan = 4, .ao_fifo = 4, .ai_nchan = 32, @@ -317,9 +296,9 @@ static const struct me4000_board me4000_boards[] = { .ex_trig_analog = 1, .dio_nchan = 32, .has_counter = 1, - }, { + }, + [BOARD_ME4680I] = { .name = "ME-4680i", - .device_id = PCI_DEVICE_ID_MEILHAUS_ME4680I, .ao_nchan = 4, .ao_fifo = 4, .ai_nchan = 32, @@ -327,9 +306,9 @@ static const struct me4000_board me4000_boards[] = { .ex_trig_analog = 1, .dio_nchan = 32, .has_counter = 1, - }, { + }, + [BOARD_ME4680S] = { .name = "ME-4680s", - .device_id = PCI_DEVICE_ID_MEILHAUS_ME4680S, .ao_nchan = 4, .ao_fifo = 4, .ai_nchan = 32, @@ -338,9 +317,9 @@ static const struct me4000_board me4000_boards[] = { .ex_trig_analog = 1, .dio_nchan = 32, .has_counter = 1, - }, { + }, + [BOARD_ME4680IS] = { .name = "ME-4680is", - .device_id = PCI_DEVICE_ID_MEILHAUS_ME4680IS, .ao_nchan = 4, .ao_fifo = 4, .ai_nchan = 32, @@ -376,6 +355,7 @@ static int xilinx_download(struct comedi_device *dev) wait_queue_head_t queue; int idx = 0; int size = 0; + unsigned int intcsr; if (!xilinx_iobase) return -ENODEV; @@ -386,27 +366,28 @@ static int xilinx_download(struct comedi_device *dev) * Set PLX local interrupt 2 polarity to high. * Interrupt is thrown by init pin of xilinx. */ - outl(0x10, info->plx_regbase + PLX_INTCSR); + outl(PLX9052_INTCSR_LI2POL, info->plx_regbase + PLX9052_INTCSR); /* Set /CS and /WRITE of the Xilinx */ - value = inl(info->plx_regbase + PLX_ICR); - value |= 0x100; - outl(value, info->plx_regbase + PLX_ICR); + value = inl(info->plx_regbase + PLX9052_CNTRL); + value |= PLX9052_CNTRL_UIO2_DATA; + outl(value, info->plx_regbase + PLX9052_CNTRL); /* Init Xilinx with CS1 */ inb(xilinx_iobase + 0xC8); /* Wait until /INIT pin is set */ udelay(20); - if (!(inl(info->plx_regbase + PLX_INTCSR) & 0x20)) { + intcsr = inl(info->plx_regbase + PLX9052_INTCSR); + if (!(intcsr & PLX9052_INTCSR_LI2STAT)) { dev_err(dev->class_dev, "Can't init Xilinx\n"); return -EIO; } /* Reset /CS and /WRITE of the Xilinx */ - value = inl(info->plx_regbase + PLX_ICR); - value &= ~0x100; - outl(value, info->plx_regbase + PLX_ICR); + value = inl(info->plx_regbase + PLX9052_CNTRL); + value &= ~PLX9052_CNTRL_UIO2_DATA; + outl(value, info->plx_regbase + PLX9052_CNTRL); if (FIRMWARE_NOT_AVAILABLE) { dev_err(dev->class_dev, "xilinx firmware unavailable due to licensing, aborting"); @@ -422,7 +403,7 @@ static int xilinx_download(struct comedi_device *dev) udelay(10); /* Check if BUSY flag is low */ - if (inl(info->plx_regbase + PLX_ICR) & 0x20) { + if (inl(info->plx_regbase + PLX9052_CNTRL) & PLX9052_CNTRL_UIO1_DATA) { dev_err(dev->class_dev, "Xilinx is still busy (idx = %d)\n", idx); @@ -432,7 +413,7 @@ static int xilinx_download(struct comedi_device *dev) } /* If done flag is high download was successful */ - if (inl(info->plx_regbase + PLX_ICR) & 0x4) { + if (inl(info->plx_regbase + PLX9052_CNTRL) & PLX9052_CNTRL_UIO0_DATA) { } else { dev_err(dev->class_dev, "DONE flag is not set\n"); dev_err(dev->class_dev, "Download not successful\n"); @@ -440,9 +421,9 @@ static int xilinx_download(struct comedi_device *dev) } /* Set /CS and /WRITE */ - value = inl(info->plx_regbase + PLX_ICR); - value |= 0x100; - outl(value, info->plx_regbase + PLX_ICR); + value = inl(info->plx_regbase + PLX9052_CNTRL); + value |= PLX9052_CNTRL_UIO2_DATA; + outl(value, info->plx_regbase + PLX9052_CNTRL); return 0; } @@ -454,11 +435,11 @@ static void me4000_reset(struct comedi_device *dev) int chan; /* Make a hardware reset */ - 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); + val = inl(info->plx_regbase + PLX9052_CNTRL); + val |= PLX9052_CNTRL_PCI_RESET; + outl(val, info->plx_regbase + PLX9052_CNTRL); + val &= ~PLX9052_CNTRL_PCI_RESET; + outl(val , info->plx_regbase + PLX9052_CNTRL); /* 0x8000 to the DACs means an output voltage of 0V */ for (chan = 0; chan < 4; chan++) @@ -474,7 +455,9 @@ static void me4000_reset(struct comedi_device *dev) outl(val, dev->iobase + ME4000_AO_CTRL_REG(chan)); /* Enable interrupts on the PLX */ - outl(0x43, info->plx_regbase + PLX_INTCSR); + outl(PLX9052_INTCSR_LI1ENAB | + PLX9052_INTCSR_LI1POL | + PLX9052_INTCSR_PCIENAB, info->plx_regbase + PLX9052_INTCSR); /* Set the adustment register for AO demux */ outl(ME4000_AO_DEMUX_ADJUST_VALUE, @@ -1550,30 +1533,17 @@ static int me4000_cnt_insn_write(struct comedi_device *dev, return 1; } -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_auto_attach(struct comedi_device *dev, - unsigned long context_unused) + unsigned long context) { struct pci_dev *pcidev = comedi_to_pci_dev(dev); - const struct me4000_board *thisboard; + const struct me4000_board *thisboard = NULL; struct me4000_info *info; struct comedi_subdevice *s; int result; - thisboard = me4000_find_boardinfo(dev, pcidev); + if (context < ARRAY_SIZE(me4000_boards)) + thisboard = &me4000_boards[context]; if (!thisboard) return -ENODEV; dev->board_ptr = thisboard; @@ -1584,7 +1554,7 @@ static int me4000_auto_attach(struct comedi_device *dev, return -ENOMEM; dev->private = info; - result = comedi_pci_enable(pcidev, dev->board_name); + result = comedi_pci_enable(dev); if (result) return result; @@ -1710,16 +1680,11 @@ static int me4000_auto_attach(struct comedi_device *dev, static void me4000_detach(struct comedi_device *dev) { - 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); - } - } + if (dev->iobase) + me4000_reset(dev); + comedi_pci_disable(dev); } static struct comedi_driver me4000_driver = { @@ -1730,26 +1695,26 @@ static struct comedi_driver me4000_driver = { }; static int me4000_pci_probe(struct pci_dev *dev, - const struct pci_device_id *ent) + const struct pci_device_id *id) { - return comedi_pci_auto_config(dev, &me4000_driver); + return comedi_pci_auto_config(dev, &me4000_driver, id->driver_data); } static DEFINE_PCI_DEVICE_TABLE(me4000_pci_table) = { - {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} + { PCI_VDEVICE(MEILHAUS, 0x4650), BOARD_ME4650 }, + { PCI_VDEVICE(MEILHAUS, 0x4660), BOARD_ME4660 }, + { PCI_VDEVICE(MEILHAUS, 0x4661), BOARD_ME4660I }, + { PCI_VDEVICE(MEILHAUS, 0x4662), BOARD_ME4660S }, + { PCI_VDEVICE(MEILHAUS, 0x4663), BOARD_ME4660IS }, + { PCI_VDEVICE(MEILHAUS, 0x4670), BOARD_ME4670 }, + { PCI_VDEVICE(MEILHAUS, 0x4671), BOARD_ME4670I }, + { PCI_VDEVICE(MEILHAUS, 0x4672), BOARD_ME4670S }, + { PCI_VDEVICE(MEILHAUS, 0x4673), BOARD_ME4670IS }, + { PCI_VDEVICE(MEILHAUS, 0x4680), BOARD_ME4680 }, + { PCI_VDEVICE(MEILHAUS, 0x4681), BOARD_ME4680I }, + { PCI_VDEVICE(MEILHAUS, 0x4682), BOARD_ME4680S }, + { PCI_VDEVICE(MEILHAUS, 0x4683), BOARD_ME4680IS }, + { 0 } }; MODULE_DEVICE_TABLE(pci, me4000_pci_table); |