amplc_dio200: Support PCIe215, PCIe236 and PCIe296.
authorIan Abbott <abbotti@mev.co.uk>
Mon, 28 May 2012 09:40:41 +0000 (10:40 +0100)
committerIan Abbott <abbotti@mev.co.uk>
Mon, 28 May 2012 09:40:41 +0000 (10:40 +0100)
Added preliminary support for the above PCIe boards.  The interrupt
subdevice is not working yet as the boards need some additional
initialization to enable interrupts.  Left an unused subdevice that will
eventually become a timer subdevice.

Signed-off-by: Ian Abbott <abbotti@mev.co.uk>
comedi/drivers/amplc_dio200.c

index 5e6823de8bac04cb19bbc52376c2c2d50a987710..cee61e958f66c306924b0034f210e4cd99eb15ca 100644 (file)
@@ -1,10 +1,10 @@
 /*
     comedi/drivers/amplc_dio200.c
-    Driver for Amplicon PC272E and PCI272 DIO boards.
+    Driver for various Amplicon 200 series DIO boards.
     (Support for other boards in Amplicon 200 series may be added at
     a later date, e.g. PCI215.)
 
-    Copyright (C) 2005 MEV Ltd. <http://www.mev.co.uk/>
+    Copyright (C) 2005-2012 MEV Ltd. <http://www.mev.co.uk/>
 
     COMEDI - Linux Control and Measurement Device Interface
     Copyright (C) 1998,2000 David A. Schleef <ds@schleef.org>
@@ -29,16 +29,17 @@ Driver: amplc_dio200
 Description: Amplicon 200 Series Digital I/O
 Author: Ian Abbott <abbotti@mev.co.uk>
 Devices: [Amplicon] PC212E (pc212e), PC214E (pc214e), PC215E (pc215e),
-  PCI215 (pci215 or amplc_dio200), PC218E (pc218e), PC272E (pc272e),
-  PCI272 (pci272 or amplc_dio200)
-Updated: Wed, 22 Oct 2008 13:36:02 +0100
+  PCI215 (pci215 or amplc_dio200), PCIe215 (pcie215 or amplc_dio200),
+  PC218E (pc218e), PCIe236 (pcie236 or amplc_dio200), PC272E (pc272e),
+  PCI272 (pci272 or amplc_dio200), PCIe296 (pcie296 or amplc_dio200)
+Updated: Wed, 16 May 2012 13:57:58 +0100
 Status: works
 
 Configuration options - PC212E, PC214E, PC215E, PC218E, PC272E:
   [0] - I/O port base address
   [1] - IRQ (optional, but commands won't work without it)
 
-Configuration options - PCI215, PCI272:
+Configuration options - PCI215, PCIe215, PCIe236, PCI272, PCIe296:
   [0] - PCI bus of device (optional)
   [1] - PCI slot of device (optional)
   If bus/slot is not specified, the first available PCI device will
@@ -48,24 +49,39 @@ Passing a zero for an option is the same as leaving it unspecified.
 
 SUBDEVICES
 
-                    PC218E         PC212E      PC215E/PCI215
+                    PC212E         PC214E      PC215E/PCI215
                  -------------  -------------  -------------
-  Subdevices           7              6              5
-   0                 CTR-X1         PPI-X          PPI-X
-   1                 CTR-X2         CTR-Y1         PPI-Y
-   2                 CTR-Y1         CTR-Y2         CTR-Z1
-   3                 CTR-Y2         CTR-Z1         CTR-Z2
-   4                 CTR-Z1         CTR-Z2       INTERRUPT
-   5                 CTR-Z2       INTERRUPT
-   6               INTERRUPT
-
-                    PC214E      PC272E/PCI272
+  Subdevices           6              4              5
+   0                 PPI-X          PPI-X          PPI-X
+   1                 CTR-Y1         PPI-Y          PPI-Y
+   2                 CTR-Y2         CTR-Z1*        CTR-Z1
+   3                 CTR-Z1       INTERRUPT*       CTR-Z2
+   4                 CTR-Z2                      INTERRUPT
+   5               INTERRUPT
+
+                    PCIe215        PC218E         PCIe236
+                 -------------  -------------  -------------
+  Subdevices           8              7              8
+   0                 PPI-X          CTR-X1         PPI-X
+   1                 UNUSED         CTR-X2         UNUSED
+   2                 PPI-Y          CTR-Y1         UNUSED
+   3                 UNUSED         CTR-Y2         UNUSED
+   4                 CTR-Z1         CTR-Z1         CTR-Z1
+   5                 CTR-Z2         CTR-Z2         CTR-Z2
+   6                 TIMER        INTERRUPT        TIMER
+   7               INTERRUPT                     INTERRUPT
+
+                 PC272E/PCI272     PCIe296
                  -------------  -------------
-  Subdevices           4              4
-   0                 PPI-X          PPI-X
-   1                 PPI-Y          PPI-Y
-   2                 CTR-Z1*        PPI-Z
-   3               INTERRUPT*     INTERRUPT
+  Subdevices           4              8
+   0                 PPI-X          PPI-X1
+   1                 PPI-Y          PPI-X2
+   2                 PPI-Z          PPI-Y1
+   3               INTERRUPT        PPI-Y2
+   4                                CTR-Z1
+   5                                CTR-Z2
+   6                                TIMER
+   7                              INTERRUPT
 
 Each PPI is a 8255 chip providing 24 DIO channels.  The DIO channels
 are configurable as inputs or outputs in four groups:
@@ -145,6 +161,8 @@ Clock and gate interconnection notes:
   3.  The counter subdevices are connected in a ring, so the highest
   counter subdevice precedes the lowest.
 
+The 'TIMER' subdevice is a free-running 32-bit timer subdevice.
+
 The 'INTERRUPT' subdevice pretends to be a digital input subdevice.  The
 digital inputs come from the interrupt status register.  The number of
 channels matches the number of interrupt sources.  The PC214E does not
@@ -153,25 +171,35 @@ below.
 
 INTERRUPT SOURCES
 
-                    PC218E         PC212E      PC215E/PCI215
+                    PC212E         PC214E      PC215E/PCI215
+                 -------------  -------------  -------------
+  Sources              6              1              6
+   0               PPI-X-C0       JUMPER-J5      PPI-X-C0
+   1               PPI-X-C3                      PPI-X-C3
+   2              CTR-Y1-OUT                     PPI-Y-C0
+   3              CTR-Y2-OUT                     PPI-Y-C3
+   4              CTR-Z1-OUT                    CTR-Z1-OUT
+   5              CTR-Z2-OUT                    CTR-Z2-OUT
+
+                    PCIe215        PC218E         PCIe236
                  -------------  -------------  -------------
   Sources              6              6              6
-   0              CTR-X1-OUT      PPI-X-C0       PPI-X-C0
-   1              CTR-X2-OUT      PPI-X-C3       PPI-X-C3
-   2              CTR-Y1-OUT     CTR-Y1-OUT      PPI-Y-C0
-   3              CTR-Y2-OUT     CTR-Y2-OUT      PPI-Y-C3
+   0               PPI-X-C0      CTR-X1-OUT      PPI-X-C0
+   1               PPI-X-C3      CTR-X2-OUT      PPI-X-C3
+   2               PPI-Y-C0      CTR-Y1-OUT       unused
+   3               PPI-Y-C3      CTR-Y2-OUT       unused
    4              CTR-Z1-OUT     CTR-Z1-OUT     CTR-Z1-OUT
    5              CTR-Z2-OUT     CTR-Z2-OUT     CTR-Z2-OUT
 
-                    PC214E      PC272E/PCI272
+                 PC272E/PCI272     PCIe296
                  -------------  -------------
-  Sources              1              6
-   0               JUMPER-J5      PPI-X-C0
-   1                              PPI-X-C3
-   2                              PPI-Y-C0
-   3                              PPI-Y-C3
-   4                              PPI-Z-C0
-   5                              PPI-Z-C3
+  Sources              6              6
+   0               PPI-X-C0       PPI-X1-C0
+   1               PPI-X-C3       PPI-X1-C3
+   2               PPI-Y-C0       PPI-Y1-C0
+   3               PPI-Y-C3       PPI-Y2-C3
+   4               PPI-Z-C0      CTR-Z1-OUT
+   5               PPI-Z-C3      CTR-Z2-OUT
 
 When an interrupt source is enabled in the interrupt source enable
 register, a rising edge on the source signal latches the corresponding
@@ -218,6 +246,9 @@ order they appear in the channel list.
 /* #define PCI_VENDOR_ID_AMPLICON 0x14dc */
 #define PCI_DEVICE_ID_AMPLICON_PCI272 0x000a
 #define PCI_DEVICE_ID_AMPLICON_PCI215 0x000b
