2 comedi/drivers/amplc_dio200.c
3 Driver for various Amplicon 200 series DIO boards.
4 (Support for other boards in Amplicon 200 series may be added at
5 a later date, e.g. PCI215.)
7 Copyright (C) 2005-2012 MEV Ltd. <http://www.mev.co.uk/>
9 COMEDI - Linux Control and Measurement Device Interface
10 Copyright (C) 1998,2000 David A. Schleef <ds@schleef.org>
12 This program is free software; you can redistribute it and/or modify
13 it under the terms of the GNU General Public License as published by
14 the Free Software Foundation; either version 2 of the License, or
15 (at your option) any later version.
17 This program is distributed in the hope that it will be useful,
18 but WITHOUT ANY WARRANTY; without even the implied warranty of
19 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 GNU General Public License for more details.
22 You should have received a copy of the GNU General Public License
23 along with this program; if not, write to the Free Software
24 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
29 Description: Amplicon 200 Series Digital I/O
30 Author: Ian Abbott <abbotti@mev.co.uk>
31 Devices: [Amplicon] PC212E (pc212e), PC214E (pc214e), PC215E (pc215e),
32 PCI215 (pci215 or amplc_dio200), PCIe215 (pcie215 or amplc_dio200),
33 PC218E (pc218e), PCIe236 (pcie236 or amplc_dio200), PC272E (pc272e),
34 PCI272 (pci272 or amplc_dio200), PCIe296 (pcie296 or amplc_dio200)
35 Updated: Wed, 16 May 2012 13:57:58 +0100
38 Configuration options - PC212E, PC214E, PC215E, PC218E, PC272E:
39 [0] - I/O port base address
40 [1] - IRQ (optional, but commands won't work without it)
42 Configuration options - PCI215, PCIe215, PCIe236, PCI272, PCIe296:
43 [0] - PCI bus of device (optional)
44 [1] - PCI slot of device (optional)
45 If bus/slot is not specified, the first available PCI device will
48 Passing a zero for an option is the same as leaving it unspecified.
52 PC212E PC214E PC215E/PCI215
53 ------------- ------------- -------------
57 2 CTR-Y2 CTR-Z1* CTR-Z1
58 3 CTR-Z1 INTERRUPT* CTR-Z2
62 PCIe215 PC218E PCIe236
63 ------------- ------------- -------------
66 1 UNUSED CTR-X2 UNUSED
68 3 UNUSED CTR-Y2 UNUSED
69 4 CTR-Z1 CTR-Z1 CTR-Z1
70 5 CTR-Z2 CTR-Z2 CTR-Z2
71 6 TIMER INTERRUPT TIMER
75 ------------- -------------
86 Each PPI is a 8255 chip providing 24 DIO channels. The DIO channels
87 are configurable as inputs or outputs in four groups:
89 Port A - channels 0 to 7
90 Port B - channels 8 to 15
91 Port CL - channels 16 to 19
92 Port CH - channels 20 to 23
94 Only mode 0 of the 8255 chips is supported.
96 Each CTR is a 8254 chip providing 3 16-bit counter channels. Each
97 channel is configured individually with INSN_CONFIG instructions. The
98 specific type of configuration instruction is specified in data[0].
99 Some configuration instructions expect an additional parameter in
100 data[1]; others return a value in data[1]. The following configuration
101 instructions are supported:
103 INSN_CONFIG_SET_COUNTER_MODE. Sets the counter channel's mode and
104 BCD/binary setting specified in data[1].
106 INSN_CONFIG_8254_READ_STATUS. Reads the status register value for the
107 counter channel into data[1].
109 INSN_CONFIG_SET_CLOCK_SRC. Sets the counter channel's clock source as
110 specified in data[1] (this is a hardware-specific value). Not
111 supported on PC214E. For the other boards, valid clock sources are
114 0. CLK n, the counter channel's dedicated CLK input from the SK1
115 connector. (N.B. for other values, the counter channel's CLKn
116 pin on the SK1 connector is an output!)
117 1. Internal 10 MHz clock.
118 2. Internal 1 MHz clock.
119 3. Internal 100 kHz clock.
120 4. Internal 10 kHz clock.
121 5. Internal 1 kHz clock.
122 6. OUT n-1, the output of counter channel n-1 (see note 1 below).
123 7. Ext Clock, the counter chip's dedicated Ext Clock input from
124 the SK1 connector. This pin is shared by all three counter
125 channels on the chip.
127 INSN_CONFIG_GET_CLOCK_SRC. Returns the counter channel's current
128 clock source in data[1]. For internal clock sources, data[2] is set
131 INSN_CONFIG_SET_GATE_SRC. Sets the counter channel's gate source as
132 specified in data[2] (this is a hardware-specific value). Not
133 supported on PC214E. For the other boards, valid gate sources are 0
136 0. VCC (internal +5V d.c.), i.e. gate permanently enabled.
137 1. GND (internal 0V d.c.), i.e. gate permanently disabled.
138 2. GAT n, the counter channel's dedicated GAT input from the SK1
139 connector. (N.B. for other values, the counter channel's GATn
140 pin on the SK1 connector is an output!)
141 3. /OUT n-2, the inverted output of counter channel n-2 (see note
148 INSN_CONFIG_GET_GATE_SRC. Returns the counter channel's current gate
151 Clock and gate interconnection notes:
153 1. Clock source OUT n-1 is the output of the preceding channel on the
154 same counter subdevice if n > 0, or the output of channel 2 on the
155 preceding counter subdevice (see note 3) if n = 0.
157 2. Gate source /OUT n-2 is the inverted output of channel 0 on the
158 same counter subdevice if n = 2, or the inverted output of channel n+1
159 on the preceding counter subdevice (see note 3) if n < 2.
161 3. The counter subdevices are connected in a ring, so the highest
162 counter subdevice precedes the lowest.
164 The 'TIMER' subdevice is a free-running 32-bit timer subdevice.
166 The 'INTERRUPT' subdevice pretends to be a digital input subdevice. The
167 digital inputs come from the interrupt status register. The number of
168 channels matches the number of interrupt sources. The PC214E does not
169 have an interrupt status register; see notes on 'INTERRUPT SOURCES'
174 PC212E PC214E PC215E/PCI215
175 ------------- ------------- -------------
177 0 PPI-X-C0 JUMPER-J5 PPI-X-C0
179 2 CTR-Y1-OUT1 PPI-Y-C0
180 3 CTR-Y2-OUT1 PPI-Y-C3
181 4 CTR-Z1-OUT1 CTR-Z1-OUT1
182 5 CTR-Z2-OUT1 CTR-Z2-OUT1
184 PCIe215 PC218E PCIe236
185 ------------- ------------- -------------
187 0 PPI-X-C0 CTR-X1-OUT1 PPI-X-C0
188 1 PPI-X-C3 CTR-X2-OUT1 PPI-X-C3
189 2 PPI-Y-C0 CTR-Y1-OUT1 unused
190 3 PPI-Y-C3 CTR-Y2-OUT1 unused
191 4 CTR-Z1-OUT1 CTR-Z1-OUT1 CTR-Z1-OUT1
192 5 CTR-Z2-OUT1 CTR-Z2-OUT1 CTR-Z2-OUT1
194 PC272E/PCI272 PCIe296
195 ------------- -------------
201 4 PPI-Z-C0 CTR-Z1-OUT1
202 5 PPI-Z-C3 CTR-Z2-OUT1
204 When an interrupt source is enabled in the interrupt source enable
205 register, a rising edge on the source signal latches the corresponding
206 bit to 1 in the interrupt status register.
208 When the interrupt status register value as a whole (actually, just the
209 6 least significant bits) goes from zero to non-zero, the board will
210 generate an interrupt. For level-triggered hardware interrupts (PCI
211 card), the interrupt will remain asserted until the interrupt status
212 register is cleared to zero. For edge-triggered hardware interrupts
213 (ISA card), no further interrupts will occur until the interrupt status
214 register is cleared to zero. To clear a bit to zero in the interrupt
215 status register, the corresponding interrupt source must be disabled
216 in the interrupt source enable register (there is no separate interrupt
219 The PC214E does not have an interrupt source enable register or an
220 interrupt status register; its 'INTERRUPT' subdevice has a single
221 channel and its interrupt source is selected by the position of jumper
226 The driver supports a read streaming acquisition command on the
227 'INTERRUPT' subdevice. The channel list selects the interrupt sources
228 to be enabled. All channels will be sampled together (convert_src ==
229 TRIG_NOW). The scan begins a short time after the hardware interrupt
230 occurs, subject to interrupt latencies (scan_begin_src == TRIG_EXT,
231 scan_begin_arg == 0). The value read from the interrupt status register
232 is packed into a sampl_t value, one bit per requested channel, in the
233 order they appear in the channel list.
236 #include <linux/comedidev.h>
238 #include "comedi_pci.h"
243 #define DIO200_DRIVER_NAME "amplc_dio200"
246 /* #define PCI_VENDOR_ID_AMPLICON 0x14dc */
247 #define PCI_DEVICE_ID_AMPLICON_PCI272 0x000a
248 #define PCI_DEVICE_ID_AMPLICON_PCI215 0x000b
249 #define PCI_DEVICE_ID_AMPLICON_PCIE236 0x0011
250 #define PCI_DEVICE_ID_AMPLICON_PCIE215 0x0012
251 #define PCI_DEVICE_ID_AMPLICON_PCIE296 0x0014
252 #define PCI_DEVICE_ID_INVALID 0xffff
254 /* 8255 control register bits */
255 #define CR_C_LO_IO 0x01
257 #define CR_B_MODE 0x04
258 #define CR_C_HI_IO 0x08
260 #define CR_A_MODE(a) ((a)<<5)
263 /* 200 series registers */
264 #define DIO200_IO_SIZE 0x20
265 #define DIO200_PCIE_IO_SIZE 0x4000
266 #define DIO200_XCLK_SCE 0x18 /* Group X clock selection register */
267 #define DIO200_YCLK_SCE 0x19 /* Group Y clock selection register */
268 #define DIO200_ZCLK_SCE 0x1a /* Group Z clock selection register */
269 #define DIO200_XGAT_SCE 0x1b /* Group X gate selection register */
270 #define DIO200_YGAT_SCE 0x1c /* Group Y gate selection register */
271 #define DIO200_ZGAT_SCE 0x1d /* Group Z gate selection register */
272 #define DIO200_INT_SCE 0x1e /* Interrupt enable/status register */
273 /* Extra registers for new PCIe boards */
274 #define DIO200_ENHANCE 0x20 /* 1 to enable enhanced features */
275 #define DIO200_VERSION 0x24 /* Hardware version */
278 * Macros for constructing value for DIO_200_?CLK_SCE and
279 * DIO_200_?GAT_SCE registers:
281 * 'which' is: 0 for CTR-X1, CTR-Y1, CTR-Z1; 1 for CTR-X2, CTR-Y2 or CTR-Z2.
282 * 'chan' is the channel: 0, 1 or 2.
283 * 'source' is the signal source: 0 to 7, or 0 to 31 for "enhanced" boards.
285 #define CLK_SCE(which, chan, source) (((which) << 5) | ((chan) << 3) | \
286 (((source) & 030) << 3) | ((source) & 007))
287 #define GAT_SCE(which, chan, source) (((which) << 5) | ((chan) << 3) | \
288 (((source) & 030) << 3) | ((source) & 007))
291 * Periods of the internal clock sources in nanoseconds.
293 static const unsigned clock_period[32] = {
294 0, /* dedicated clock input/output pin */
301 0, /* group clock input pin */
302 0, /* HIGH (VCC) (enhanced) */
303 0, /* LOW (GND) (enhanced) */
304 0, /* pattern present (enhanced) */
305 50, /* 20 MHz (enhanced) */
306 /* remaining clock sources reserved (enhanced) */
312 enum dio200_regtype { no_regtype, io_regtype, mmio_regtype };
313 struct dio200_region {
315 unsigned long iobase; /* I/O base address */
316 unsigned char __iomem *membase; /* Mapped MMIO base address */
318 unsigned char regtype;
319 unsigned char regshift;
323 * Board descriptions.
326 enum dio200_bustype { isa_bustype, pci_bustype };
331 pc215e_model, pci215_model, pcie215_model,
334 pc272e_model, pci272_model,
345 #ifdef CONFIG_COMEDI_PCI
353 typedef struct dio200_board_struct {
355 unsigned short devid;
356 enum dio200_bustype bustype;
357 enum dio200_model model;
358 enum dio200_layout layout;
359 unsigned char mainbar;
360 unsigned char mainshift;
361 unsigned int mainsize;
364 static const dio200_board dio200_boards[] = {
367 bustype: isa_bustype,
369 layout: pc212_layout,
370 mainsize: DIO200_IO_SIZE,
374 bustype: isa_bustype,
376 layout: pc214_layout,
377 mainsize: DIO200_IO_SIZE,
381 bustype: isa_bustype,
383 layout: pc215_layout,
384 mainsize: DIO200_IO_SIZE,
386 #ifdef CONFIG_COMEDI_PCI
389 devid: PCI_DEVICE_ID_AMPLICON_PCI215,
390 bustype: pci_bustype,
392 layout: pc215_layout,
393 mainsize: DIO200_IO_SIZE,
397 #ifdef CONFIG_COMEDI_PCI
400 devid: PCI_DEVICE_ID_AMPLICON_PCIE215,
401 bustype: pci_bustype,
402 model: pcie215_model,
403 layout: pcie215_layout,
404 mainsize: DIO200_PCIE_IO_SIZE,
411 bustype: isa_bustype,
413 layout: pc218_layout,
414 mainsize: DIO200_IO_SIZE,
416 #ifdef CONFIG_COMEDI_PCI
419 devid: PCI_DEVICE_ID_AMPLICON_PCIE236,
420 bustype: pci_bustype,
421 model: pcie236_model,
422 layout: pcie236_layout,
423 mainsize: DIO200_PCIE_IO_SIZE,
430 bustype: isa_bustype,
432 layout: pc272_layout,
433 mainsize: DIO200_IO_SIZE,
435 #ifdef CONFIG_COMEDI_PCI
438 devid: PCI_DEVICE_ID_AMPLICON_PCI272,
439 bustype: pci_bustype,
441 layout: pc272_layout,
442 mainsize: DIO200_IO_SIZE,
446 #ifdef CONFIG_COMEDI_PCI
449 devid: PCI_DEVICE_ID_AMPLICON_PCIE296,
450 bustype: pci_bustype,
451 model: pcie296_model,
452 layout: pcie296_layout,
453 mainsize: DIO200_PCIE_IO_SIZE,
458 #ifdef CONFIG_COMEDI_PCI
460 name: DIO200_DRIVER_NAME,
461 devid: PCI_DEVICE_ID_INVALID,
462 bustype: pci_bustype,
463 model: anypci_model, /* wildcard */
469 * Layout descriptions - some ISA and PCI board descriptions share the same
473 enum dio200_sdtype { sd_none, sd_intr, sd_8255, sd_8254, sd_timer };
475 #define DIO200_MAX_SUBDEVS 8
476 #define DIO200_MAX_ISNS 6
478 typedef struct dio200_layout_struct {
479 unsigned short n_subdevs; /* number of subdevices */
480 unsigned char sdtype[DIO200_MAX_SUBDEVS]; /* enum dio200_sdtype */
481 unsigned char sdinfo[DIO200_MAX_SUBDEVS]; /* depends on sdtype */
482 char has_int_sce; /* has interrupt enable/status register */
483 char has_clk_gat_sce; /* has clock/gate selection registers */
484 char has_enhancements; /* has enhanced features */
487 static const dio200_layout dio200_layouts[] = {
490 sdtype: {sd_8255, sd_8254, sd_8254, sd_8254,
493 sdinfo: {0x00, 0x08, 0x0C, 0x10, 0x14,
501 sdtype: {sd_8255, sd_8255, sd_8254,
503 sdinfo: {0x00, 0x08, 0x10, 0x01},
510 sdtype: {sd_8255, sd_8255, sd_8254,
513 sdinfo: {0x00, 0x08, 0x10, 0x14, 0x3F},
520 sdtype: {sd_8254, sd_8254, sd_8255, sd_8254,
523 sdinfo: {0x00, 0x04, 0x08, 0x0C, 0x10,
532 sdtype: {sd_8255, sd_8255, sd_8255,
534 sdinfo: {0x00, 0x08, 0x10, 0x3F},
539 #ifdef CONFIG_COMEDI_PCI
542 sdtype: {sd_8255, sd_none, sd_8255, sd_none, sd_8254, sd_8254,
544 sdinfo: {0x00, 0x00, 0x08, 0x00, 0x10, 0x14, 0x00, 0x3F},
551 sdtype: {sd_8255, sd_none, sd_none, sd_none, sd_8254, sd_8254,
553 sdinfo: {0x00, 0x00, 0x00, 0x00, 0x10, 0x14, 0x00, 0x3F},
560 sdtype: {sd_8255, sd_8255, sd_8255, sd_8255, sd_8254, sd_8254,
562 sdinfo: {0x00, 0x04, 0x08, 0x0C, 0x10, 0x14, 0x00, 0x3F},
574 #ifdef CONFIG_COMEDI_PCI
575 static DEFINE_PCI_DEVICE_TABLE(dio200_pci_table) = {
576 {PCI_VENDOR_ID_AMPLICON, PCI_DEVICE_ID_AMPLICON_PCI215,
577 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
578 {PCI_VENDOR_ID_AMPLICON, PCI_DEVICE_ID_AMPLICON_PCI272,
579 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
580 {PCI_VENDOR_ID_AMPLICON, PCI_DEVICE_ID_AMPLICON_PCIE236,
581 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
582 {PCI_VENDOR_ID_AMPLICON, PCI_DEVICE_ID_AMPLICON_PCIE215,
583 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
584 {PCI_VENDOR_ID_AMPLICON, PCI_DEVICE_ID_AMPLICON_PCIE296,
585 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
589 MODULE_DEVICE_TABLE(pci, dio200_pci_table);
590 #endif /* CONFIG_COMEDI_PCI */
593 * Useful for shorthand access to the particular board structure
595 #define thisboard ((const dio200_board *)dev->board_ptr)
596 #define thislayout (&dio200_layouts[((dio200_board *)dev->board_ptr)->layout])
598 /* this structure is for data unique to this hardware driver. If
599 several hardware drivers keep similar information in this structure,
600 feel free to suggest moving the variable to the comedi_device struct. */
602 #ifdef CONFIG_COMEDI_PCI
603 struct pci_dev *pci_dev; /* PCI device */
605 struct dio200_region io; /* Register region */
609 #define devpriv ((dio200_private *)dev->private)
612 unsigned int ofs; /* Counter base offset */
613 unsigned int clk_sce_ofs; /* CLK_SCE base offset */
614 unsigned int gat_sce_ofs; /* GAT_SCE base offset */
615 int which; /* Bit 5 of CLK_SCE or GAT_SCE */
616 unsigned int clock_src[3]; /* Current clock sources */
617 unsigned int gate_src[3]; /* Current gate sources */
619 } dio200_subdev_8254;
622 unsigned int ofs; /* DIO base offset */
623 } dio200_subdev_8255;
629 unsigned int valid_isns;
630 unsigned int enabled_isns;
631 unsigned int stopcount;
633 } dio200_subdev_intr;
636 * The comedi_driver structure tells the Comedi core module
637 * which functions to call to configure/deconfigure (attach/detach)
638 * the board, and also about the kernel module that contains
641 static int dio200_attach(comedi_device * dev, comedi_devconfig * it);
642 static int dio200_detach(comedi_device * dev);
643 static comedi_driver driver_amplc_dio200 = {
644 driver_name:DIO200_DRIVER_NAME,
646 attach:dio200_attach,
647 detach:dio200_detach,
648 board_name:&dio200_boards[0].name,
649 offset:sizeof(dio200_board),
650 num_names:sizeof(dio200_boards) / sizeof(dio200_board),
653 #ifdef CONFIG_COMEDI_PCI
654 COMEDI_PCI_INITCLEANUP(driver_amplc_dio200, dio200_pci_table);
656 COMEDI_INITCLEANUP(driver_amplc_dio200);
660 * Read 8-bit register.
662 static unsigned char dio200_read8(comedi_device * dev, unsigned int offset)
664 offset <<= devpriv->io.regshift;
665 if (devpriv->io.regtype == io_regtype)
666 return inb(devpriv->io.u.iobase + offset);
668 return readb(devpriv->io.u.membase + offset);
672 * Write 8-bit register.
674 static void dio200_write8(comedi_device * dev, unsigned int offset,
677 offset <<= devpriv->io.regshift;
678 if (devpriv->io.regtype == io_regtype)
679 outb(val, devpriv->io.u.iobase + offset);
681 writeb(val, devpriv->io.u.membase + offset);
685 * Read 32-bit register.
687 #ifdef CONFIG_COMEDI_PCI
688 static unsigned int dio200_read32(comedi_device * dev, unsigned int offset)
690 offset <<= devpriv->io.regshift;
691 if (devpriv->io.regtype == io_regtype)
692 return inl(devpriv->io.u.iobase + offset);
694 return readl(devpriv->io.u.membase + offset);
699 * Write 32-bit register.
701 #ifdef CONFIG_COMEDI_PCI
702 static void dio200_write32(comedi_device * dev, unsigned int offset,
705 offset <<= devpriv->io.regshift;
706 if (devpriv->io.regtype == io_regtype)
707 outl(val, devpriv->io.u.iobase + offset);
709 writel(val, devpriv->io.u.membase + offset);
714 * This function looks for a PCI device matching the requested board name,
717 #ifdef CONFIG_COMEDI_PCI
719 dio200_find_pci(comedi_device * dev, int bus, int slot,
720 struct pci_dev **pci_dev_p)
722 struct pci_dev *pci_dev = NULL;
726 /* Look for matching PCI device. */
727 for (pci_dev = pci_get_device(PCI_VENDOR_ID_AMPLICON, PCI_ANY_ID, NULL);
729 pci_dev = pci_get_device(PCI_VENDOR_ID_AMPLICON,
730 PCI_ANY_ID, pci_dev)) {
731 /* If bus/slot specified, check them. */
733 if (bus != pci_dev->bus->number
734 || slot != PCI_SLOT(pci_dev->devfn))
737 if (thisboard->model == anypci_model) {
738 /* Match any supported model. */
741 for (i = 0; i < ARRAY_SIZE(dio200_boards); i++) {
742 if (dio200_boards[i].bustype != pci_bustype)
744 if (pci_dev->device == dio200_boards[i].devid) {
745 /* Change board_ptr to matched board. */
746 dev->board_ptr = &dio200_boards[i];
750 if (i == ARRAY_SIZE(dio200_boards))
753 /* Match specific model name. */
754 if (pci_dev->device != thisboard->devid)
759 *pci_dev_p = pci_dev;
762 /* No match found. */
765 "comedi%d: error! no %s found at pci %02x:%02x!\n",
766 dev->minor, thisboard->name, bus, slot);
768 printk(KERN_ERR "comedi%d: error! no %s found!\n",
769 dev->minor, thisboard->name);
776 * This function checks and requests an I/O region, reporting an error
777 * if there is a conflict.
780 dio200_request_region(unsigned minor, unsigned long from, unsigned long extent)
782 if (!from || !request_region(from, extent, DIO200_DRIVER_NAME)) {
783 printk(KERN_ERR "comedi%d: I/O port conflict (%#lx,%lu)!\n",
784 minor, from, extent);
791 * 'insn_bits' function for an 'INTERRUPT' subdevice.
794 dio200_subdev_intr_insn_bits(comedi_device * dev, comedi_subdevice * s,
795 comedi_insn * insn, lsampl_t * data)
797 dio200_subdev_intr *subpriv = s->private;
799 if (thislayout->has_int_sce) {
800 /* Just read the interrupt status register. */
801 data[1] = dio200_read8(dev, subpriv->ofs) & subpriv->valid_isns;
803 /* No interrupt status register. */
811 * Called to stop acquisition for an 'INTERRUPT' subdevice.
813 static void dio200_stop_intr(comedi_device * dev, comedi_subdevice * s)
815 dio200_subdev_intr *subpriv = s->private;
818 subpriv->enabled_isns = 0;
819 if (thislayout->has_int_sce) {
820 dio200_write8(dev, subpriv->ofs, 0);
825 * Called to start acquisition for an 'INTERRUPT' subdevice.
827 static int dio200_start_intr(comedi_device * dev, comedi_subdevice * s)
831 dio200_subdev_intr *subpriv = s->private;
832 comedi_cmd *cmd = &s->async->cmd;
835 if (!subpriv->continuous && subpriv->stopcount == 0) {
836 /* An empty acquisition! */
837 s->async->events |= COMEDI_CB_EOA;
841 /* Determine interrupt sources to enable. */
844 for (n = 0; n < cmd->chanlist_len; n++) {
845 isn_bits |= (1U << CR_CHAN(cmd->chanlist[n]));
848 isn_bits &= subpriv->valid_isns;
849 /* Enable interrupt sources. */
850 subpriv->enabled_isns = isn_bits;
851 if (thislayout->has_int_sce) {
852 dio200_write8(dev, subpriv->ofs, isn_bits);
860 * Internal trigger function to start acquisition for an 'INTERRUPT' subdevice.
863 dio200_inttrig_start_intr(comedi_device * dev, comedi_subdevice * s,
864 unsigned int trignum)
866 dio200_subdev_intr *subpriv;
873 subpriv = s->private;
875 comedi_spin_lock_irqsave(&subpriv->spinlock, flags);
876 s->async->inttrig = 0;
877 if (subpriv->active) {
878 event = dio200_start_intr(dev, s);
880 comedi_spin_unlock_irqrestore(&subpriv->spinlock, flags);
883 comedi_event(dev, s);
890 * This is called from the interrupt service routine to handle a read
891 * scan on an 'INTERRUPT' subdevice.
893 static int dio200_handle_read_intr(comedi_device * dev, comedi_subdevice * s)
895 dio200_subdev_intr *subpriv = s->private;
898 unsigned cur_enabled;
899 unsigned int oldevents;
901 unsigned int int_sce_ofs;
903 int_sce_ofs = subpriv->ofs;
906 comedi_spin_lock_irqsave(&subpriv->spinlock, flags);
907 oldevents = s->async->events;
908 if (thislayout->has_int_sce) {
910 * Collect interrupt sources that have triggered and disable
911 * them temporarily. Loop around until no extra interrupt
912 * sources have triggered, at which point, the valid part of
913 * the interrupt status register will read zero, clearing the
914 * cause of the interrupt.
916 * Mask off interrupt sources already seen to avoid infinite
917 * loop in case of misconfiguration.
919 cur_enabled = subpriv->enabled_isns;
920 while ((intstat = (dio200_read8(dev, int_sce_ofs)
921 & subpriv->valid_isns & ~triggered))
923 triggered |= intstat;
924 cur_enabled &= ~triggered;
925 dio200_write8(dev, int_sce_ofs, cur_enabled);
929 * No interrupt status register. Assume the single interrupt
930 * source has triggered.
932 triggered = subpriv->enabled_isns;
937 * Some interrupt sources have triggered and have been
938 * temporarily disabled to clear the cause of the interrupt.
940 * Reenable them NOW to minimize the time they are disabled.
942 cur_enabled = subpriv->enabled_isns;
943 if (thislayout->has_int_sce) {
944 dio200_write8(dev, int_sce_ofs, cur_enabled);
947 if (subpriv->active) {
949 * The command is still active.
951 * Ignore interrupt sources that the command isn't
952 * interested in (just in case there's a race
955 if (triggered & subpriv->enabled_isns) {
956 /* Collect scan data. */
958 unsigned int n, ch, len;
961 len = s->async->cmd.chanlist_len;
962 for (n = 0; n < len; n++) {
963 ch = CR_CHAN(s->async->cmd.chanlist[n]);
964 if (triggered & (1U << ch)) {
968 /* Write the scan to the buffer. */
969 if (comedi_buf_put(s->async, val)) {
970 s->async->events |= (COMEDI_CB_BLOCK |
973 /* Error! Stop acquisition. */
974 dio200_stop_intr(dev, s);
975 s->async->events |= COMEDI_CB_ERROR
976 | COMEDI_CB_OVERFLOW;
977 comedi_error(dev, "buffer overflow");
980 /* Check for end of acquisition. */
981 if (!subpriv->continuous) {
982 /* stop_src == TRIG_COUNT */
983 if (subpriv->stopcount > 0) {
984 subpriv->stopcount--;
985 if (subpriv->stopcount == 0) {
988 dio200_stop_intr(dev,
996 comedi_spin_unlock_irqrestore(&subpriv->spinlock, flags);
998 if (oldevents != s->async->events) {
999 comedi_event(dev, s);
1002 return (triggered != 0);
1006 * 'cancel' function for an 'INTERRUPT' subdevice.
1008 static int dio200_subdev_intr_cancel(comedi_device * dev, comedi_subdevice * s)
1010 dio200_subdev_intr *subpriv = s->private;
1011 unsigned long flags;
1013 comedi_spin_lock_irqsave(&subpriv->spinlock, flags);
1014 if (subpriv->active) {
1015 dio200_stop_intr(dev, s);
1017 comedi_spin_unlock_irqrestore(&subpriv->spinlock, flags);
1023 * 'do_cmdtest' function for an 'INTERRUPT' subdevice.
1026 dio200_subdev_intr_cmdtest(comedi_device * dev, comedi_subdevice * s,
1032 /* step 1: make sure trigger sources are trivially valid */
1034 tmp = cmd->start_src;
1035 cmd->start_src &= (TRIG_NOW | TRIG_INT);
1036 if (!cmd->start_src || tmp != cmd->start_src)
1039 tmp = cmd->scan_begin_src;
1040 cmd->scan_begin_src &= TRIG_EXT;
1041 if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
1044 tmp = cmd->convert_src;
1045 cmd->convert_src &= TRIG_NOW;
1046 if (!cmd->convert_src || tmp != cmd->convert_src)
1049 tmp = cmd->scan_end_src;
1050 cmd->scan_end_src &= TRIG_COUNT;
1051 if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
1054 tmp = cmd->stop_src;
1055 cmd->stop_src &= (TRIG_COUNT | TRIG_NONE);
1056 if (!cmd->stop_src || tmp != cmd->stop_src)
1062 /* step 2: make sure trigger sources are unique and mutually compatible */
1064 /* these tests are true if more than one _src bit is set */
1065 if ((cmd->start_src & (cmd->start_src - 1)) != 0)
1067 if ((cmd->scan_begin_src & (cmd->scan_begin_src - 1)) != 0)
1069 if ((cmd->convert_src & (cmd->convert_src - 1)) != 0)
1071 if ((cmd->scan_end_src & (cmd->scan_end_src - 1)) != 0)
1073 if ((cmd->stop_src & (cmd->stop_src - 1)) != 0)
1079 /* step 3: make sure arguments are trivially compatible */
1081 /* cmd->start_src == TRIG_NOW || cmd->start_src == TRIG_INT */
1082 if (cmd->start_arg != 0) {
1087 /* cmd->scan_begin_src == TRIG_EXT */
1088 if (cmd->scan_begin_arg != 0) {
1089 cmd->scan_begin_arg = 0;
1093 /* cmd->convert_src == TRIG_NOW */
1094 if (cmd->convert_arg != 0) {
1095 cmd->convert_arg = 0;
1099 /* cmd->scan_end_src == TRIG_COUNT */
1100 if (cmd->scan_end_arg != cmd->chanlist_len) {
1101 cmd->scan_end_arg = cmd->chanlist_len;
1105 switch (cmd->stop_src) {
1107 /* any count allowed */
1110 if (cmd->stop_arg != 0) {
1122 /* step 4: fix up any arguments */
1124 /* if (err) return 4; */
1130 * 'do_cmd' function for an 'INTERRUPT' subdevice.
1132 static int dio200_subdev_intr_cmd(comedi_device * dev, comedi_subdevice * s)
1134 comedi_cmd *cmd = &s->async->cmd;
1135 dio200_subdev_intr *subpriv = s->private;
1136 unsigned long flags;
1139 comedi_spin_lock_irqsave(&subpriv->spinlock, flags);
1140 subpriv->active = 1;
1142 /* Set up end of acquisition. */
1143 switch (cmd->stop_src) {
1145 subpriv->continuous = 0;
1146 subpriv->stopcount = cmd->stop_arg;
1150 subpriv->continuous = 1;
1151 subpriv->stopcount = 0;
1155 /* Set up start of acquisition. */
1156 switch (cmd->start_src) {
1158 s->async->inttrig = dio200_inttrig_start_intr;
1162 event = dio200_start_intr(dev, s);
1165 comedi_spin_unlock_irqrestore(&subpriv->spinlock, flags);
1168 comedi_event(dev, s);
1175 * This function initializes an 'INTERRUPT' subdevice.
1178 dio200_subdev_intr_init(comedi_device * dev, comedi_subdevice * s,
1179 unsigned int offset, unsigned valid_isns)
1181 dio200_subdev_intr *subpriv;
1183 subpriv = kzalloc(sizeof(*subpriv), GFP_KERNEL);
1185 printk(KERN_ERR "comedi%d: error! out of memory!\n",
1189 subpriv->ofs = offset;
1190 subpriv->valid_isns = valid_isns;
1191 spin_lock_init(&subpriv->spinlock);
1193 if (thislayout->has_int_sce) {
1194 /* Disable interrupt sources. */
1195 dio200_write8(dev, subpriv->ofs, 0);
1198 s->private = subpriv;
1199 s->type = COMEDI_SUBD_DI;
1200 s->subdev_flags = SDF_READABLE | SDF_CMD_READ;
1201 if (thislayout->has_int_sce) {
1202 s->n_chan = DIO200_MAX_ISNS;
1203 s->len_chanlist = DIO200_MAX_ISNS;
1205 /* No interrupt source register. Support single channel. */
1207 s->len_chanlist = 1;
1209 s->range_table = &range_digital;
1211 s->insn_bits = dio200_subdev_intr_insn_bits;
1212 s->do_cmdtest = dio200_subdev_intr_cmdtest;
1213 s->do_cmd = dio200_subdev_intr_cmd;
1214 s->cancel = dio200_subdev_intr_cancel;
1220 * This function cleans up an 'INTERRUPT' subdevice.
1223 dio200_subdev_intr_cleanup(comedi_device * dev, comedi_subdevice * s)
1225 dio200_subdev_intr *subpriv = s->private;
1233 * Interrupt service routine.
1235 static irqreturn_t dio200_interrupt(int irq, void *d PT_REGS_ARG)
1237 comedi_device *dev = d;
1240 if (!dev->attached) {
1244 if (devpriv->intr_sd >= 0) {
1245 handled = dio200_handle_read_intr(dev,
1246 dev->subdevices + devpriv->intr_sd);
1251 return IRQ_RETVAL(handled);
1255 * Read an '8254' counter subdevice channel.
1257 static inline unsigned int
1258 dio200_subdev_8254_read_chan(comedi_device * dev, comedi_subdevice * s,
1261 unsigned int i8254_ofs = ((dio200_subdev_8254 *)s->private)->ofs;
1266 dio200_write8(dev, i8254_ofs + i8254_control_reg, val);
1269 val = dio200_read8(dev, i8254_ofs + chan);
1271 val += dio200_read8(dev, i8254_ofs + chan) << 8;
1277 * Write an '8254' counter subdevice channel.
1280 dio200_subdev_8254_write_chan(comedi_device * dev, comedi_subdevice * s,
1281 unsigned int chan, unsigned int count)
1283 unsigned int i8254_ofs = ((dio200_subdev_8254 *)s->private)->ofs;
1286 dio200_write8(dev, i8254_ofs + chan, count & 0xff);
1288 dio200_write8(dev, i8254_ofs + chan, (count >> 8) & 0xff);
1292 * Set mode of an '8254' counter subdevice channel.
1295 dio200_subdev_8254_set_mode(comedi_device * dev, comedi_subdevice * s,
1296 unsigned int chan, unsigned int mode)
1298 unsigned int i8254_ofs = ((dio200_subdev_8254 *)s->private)->ofs;
1302 byte |= 0x30; /* load lsb then msb */
1303 byte |= (mode & 0xf); /* set counter mode and BCD|binary */
1304 dio200_write8(dev, i8254_ofs + i8254_control_reg, byte);
1308 * Read status byte of an '8254' counter subdevice channel.
1310 static inline unsigned int
1311 dio200_subdev_8254_status(comedi_device * dev, comedi_subdevice * s,
1314 unsigned int i8254_ofs = ((dio200_subdev_8254 *)s->private)->ofs;
1316 dio200_write8(dev, i8254_ofs + i8254_control_reg, (0xE0 | 2 << chan));
1317 return dio200_read8(dev, i8254_ofs + chan);
1321 * Handle 'insn_read' for an '8254' counter subdevice.
1324 dio200_subdev_8254_read(comedi_device * dev, comedi_subdevice * s,
1325 comedi_insn * insn, lsampl_t * data)
1327 dio200_subdev_8254 *subpriv = s->private;
1328 int chan = CR_CHAN(insn->chanspec);
1329 unsigned long flags;
1334 comedi_spin_lock_irqsave(&subpriv->spinlock, flags);
1335 data[0] = dio200_subdev_8254_read_chan(dev, s, chan);
1336 comedi_spin_unlock_irqrestore(&subpriv->spinlock, flags);
1342 * Handle 'insn_write' for an '8254' counter subdevice.
1345 dio200_subdev_8254_write(comedi_device * dev, comedi_subdevice * s,
1346 comedi_insn * insn, lsampl_t * data)
1348 dio200_subdev_8254 *subpriv = s->private;
1349 int chan = CR_CHAN(insn->chanspec);
1350 unsigned long flags;
1355 comedi_spin_lock_irqsave(&subpriv->spinlock, flags);
1356 dio200_subdev_8254_write_chan(dev, s, chan, data[0]);
1357 comedi_spin_unlock_irqrestore(&subpriv->spinlock, flags);
1363 * Set gate source for an '8254' counter subdevice channel.
1366 dio200_subdev_8254_set_gate_src(comedi_device * dev, comedi_subdevice *s,
1367 unsigned int counter_number, unsigned int gate_src)
1369 dio200_subdev_8254 *subpriv = s->private;
1372 if (!thislayout->has_clk_gat_sce)
1374 if (counter_number > 2)
1376 if (gate_src > (thislayout->has_enhancements ? 31 : 7))
1379 subpriv->gate_src[counter_number] = gate_src;
1380 byte = GAT_SCE(subpriv->which, counter_number, gate_src);
1381 dio200_write8(dev, subpriv->gat_sce_ofs, byte);
1387 * Get gate source for an '8254' counter subdevice channel.
1390 dio200_subdev_8254_get_gate_src(comedi_device * dev, comedi_subdevice *s,
1391 unsigned int counter_number)
1393 dio200_subdev_8254 *subpriv = s->private;
1395 if (!thislayout->has_clk_gat_sce)
1397 if (counter_number > 2)
1400 return subpriv->gate_src[counter_number];
1404 * Set clock source for an '8254' counter subdevice channel.
1407 dio200_subdev_8254_set_clock_src(comedi_device * dev, comedi_subdevice *s,
1408 unsigned int counter_number, unsigned int clock_src)
1410 dio200_subdev_8254 *subpriv = s->private;
1413 if (!thislayout->has_clk_gat_sce)
1415 if (counter_number > 2)
1417 if (clock_src > (thislayout->has_enhancements ? 31 : 7))
1420 subpriv->clock_src[counter_number] = clock_src;
1421 byte = CLK_SCE(subpriv->which, counter_number, clock_src);
1422 dio200_write8(dev, subpriv->clk_sce_ofs, byte);
1428 * Get clock source for an '8254' counter subdevice channel.
1431 dio200_subdev_8254_get_clock_src(comedi_device * dev, comedi_subdevice *s,
1432 unsigned int counter_number, lsampl_t * period_ns)
1434 dio200_subdev_8254 *subpriv = s->private;
1437 if (!thislayout->has_clk_gat_sce)
1439 if (counter_number > 2)
1442 clock_src = subpriv->clock_src[counter_number];
1443 *period_ns = clock_period[clock_src];
1448 * Handle 'insn_config' for an '8254' counter subdevice.
1451 dio200_subdev_8254_config(comedi_device * dev, comedi_subdevice * s,
1452 comedi_insn * insn, lsampl_t * data)
1454 dio200_subdev_8254 *subpriv = s->private;
1456 int chan = CR_CHAN(insn->chanspec);
1457 unsigned long flags;
1459 comedi_spin_lock_irqsave(&subpriv->spinlock, flags);
1461 case INSN_CONFIG_SET_COUNTER_MODE:
1462 if (data[1] > (I8254_MODE5 | I8254_BINARY))
1465 dio200_subdev_8254_set_mode(dev, s, chan, data[1]);
1467 case INSN_CONFIG_8254_READ_STATUS:
1468 data[1] = dio200_subdev_8254_status(dev, s, chan);
1470 case INSN_CONFIG_SET_GATE_SRC:
1471 ret = dio200_subdev_8254_set_gate_src(dev, s, chan, data[2]);
1475 case INSN_CONFIG_GET_GATE_SRC:
1476 ret = dio200_subdev_8254_get_gate_src(dev, s, chan);
1483 case INSN_CONFIG_SET_CLOCK_SRC:
1484 ret = dio200_subdev_8254_set_clock_src(dev, s, chan, data[1]);
1488 case INSN_CONFIG_GET_CLOCK_SRC:
1489 ret = dio200_subdev_8254_get_clock_src(dev, s, chan, &data[2]);
1500 comedi_spin_unlock_irqrestore(&subpriv->spinlock, flags);
1501 return ret < 0 ? ret : insn->n;
1505 * This function initializes an '8254' counter subdevice.
1507 * offset is the offset to the 8254 chip.
1510 dio200_subdev_8254_init(comedi_device * dev, comedi_subdevice * s,
1511 unsigned int offset)
1513 dio200_subdev_8254 *subpriv;
1516 subpriv = kzalloc(sizeof(*subpriv), GFP_KERNEL);
1518 printk(KERN_ERR "comedi%d: error! out of memory!\n",
1523 s->private = subpriv;
1524 s->type = COMEDI_SUBD_COUNTER;
1525 s->subdev_flags = SDF_WRITABLE | SDF_READABLE;
1527 s->maxdata = 0xFFFF;
1528 s->insn_read = dio200_subdev_8254_read;
1529 s->insn_write = dio200_subdev_8254_write;
1530 s->insn_config = dio200_subdev_8254_config;
1532 spin_lock_init(&subpriv->spinlock);
1533 subpriv->ofs = offset;
1534 if (thislayout->has_clk_gat_sce) {
1535 /* Derive CLK_SCE and GAT_SCE register offsets from
1537 subpriv->clk_sce_ofs =
1538 DIO200_XCLK_SCE + (offset >> 3);
1539 subpriv->gat_sce_ofs =
1540 DIO200_XGAT_SCE + (offset >> 3);
1541 subpriv->which = (offset >> 2) & 1;
1544 /* Initialize channels. */
1545 for (chan = 0; chan < 3; chan++) {
1546 dio200_subdev_8254_set_mode(dev, s, chan,
1547 (I8254_MODE0 | I8254_BINARY));
1548 if (thislayout->has_clk_gat_sce) {
1549 /* Gate source 0 is VCC (logic 1). */
1550 dio200_subdev_8254_set_gate_src(dev, s, chan, 0);
1551 /* Clock source 0 is the dedicated clock input. */
1552 dio200_subdev_8254_set_clock_src(dev, s, chan, 0);
1560 * This function cleans up an '8254' counter subdevice.
1563 dio200_subdev_8254_cleanup(comedi_device * dev, comedi_subdevice * s)
1565 dio200_subdev_8254 *subpriv = s->private;
1573 * This function sets I/O directions for an '8255' DIO subdevice.
1576 dio200_subdev_8255_set_dir(comedi_device * dev, comedi_subdevice * s)
1578 dio200_subdev_8255 *subpriv = s->private;
1582 /* 1 in io_bits indicates output, 1 in config indicates input */
1583 if (!(s->io_bits & 0x0000ff))
1585 if (!(s->io_bits & 0x00ff00))
1587 if (!(s->io_bits & 0x0f0000))
1588 config |= CR_C_LO_IO;
1589 if (!(s->io_bits & 0xf00000))
1590 config |= CR_C_HI_IO;
1592 dio200_write8(dev, subpriv->ofs + 3, config);
1596 * Handle 'insn_bits' for an '8255' DIO subdevice.
1599 dio200_subdev_8255_bits(comedi_device * dev, comedi_subdevice * s,
1600 comedi_insn * insn, lsampl_t * data)
1602 unsigned int i8255_ofs = ((dio200_subdev_8255 *)s->private)->ofs;
1605 s->state &= ~data[0];
1606 s->state |= (data[0] & data[1]);
1608 if (data[0] & 0xff) {
1609 dio200_write8(dev, i8255_ofs, s->state & 0xff);
1611 if (data[0] & 0xff00) {
1612 dio200_write8(dev, i8255_ofs + 1,
1613 (s->state >> 8) & 0xff);
1615 if (data[0] & 0xff0000) {
1616 dio200_write8(dev, i8255_ofs + 2,
1617 (s->state >> 16) & 0xff);
1621 data[1] = dio200_read8(dev, i8255_ofs);
1622 data[1] |= dio200_read8(dev, i8255_ofs + 1) << 8;
1623 data[1] |= dio200_read8(dev, i8255_ofs + 2) << 16;
1629 * Handle 'insn_config' for an '8255' DIO subdevice.
1632 dio200_subdev_8255_config(comedi_device * dev, comedi_subdevice * s,
1633 comedi_insn * insn, lsampl_t * data)
1638 mask = 1 << CR_CHAN(insn->chanspec);
1639 if (mask & 0x0000ff) {
1641 } else if (mask & 0x00ff00) {
1643 } else if (mask & 0x0f0000) {
1650 case INSN_CONFIG_DIO_INPUT:
1651 s->io_bits &= ~bits;
1653 case INSN_CONFIG_DIO_OUTPUT:
1656 case INSN_CONFIG_DIO_QUERY:
1657 data[1] = (s->io_bits & bits) ? COMEDI_OUTPUT : COMEDI_INPUT;
1664 dio200_subdev_8255_set_dir(dev, s);
1670 * This function initializes an '8255' DIO subdevice.
1672 * offset is the offset to the 8255 chip.
1675 dio200_subdev_8255_init(comedi_device * dev, comedi_subdevice * s,
1676 unsigned int offset)
1678 dio200_subdev_8255 *subpriv;
1680 subpriv = kzalloc(sizeof(*subpriv), GFP_KERNEL);
1682 printk(KERN_ERR "comedi%d: error! out of memory!\n",
1687 subpriv->ofs = offset;
1689 s->private = subpriv;
1690 s->type = COMEDI_SUBD_DIO;
1691 s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
1693 s->range_table = &range_digital;
1695 s->insn_bits = dio200_subdev_8255_bits;
1696 s->insn_config = dio200_subdev_8255_config;
1700 dio200_subdev_8255_set_dir(dev, s);
1706 * This function cleans up an '8255' DIO subdevice.
1709 dio200_subdev_8255_cleanup(comedi_device * dev, comedi_subdevice * s)
1711 dio200_subdev_8255 *subpriv = s->private;
1718 #ifdef CONFIG_COMEDI_PCI
1720 * This function does some special set-up for the PCIe boards
1721 * PCIe215, PCIe236, PCIe296.
1724 dio200_pcie_board_setup(comedi_device * dev)
1726 struct pci_dev *pci_dev = devpriv->pci_dev;
1727 unsigned char __iomem *brbase;
1728 resource_size_t brlen;
1731 * The board uses Altera Cyclone IV with PCI-Express hard IP.
1732 * The FPGA configuration has the PCI-Express Avalon-MM Bridge
1733 * Control registers in PCI BAR 0, offset 0, and the length of
1734 * these registers is 0x4000.
1736 * We need to write 0x80 to the "Avalon-MM to PCI-Express Interrupt
1737 * Enable" register at offset 0x50 to allow generation of PCIe
1738 * interrupts when RXmlrq_i is asserted in the SOPC Builder system.
1740 brlen = pci_resource_len(pci_dev, 0);
1741 if (brlen < 0x4000 ||
1742 !(pci_resource_flags(pci_dev, 0) & IORESOURCE_MEM)) {
1743 printk(KERN_ERR "comedi%d: error! bad PCI region!\n",
1747 brbase = ioremap_nocache(pci_resource_start(pci_dev, 0), brlen);
1749 printk(KERN_ERR "comedi%d: error! failed to map registers!\n",
1753 writel(0x80, brbase + 0x50);
1756 * Enable "enhanced" features of board.
1758 dio200_write8(dev, DIO200_ENHANCE, 1);
1764 * Attach is called by the Comedi core to configure the driver
1765 * for a particular board. If you specified a board_name array
1766 * in the driver structure, dev->board_ptr contains that
1769 static int dio200_attach(comedi_device * dev, comedi_devconfig * it)
1771 comedi_subdevice *s;
1772 unsigned long iobase = 0;
1773 unsigned int irq = 0;
1774 #ifdef CONFIG_COMEDI_PCI
1775 struct pci_dev *pci_dev = NULL;
1776 int bus = 0, slot = 0;
1778 const dio200_layout *layout;
1784 printk(KERN_DEBUG "comedi%d: %s: attach\n", dev->minor,
1785 DIO200_DRIVER_NAME);
1787 if ((ret = alloc_private(dev, sizeof(dio200_private))) < 0) {
1788 printk(KERN_ERR "comedi%d: error! out of memory!\n",
1793 /* Process options. */
1794 switch (thisboard->bustype) {
1796 iobase = it->options[0];
1797 irq = it->options[1];
1800 #ifdef CONFIG_COMEDI_PCI
1802 bus = it->options[0];
1803 slot = it->options[1];
1806 if ((ret = dio200_find_pci(dev, bus, slot, &pci_dev)) < 0)
1808 devpriv->pci_dev = pci_dev;
1813 "comedi%d: %s: BUG! cannot determine board type!\n",
1814 dev->minor, DIO200_DRIVER_NAME);
1819 devpriv->intr_sd = -1;
1820 devpriv->io.regtype = no_regtype;
1821 devpriv->io.regshift = thisboard->mainshift;
1823 /* Enable device and reserve I/O spaces. */
1824 #ifdef CONFIG_COMEDI_PCI
1826 resource_size_t base, len;
1829 ret = comedi_pci_enable(pci_dev, DIO200_DRIVER_NAME);
1832 "comedi%d: error! cannot enable PCI device and request regions!\n",
1836 bar = thisboard->mainbar;
1837 base = pci_resource_start(pci_dev, bar);
1838 len = pci_resource_len(pci_dev, bar);
1839 if (len < thisboard->mainsize) {
1841 "comedi%d: error! PCI region size too small!\n",
1845 if ((pci_resource_flags(pci_dev, bar) & IORESOURCE_MEM) != 0) {
1846 devpriv->io.u.membase = ioremap_nocache(base, len);
1847 if (!devpriv->io.u.membase) {
1849 "comedi%d: error! cannot remap registers!\n",
1853 devpriv->io.regtype = mmio_regtype;
1855 devpriv->io.u.iobase = (unsigned long)base;
1856 devpriv->io.regtype = io_regtype;
1862 ret = dio200_request_region(dev->minor, iobase,
1863 thisboard->mainsize);
1867 devpriv->io.u.iobase = iobase;
1868 devpriv->io.regtype = io_regtype;
1871 switch (thisboard->model) {
1872 #ifdef CONFIG_COMEDI_PCI
1876 ret = dio200_pcie_board_setup(dev);
1886 layout = thislayout;
1887 if ((ret = alloc_subdevices(dev, layout->n_subdevs)) < 0) {
1888 printk(KERN_ERR "comedi%d: error! out of memory!\n",
1893 for (n = 0; n < dev->n_subdevices; n++) {
1894 s = &dev->subdevices[n];
1895 switch (layout->sdtype[n]) {
1897 /* counter subdevice (8254) */
1898 ret = dio200_subdev_8254_init(dev, s,
1905 /* digital i/o subdevice (8255) */
1906 ret = dio200_subdev_8255_init(dev, s,
1913 /* 'INTERRUPT' subdevice */
1915 ret = dio200_subdev_intr_init(dev, s,
1916 DIO200_INT_SCE, layout->sdinfo[n]);
1920 devpriv->intr_sd = n;
1922 s->type = COMEDI_SUBD_UNUSED;
1926 /* TODO. Fall-thru to default for now. */
1928 s->type = COMEDI_SUBD_UNUSED;
1933 sdx = devpriv->intr_sd;
1934 if (sdx >= 0 && sdx < dev->n_subdevices) {
1935 dev->read_subdev = &dev->subdevices[sdx];
1938 dev->board_name = thisboard->name;
1941 unsigned long flags = share_irq ? IRQF_SHARED : 0;
1943 if (comedi_request_irq(irq, dio200_interrupt, flags,
1944 DIO200_DRIVER_NAME, dev) >= 0) {
1948 "comedi%d: warning! irq %u unavailable!\n",
1953 printk(KERN_INFO "comedi%d: %s ", dev->minor, dev->board_name);
1954 if (thisboard->bustype == isa_bustype) {
1955 printk("(base %#lx) ", iobase);
1957 #ifdef CONFIG_COMEDI_PCI
1958 printk("(pci %s) ", pci_name(pci_dev));
1962 printk("(irq %u%s) ", irq, (dev->irq ? "" : " UNAVAILABLE"));
1964 printk("(no irq) ");
1967 printk("attached\n");
1973 * _detach is called to deconfigure a device. It should deallocate
1975 * This function is also called when _attach() fails, so it should be
1976 * careful not to release resources that were not necessarily
1977 * allocated by _attach(). dev->private and dev->subdevices are
1978 * deallocated automatically by the core.
1980 static int dio200_detach(comedi_device * dev)
1982 const dio200_layout *layout;
1985 printk(KERN_DEBUG "comedi%d: %s: detach\n", dev->minor,
1986 DIO200_DRIVER_NAME);
1989 comedi_free_irq(dev->irq, dev);
1991 if (dev->subdevices) {
1992 layout = thislayout;
1993 for (n = 0; n < dev->n_subdevices; n++) {
1994 comedi_subdevice *s = &dev->subdevices[n];
1995 switch (layout->sdtype[n]) {
1997 dio200_subdev_8254_cleanup(dev, s);
2000 dio200_subdev_8255_cleanup(dev, s);
2003 dio200_subdev_intr_cleanup(dev, s);
2011 if (devpriv->io.regtype == mmio_regtype) {
2012 iounmap(devpriv->io.u.membase);
2014 #ifdef CONFIG_COMEDI_PCI
2015 if (devpriv->pci_dev) {
2016 if (devpriv->io.regtype != no_regtype) {
2017 comedi_pci_disable(devpriv->pci_dev);
2019 pci_dev_put(devpriv->pci_dev);
2023 if (devpriv->io.regtype == io_regtype) {
2024 release_region(devpriv->io.u.iobase,
2025 thisboard->mainsize);
2029 if (dev->board_name) {
2030 printk(KERN_INFO "comedi%d: %s removed\n",
2031 dev->minor, dev->board_name);