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-OUT PPI-Y-C0
180 3 CTR-Y2-OUT PPI-Y-C3
181 4 CTR-Z1-OUT CTR-Z1-OUT
182 5 CTR-Z2-OUT CTR-Z2-OUT
184 PCIe215 PC218E PCIe236
185 ------------- ------------- -------------
187 0 PPI-X-C0 CTR-X1-OUT PPI-X-C0
188 1 PPI-X-C3 CTR-X2-OUT PPI-X-C3
189 2 PPI-Y-C0 CTR-Y1-OUT unused
190 3 PPI-Y-C3 CTR-Y2-OUT unused
191 4 CTR-Z1-OUT CTR-Z1-OUT CTR-Z1-OUT
192 5 CTR-Z2-OUT CTR-Z2-OUT CTR-Z2-OUT
194 PC272E/PCI272 PCIe296
195 ------------- -------------
201 4 PPI-Z-C0 CTR-Z1-OUT
202 5 PPI-Z-C3 CTR-Z2-OUT
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 */
275 * Macros for constructing value for DIO_200_?CLK_SCE and
276 * DIO_200_?GAT_SCE registers:
278 * 'which' is: 0 for CTR-X1, CTR-Y1, CTR-Z1; 1 for CTR-X2, CTR-Y2 or CTR-Z2.
279 * 'chan' is the channel: 0, 1 or 2.
280 * 'source' is the signal source: 0 to 7.
282 #define CLK_SCE(which, chan, source) (((which) << 5) | ((chan) << 3) | (source))
283 #define GAT_SCE(which, chan, source) (((which) << 5) | ((chan) << 3) | (source))
286 * Periods of the internal clock sources in nanoseconds.
288 static const unsigned clock_period[8] = {
289 0, /* dedicated clock input/output pin */
296 0 /* group clock input pin */
302 enum dio200_regtype { no_regtype, io_regtype, mmio_regtype };
303 struct dio200_region {
305 unsigned long iobase; /* I/O base address */
306 unsigned char __iomem *membase; /* Mapped MMIO base address */
308 unsigned char regtype;
309 unsigned char regshift;
313 * Board descriptions.
316 enum dio200_bustype { isa_bustype, pci_bustype };
321 pc215e_model, pci215_model, pcie215_model,
324 pc272e_model, pci272_model,
335 #ifdef CONFIG_COMEDI_PCI
343 typedef struct dio200_board_struct {
345 unsigned short devid;
346 enum dio200_bustype bustype;
347 enum dio200_model model;
348 enum dio200_layout layout;
349 unsigned char mainbar;
350 unsigned char mainshift;
351 unsigned int mainsize;
354 static const dio200_board dio200_boards[] = {
357 bustype: isa_bustype,
359 layout: pc212_layout,
360 mainsize: DIO200_IO_SIZE,
364 bustype: isa_bustype,
366 layout: pc214_layout,
367 mainsize: DIO200_IO_SIZE,
371 bustype: isa_bustype,
373 layout: pc215_layout,
374 mainsize: DIO200_IO_SIZE,
376 #ifdef CONFIG_COMEDI_PCI
379 devid: PCI_DEVICE_ID_AMPLICON_PCI215,
380 bustype: pci_bustype,
382 layout: pc215_layout,
383 mainsize: DIO200_IO_SIZE,
387 #ifdef CONFIG_COMEDI_PCI
390 devid: PCI_DEVICE_ID_AMPLICON_PCIE215,
391 bustype: pci_bustype,
392 model: pcie215_model,
393 layout: pcie215_layout,
394 mainsize: DIO200_PCIE_IO_SIZE,
401 bustype: isa_bustype,
403 layout: pc218_layout,
404 mainsize: DIO200_IO_SIZE,
406 #ifdef CONFIG_COMEDI_PCI
409 devid: PCI_DEVICE_ID_AMPLICON_PCIE236,
410 bustype: pci_bustype,
411 model: pcie236_model,
412 layout: pcie236_layout,
413 mainsize: DIO200_PCIE_IO_SIZE,
420 bustype: isa_bustype,
422 layout: pc272_layout,
423 mainsize: DIO200_IO_SIZE,
425 #ifdef CONFIG_COMEDI_PCI
428 devid: PCI_DEVICE_ID_AMPLICON_PCI272,
429 bustype: pci_bustype,
431 layout: pc272_layout,
432 mainsize: DIO200_IO_SIZE,
436 #ifdef CONFIG_COMEDI_PCI
439 devid: PCI_DEVICE_ID_AMPLICON_PCIE296,
440 bustype: pci_bustype,
441 model: pcie296_model,
442 layout: pcie296_layout,
443 mainsize: DIO200_PCIE_IO_SIZE,
448 #ifdef CONFIG_COMEDI_PCI
450 name: DIO200_DRIVER_NAME,
451 devid: PCI_DEVICE_ID_INVALID,
452 bustype: pci_bustype,
453 model: anypci_model, /* wildcard */
459 * Layout descriptions - some ISA and PCI board descriptions share the same
463 enum dio200_sdtype { sd_none, sd_intr, sd_8255, sd_8254, sd_timer };
465 #define DIO200_MAX_SUBDEVS 8
466 #define DIO200_MAX_ISNS 6
468 typedef struct dio200_layout_struct {
469 unsigned short n_subdevs; /* number of subdevices */
470 unsigned char sdtype[DIO200_MAX_SUBDEVS]; /* enum dio200_sdtype */
471 unsigned char sdinfo[DIO200_MAX_SUBDEVS]; /* depends on sdtype */
472 char has_int_sce; /* has interrupt enable/status register */
473 char has_clk_gat_sce; /* has clock/gate selection registers */
476 static const dio200_layout dio200_layouts[] = {
479 sdtype: {sd_8255, sd_8254, sd_8254, sd_8254,
482 sdinfo: {0x00, 0x08, 0x0C, 0x10, 0x14,
489 sdtype: {sd_8255, sd_8255, sd_8254,
491 sdinfo: {0x00, 0x08, 0x10, 0x01},
497 sdtype: {sd_8255, sd_8255, sd_8254,
500 sdinfo: {0x00, 0x08, 0x10, 0x14, 0x3F},
506 sdtype: {sd_8254, sd_8254, sd_8255, sd_8254,
509 sdinfo: {0x00, 0x04, 0x08, 0x0C, 0x10,
517 sdtype: {sd_8255, sd_8255, sd_8255,
519 sdinfo: {0x00, 0x08, 0x10, 0x3F},
523 #ifdef CONFIG_COMEDI_PCI
526 sdtype: {sd_8255, sd_none, sd_8255, sd_none, sd_8254, sd_8254,
528 sdinfo: {0x00, 0x00, 0x08, 0x00, 0x10, 0x14, 0x00, 0x3F},
534 sdtype: {sd_8255, sd_none, sd_none, sd_none, sd_8254, sd_8254,
536 sdinfo: {0x00, 0x00, 0x00, 0x00, 0x10, 0x14, 0x00, 0x3F},
542 sdtype: {sd_8255, sd_8255, sd_8255, sd_8255, sd_8254, sd_8254,
544 sdinfo: {0x00, 0x04, 0x08, 0x0C, 0x10, 0x14, 0x00, 0x3F},
555 #ifdef CONFIG_COMEDI_PCI
556 static DEFINE_PCI_DEVICE_TABLE(dio200_pci_table) = {
557 {PCI_VENDOR_ID_AMPLICON, PCI_DEVICE_ID_AMPLICON_PCI215,
558 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
559 {PCI_VENDOR_ID_AMPLICON, PCI_DEVICE_ID_AMPLICON_PCI272,
560 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
561 {PCI_VENDOR_ID_AMPLICON, PCI_DEVICE_ID_AMPLICON_PCIE236,
562 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
563 {PCI_VENDOR_ID_AMPLICON, PCI_DEVICE_ID_AMPLICON_PCIE215,
564 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
565 {PCI_VENDOR_ID_AMPLICON, PCI_DEVICE_ID_AMPLICON_PCIE296,
566 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
570 MODULE_DEVICE_TABLE(pci, dio200_pci_table);
571 #endif /* CONFIG_COMEDI_PCI */
574 * Useful for shorthand access to the particular board structure
576 #define thisboard ((const dio200_board *)dev->board_ptr)
577 #define thislayout (&dio200_layouts[((dio200_board *)dev->board_ptr)->layout])
579 /* this structure is for data unique to this hardware driver. If
580 several hardware drivers keep similar information in this structure,
581 feel free to suggest moving the variable to the comedi_device struct. */
583 #ifdef CONFIG_COMEDI_PCI
584 struct pci_dev *pci_dev; /* PCI device */
586 struct dio200_region io; /* Register region */
590 #define devpriv ((dio200_private *)dev->private)
593 unsigned int ofs; /* Counter base offset */
594 unsigned int clk_sce_ofs; /* CLK_SCE base offset */
595 unsigned int gat_sce_ofs; /* GAT_SCE base offset */
596 int which; /* Bit 5 of CLK_SCE or GAT_SCE */
597 unsigned int clock_src[3]; /* Current clock sources */
598 unsigned int gate_src[3]; /* Current gate sources */
600 } dio200_subdev_8254;
603 unsigned int ofs; /* DIO base offset */
604 } dio200_subdev_8255;
610 unsigned int valid_isns;
611 unsigned int enabled_isns;
612 unsigned int stopcount;
614 } dio200_subdev_intr;
617 * The comedi_driver structure tells the Comedi core module
618 * which functions to call to configure/deconfigure (attach/detach)
619 * the board, and also about the kernel module that contains
622 static int dio200_attach(comedi_device * dev, comedi_devconfig * it);
623 static int dio200_detach(comedi_device * dev);
624 static comedi_driver driver_amplc_dio200 = {
625 driver_name:DIO200_DRIVER_NAME,
627 attach:dio200_attach,
628 detach:dio200_detach,
629 board_name:&dio200_boards[0].name,
630 offset:sizeof(dio200_board),
631 num_names:sizeof(dio200_boards) / sizeof(dio200_board),
634 #ifdef CONFIG_COMEDI_PCI
635 COMEDI_PCI_INITCLEANUP(driver_amplc_dio200, dio200_pci_table);
637 COMEDI_INITCLEANUP(driver_amplc_dio200);
641 * Read 8-bit register.
643 static unsigned char dio200_read8(comedi_device * dev, unsigned int offset)
645 offset <<= devpriv->io.regshift;
646 if (devpriv->io.regtype == io_regtype)
647 return inb(devpriv->io.u.iobase + offset);
649 return readb(devpriv->io.u.membase + offset);
653 * Write 8-bit register.
655 static void dio200_write8(comedi_device * dev, unsigned int offset,
658 offset <<= devpriv->io.regshift;
659 if (devpriv->io.regtype == io_regtype)
660 outb(val, devpriv->io.u.iobase + offset);
662 writeb(val, devpriv->io.u.membase + offset);
666 * This function looks for a PCI device matching the requested board name,
669 #ifdef CONFIG_COMEDI_PCI
671 dio200_find_pci(comedi_device * dev, int bus, int slot,
672 struct pci_dev **pci_dev_p)
674 struct pci_dev *pci_dev = NULL;
678 /* Look for matching PCI device. */
679 for (pci_dev = pci_get_device(PCI_VENDOR_ID_AMPLICON, PCI_ANY_ID, NULL);
681 pci_dev = pci_get_device(PCI_VENDOR_ID_AMPLICON,
682 PCI_ANY_ID, pci_dev)) {
683 /* If bus/slot specified, check them. */
685 if (bus != pci_dev->bus->number
686 || slot != PCI_SLOT(pci_dev->devfn))
689 if (thisboard->model == anypci_model) {
690 /* Match any supported model. */
693 for (i = 0; i < ARRAY_SIZE(dio200_boards); i++) {
694 if (dio200_boards[i].bustype != pci_bustype)
696 if (pci_dev->device == dio200_boards[i].devid) {
697 /* Change board_ptr to matched board. */
698 dev->board_ptr = &dio200_boards[i];
702 if (i == ARRAY_SIZE(dio200_boards))
705 /* Match specific model name. */
706 if (pci_dev->device != thisboard->devid)
711 *pci_dev_p = pci_dev;
714 /* No match found. */
717 "comedi%d: error! no %s found at pci %02x:%02x!\n",
718 dev->minor, thisboard->name, bus, slot);
720 printk(KERN_ERR "comedi%d: error! no %s found!\n",
721 dev->minor, thisboard->name);
728 * This function checks and requests an I/O region, reporting an error
729 * if there is a conflict.
732 dio200_request_region(unsigned minor, unsigned long from, unsigned long extent)
734 if (!from || !request_region(from, extent, DIO200_DRIVER_NAME)) {
735 printk(KERN_ERR "comedi%d: I/O port conflict (%#lx,%lu)!\n",
736 minor, from, extent);
743 * 'insn_bits' function for an 'INTERRUPT' subdevice.
746 dio200_subdev_intr_insn_bits(comedi_device * dev, comedi_subdevice * s,
747 comedi_insn * insn, lsampl_t * data)
749 dio200_subdev_intr *subpriv = s->private;
751 if (thislayout->has_int_sce) {
752 /* Just read the interrupt status register. */
753 data[1] = dio200_read8(dev, subpriv->ofs) & subpriv->valid_isns;
755 /* No interrupt status register. */
763 * Called to stop acquisition for an 'INTERRUPT' subdevice.
765 static void dio200_stop_intr(comedi_device * dev, comedi_subdevice * s)
767 dio200_subdev_intr *subpriv = s->private;
770 subpriv->enabled_isns = 0;
771 if (thislayout->has_int_sce) {
772 dio200_write8(dev, subpriv->ofs, 0);
777 * Called to start acquisition for an 'INTERRUPT' subdevice.
779 static int dio200_start_intr(comedi_device * dev, comedi_subdevice * s)
783 dio200_subdev_intr *subpriv = s->private;
784 comedi_cmd *cmd = &s->async->cmd;
787 if (!subpriv->continuous && subpriv->stopcount == 0) {
788 /* An empty acquisition! */
789 s->async->events |= COMEDI_CB_EOA;
793 /* Determine interrupt sources to enable. */
796 for (n = 0; n < cmd->chanlist_len; n++) {
797 isn_bits |= (1U << CR_CHAN(cmd->chanlist[n]));
800 isn_bits &= subpriv->valid_isns;
801 /* Enable interrupt sources. */
802 subpriv->enabled_isns = isn_bits;
803 if (thislayout->has_int_sce) {
804 dio200_write8(dev, subpriv->ofs, isn_bits);
812 * Internal trigger function to start acquisition for an 'INTERRUPT' subdevice.
815 dio200_inttrig_start_intr(comedi_device * dev, comedi_subdevice * s,
816 unsigned int trignum)
818 dio200_subdev_intr *subpriv;
825 subpriv = s->private;
827 comedi_spin_lock_irqsave(&subpriv->spinlock, flags);
828 s->async->inttrig = 0;
829 if (subpriv->active) {
830 event = dio200_start_intr(dev, s);
832 comedi_spin_unlock_irqrestore(&subpriv->spinlock, flags);
835 comedi_event(dev, s);
842 * This is called from the interrupt service routine to handle a read
843 * scan on an 'INTERRUPT' subdevice.
845 static int dio200_handle_read_intr(comedi_device * dev, comedi_subdevice * s)
847 dio200_subdev_intr *subpriv = s->private;
850 unsigned cur_enabled;
851 unsigned int oldevents;
853 unsigned int int_sce_ofs;
855 int_sce_ofs = subpriv->ofs;
858 comedi_spin_lock_irqsave(&subpriv->spinlock, flags);
859 oldevents = s->async->events;
860 if (thislayout->has_int_sce) {
862 * Collect interrupt sources that have triggered and disable
863 * them temporarily. Loop around until no extra interrupt
864 * sources have triggered, at which point, the valid part of
865 * the interrupt status register will read zero, clearing the
866 * cause of the interrupt.
868 * Mask off interrupt sources already seen to avoid infinite
869 * loop in case of misconfiguration.
871 cur_enabled = subpriv->enabled_isns;
872 while ((intstat = (dio200_read8(dev, int_sce_ofs)
873 & subpriv->valid_isns & ~triggered))
875 triggered |= intstat;
876 cur_enabled &= ~triggered;
877 dio200_write8(dev, int_sce_ofs, cur_enabled);
881 * No interrupt status register. Assume the single interrupt
882 * source has triggered.
884 triggered = subpriv->enabled_isns;
889 * Some interrupt sources have triggered and have been
890 * temporarily disabled to clear the cause of the interrupt.
892 * Reenable them NOW to minimize the time they are disabled.
894 cur_enabled = subpriv->enabled_isns;
895 if (thislayout->has_int_sce) {
896 dio200_write8(dev, int_sce_ofs, cur_enabled);
899 if (subpriv->active) {
901 * The command is still active.
903 * Ignore interrupt sources that the command isn't
904 * interested in (just in case there's a race
907 if (triggered & subpriv->enabled_isns) {
908 /* Collect scan data. */
910 unsigned int n, ch, len;
913 len = s->async->cmd.chanlist_len;
914 for (n = 0; n < len; n++) {
915 ch = CR_CHAN(s->async->cmd.chanlist[n]);
916 if (triggered & (1U << ch)) {
920 /* Write the scan to the buffer. */
921 if (comedi_buf_put(s->async, val)) {
922 s->async->events |= (COMEDI_CB_BLOCK |
925 /* Error! Stop acquisition. */
926 dio200_stop_intr(dev, s);
927 s->async->events |= COMEDI_CB_ERROR
928 | COMEDI_CB_OVERFLOW;
929 comedi_error(dev, "buffer overflow");
932 /* Check for end of acquisition. */
933 if (!subpriv->continuous) {
934 /* stop_src == TRIG_COUNT */
935 if (subpriv->stopcount > 0) {
936 subpriv->stopcount--;
937 if (subpriv->stopcount == 0) {
940 dio200_stop_intr(dev,
948 comedi_spin_unlock_irqrestore(&subpriv->spinlock, flags);
950 if (oldevents != s->async->events) {
951 comedi_event(dev, s);
954 return (triggered != 0);
958 * 'cancel' function for an 'INTERRUPT' subdevice.
960 static int dio200_subdev_intr_cancel(comedi_device * dev, comedi_subdevice * s)
962 dio200_subdev_intr *subpriv = s->private;
965 comedi_spin_lock_irqsave(&subpriv->spinlock, flags);
966 if (subpriv->active) {
967 dio200_stop_intr(dev, s);
969 comedi_spin_unlock_irqrestore(&subpriv->spinlock, flags);
975 * 'do_cmdtest' function for an 'INTERRUPT' subdevice.
978 dio200_subdev_intr_cmdtest(comedi_device * dev, comedi_subdevice * s,
984 /* step 1: make sure trigger sources are trivially valid */
986 tmp = cmd->start_src;
987 cmd->start_src &= (TRIG_NOW | TRIG_INT);
988 if (!cmd->start_src || tmp != cmd->start_src)
991 tmp = cmd->scan_begin_src;
992 cmd->scan_begin_src &= TRIG_EXT;
993 if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
996 tmp = cmd->convert_src;
997 cmd->convert_src &= TRIG_NOW;
998 if (!cmd->convert_src || tmp != cmd->convert_src)
1001 tmp = cmd->scan_end_src;
1002 cmd->scan_end_src &= TRIG_COUNT;
1003 if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
1006 tmp = cmd->stop_src;
1007 cmd->stop_src &= (TRIG_COUNT | TRIG_NONE);
1008 if (!cmd->stop_src || tmp != cmd->stop_src)
1014 /* step 2: make sure trigger sources are unique and mutually compatible */
1016 /* these tests are true if more than one _src bit is set */
1017 if ((cmd->start_src & (cmd->start_src - 1)) != 0)
1019 if ((cmd->scan_begin_src & (cmd->scan_begin_src - 1)) != 0)
1021 if ((cmd->convert_src & (cmd->convert_src - 1)) != 0)
1023 if ((cmd->scan_end_src & (cmd->scan_end_src - 1)) != 0)
1025 if ((cmd->stop_src & (cmd->stop_src - 1)) != 0)
1031 /* step 3: make sure arguments are trivially compatible */
1033 /* cmd->start_src == TRIG_NOW || cmd->start_src == TRIG_INT */
1034 if (cmd->start_arg != 0) {
1039 /* cmd->scan_begin_src == TRIG_EXT */
1040 if (cmd->scan_begin_arg != 0) {
1041 cmd->scan_begin_arg = 0;
1045 /* cmd->convert_src == TRIG_NOW */
1046 if (cmd->convert_arg != 0) {
1047 cmd->convert_arg = 0;
1051 /* cmd->scan_end_src == TRIG_COUNT */
1052 if (cmd->scan_end_arg != cmd->chanlist_len) {
1053 cmd->scan_end_arg = cmd->chanlist_len;
1057 switch (cmd->stop_src) {
1059 /* any count allowed */
1062 if (cmd->stop_arg != 0) {
1074 /* step 4: fix up any arguments */
1076 /* if (err) return 4; */
1082 * 'do_cmd' function for an 'INTERRUPT' subdevice.
1084 static int dio200_subdev_intr_cmd(comedi_device * dev, comedi_subdevice * s)
1086 comedi_cmd *cmd = &s->async->cmd;
1087 dio200_subdev_intr *subpriv = s->private;
1088 unsigned long flags;
1091 comedi_spin_lock_irqsave(&subpriv->spinlock, flags);
1092 subpriv->active = 1;
1094 /* Set up end of acquisition. */
1095 switch (cmd->stop_src) {
1097 subpriv->continuous = 0;
1098 subpriv->stopcount = cmd->stop_arg;
1102 subpriv->continuous = 1;
1103 subpriv->stopcount = 0;
1107 /* Set up start of acquisition. */
1108 switch (cmd->start_src) {
1110 s->async->inttrig = dio200_inttrig_start_intr;
1114 event = dio200_start_intr(dev, s);
1117 comedi_spin_unlock_irqrestore(&subpriv->spinlock, flags);
1120 comedi_event(dev, s);
1127 * This function initializes an 'INTERRUPT' subdevice.
1130 dio200_subdev_intr_init(comedi_device * dev, comedi_subdevice * s,
1131 unsigned int offset, unsigned valid_isns)
1133 dio200_subdev_intr *subpriv;
1135 subpriv = kzalloc(sizeof(*subpriv), GFP_KERNEL);
1137 printk(KERN_ERR "comedi%d: error! out of memory!\n",
1141 subpriv->ofs = offset;
1142 subpriv->valid_isns = valid_isns;
1143 spin_lock_init(&subpriv->spinlock);
1145 if (thislayout->has_int_sce) {
1146 /* Disable interrupt sources. */
1147 dio200_write8(dev, subpriv->ofs, 0);
1150 s->private = subpriv;
1151 s->type = COMEDI_SUBD_DI;
1152 s->subdev_flags = SDF_READABLE | SDF_CMD_READ;
1153 if (thislayout->has_int_sce) {
1154 s->n_chan = DIO200_MAX_ISNS;
1155 s->len_chanlist = DIO200_MAX_ISNS;
1157 /* No interrupt source register. Support single channel. */
1159 s->len_chanlist = 1;
1161 s->range_table = &range_digital;
1163 s->insn_bits = dio200_subdev_intr_insn_bits;
1164 s->do_cmdtest = dio200_subdev_intr_cmdtest;
1165 s->do_cmd = dio200_subdev_intr_cmd;
1166 s->cancel = dio200_subdev_intr_cancel;
1172 * This function cleans up an 'INTERRUPT' subdevice.
1175 dio200_subdev_intr_cleanup(comedi_device * dev, comedi_subdevice * s)
1177 dio200_subdev_intr *subpriv = s->private;
1185 * Interrupt service routine.
1187 static irqreturn_t dio200_interrupt(int irq, void *d PT_REGS_ARG)
1189 comedi_device *dev = d;
1192 if (!dev->attached) {
1196 if (devpriv->intr_sd >= 0) {
1197 handled = dio200_handle_read_intr(dev,
1198 dev->subdevices + devpriv->intr_sd);
1203 return IRQ_RETVAL(handled);
1207 * Read an '8254' counter subdevice channel.
1209 static inline unsigned int
1210 dio200_subdev_8254_read_chan(comedi_device * dev, comedi_subdevice * s,
1213 unsigned int i8254_ofs = ((dio200_subdev_8254 *)s->private)->ofs;
1218 dio200_write8(dev, i8254_ofs + i8254_control_reg, val);
1221 val = dio200_read8(dev, i8254_ofs + chan);
1223 val += dio200_read8(dev, i8254_ofs + chan) << 8;
1229 * Write an '8254' counter subdevice channel.
1232 dio200_subdev_8254_write_chan(comedi_device * dev, comedi_subdevice * s,
1233 unsigned int chan, unsigned int count)
1235 unsigned int i8254_ofs = ((dio200_subdev_8254 *)s->private)->ofs;
1238 dio200_write8(dev, i8254_ofs + chan, count & 0xff);
1240 dio200_write8(dev, i8254_ofs + chan, (count >> 8) & 0xff);
1244 * Set mode of an '8254' counter subdevice channel.
1247 dio200_subdev_8254_set_mode(comedi_device * dev, comedi_subdevice * s,
1248 unsigned int chan, unsigned int mode)
1250 unsigned int i8254_ofs = ((dio200_subdev_8254 *)s->private)->ofs;
1254 byte |= 0x30; /* load lsb then msb */
1255 byte |= (mode & 0xf); /* set counter mode and BCD|binary */
1256 dio200_write8(dev, i8254_ofs + i8254_control_reg, byte);
1260 * Read status byte of an '8254' counter subdevice channel.
1262 static inline unsigned int
1263 dio200_subdev_8254_status(comedi_device * dev, comedi_subdevice * s,
1266 unsigned int i8254_ofs = ((dio200_subdev_8254 *)s->private)->ofs;
1268 dio200_write8(dev, i8254_ofs + i8254_control_reg, (0xE0 | 2 << chan));
1269 return dio200_read8(dev, i8254_ofs + chan);
1273 * Handle 'insn_read' for an '8254' counter subdevice.
1276 dio200_subdev_8254_read(comedi_device * dev, comedi_subdevice * s,
1277 comedi_insn * insn, lsampl_t * data)
1279 dio200_subdev_8254 *subpriv = s->private;
1280 int chan = CR_CHAN(insn->chanspec);
1281 unsigned long flags;
1286 comedi_spin_lock_irqsave(&subpriv->spinlock, flags);
1287 data[0] = dio200_subdev_8254_read_chan(dev, s, chan);
1288 comedi_spin_unlock_irqrestore(&subpriv->spinlock, flags);
1294 * Handle 'insn_write' for an '8254' counter subdevice.
1297 dio200_subdev_8254_write(comedi_device * dev, comedi_subdevice * s,
1298 comedi_insn * insn, lsampl_t * data)
1300 dio200_subdev_8254 *subpriv = s->private;
1301 int chan = CR_CHAN(insn->chanspec);
1302 unsigned long flags;
1307 comedi_spin_lock_irqsave(&subpriv->spinlock, flags);
1308 dio200_subdev_8254_write_chan(dev, s, chan, data[0]);
1309 comedi_spin_unlock_irqrestore(&subpriv->spinlock, flags);
1315 * Set gate source for an '8254' counter subdevice channel.
1318 dio200_subdev_8254_set_gate_src(comedi_device * dev, comedi_subdevice *s,
1319 unsigned int counter_number, unsigned int gate_src)
1321 dio200_subdev_8254 *subpriv = s->private;
1324 if (!thislayout->has_clk_gat_sce)
1326 if (counter_number > 2)
1331 subpriv->gate_src[counter_number] = gate_src;
1332 byte = GAT_SCE(subpriv->which, counter_number, gate_src);
1333 dio200_write8(dev, subpriv->gat_sce_ofs, byte);
1339 * Get gate source for an '8254' counter subdevice channel.
1342 dio200_subdev_8254_get_gate_src(comedi_device * dev, comedi_subdevice *s,
1343 unsigned int counter_number)
1345 dio200_subdev_8254 *subpriv = s->private;
1347 if (!thislayout->has_clk_gat_sce)
1349 if (counter_number > 2)
1352 return subpriv->gate_src[counter_number];
1356 * Set clock source for an '8254' counter subdevice channel.
1359 dio200_subdev_8254_set_clock_src(comedi_device * dev, comedi_subdevice *s,
1360 unsigned int counter_number, unsigned int clock_src)
1362 dio200_subdev_8254 *subpriv = s->private;
1365 if (!thislayout->has_clk_gat_sce)
1367 if (counter_number > 2)
1372 subpriv->clock_src[counter_number] = clock_src;
1373 byte = CLK_SCE(subpriv->which, counter_number, clock_src);
1374 dio200_write8(dev, subpriv->clk_sce_ofs, byte);
1380 * Get clock source for an '8254' counter subdevice channel.
1383 dio200_subdev_8254_get_clock_src(comedi_device * dev, comedi_subdevice *s,
1384 unsigned int counter_number, lsampl_t * period_ns)
1386 dio200_subdev_8254 *subpriv = s->private;
1389 if (!thislayout->has_clk_gat_sce)
1391 if (counter_number > 2)
1394 clock_src = subpriv->clock_src[counter_number];
1395 *period_ns = clock_period[clock_src];
1400 * Handle 'insn_config' for an '8254' counter subdevice.
1403 dio200_subdev_8254_config(comedi_device * dev, comedi_subdevice * s,
1404 comedi_insn * insn, lsampl_t * data)
1406 dio200_subdev_8254 *subpriv = s->private;
1408 int chan = CR_CHAN(insn->chanspec);
1409 unsigned long flags;
1411 comedi_spin_lock_irqsave(&subpriv->spinlock, flags);
1413 case INSN_CONFIG_SET_COUNTER_MODE:
1414 if (data[1] > (I8254_MODE5 | I8254_BINARY))
1417 dio200_subdev_8254_set_mode(dev, s, chan, data[1]);
1419 case INSN_CONFIG_8254_READ_STATUS:
1420 data[1] = dio200_subdev_8254_status(dev, s, chan);
1422 case INSN_CONFIG_SET_GATE_SRC:
1423 ret = dio200_subdev_8254_set_gate_src(dev, s, chan, data[2]);
1427 case INSN_CONFIG_GET_GATE_SRC:
1428 ret = dio200_subdev_8254_get_gate_src(dev, s, chan);
1435 case INSN_CONFIG_SET_CLOCK_SRC:
1436 ret = dio200_subdev_8254_set_clock_src(dev, s, chan, data[1]);
1440 case INSN_CONFIG_GET_CLOCK_SRC:
1441 ret = dio200_subdev_8254_get_clock_src(dev, s, chan, &data[2]);
1452 comedi_spin_unlock_irqrestore(&subpriv->spinlock, flags);
1453 return ret < 0 ? ret : insn->n;
1457 * This function initializes an '8254' counter subdevice.
1459 * offset is the offset to the 8254 chip.
1462 dio200_subdev_8254_init(comedi_device * dev, comedi_subdevice * s,
1463 unsigned int offset)
1465 dio200_subdev_8254 *subpriv;
1468 subpriv = kzalloc(sizeof(*subpriv), GFP_KERNEL);
1470 printk(KERN_ERR "comedi%d: error! out of memory!\n",
1475 s->private = subpriv;
1476 s->type = COMEDI_SUBD_COUNTER;
1477 s->subdev_flags = SDF_WRITABLE | SDF_READABLE;
1479 s->maxdata = 0xFFFF;
1480 s->insn_read = dio200_subdev_8254_read;
1481 s->insn_write = dio200_subdev_8254_write;
1482 s->insn_config = dio200_subdev_8254_config;
1484 spin_lock_init(&subpriv->spinlock);
1485 subpriv->ofs = offset;
1486 if (thislayout->has_clk_gat_sce) {
1487 /* Derive CLK_SCE and GAT_SCE register offsets from
1489 subpriv->clk_sce_ofs =
1490 DIO200_XCLK_SCE + (offset >> 3);
1491 subpriv->gat_sce_ofs =
1492 DIO200_XGAT_SCE + (offset >> 3);
1493 subpriv->which = (offset >> 2) & 1;
1496 /* Initialize channels. */
1497 for (chan = 0; chan < 3; chan++) {
1498 dio200_subdev_8254_set_mode(dev, s, chan,
1499 (I8254_MODE0 | I8254_BINARY));
1500 if (thislayout->has_clk_gat_sce) {
1501 /* Gate source 0 is VCC (logic 1). */
1502 dio200_subdev_8254_set_gate_src(dev, s, chan, 0);
1503 /* Clock source 0 is the dedicated clock input. */
1504 dio200_subdev_8254_set_clock_src(dev, s, chan, 0);
1512 * This function cleans up an '8254' counter subdevice.
1515 dio200_subdev_8254_cleanup(comedi_device * dev, comedi_subdevice * s)
1517 dio200_subdev_8254 *subpriv = s->private;
1525 * This function sets I/O directions for an '8255' DIO subdevice.
1528 dio200_subdev_8255_set_dir(comedi_device * dev, comedi_subdevice * s)
1530 dio200_subdev_8255 *subpriv = s->private;
1534 /* 1 in io_bits indicates output, 1 in config indicates input */
1535 if (!(s->io_bits & 0x0000ff))
1537 if (!(s->io_bits & 0x00ff00))
1539 if (!(s->io_bits & 0x0f0000))
1540 config |= CR_C_LO_IO;
1541 if (!(s->io_bits & 0xf00000))
1542 config |= CR_C_HI_IO;
1544 dio200_write8(dev, subpriv->ofs + 3, config);
1548 * Handle 'insn_bits' for an '8255' DIO subdevice.
1551 dio200_subdev_8255_bits(comedi_device * dev, comedi_subdevice * s,
1552 comedi_insn * insn, lsampl_t * data)
1554 unsigned int i8255_ofs = ((dio200_subdev_8255 *)s->private)->ofs;
1557 s->state &= ~data[0];
1558 s->state |= (data[0] & data[1]);
1560 if (data[0] & 0xff) {
1561 dio200_write8(dev, i8255_ofs, s->state & 0xff);
1563 if (data[0] & 0xff00) {
1564 dio200_write8(dev, i8255_ofs + 1,
1565 (s->state >> 8) & 0xff);
1567 if (data[0] & 0xff0000) {
1568 dio200_write8(dev, i8255_ofs + 2,
1569 (s->state >> 16) & 0xff);
1573 data[1] = dio200_read8(dev, i8255_ofs);
1574 data[1] |= dio200_read8(dev, i8255_ofs + 1) << 8;
1575 data[1] |= dio200_read8(dev, i8255_ofs + 2) << 16;
1581 * Handle 'insn_config' for an '8255' DIO subdevice.
1584 dio200_subdev_8255_config(comedi_device * dev, comedi_subdevice * s,
1585 comedi_insn * insn, lsampl_t * data)
1590 mask = 1 << CR_CHAN(insn->chanspec);
1591 if (mask & 0x0000ff) {
1593 } else if (mask & 0x00ff00) {
1595 } else if (mask & 0x0f0000) {
1602 case INSN_CONFIG_DIO_INPUT:
1603 s->io_bits &= ~bits;
1605 case INSN_CONFIG_DIO_OUTPUT:
1608 case INSN_CONFIG_DIO_QUERY:
1609 data[1] = (s->io_bits & bits) ? COMEDI_OUTPUT : COMEDI_INPUT;
1616 dio200_subdev_8255_set_dir(dev, s);
1622 * This function initializes an '8255' DIO subdevice.
1624 * offset is the offset to the 8255 chip.
1627 dio200_subdev_8255_init(comedi_device * dev, comedi_subdevice * s,
1628 unsigned int offset)
1630 dio200_subdev_8255 *subpriv;
1632 subpriv = kzalloc(sizeof(*subpriv), GFP_KERNEL);
1634 printk(KERN_ERR "comedi%d: error! out of memory!\n",
1639 subpriv->ofs = offset;
1641 s->private = subpriv;
1642 s->type = COMEDI_SUBD_DIO;
1643 s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
1645 s->range_table = &range_digital;
1647 s->insn_bits = dio200_subdev_8255_bits;
1648 s->insn_config = dio200_subdev_8255_config;
1652 dio200_subdev_8255_set_dir(dev, s);
1658 * This function cleans up an '8255' DIO subdevice.
1661 dio200_subdev_8255_cleanup(comedi_device * dev, comedi_subdevice * s)
1663 dio200_subdev_8255 *subpriv = s->private;
1670 #ifdef CONFIG_COMEDI_PCI
1672 * This function does some special set-up for the PCIe boards
1673 * PCIe215, PCIe236, PCIe296.
1676 dio200_pcie_board_setup(comedi_device * dev)
1678 struct pci_dev *pci_dev = devpriv->pci_dev;
1679 unsigned char __iomem *brbase;
1680 resource_size_t brlen;
1683 * The board uses Altera Cyclone IV with PCI-Express hard IP.
1684 * The FPGA configuration has the PCI-Express Avalon-MM Bridge
1685 * Control registers in PCI BAR 0, offset 0, and the length of
1686 * these registers is 0x4000.
1688 * We need to write 0x80 to the "Avalon-MM to PCI-Express Interrupt
1689 * Enable" register at offset 0x50 to allow generation of PCIe
1690 * interrupts when RXmlrq_i is asserted in the SOPC Builder system.
1692 brlen = pci_resource_len(pci_dev, 0);
1693 if (brlen < 0x4000 ||
1694 !(pci_resource_flags(pci_dev, 0) & IORESOURCE_MEM)) {
1695 printk(KERN_ERR "comedi%d: error! bad PCI region!\n",
1699 brbase = ioremap_nocache(pci_resource_start(pci_dev, 0), brlen);
1701 printk(KERN_ERR "comedi%d: error! failed to map registers!\n",
1705 writel(0x80, brbase + 0x50);
1712 * Attach is called by the Comedi core to configure the driver
1713 * for a particular board. If you specified a board_name array
1714 * in the driver structure, dev->board_ptr contains that
1717 static int dio200_attach(comedi_device * dev, comedi_devconfig * it)
1719 comedi_subdevice *s;
1720 unsigned long iobase = 0;
1721 unsigned int irq = 0;
1722 #ifdef CONFIG_COMEDI_PCI
1723 struct pci_dev *pci_dev = NULL;
1724 int bus = 0, slot = 0;
1726 const dio200_layout *layout;
1732 printk(KERN_DEBUG "comedi%d: %s: attach\n", dev->minor,
1733 DIO200_DRIVER_NAME);
1735 if ((ret = alloc_private(dev, sizeof(dio200_private))) < 0) {
1736 printk(KERN_ERR "comedi%d: error! out of memory!\n",
1741 /* Process options. */
1742 switch (thisboard->bustype) {
1744 iobase = it->options[0];
1745 irq = it->options[1];
1748 #ifdef CONFIG_COMEDI_PCI
1750 bus = it->options[0];
1751 slot = it->options[1];
1754 if ((ret = dio200_find_pci(dev, bus, slot, &pci_dev)) < 0)
1756 devpriv->pci_dev = pci_dev;
1761 "comedi%d: %s: BUG! cannot determine board type!\n",
1762 dev->minor, DIO200_DRIVER_NAME);
1767 devpriv->intr_sd = -1;
1768 devpriv->io.regtype = no_regtype;
1769 devpriv->io.regshift = thisboard->mainshift;
1771 /* Enable device and reserve I/O spaces. */
1772 #ifdef CONFIG_COMEDI_PCI
1774 resource_size_t base, len;
1777 ret = comedi_pci_enable(pci_dev, DIO200_DRIVER_NAME);
1780 "comedi%d: error! cannot enable PCI device and request regions!\n",
1784 bar = thisboard->mainbar;
1785 base = pci_resource_start(pci_dev, bar);
1786 len = pci_resource_len(pci_dev, bar);
1787 if (len < thisboard->mainsize) {
1789 "comedi%d: error! PCI region size too small!\n",
1793 if ((pci_resource_flags(pci_dev, bar) & IORESOURCE_MEM) != 0) {
1794 devpriv->io.u.membase = ioremap_nocache(base, len);
1795 if (!devpriv->io.u.membase) {
1797 "comedi%d: error! cannot remap registers!\n",
1801 devpriv->io.regtype = mmio_regtype;
1803 devpriv->io.u.iobase = (unsigned long)base;
1804 devpriv->io.regtype = io_regtype;
1810 ret = dio200_request_region(dev->minor, iobase,
1811 thisboard->mainsize);
1815 devpriv->io.u.iobase = iobase;
1816 devpriv->io.regtype = io_regtype;
1819 switch (thisboard->model) {
1820 #ifdef CONFIG_COMEDI_PCI
1824 ret = dio200_pcie_board_setup(dev);
1834 layout = thislayout;
1835 if ((ret = alloc_subdevices(dev, layout->n_subdevs)) < 0) {
1836 printk(KERN_ERR "comedi%d: error! out of memory!\n",
1841 for (n = 0; n < dev->n_subdevices; n++) {
1842 s = &dev->subdevices[n];
1843 switch (layout->sdtype[n]) {
1845 /* counter subdevice (8254) */
1846 ret = dio200_subdev_8254_init(dev, s,
1853 /* digital i/o subdevice (8255) */
1854 ret = dio200_subdev_8255_init(dev, s,
1861 /* 'INTERRUPT' subdevice */
1863 ret = dio200_subdev_intr_init(dev, s,
1864 DIO200_INT_SCE, layout->sdinfo[n]);
1868 devpriv->intr_sd = n;
1870 s->type = COMEDI_SUBD_UNUSED;
1874 /* TODO. Fall-thru to default for now. */
1876 s->type = COMEDI_SUBD_UNUSED;
1881 sdx = devpriv->intr_sd;
1882 if (sdx >= 0 && sdx < dev->n_subdevices) {
1883 dev->read_subdev = &dev->subdevices[sdx];
1886 dev->board_name = thisboard->name;
1889 unsigned long flags = share_irq ? IRQF_SHARED : 0;
1891 if (comedi_request_irq(irq, dio200_interrupt, flags,
1892 DIO200_DRIVER_NAME, dev) >= 0) {
1896 "comedi%d: warning! irq %u unavailable!\n",
1901 printk(KERN_INFO "comedi%d: %s ", dev->minor, dev->board_name);
1902 if (thisboard->bustype == isa_bustype) {
1903 printk("(base %#lx) ", iobase);
1905 #ifdef CONFIG_COMEDI_PCI
1906 printk("(pci %s) ", pci_name(pci_dev));
1910 printk("(irq %u%s) ", irq, (dev->irq ? "" : " UNAVAILABLE"));
1912 printk("(no irq) ");
1915 printk("attached\n");
1921 * _detach is called to deconfigure a device. It should deallocate
1923 * This function is also called when _attach() fails, so it should be
1924 * careful not to release resources that were not necessarily
1925 * allocated by _attach(). dev->private and dev->subdevices are
1926 * deallocated automatically by the core.
1928 static int dio200_detach(comedi_device * dev)
1930 const dio200_layout *layout;
1933 printk(KERN_DEBUG "comedi%d: %s: detach\n", dev->minor,
1934 DIO200_DRIVER_NAME);
1937 comedi_free_irq(dev->irq, dev);
1939 if (dev->subdevices) {
1940 layout = thislayout;
1941 for (n = 0; n < dev->n_subdevices; n++) {
1942 comedi_subdevice *s = &dev->subdevices[n];
1943 switch (layout->sdtype[n]) {
1945 dio200_subdev_8254_cleanup(dev, s);
1948 dio200_subdev_8255_cleanup(dev, s);
1951 dio200_subdev_intr_cleanup(dev, s);
1959 if (devpriv->io.regtype == mmio_regtype) {
1960 iounmap(devpriv->io.u.membase);
1962 #ifdef CONFIG_COMEDI_PCI
1963 if (devpriv->pci_dev) {
1964 if (devpriv->io.regtype != no_regtype) {
1965 comedi_pci_disable(devpriv->pci_dev);
1967 pci_dev_put(devpriv->pci_dev);
1971 if (devpriv->io.regtype == io_regtype) {
1972 release_region(devpriv->io.u.iobase,
1973 thisboard->mainsize);
1977 if (dev->board_name) {
1978 printk(KERN_INFO "comedi%d: %s removed\n",
1979 dev->minor, dev->board_name);