+#define PCI_DEVICE_ID_AMPLICON_PCIE236 0x0011
+#define PCI_DEVICE_ID_AMPLICON_PCIE215 0x0012
+#define PCI_DEVICE_ID_AMPLICON_PCIE296 0x0014
 #define PCI_DEVICE_ID_INVALID 0xffff
 
 /* 8255 control register bits */
@@ -231,6 +262,7 @@ order they appear in the channel list.
 
 /* 200 series registers */
 #define DIO200_IO_SIZE         0x20
+#define DIO200_PCIE_IO_SIZE    0x4000
 #define DIO200_XCLK_SCE                0x18    /* Group X clock selection register */
 #define DIO200_YCLK_SCE                0x19    /* Group Y clock selection register */
 #define DIO200_ZCLK_SCE                0x1a    /* Group Z clock selection register */
@@ -274,6 +306,7 @@ struct dio200_region {
                unsigned char __iomem *membase; /* Mapped MMIO base address */
        } u;
        unsigned char regtype;
+       unsigned char regshift;
 };
 
 /*
@@ -285,9 +318,11 @@ enum dio200_bustype { isa_bustype, pci_bustype };
 enum dio200_model {
        pc212e_model,
        pc214e_model,
-       pc215e_model, pci215_model,
+       pc215e_model, pci215_model, pcie215_model,
        pc218e_model,
+       pcie236_model,
        pc272e_model, pci272_model,
+       pcie296_model,
        anypci_model
 };
 
@@ -296,7 +331,13 @@ enum dio200_layout {
        pc214_layout,
        pc215_layout,
        pc218_layout,
-       pc272_layout
+       pc272_layout,
+#ifdef CONFIG_COMEDI_PCI
+       pcie215_layout,
+       pcie236_layout,
+       pcie296_layout,
+#endif
+       num_layouts
 };
 
 typedef struct dio200_board_struct {
@@ -306,6 +347,7 @@ typedef struct dio200_board_struct {
        enum dio200_model model;
        enum dio200_layout layout;
        unsigned char mainbar;
+       unsigned char mainshift;
        unsigned int mainsize;
 } dio200_board;
 
@@ -341,6 +383,18 @@ static const dio200_board dio200_boards[] = {
              mainsize: DIO200_IO_SIZE,
              mainbar:  2,
                },
+#endif
+#ifdef CONFIG_COMEDI_PCI
+       {
+             name:     "pcie215",
+             devid:    PCI_DEVICE_ID_AMPLICON_PCIE215,
+             bustype:  pci_bustype,
+             model:    pcie215_model,
+             layout:   pcie215_layout,
+             mainsize: DIO200_PCIE_IO_SIZE,
+             mainbar:  1,
+             mainshift: 3,
+               },
 #endif
        {
              name:     "pc218e",
@@ -349,6 +403,18 @@ static const dio200_board dio200_boards[] = {
              layout:   pc218_layout,
              mainsize: DIO200_IO_SIZE,
                },
+#ifdef CONFIG_COMEDI_PCI
+       {
+             name:     "pcie236",
+             devid:    PCI_DEVICE_ID_AMPLICON_PCIE236,
+             bustype:  pci_bustype,
+             model:    pcie236_model,
+             layout:   pcie236_layout,
+             mainsize: DIO200_PCIE_IO_SIZE,
+             mainbar:  1,
+             mainshift: 3,
+               },
+#endif
        {
              name:     "pc272e",
              bustype:  isa_bustype,
@@ -367,6 +433,18 @@ static const dio200_board dio200_boards[] = {
              mainbar:  2,
                },
 #endif
+#ifdef CONFIG_COMEDI_PCI
+       {
+             name:     "pcie296",
+             devid:    PCI_DEVICE_ID_AMPLICON_PCIE296,
+             bustype:  pci_bustype,
+             model:    pcie296_model,
+             layout:   pcie296_layout,
+             mainsize: DIO200_PCIE_IO_SIZE,
+             mainbar:  1,
+             mainshift: 3,
+               },
+#endif
 #ifdef CONFIG_COMEDI_PCI
        {
              name:     DIO200_DRIVER_NAME,
@@ -382,9 +460,9 @@ static const dio200_board dio200_boards[] = {
  * layout.
  */
 
