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 */
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 * This function looks for a PCI device matching the requested board name,
688 #ifdef CONFIG_COMEDI_PCI
690 dio200_find_pci(comedi_device * dev, int bus, int slot,
691 struct pci_dev **pci_dev_p)
693 struct pci_dev *pci_dev = NULL;
697 /* Look for matching PCI device. */
698 for (pci_dev = pci_get_device(PCI_VENDOR_ID_AMPLICON, PCI_ANY_ID, NULL);
700 pci_dev = pci_get_device(PCI_VENDOR_ID_AMPLICON,
701 PCI_ANY_ID, pci_dev)) {
702 /* If bus/slot specified, check them. */
704 if (bus != pci_dev->bus->number
705 || slot != PCI_SLOT(pci_dev->devfn))
708 if (thisboard->model == anypci_model) {
709 /* Match any supported model. */
712 for (i = 0; i < ARRAY_SIZE(dio200_boards); i++) {
713 if (dio200_boards[i].bustype != pci_bustype)
715 if (pci_dev->device == dio200_boards[i].devid) {
716 /* Change board_ptr to matched board. */
717 dev->board_ptr = &dio200_boards[i];
721 if (i == ARRAY_SIZE(dio200_boards))
724 /* Match specific model name. */
725 if (pci_dev->device != thisboard->devid)
730 *pci_dev_p = pci_dev;
733 /* No match found. */
736 "comedi%d: error! no %s found at pci %02x:%02x!\n",
737 dev->minor, thisboard->name, bus, slot);
739 printk(KERN_ERR "comedi%d: error! no %s found!\n",
740 dev->minor, thisboard->name);
747 * This function checks and requests an I/O region, reporting an error
748 * if there is a conflict.
751 dio200_request_region(unsigned minor, unsigned long from, unsigned long extent)
753 if (!from || !request_region(from, extent, DIO200_DRIVER_NAME)) {
754 printk(KERN_ERR "comedi%d: I/O port conflict (%#lx,%lu)!\n",
755 minor, from, extent);
762 * 'insn_bits' function for an 'INTERRUPT' subdevice.
765 dio200_subdev_intr_insn_bits(comedi_device * dev, comedi_subdevice * s,
766 comedi_insn * insn, lsampl_t * data)
768 dio200_subdev_intr *subpriv = s->private;
770 if (thislayout->has_int_sce) {
771 /* Just read the interrupt status register. */
772 data[1] = dio200_read8(dev, subpriv->ofs) & subpriv->valid_isns;
774 /* No interrupt status register. */
782 * Called to stop acquisition for an 'INTERRUPT' subdevice.
784 static void dio200_stop_intr(comedi_device * dev, comedi_subdevice * s)
786 dio200_subdev_intr *subpriv = s->private;
789 subpriv->enabled_isns = 0;
790 if (thislayout->has_int_sce) {
791 dio200_write8(dev, subpriv->ofs, 0);
796 * Called to start acquisition for an 'INTERRUPT' subdevice.
798 static int dio200_start_intr(comedi_device * dev, comedi_subdevice * s)
802 dio200_subdev_intr *subpriv = s->private;
803 comedi_cmd *cmd = &s->async->cmd;
806 if (!subpriv->continuous && subpriv->stopcount == 0) {
807 /* An empty acquisition! */
808 s->async->events |= COMEDI_CB_EOA;
812 /* Determine interrupt sources to enable. */
815 for (n = 0; n < cmd->chanlist_len; n++) {
816 isn_bits |= (1U << CR_CHAN(cmd->chanlist[n]));
819 isn_bits &= subpriv->valid_isns;
820 /* Enable interrupt sources. */
821 subpriv->enabled_isns = isn_bits;
822 if (thislayout->has_int_sce) {
823 dio200_write8(dev, subpriv->ofs, isn_bits);
831 * Internal trigger function to start acquisition for an 'INTERRUPT' subdevice.
834 dio200_inttrig_start_intr(comedi_device * dev, comedi_subdevice * s,
835 unsigned int trignum)
837 dio200_subdev_intr *subpriv;
844 subpriv = s->private;
846 comedi_spin_lock_irqsave(&subpriv->spinlock, flags);
847 s->async->inttrig = 0;
848 if (subpriv->active) {
849 event = dio200_start_intr(dev, s);
851 comedi_spin_unlock_irqrestore(&subpriv->spinlock, flags);
854 comedi_event(dev, s);
861 * This is called from the interrupt service routine to handle a read
862 * scan on an 'INTERRUPT' subdevice.
864 static int dio200_handle_read_intr(comedi_device * dev, comedi_subdevice * s)
866 dio200_subdev_intr *subpriv = s->private;
869 unsigned cur_enabled;
870 unsigned int oldevents;
872 unsigned int int_sce_ofs;
874 int_sce_ofs = subpriv->ofs;
877 comedi_spin_lock_irqsave(&subpriv->spinlock, flags);
878 oldevents = s->async->events;
879 if (thislayout->has_int_sce) {
881 * Collect interrupt sources that have triggered and disable
882 * them temporarily. Loop around until no extra interrupt
883 * sources have triggered, at which point, the valid part of
884 * the interrupt status register will read zero, clearing the
885 * cause of the interrupt.
887 * Mask off interrupt sources already seen to avoid infinite
888 * loop in case of misconfiguration.
890 cur_enabled = subpriv->enabled_isns;
891 while ((intstat = (dio200_read8(dev, int_sce_ofs)
892 & subpriv->valid_isns & ~triggered))
894 triggered |= intstat;
895 cur_enabled &= ~triggered;
896 dio200_write8(dev, int_sce_ofs, cur_enabled);
900 * No interrupt status register. Assume the single interrupt
901 * source has triggered.
903 triggered = subpriv->enabled_isns;
908 * Some interrupt sources have triggered and have been
909 * temporarily disabled to clear the cause of the interrupt.
911 * Reenable them NOW to minimize the time they are disabled.
913 cur_enabled = subpriv->enabled_isns;
914 if (thislayout->has_int_sce) {
915 dio200_write8(dev, int_sce_ofs, cur_enabled);
918 if (subpriv->active) {
920 * The command is still active.
922 * Ignore interrupt sources that the command isn't
923 * interested in (just in case there's a race
926 if (triggered & subpriv->enabled_isns) {
927 /* Collect scan data. */
929 unsigned int n, ch, len;
932 len = s->async->cmd.chanlist_len;
933 for (n = 0; n < len; n++) {
934 ch = CR_CHAN(s->async->cmd.chanlist[n]);
935 if (triggered & (1U << ch)) {
939 /* Write the scan to the buffer. */
940 if (comedi_buf_put(s->async, val)) {
941 s->async->events |= (COMEDI_CB_BLOCK |
944 /* Error! Stop acquisition. */
945 dio200_stop_intr(dev, s);
946 s->async->events |= COMEDI_CB_ERROR
947 | COMEDI_CB_OVERFLOW;
948 comedi_error(dev, "buffer overflow");
951 /* Check for end of acquisition. */
952 if (!subpriv->continuous) {
953 /* stop_src == TRIG_COUNT */
954 if (subpriv->stopcount > 0) {
955 subpriv->stopcount--;
956 if (subpriv->stopcount == 0) {
959 dio200_stop_intr(dev,
967 comedi_spin_unlock_irqrestore(&subpriv->spinlock, flags);
969 if (oldevents != s->async->events) {
970 comedi_event(dev, s);
973 return (triggered != 0);
977 * 'cancel' function for an 'INTERRUPT' subdevice.
979 static int dio200_subdev_intr_cancel(comedi_device * dev, comedi_subdevice * s)
981 dio200_subdev_intr *subpriv = s->private;
984 comedi_spin_lock_irqsave(&subpriv->spinlock, flags);
985 if (subpriv->active) {
986 dio200_stop_intr(dev, s);
988 comedi_spin_unlock_irqrestore(&subpriv->spinlock, flags);
994 * 'do_cmdtest' function for an 'INTERRUPT' subdevice.
997 dio200_subdev_intr_cmdtest(comedi_device * dev, comedi_subdevice * s,
1003 /* step 1: make sure trigger sources are trivially valid */
1005 tmp = cmd->start_src;
1006 cmd->start_src &= (TRIG_NOW | TRIG_INT);
1007 if (!cmd->start_src || tmp != cmd->start_src)
1010 tmp = cmd->scan_begin_src;
1011 cmd->scan_begin_src &= TRIG_EXT;
1012 if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
1015 tmp = cmd->convert_src;
1016 cmd->convert_src &= TRIG_NOW;
1017 if (!cmd->convert_src || tmp != cmd->convert_src)
1020 tmp = cmd->scan_end_src;
1021 cmd->scan_end_src &= TRIG_COUNT;
1022 if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
1025 tmp = cmd->stop_src;
1026 cmd->stop_src &= (TRIG_COUNT | TRIG_NONE);
1027 if (!cmd->stop_src || tmp != cmd->stop_src)
1033 /* step 2: make sure trigger sources are unique and mutually compatible */
1035 /* these tests are true if more than one _src bit is set */
1036 if ((cmd->start_src & (cmd->start_src - 1)) != 0)
1038 if ((cmd->scan_begin_src & (cmd->scan_begin_src - 1)) != 0)
1040 if ((cmd->convert_src & (cmd->convert_src - 1)) != 0)
1042 if ((cmd->scan_end_src & (cmd->scan_end_src - 1)) != 0)
1044 if ((cmd->stop_src & (cmd->stop_src - 1)) != 0)
1050 /* step 3: make sure arguments are trivially compatible */
1052 /* cmd->start_src == TRIG_NOW || cmd->start_src == TRIG_INT */
1053 if (cmd->start_arg != 0) {
1058 /* cmd->scan_begin_src == TRIG_EXT */
1059 if (cmd->scan_begin_arg != 0) {
1060 cmd->scan_begin_arg = 0;
1064 /* cmd->convert_src == TRIG_NOW */
1065 if (cmd->convert_arg != 0) {
1066 cmd->convert_arg = 0;
1070 /* cmd->scan_end_src == TRIG_COUNT */
1071 if (cmd->scan_end_arg != cmd->chanlist_len) {
1072 cmd->scan_end_arg = cmd->chanlist_len;
1076 switch (cmd->stop_src) {
1078 /* any count allowed */
1081 if (cmd->stop_arg != 0) {
1093 /* step 4: fix up any arguments */
1095 /* if (err) return 4; */
1101 * 'do_cmd' function for an 'INTERRUPT' subdevice.
1103 static int dio200_subdev_intr_cmd(comedi_device * dev, comedi_subdevice * s)
1105 comedi_cmd *cmd = &s->async->cmd;
1106 dio200_subdev_intr *subpriv = s->private;
1107 unsigned long flags;
1110 comedi_spin_lock_irqsave(&subpriv->spinlock, flags);
1111 subpriv->active = 1;
1113 /* Set up end of acquisition. */
1114 switch (cmd->stop_src) {
1116 subpriv->continuous = 0;
1117 subpriv->stopcount = cmd->stop_arg;
1121 subpriv->continuous = 1;
1122 subpriv->stopcount = 0;
1126 /* Set up start of acquisition. */
1127 switch (cmd->start_src) {
1129 s->async->inttrig = dio200_inttrig_start_intr;
1133 event = dio200_start_intr(dev, s);
1136 comedi_spin_unlock_irqrestore(&subpriv->spinlock, flags);
1139 comedi_event(dev, s);
1146 * This function initializes an 'INTERRUPT' subdevice.
1149 dio200_subdev_intr_init(comedi_device * dev, comedi_subdevice * s,
1150 unsigned int offset, unsigned valid_isns)
1152 dio200_subdev_intr *subpriv;
1154 subpriv = kzalloc(sizeof(*subpriv), GFP_KERNEL);
1156 printk(KERN_ERR "comedi%d: error! out of memory!\n",
1160 subpriv->ofs = offset;
1161 subpriv->valid_isns = valid_isns;
1162 spin_lock_init(&subpriv->spinlock);
1164 if (thislayout->has_int_sce) {
1165 /* Disable interrupt sources. */
1166 dio200_write8(dev, subpriv->ofs, 0);
1169 s->private = subpriv;
1170 s->type = COMEDI_SUBD_DI;
1171 s->subdev_flags = SDF_READABLE | SDF_CMD_READ;
1172 if (thislayout->has_int_sce) {
1173 s->n_chan = DIO200_MAX_ISNS;
1174 s->len_chanlist = DIO200_MAX_ISNS;
1176 /* No interrupt source register. Support single channel. */
1178 s->len_chanlist = 1;
1180 s->range_table = &range_digital;
1182 s->insn_bits = dio200_subdev_intr_insn_bits;
1183 s->do_cmdtest = dio200_subdev_intr_cmdtest;
1184 s->do_cmd = dio200_subdev_intr_cmd;
1185 s->cancel = dio200_subdev_intr_cancel;
1191 * This function cleans up an 'INTERRUPT' subdevice.
1194 dio200_subdev_intr_cleanup(comedi_device * dev, comedi_subdevice * s)
1196 dio200_subdev_intr *subpriv = s->private;
1204 * Interrupt service routine.
1206 static irqreturn_t dio200_interrupt(int irq, void *d PT_REGS_ARG)
1208 comedi_device *dev = d;
1211 if (!dev->attached) {
1215 if (devpriv->intr_sd >= 0) {
1216 handled = dio200_handle_read_intr(dev,
1217 dev->subdevices + devpriv->intr_sd);
1222 return IRQ_RETVAL(handled);
1226 * Read an '8254' counter subdevice channel.
1228 static inline unsigned int
1229 dio200_subdev_8254_read_chan(comedi_device * dev, comedi_subdevice * s,
1232 unsigned int i8254_ofs = ((dio200_subdev_8254 *)s->private)->ofs;
1237 dio200_write8(dev, i8254_ofs + i8254_control_reg, val);
1240 val = dio200_read8(dev, i8254_ofs + chan);
1242 val += dio200_read8(dev, i8254_ofs + chan) << 8;
1248 * Write an '8254' counter subdevice channel.
1251 dio200_subdev_8254_write_chan(comedi_device * dev, comedi_subdevice * s,
1252 unsigned int chan, unsigned int count)
1254 unsigned int i8254_ofs = ((dio200_subdev_8254 *)s->private)->ofs;
1257 dio200_write8(dev, i8254_ofs + chan, count & 0xff);
1259 dio200_write8(dev, i8254_ofs + chan, (count >> 8) & 0xff);
1263 * Set mode of an '8254' counter subdevice channel.
1266 dio200_subdev_8254_set_mode(comedi_device * dev, comedi_subdevice * s,
1267 unsigned int chan, unsigned int mode)
1269 unsigned int i8254_ofs = ((dio200_subdev_8254 *)s->private)->ofs;
1273 byte |= 0x30; /* load lsb then msb */
1274 byte |= (mode & 0xf); /* set counter mode and BCD|binary */
1275 dio200_write8(dev, i8254_ofs + i8254_control_reg, byte);
1279 * Read status byte of an '8254' counter subdevice channel.
1281 static inline unsigned int
1282 dio200_subdev_8254_status(comedi_device * dev, comedi_subdevice * s,
1285 unsigned int i8254_ofs = ((dio200_subdev_8254 *)s->private)->ofs;
1287 dio200_write8(dev, i8254_ofs + i8254_control_reg, (0xE0 | 2 << chan));
1288 return dio200_read8(dev, i8254_ofs + chan);
1292 * Handle 'insn_read' for an '8254' counter subdevice.
1295 dio200_subdev_8254_read(comedi_device * dev, comedi_subdevice * s,
1296 comedi_insn * insn, lsampl_t * data)
1298 dio200_subdev_8254 *subpriv = s->private;
1299 int chan = CR_CHAN(insn->chanspec);
1300 unsigned long flags;
1305 comedi_spin_lock_irqsave(&subpriv->spinlock, flags);
1306 data[0] = dio200_subdev_8254_read_chan(dev, s, chan);
1307 comedi_spin_unlock_irqrestore(&subpriv->spinlock, flags);
1313 * Handle 'insn_write' for an '8254' counter subdevice.
1316 dio200_subdev_8254_write(comedi_device * dev, comedi_subdevice * s,
1317 comedi_insn * insn, lsampl_t * data)
1319 dio200_subdev_8254 *subpriv = s->private;
1320 int chan = CR_CHAN(insn->chanspec);
1321 unsigned long flags;
1326 comedi_spin_lock_irqsave(&subpriv->spinlock, flags);
1327 dio200_subdev_8254_write_chan(dev, s, chan, data[0]);
1328 comedi_spin_unlock_irqrestore(&subpriv->spinlock, flags);
1334 * Set gate source for an '8254' counter subdevice channel.
1337 dio200_subdev_8254_set_gate_src(comedi_device * dev, comedi_subdevice *s,
1338 unsigned int counter_number, unsigned int gate_src)
1340 dio200_subdev_8254 *subpriv = s->private;
1343 if (!thislayout->has_clk_gat_sce)
1345 if (counter_number > 2)
1347 if (gate_src > (thislayout->has_enhancements ? 31 : 7))
1350 subpriv->gate_src[counter_number] = gate_src;
1351 byte = GAT_SCE(subpriv->which, counter_number, gate_src);
1352 dio200_write8(dev, subpriv->gat_sce_ofs, byte);
1358 * Get gate source for an '8254' counter subdevice channel.
1361 dio200_subdev_8254_get_gate_src(comedi_device * dev, comedi_subdevice *s,
1362 unsigned int counter_number)
1364 dio200_subdev_8254 *subpriv = s->private;
1366 if (!thislayout->has_clk_gat_sce)
1368 if (counter_number > 2)
1371 return subpriv->gate_src[counter_number];
1375 * Set clock source for an '8254' counter subdevice channel.
1378 dio200_subdev_8254_set_clock_src(comedi_device * dev, comedi_subdevice *s,
1379 unsigned int counter_number, unsigned int clock_src)
1381 dio200_subdev_8254 *subpriv = s->private;
1384 if (!thislayout->has_clk_gat_sce)
1386 if (counter_number > 2)
1388 if (clock_src > (thislayout->has_enhancements ? 31 : 7))
1391 subpriv->clock_src[counter_number] = clock_src;
1392 byte = CLK_SCE(subpriv->which, counter_number, clock_src);
1393 dio200_write8(dev, subpriv->clk_sce_ofs, byte);
1399 * Get clock source for an '8254' counter subdevice channel.
1402 dio200_subdev_8254_get_clock_src(comedi_device * dev, comedi_subdevice *s,
1403 unsigned int counter_number, lsampl_t * period_ns)
1405 dio200_subdev_8254 *subpriv = s->private;
1408 if (!thislayout->has_clk_gat_sce)
1410 if (counter_number > 2)
1413 clock_src = subpriv->clock_src[counter_number];
1414 *period_ns = clock_period[clock_src];
1419 * Handle 'insn_config' for an '8254' counter subdevice.
1422 dio200_subdev_8254_config(comedi_device * dev, comedi_subdevice * s,
1423 comedi_insn * insn, lsampl_t * data)
1425 dio200_subdev_8254 *subpriv = s->private;
1427 int chan = CR_CHAN(insn->chanspec);
1428 unsigned long flags;
1430 comedi_spin_lock_irqsave(&subpriv->spinlock, flags);
1432 case INSN_CONFIG_SET_COUNTER_MODE:
1433 if (data[1] > (I8254_MODE5 | I8254_BINARY))
1436 dio200_subdev_8254_set_mode(dev, s, chan, data[1]);
1438 case INSN_CONFIG_8254_READ_STATUS:
1439 data[1] = dio200_subdev_8254_status(dev, s, chan);
1441 case INSN_CONFIG_SET_GATE_SRC:
1442 ret = dio200_subdev_8254_set_gate_src(dev, s, chan, data[2]);
1446 case INSN_CONFIG_GET_GATE_SRC:
1447 ret = dio200_subdev_8254_get_gate_src(dev, s, chan);
1454 case INSN_CONFIG_SET_CLOCK_SRC:
1455 ret = dio200_subdev_8254_set_clock_src(dev, s, chan, data[1]);
1459 case INSN_CONFIG_GET_CLOCK_SRC:
1460 ret = dio200_subdev_8254_get_clock_src(dev, s, chan, &data[2]);
1471 comedi_spin_unlock_irqrestore(&subpriv->spinlock, flags);
1472 return ret < 0 ? ret : insn->n;
1476 * This function initializes an '8254' counter subdevice.
1478 * offset is the offset to the 8254 chip.
1481 dio200_subdev_8254_init(comedi_device * dev, comedi_subdevice * s,
1482 unsigned int offset)
1484 dio200_subdev_8254 *subpriv;
1487 subpriv = kzalloc(sizeof(*subpriv), GFP_KERNEL);
1489 printk(KERN_ERR "comedi%d: error! out of memory!\n",
1494 s->private = subpriv;
1495 s->type = COMEDI_SUBD_COUNTER;
1496 s->subdev_flags = SDF_WRITABLE | SDF_READABLE;
1498 s->maxdata = 0xFFFF;
1499 s->insn_read = dio200_subdev_8254_read;
1500 s->insn_write = dio200_subdev_8254_write;
1501 s->insn_config = dio200_subdev_8254_config;
1503 spin_lock_init(&subpriv->spinlock);
1504 subpriv->ofs = offset;
1505 if (thislayout->has_clk_gat_sce) {
1506 /* Derive CLK_SCE and GAT_SCE register offsets from
1508 subpriv->clk_sce_ofs =
1509 DIO200_XCLK_SCE + (offset >> 3);
1510 subpriv->gat_sce_ofs =
1511 DIO200_XGAT_SCE + (offset >> 3);
1512 subpriv->which = (offset >> 2) & 1;
1515 /* Initialize channels. */
1516 for (chan = 0; chan < 3; chan++) {
1517 dio200_subdev_8254_set_mode(dev, s, chan,
1518 (I8254_MODE0 | I8254_BINARY));
1519 if (thislayout->has_clk_gat_sce) {
1520 /* Gate source 0 is VCC (logic 1). */
1521 dio200_subdev_8254_set_gate_src(dev, s, chan, 0);
1522 /* Clock source 0 is the dedicated clock input. */
1523 dio200_subdev_8254_set_clock_src(dev, s, chan, 0);
1531 * This function cleans up an '8254' counter subdevice.
1534 dio200_subdev_8254_cleanup(comedi_device * dev, comedi_subdevice * s)
1536 dio200_subdev_8254 *subpriv = s->private;
1544 * This function sets I/O directions for an '8255' DIO subdevice.
1547 dio200_subdev_8255_set_dir(comedi_device * dev, comedi_subdevice * s)
1549 dio200_subdev_8255 *subpriv = s->private;
1553 /* 1 in io_bits indicates output, 1 in config indicates input */
1554 if (!(s->io_bits & 0x0000ff))
1556 if (!(s->io_bits & 0x00ff00))
1558 if (!(s->io_bits & 0x0f0000))
1559 config |= CR_C_LO_IO;
1560 if (!(s->io_bits & 0xf00000))
1561 config |= CR_C_HI_IO;
1563 dio200_write8(dev, subpriv->ofs + 3, config);
1567 * Handle 'insn_bits' for an '8255' DIO subdevice.
1570 dio200_subdev_8255_bits(comedi_device * dev, comedi_subdevice * s,
1571 comedi_insn * insn, lsampl_t * data)
1573 unsigned int i8255_ofs = ((dio200_subdev_8255 *)s->private)->ofs;
1576 s->state &= ~data[0];
1577 s->state |= (data[0] & data[1]);
1579 if (data[0] & 0xff) {
1580 dio200_write8(dev, i8255_ofs, s->state & 0xff);
1582 if (data[0] & 0xff00) {
1583 dio200_write8(dev, i8255_ofs + 1,
1584 (s->state >> 8) & 0xff);
1586 if (data[0] & 0xff0000) {
1587 dio200_write8(dev, i8255_ofs + 2,
1588 (s->state >> 16) & 0xff);
1592 data[1] = dio200_read8(dev, i8255_ofs);
1593 data[1] |= dio200_read8(dev, i8255_ofs + 1) << 8;
1594 data[1] |= dio200_read8(dev, i8255_ofs + 2) << 16;
1600 * Handle 'insn_config' for an '8255' DIO subdevice.
1603 dio200_subdev_8255_config(comedi_device * dev, comedi_subdevice * s,
1604 comedi_insn * insn, lsampl_t * data)
1609 mask = 1 << CR_CHAN(insn->chanspec);
1610 if (mask & 0x0000ff) {
1612 } else if (mask & 0x00ff00) {
1614 } else if (mask & 0x0f0000) {
1621 case INSN_CONFIG_DIO_INPUT:
1622 s->io_bits &= ~bits;
1624 case INSN_CONFIG_DIO_OUTPUT:
1627 case INSN_CONFIG_DIO_QUERY:
1628 data[1] = (s->io_bits & bits) ? COMEDI_OUTPUT : COMEDI_INPUT;
1635 dio200_subdev_8255_set_dir(dev, s);
1641 * This function initializes an '8255' DIO subdevice.
1643 * offset is the offset to the 8255 chip.
1646 dio200_subdev_8255_init(comedi_device * dev, comedi_subdevice * s,
1647 unsigned int offset)
1649 dio200_subdev_8255 *subpriv;
1651 subpriv = kzalloc(sizeof(*subpriv), GFP_KERNEL);
1653 printk(KERN_ERR "comedi%d: error! out of memory!\n",
1658 subpriv->ofs = offset;
1660 s->private = subpriv;
1661 s->type = COMEDI_SUBD_DIO;
1662 s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
1664 s->range_table = &range_digital;
1666 s->insn_bits = dio200_subdev_8255_bits;
1667 s->insn_config = dio200_subdev_8255_config;
1671 dio200_subdev_8255_set_dir(dev, s);
1677 * This function cleans up an '8255' DIO subdevice.
1680 dio200_subdev_8255_cleanup(comedi_device * dev, comedi_subdevice * s)
1682 dio200_subdev_8255 *subpriv = s->private;
1689 #ifdef CONFIG_COMEDI_PCI
1691 * This function does some special set-up for the PCIe boards
1692 * PCIe215, PCIe236, PCIe296.
1695 dio200_pcie_board_setup(comedi_device * dev)
1697 struct pci_dev *pci_dev = devpriv->pci_dev;
1698 unsigned char __iomem *brbase;
1699 resource_size_t brlen;
1702 * The board uses Altera Cyclone IV with PCI-Express hard IP.
1703 * The FPGA configuration has the PCI-Express Avalon-MM Bridge
1704 * Control registers in PCI BAR 0, offset 0, and the length of
1705 * these registers is 0x4000.
1707 * We need to write 0x80 to the "Avalon-MM to PCI-Express Interrupt
1708 * Enable" register at offset 0x50 to allow generation of PCIe
1709 * interrupts when RXmlrq_i is asserted in the SOPC Builder system.
1711 brlen = pci_resource_len(pci_dev, 0);
1712 if (brlen < 0x4000 ||
1713 !(pci_resource_flags(pci_dev, 0) & IORESOURCE_MEM)) {
1714 printk(KERN_ERR "comedi%d: error! bad PCI region!\n",
1718 brbase = ioremap_nocache(pci_resource_start(pci_dev, 0), brlen);
1720 printk(KERN_ERR "comedi%d: error! failed to map registers!\n",
1724 writel(0x80, brbase + 0x50);
1727 * Enable "enhanced" features of board.
1729 dio200_write8(dev, DIO200_ENHANCE, 1);
1735 * Attach is called by the Comedi core to configure the driver
1736 * for a particular board. If you specified a board_name array
1737 * in the driver structure, dev->board_ptr contains that
1740 static int dio200_attach(comedi_device * dev, comedi_devconfig * it)
1742 comedi_subdevice *s;
1743 unsigned long iobase = 0;
1744 unsigned int irq = 0;
1745 #ifdef CONFIG_COMEDI_PCI
1746 struct pci_dev *pci_dev = NULL;
1747 int bus = 0, slot = 0;
1749 const dio200_layout *layout;
1755 printk(KERN_DEBUG "comedi%d: %s: attach\n", dev->minor,
1756 DIO200_DRIVER_NAME);
1758 if ((ret = alloc_private(dev, sizeof(dio200_private))) < 0) {
1759 printk(KERN_ERR "comedi%d: error! out of memory!\n",
1764 /* Process options. */
1765 switch (thisboard->bustype) {
1767 iobase = it->options[0];
1768 irq = it->options[1];
1771 #ifdef CONFIG_COMEDI_PCI
1773 bus = it->options[0];
1774 slot = it->options[1];
1777 if ((ret = dio200_find_pci(dev, bus, slot, &pci_dev)) < 0)
1779 devpriv->pci_dev = pci_dev;
1784 "comedi%d: %s: BUG! cannot determine board type!\n",
1785 dev->minor, DIO200_DRIVER_NAME);
1790 devpriv->intr_sd = -1;
1791 devpriv->io.regtype = no_regtype;
1792 devpriv->io.regshift = thisboard->mainshift;
1794 /* Enable device and reserve I/O spaces. */
1795 #ifdef CONFIG_COMEDI_PCI
1797 resource_size_t base, len;
1800 ret = comedi_pci_enable(pci_dev, DIO200_DRIVER_NAME);
1803 "comedi%d: error! cannot enable PCI device and request regions!\n",
1807 bar = thisboard->mainbar;
1808 base = pci_resource_start(pci_dev, bar);
1809 len = pci_resource_len(pci_dev, bar);
1810 if (len < thisboard->mainsize) {
1812 "comedi%d: error! PCI region size too small!\n",
1816 if ((pci_resource_flags(pci_dev, bar) & IORESOURCE_MEM) != 0) {
1817 devpriv->io.u.membase = ioremap_nocache(base, len);
1818 if (!devpriv->io.u.membase) {
1820 "comedi%d: error! cannot remap registers!\n",
1824 devpriv->io.regtype = mmio_regtype;
1826 devpriv->io.u.iobase = (unsigned long)base;
1827 devpriv->io.regtype = io_regtype;
1833 ret = dio200_request_region(dev->minor, iobase,
1834 thisboard->mainsize);
1838 devpriv->io.u.iobase = iobase;
1839 devpriv->io.regtype = io_regtype;
1842 switch (thisboard->model) {
1843 #ifdef CONFIG_COMEDI_PCI
1847 ret = dio200_pcie_board_setup(dev);
1857 layout = thislayout;
1858 if ((ret = alloc_subdevices(dev, layout->n_subdevs)) < 0) {
1859 printk(KERN_ERR "comedi%d: error! out of memory!\n",
1864 for (n = 0; n < dev->n_subdevices; n++) {
1865 s = &dev->subdevices[n];
1866 switch (layout->sdtype[n]) {
1868 /* counter subdevice (8254) */
1869 ret = dio200_subdev_8254_init(dev, s,
1876 /* digital i/o subdevice (8255) */
1877 ret = dio200_subdev_8255_init(dev, s,
1884 /* 'INTERRUPT' subdevice */
1886 ret = dio200_subdev_intr_init(dev, s,
1887 DIO200_INT_SCE, layout->sdinfo[n]);
1891 devpriv->intr_sd = n;
1893 s->type = COMEDI_SUBD_UNUSED;
1897 /* TODO. Fall-thru to default for now. */
1899 s->type = COMEDI_SUBD_UNUSED;
1904 sdx = devpriv->intr_sd;
1905 if (sdx >= 0 && sdx < dev->n_subdevices) {
1906 dev->read_subdev = &dev->subdevices[sdx];
1909 dev->board_name = thisboard->name;
1912 unsigned long flags = share_irq ? IRQF_SHARED : 0;
1914 if (comedi_request_irq(irq, dio200_interrupt, flags,
1915 DIO200_DRIVER_NAME, dev) >= 0) {
1919 "comedi%d: warning! irq %u unavailable!\n",
1924 printk(KERN_INFO "comedi%d: %s ", dev->minor, dev->board_name);
1925 if (thisboard->bustype == isa_bustype) {
1926 printk("(base %#lx) ", iobase);
1928 #ifdef CONFIG_COMEDI_PCI
1929 printk("(pci %s) ", pci_name(pci_dev));
1933 printk("(irq %u%s) ", irq, (dev->irq ? "" : " UNAVAILABLE"));
1935 printk("(no irq) ");
1938 printk("attached\n");
1944 * _detach is called to deconfigure a device. It should deallocate
1946 * This function is also called when _attach() fails, so it should be
1947 * careful not to release resources that were not necessarily
1948 * allocated by _attach(). dev->private and dev->subdevices are
1949 * deallocated automatically by the core.
1951 static int dio200_detach(comedi_device * dev)
1953 const dio200_layout *layout;
1956 printk(KERN_DEBUG "comedi%d: %s: detach\n", dev->minor,
1957 DIO200_DRIVER_NAME);
1960 comedi_free_irq(dev->irq, dev);
1962 if (dev->subdevices) {
1963 layout = thislayout;
1964 for (n = 0; n < dev->n_subdevices; n++) {
1965 comedi_subdevice *s = &dev->subdevices[n];
1966 switch (layout->sdtype[n]) {
1968 dio200_subdev_8254_cleanup(dev, s);
1971 dio200_subdev_8255_cleanup(dev, s);
1974 dio200_subdev_intr_cleanup(dev, s);
1982 if (devpriv->io.regtype == mmio_regtype) {
1983 iounmap(devpriv->io.u.membase);
1985 #ifdef CONFIG_COMEDI_PCI
1986 if (devpriv->pci_dev) {
1987 if (devpriv->io.regtype != no_regtype) {
1988 comedi_pci_disable(devpriv->pci_dev);
1990 pci_dev_put(devpriv->pci_dev);
1994 if (devpriv->io.regtype == io_regtype) {
1995 release_region(devpriv->io.u.iobase,
1996 thisboard->mainsize);
2000 if (dev->board_name) {
2001 printk(KERN_INFO "comedi%d: %s removed\n",
2002 dev->minor, dev->board_name);