Merge tag 'asoc-v3.10-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie...
[firefly-linux-kernel-4.4.55.git] / drivers / staging / comedi / drivers / me4000.c
index b766bb93efd6f599f5ebc3c52ff375f0df9270c1..641e693d5d0e9ffd68f5a43173450f7b2b0d1277 100644 (file)
@@ -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);