-enum dio200_sdtype { sd_none, sd_intr, sd_8255, sd_8254 };
+enum dio200_sdtype { sd_none, sd_intr, sd_8255, sd_8254, sd_timer };
 
-#define DIO200_MAX_SUBDEVS     7
+#define DIO200_MAX_SUBDEVS     8
 #define DIO200_MAX_ISNS                6
 
 typedef struct dio200_layout_struct {
@@ -442,6 +520,32 @@ static const dio200_layout dio200_layouts[] = {
              has_int_sce:1,
              has_clk_gat_sce:0,
                },
+#ifdef CONFIG_COMEDI_PCI
+       [pcie215_layout] = {
+             n_subdevs:8,
+             sdtype:   {sd_8255, sd_none, sd_8255, sd_none, sd_8254, sd_8254,
+                               sd_timer, sd_intr},
+             sdinfo:   {0x00, 0x00, 0x08, 0x00, 0x10, 0x14, 0x00, 0x3F},
+             has_int_sce:1,
+             has_clk_gat_sce:1,
+               },
+       [pcie236_layout] = {
+             n_subdevs:8,
+             sdtype:   {sd_8255, sd_none, sd_none, sd_none, sd_8254, sd_8254,
+                               sd_timer, sd_intr},
+             sdinfo:   {0x00, 0x00, 0x00, 0x00, 0x10, 0x14, 0x00, 0x3F},
+             has_int_sce:1,
+             has_clk_gat_sce:1,
+               },
+       [pcie296_layout] = {
+             n_subdevs:8,
+             sdtype:   {sd_8255, sd_8255, sd_8255, sd_8255, sd_8254, sd_8254,
+                               sd_timer, sd_intr},
+             sdinfo:   {0x00, 0x04, 0x08, 0x0C, 0x10, 0x14, 0x00, 0x3F},
+             has_int_sce:1,
+             has_clk_gat_sce:1,
+               },
+#endif
 };
 
 /*
@@ -454,6 +558,12 @@ static DEFINE_PCI_DEVICE_TABLE(dio200_pci_table) = {
                PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
        {PCI_VENDOR_ID_AMPLICON, PCI_DEVICE_ID_AMPLICON_PCI272,
                PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+       {PCI_VENDOR_ID_AMPLICON, PCI_DEVICE_ID_AMPLICON_PCIE236,
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+       {PCI_VENDOR_ID_AMPLICON, PCI_DEVICE_ID_AMPLICON_PCIE215,
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+       {PCI_VENDOR_ID_AMPLICON, PCI_DEVICE_ID_AMPLICON_PCIE296,
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
        {0}
 };
 
@@ -532,6 +642,7 @@ COMEDI_INITCLEANUP(driver_amplc_dio200);
  */
 static unsigned char dio200_read8(comedi_device * dev, unsigned int offset)
 {
+       offset <<= devpriv->io.regshift;
        if (devpriv->io.regtype == io_regtype)
                return inb(devpriv->io.u.iobase + offset);
        else
@@ -544,6 +655,7 @@ static unsigned char dio200_read8(comedi_device * dev, unsigned int offset)
 static void dio200_write8(comedi_device * dev, unsigned int offset,
                unsigned char val)
 {
+       offset <<= devpriv->io.regshift;
        if (devpriv->io.regtype == io_regtype)
                outb(val, devpriv->io.u.iobase + offset);
        else
@@ -1613,6 +1725,7 @@ static int dio200_attach(comedi_device * dev, comedi_devconfig * it)
 
        devpriv->intr_sd = -1;
        devpriv->io.regtype = no_regtype;
+       devpriv->io.regshift = thisboard->mainshift;
 
        /* Enable device and reserve I/O spaces. */
 #ifdef CONFIG_COMEDI_PCI
@@ -1701,6 +1814,8 @@ static int dio200_attach(comedi_device * dev, comedi_devconfig * it)
                                s->type = COMEDI_SUBD_UNUSED;
                        }
                        break;
+               case sd_timer:
+                       /* TODO.  Fall-thru to default for now. */
                default:
                        s->type = COMEDI_SUBD_UNUSED;
                        break;