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, 03 Oct 2012 17:54:05 +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 */
276 #define DIO200_TS_CONFIG 0x600 /* Timestamp timer config register */
277 #define DIO200_TS_COUNT 0x602 /* Timestamp timer count register */
280 * Macros for constructing value for DIO_200_?CLK_SCE and
281 * DIO_200_?GAT_SCE registers:
283 * 'which' is: 0 for CTR-X1, CTR-Y1, CTR-Z1; 1 for CTR-X2, CTR-Y2 or CTR-Z2.
284 * 'chan' is the channel: 0, 1 or 2.
285 * 'source' is the signal source: 0 to 7, or 0 to 31 for "enhanced" boards.
287 #define CLK_SCE(which, chan, source) (((which) << 5) | ((chan) << 3) | \
288 (((source) & 030) << 3) | ((source) & 007))
289 #define GAT_SCE(which, chan, source) (((which) << 5) | ((chan) << 3) | \
290 (((source) & 030) << 3) | ((source) & 007))
293 * Timestamp timer configuration register (for new PCIe boards).
295 #define TS_CONFIG_RESET 0x100 /* Reset counter to zero. */
296 #define TS_CONFIG_CLK_SRC_MASK 0x0FF /* Clock source. */
297 #define TS_CONFIG_MAX_CLK_SRC 2 /* Maximum clock source value. */
300 * Periods of the timestamp timer clock sources in nanoseconds.
302 static const unsigned ts_clock_period[TS_CONFIG_MAX_CLK_SRC + 1] = {
303 1, /* 1 nanosecond (but with 20 ns granularity). */
304 1000, /* 1 microsecond. */
305 1000000, /* 1 millisecond. */
309 * Periods of the internal counter clock sources in nanoseconds.
311 static const unsigned clock_period[32] = {
312 0, /* dedicated clock input/output pin */
319 0, /* group clock input pin */
320 0, /* HIGH (VCC) (enhanced) */
321 0, /* LOW (GND) (enhanced) */
322 0, /* pattern present (enhanced) */
323 50, /* 20 MHz (enhanced) */
324 /* remaining clock sources reserved (enhanced) */
330 enum dio200_regtype { no_regtype, io_regtype, mmio_regtype };
331 struct dio200_region {
333 unsigned long iobase; /* I/O base address */
334 unsigned char __iomem *membase; /* Mapped MMIO base address */
336 unsigned char regtype;
337 unsigned char regshift;
341 * Board descriptions.
344 enum dio200_bustype { isa_bustype, pci_bustype };
349 pc215e_model, pci215_model, pcie215_model,
352 pc272e_model, pci272_model,
363 #ifdef CONFIG_COMEDI_PCI
371 typedef struct dio200_board_struct {
373 unsigned short devid;
374 enum dio200_bustype bustype;
375 enum dio200_model model;
376 enum dio200_layout layout;
377 unsigned char mainbar;
378 unsigned char mainshift;
379 unsigned int mainsize;
382 static const dio200_board dio200_boards[] = {
385 bustype: isa_bustype,
387 layout: pc212_layout,
388 mainsize: DIO200_IO_SIZE,
392 bustype: isa_bustype,
394 layout: pc214_layout,
395 mainsize: DIO200_IO_SIZE,
399 bustype: isa_bustype,
401 layout: pc215_layout,
402 mainsize: DIO200_IO_SIZE,
404 #ifdef CONFIG_COMEDI_PCI
407 devid: PCI_DEVICE_ID_AMPLICON_PCI215,
408 bustype: pci_bustype,
410 layout: pc215_layout,
411 mainsize: DIO200_IO_SIZE,
415 #ifdef CONFIG_COMEDI_PCI
418 devid: PCI_DEVICE_ID_AMPLICON_PCIE215,
419 bustype: pci_bustype,
420 model: pcie215_model,
421 layout: pcie215_layout,
422 mainsize: DIO200_PCIE_IO_SIZE,
429 bustype: isa_bustype,
431 layout: pc218_layout,
432 mainsize: DIO200_IO_SIZE,
434 #ifdef CONFIG_COMEDI_PCI
437 devid: PCI_DEVICE_ID_AMPLICON_PCIE236,
438 bustype: pci_bustype,
439 model: pcie236_model,
440 layout: pcie236_layout,
441 mainsize: DIO200_PCIE_IO_SIZE,
448 bustype: isa_bustype,
450 layout: pc272_layout,
451 mainsize: DIO200_IO_SIZE,
453 #ifdef CONFIG_COMEDI_PCI
456 devid: PCI_DEVICE_ID_AMPLICON_PCI272,
457 bustype: pci_bustype,
459 layout: pc272_layout,
460 mainsize: DIO200_IO_SIZE,
464 #ifdef CONFIG_COMEDI_PCI
467 devid: PCI_DEVICE_ID_AMPLICON_PCIE296,
468 bustype: pci_bustype,
469 model: pcie296_model,
470 layout: pcie296_layout,
471 mainsize: DIO200_PCIE_IO_SIZE,
476 #ifdef CONFIG_COMEDI_PCI
478 name: DIO200_DRIVER_NAME,
479 devid: PCI_DEVICE_ID_INVALID,
480 bustype: pci_bustype,
481 model: anypci_model, /* wildcard */
487 * Layout descriptions - some ISA and PCI board descriptions share the same
491 enum dio200_sdtype { sd_none, sd_intr, sd_8255, sd_8254, sd_timer };
493 #define DIO200_MAX_SUBDEVS 8
494 #define DIO200_MAX_ISNS 6
496 typedef struct dio200_layout_struct {
497 unsigned short n_subdevs; /* number of subdevices */
498 unsigned char sdtype[DIO200_MAX_SUBDEVS]; /* enum dio200_sdtype */
499 unsigned char sdinfo[DIO200_MAX_SUBDEVS]; /* depends on sdtype */
500 char has_int_sce; /* has interrupt enable/status register */
501 char has_clk_gat_sce; /* has clock/gate selection registers */
502 char has_enhancements; /* has enhanced features */
505 static const dio200_layout dio200_layouts[] = {
508 sdtype: {sd_8255, sd_8254, sd_8254, sd_8254,
511 sdinfo: {0x00, 0x08, 0x0C, 0x10, 0x14,
519 sdtype: {sd_8255, sd_8255, sd_8254,
521 sdinfo: {0x00, 0x08, 0x10, 0x01},
528 sdtype: {sd_8255, sd_8255, sd_8254,
531 sdinfo: {0x00, 0x08, 0x10, 0x14, 0x3F},
538 sdtype: {sd_8254, sd_8254, sd_8255, sd_8254,
541 sdinfo: {0x00, 0x04, 0x08, 0x0C, 0x10,
550 sdtype: {sd_8255, sd_8255, sd_8255,
552 sdinfo: {0x00, 0x08, 0x10, 0x3F},
557 #ifdef CONFIG_COMEDI_PCI
560 sdtype: {sd_8255, sd_none, sd_8255, sd_none, sd_8254, sd_8254,
562 sdinfo: {0x00, 0x00, 0x08, 0x00, 0x10, 0x14, 0x00, 0x3F},
569 sdtype: {sd_8255, sd_none, sd_none, sd_none, sd_8254, sd_8254,
571 sdinfo: {0x00, 0x00, 0x00, 0x00, 0x10, 0x14, 0x00, 0x3F},
578 sdtype: {sd_8255, sd_8255, sd_8255, sd_8255, sd_8254, sd_8254,
580 sdinfo: {0x00, 0x04, 0x08, 0x0C, 0x10, 0x14, 0x00, 0x3F},
592 #ifdef CONFIG_COMEDI_PCI
593 static DEFINE_PCI_DEVICE_TABLE(dio200_pci_table) = {
594 {PCI_VENDOR_ID_AMPLICON, PCI_DEVICE_ID_AMPLICON_PCI215,
595 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
596 {PCI_VENDOR_ID_AMPLICON, PCI_DEVICE_ID_AMPLICON_PCI272,
597 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
598 {PCI_VENDOR_ID_AMPLICON, PCI_DEVICE_ID_AMPLICON_PCIE236,
599 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
600 {PCI_VENDOR_ID_AMPLICON, PCI_DEVICE_ID_AMPLICON_PCIE215,
601 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
602 {PCI_VENDOR_ID_AMPLICON, PCI_DEVICE_ID_AMPLICON_PCIE296,
603 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
607 MODULE_DEVICE_TABLE(pci, dio200_pci_table);
608 #endif /* CONFIG_COMEDI_PCI */
611 * Useful for shorthand access to the particular board structure
613 #define thisboard ((const dio200_board *)dev->board_ptr)
614 #define thislayout (&dio200_layouts[((dio200_board *)dev->board_ptr)->layout])
616 /* this structure is for data unique to this hardware driver. If
617 several hardware drivers keep similar information in this structure,
618 feel free to suggest moving the variable to the comedi_device struct. */
620 #ifdef CONFIG_COMEDI_PCI
621 struct pci_dev *pci_dev; /* PCI device */
623 struct dio200_region io; /* Register region */
627 #define devpriv ((dio200_private *)dev->private)
630 unsigned int ofs; /* Counter base offset */
631 unsigned int clk_sce_ofs; /* CLK_SCE base offset */
632 unsigned int gat_sce_ofs; /* GAT_SCE base offset */
633 int which; /* Bit 5 of CLK_SCE or GAT_SCE */
634 unsigned int clock_src[3]; /* Current clock sources */
635 unsigned int gate_src[3]; /* Current gate sources */
637 } dio200_subdev_8254;
640 unsigned int ofs; /* DIO base offset */
641 } dio200_subdev_8255;
647 unsigned int valid_isns;
648 unsigned int enabled_isns;
649 unsigned int stopcount;
651 } dio200_subdev_intr;
654 * The comedi_driver structure tells the Comedi core module
655 * which functions to call to configure/deconfigure (attach/detach)
656 * the board, and also about the kernel module that contains
659 static int dio200_attach(comedi_device * dev, comedi_devconfig * it);
660 static int dio200_detach(comedi_device * dev);
661 static comedi_driver driver_amplc_dio200 = {
662 driver_name:DIO200_DRIVER_NAME,
664 attach:dio200_attach,
665 detach:dio200_detach,
666 board_name:&dio200_boards[0].name,
667 offset:sizeof(dio200_board),
668 num_names:sizeof(dio200_boards) / sizeof(dio200_board),
671 #ifdef CONFIG_COMEDI_PCI
672 COMEDI_PCI_INITCLEANUP(driver_amplc_dio200, dio200_pci_table);
674 COMEDI_INITCLEANUP(driver_amplc_dio200);
678 * Read 8-bit register.
680 static unsigned char dio200_read8(comedi_device * dev, unsigned int offset)
682 offset <<= devpriv->io.regshift;
683 if (devpriv->io.regtype == io_regtype)
684 return inb(devpriv->io.u.iobase + offset);
686 return readb(devpriv->io.u.membase + offset);
690 * Write 8-bit register.
692 static void dio200_write8(comedi_device * dev, unsigned int offset,
695 offset <<= devpriv->io.regshift;
696 if (devpriv->io.regtype == io_regtype)
697 outb(val, devpriv->io.u.iobase + offset);
699 writeb(val, devpriv->io.u.membase + offset);
703 * Read 32-bit register.
705 #ifdef CONFIG_COMEDI_PCI
706 static unsigned int dio200_read32(comedi_device * dev, unsigned int offset)
708 offset <<= devpriv->io.regshift;
709 if (devpriv->io.regtype == io_regtype)
710 return inl(devpriv->io.u.iobase + offset);
712 return readl(devpriv->io.u.membase + offset);
717 * Write 32-bit register.
719 #ifdef CONFIG_COMEDI_PCI
720 static void dio200_write32(comedi_device * dev, unsigned int offset,
723 offset <<= devpriv->io.regshift;
724 if (devpriv->io.regtype == io_regtype)
725 outl(val, devpriv->io.u.iobase + offset);
727 writel(val, devpriv->io.u.membase + offset);
732 * This function looks for a PCI device matching the requested board name,
735 #ifdef CONFIG_COMEDI_PCI
737 dio200_find_pci(comedi_device * dev, int bus, int slot,
738 struct pci_dev **pci_dev_p)
740 struct pci_dev *pci_dev = NULL;
744 /* Look for matching PCI device. */
745 for (pci_dev = pci_get_device(PCI_VENDOR_ID_AMPLICON, PCI_ANY_ID, NULL);
747 pci_dev = pci_get_device(PCI_VENDOR_ID_AMPLICON,
748 PCI_ANY_ID, pci_dev)) {
749 /* If bus/slot specified, check them. */
751 if (bus != pci_dev->bus->number
752 || slot != PCI_SLOT(pci_dev->devfn))
755 if (thisboard->model == anypci_model) {
756 /* Match any supported model. */
759 for (i = 0; i < ARRAY_SIZE(dio200_boards); i++) {
760 if (dio200_boards[i].bustype != pci_bustype)
762 if (pci_dev->device == dio200_boards[i].devid) {
763 /* Change board_ptr to matched board. */
764 dev->board_ptr = &dio200_boards[i];
768 if (i == ARRAY_SIZE(dio200_boards))
771 /* Match specific model name. */
772 if (pci_dev->device != thisboard->devid)
777 *pci_dev_p = pci_dev;
780 /* No match found. */
783 "comedi%d: error! no %s found at pci %02x:%02x!\n",
784 dev->minor, thisboard->name, bus, slot);
786 printk(KERN_ERR "comedi%d: error! no %s found!\n",
787 dev->minor, thisboard->name);
794 * This function checks and requests an I/O region, reporting an error
795 * if there is a conflict.
798 dio200_request_region(unsigned minor, unsigned long from, unsigned long extent)
800 if (!from || !request_region(from, extent, DIO200_DRIVER_NAME)) {
801 printk(KERN_ERR "comedi%d: I/O port conflict (%#lx,%lu)!\n",
802 minor, from, extent);
809 * 'insn_bits' function for an 'INTERRUPT' subdevice.
812 dio200_subdev_intr_insn_bits(comedi_device * dev, comedi_subdevice * s,
813 comedi_insn * insn, lsampl_t * data)
815 dio200_subdev_intr *subpriv = s->private;
817 if (thislayout->has_int_sce) {
818 /* Just read the interrupt status register. */
819 data[1] = dio200_read8(dev, subpriv->ofs) & subpriv->valid_isns;
821 /* No interrupt status register. */
829 * Called to stop acquisition for an 'INTERRUPT' subdevice.
831 static void dio200_stop_intr(comedi_device * dev, comedi_subdevice * s)
833 dio200_subdev_intr *subpriv = s->private;
836 subpriv->enabled_isns = 0;
837 if (thislayout->has_int_sce) {
838 dio200_write8(dev, subpriv->ofs, 0);
843 * Called to start acquisition for an 'INTERRUPT' subdevice.
845 static int dio200_start_intr(comedi_device * dev, comedi_subdevice * s)
849 dio200_subdev_intr *subpriv = s->private;
850 comedi_cmd *cmd = &s->async->cmd;
853 if (!subpriv->continuous && subpriv->stopcount == 0) {
854 /* An empty acquisition! */
855 s->async->events |= COMEDI_CB_EOA;
859 /* Determine interrupt sources to enable. */
862 for (n = 0; n < cmd->chanlist_len; n++) {
863 isn_bits |= (1U << CR_CHAN(cmd->chanlist[n]));
866 isn_bits &= subpriv->valid_isns;
867 /* Enable interrupt sources. */
868 subpriv->enabled_isns = isn_bits;
869 if (thislayout->has_int_sce) {
870 dio200_write8(dev, subpriv->ofs, isn_bits);
878 * Internal trigger function to start acquisition for an 'INTERRUPT' subdevice.
881 dio200_inttrig_start_intr(comedi_device * dev, comedi_subdevice * s,
882 unsigned int trignum)
884 dio200_subdev_intr *subpriv;
891 subpriv = s->private;
893 comedi_spin_lock_irqsave(&subpriv->spinlock, flags);
894 s->async->inttrig = 0;
895 if (subpriv->active) {
896 event = dio200_start_intr(dev, s);
898 comedi_spin_unlock_irqrestore(&subpriv->spinlock, flags);
901 comedi_event(dev, s);
908 * This is called from the interrupt service routine to handle a read
909 * scan on an 'INTERRUPT' subdevice.
911 static int dio200_handle_read_intr(comedi_device * dev, comedi_subdevice * s)
913 dio200_subdev_intr *subpriv = s->private;
916 unsigned cur_enabled;
917 unsigned int oldevents;
919 unsigned int int_sce_ofs;
921 int_sce_ofs = subpriv->ofs;
924 comedi_spin_lock_irqsave(&subpriv->spinlock, flags);
925 oldevents = s->async->events;
926 if (thislayout->has_int_sce) {
928 * Collect interrupt sources that have triggered and disable
929 * them temporarily. Loop around until no extra interrupt
930 * sources have triggered, at which point, the valid part of
931 * the interrupt status register will read zero, clearing the
932 * cause of the interrupt.
934 * Mask off interrupt sources already seen to avoid infinite
935 * loop in case of misconfiguration.
937 cur_enabled = subpriv->enabled_isns;
938 while ((intstat = (dio200_read8(dev, int_sce_ofs)
939 & subpriv->valid_isns & ~triggered))
941 triggered |= intstat;
942 cur_enabled &= ~triggered;
943 dio200_write8(dev, int_sce_ofs, cur_enabled);
947 * No interrupt status register. Assume the single interrupt
948 * source has triggered.
950 triggered = subpriv->enabled_isns;
955 * Some interrupt sources have triggered and have been
956 * temporarily disabled to clear the cause of the interrupt.
958 * Reenable them NOW to minimize the time they are disabled.
960 cur_enabled = subpriv->enabled_isns;
961 if (thislayout->has_int_sce) {
962 dio200_write8(dev, int_sce_ofs, cur_enabled);
965 if (subpriv->active) {
967 * The command is still active.
969 * Ignore interrupt sources that the command isn't
970 * interested in (just in case there's a race
973 if (triggered & subpriv->enabled_isns) {
974 /* Collect scan data. */
976 unsigned int n, ch, len;
979 len = s->async->cmd.chanlist_len;
980 for (n = 0; n < len; n++) {
981 ch = CR_CHAN(s->async->cmd.chanlist[n]);
982 if (triggered & (1U << ch)) {
986 /* Write the scan to the buffer. */
987 if (comedi_buf_put(s->async, val)) {
988 s->async->events |= (COMEDI_CB_BLOCK |
991 /* Error! Stop acquisition. */
992 dio200_stop_intr(dev, s);
993 s->async->events |= COMEDI_CB_ERROR
994 | COMEDI_CB_OVERFLOW;
995 comedi_error(dev, "buffer overflow");
998 /* Check for end of acquisition. */
999 if (!subpriv->continuous) {
1000 /* stop_src == TRIG_COUNT */
1001 if (subpriv->stopcount > 0) {
1002 subpriv->stopcount--;
1003 if (subpriv->stopcount == 0) {
1006 dio200_stop_intr(dev,
1014 comedi_spin_unlock_irqrestore(&subpriv->spinlock, flags);
1016 if (oldevents != s->async->events) {
1017 comedi_event(dev, s);
1020 return (triggered != 0);
1024 * 'cancel' function for an 'INTERRUPT' subdevice.
1026 static int dio200_subdev_intr_cancel(comedi_device * dev, comedi_subdevice * s)
1028 dio200_subdev_intr *subpriv = s->private;
1029 unsigned long flags;
1031 comedi_spin_lock_irqsave(&subpriv->spinlock, flags);
1032 if (subpriv->active) {
1033 dio200_stop_intr(dev, s);
1035 comedi_spin_unlock_irqrestore(&subpriv->spinlock, flags);
1041 * 'do_cmdtest' function for an 'INTERRUPT' subdevice.
1044 dio200_subdev_intr_cmdtest(comedi_device * dev, comedi_subdevice * s,
1050 /* step 1: make sure trigger sources are trivially valid */
1052 tmp = cmd->start_src;
1053 cmd->start_src &= (TRIG_NOW | TRIG_INT);
1054 if (!cmd->start_src || tmp != cmd->start_src)
1057 tmp = cmd->scan_begin_src;
1058 cmd->scan_begin_src &= TRIG_EXT;
1059 if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
1062 tmp = cmd->convert_src;
1063 cmd->convert_src &= TRIG_NOW;
1064 if (!cmd->convert_src || tmp != cmd->convert_src)
1067 tmp = cmd->scan_end_src;
1068 cmd->scan_end_src &= TRIG_COUNT;
1069 if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
1072 tmp = cmd->stop_src;
1073 cmd->stop_src &= (TRIG_COUNT | TRIG_NONE);
1074 if (!cmd->stop_src || tmp != cmd->stop_src)
1080 /* step 2: make sure trigger sources are unique and mutually compatible */
1082 /* these tests are true if more than one _src bit is set */
1083 if ((cmd->start_src & (cmd->start_src - 1)) != 0)
1085 if ((cmd->scan_begin_src & (cmd->scan_begin_src - 1)) != 0)
1087 if ((cmd->convert_src & (cmd->convert_src - 1)) != 0)
1089 if ((cmd->scan_end_src & (cmd->scan_end_src - 1)) != 0)
1091 if ((cmd->stop_src & (cmd->stop_src - 1)) != 0)
1097 /* step 3: make sure arguments are trivially compatible */
1099 /* cmd->start_src == TRIG_NOW || cmd->start_src == TRIG_INT */
1100 if (cmd->start_arg != 0) {
1105 /* cmd->scan_begin_src == TRIG_EXT */
1106 if (cmd->scan_begin_arg != 0) {
1107 cmd->scan_begin_arg = 0;
1111 /* cmd->convert_src == TRIG_NOW */
1112 if (cmd->convert_arg != 0) {
1113 cmd->convert_arg = 0;
1117 /* cmd->scan_end_src == TRIG_COUNT */
1118 if (cmd->scan_end_arg != cmd->chanlist_len) {
1119 cmd->scan_end_arg = cmd->chanlist_len;
1123 switch (cmd->stop_src) {
1125 /* any count allowed */
1128 if (cmd->stop_arg != 0) {
1140 /* step 4: fix up any arguments */
1142 /* if (err) return 4; */
1148 * 'do_cmd' function for an 'INTERRUPT' subdevice.
1150 static int dio200_subdev_intr_cmd(comedi_device * dev, comedi_subdevice * s)
1152 comedi_cmd *cmd = &s->async->cmd;
1153 dio200_subdev_intr *subpriv = s->private;
1154 unsigned long flags;
1157 comedi_spin_lock_irqsave(&subpriv->spinlock, flags);
1158 subpriv->active = 1;
1160 /* Set up end of acquisition. */
1161 switch (cmd->stop_src) {
1163 subpriv->continuous = 0;
1164 subpriv->stopcount = cmd->stop_arg;
1168 subpriv->continuous = 1;
1169 subpriv->stopcount = 0;
1173 /* Set up start of acquisition. */
1174 switch (cmd->start_src) {
1176 s->async->inttrig = dio200_inttrig_start_intr;
1180 event = dio200_start_intr(dev, s);
1183 comedi_spin_unlock_irqrestore(&subpriv->spinlock, flags);
1186 comedi_event(dev, s);
1193 * This function initializes an 'INTERRUPT' subdevice.
1196 dio200_subdev_intr_init(comedi_device * dev, comedi_subdevice * s,
1197 unsigned int offset, unsigned valid_isns)
1199 dio200_subdev_intr *subpriv;
1201 subpriv = kzalloc(sizeof(*subpriv), GFP_KERNEL);
1203 printk(KERN_ERR "comedi%d: error! out of memory!\n",
1207 subpriv->ofs = offset;
1208 subpriv->valid_isns = valid_isns;
1209 spin_lock_init(&subpriv->spinlock);
1211 if (thislayout->has_int_sce) {
1212 /* Disable interrupt sources. */
1213 dio200_write8(dev, subpriv->ofs, 0);
1216 s->private = subpriv;
1217 s->type = COMEDI_SUBD_DI;
1218 s->subdev_flags = SDF_READABLE | SDF_CMD_READ;
1219 if (thislayout->has_int_sce) {
1220 s->n_chan = DIO200_MAX_ISNS;
1221 s->len_chanlist = DIO200_MAX_ISNS;
1223 /* No interrupt source register. Support single channel. */
1225 s->len_chanlist = 1;
1227 s->range_table = &range_digital;
1229 s->insn_bits = dio200_subdev_intr_insn_bits;
1230 s->do_cmdtest = dio200_subdev_intr_cmdtest;
1231 s->do_cmd = dio200_subdev_intr_cmd;
1232 s->cancel = dio200_subdev_intr_cancel;
1238 * This function cleans up an 'INTERRUPT' subdevice.
1241 dio200_subdev_intr_cleanup(comedi_device * dev, comedi_subdevice * s)
1243 dio200_subdev_intr *subpriv = s->private;
1251 * Interrupt service routine.
1253 static irqreturn_t dio200_interrupt(int irq, void *d PT_REGS_ARG)
1255 comedi_device *dev = d;
1258 if (!dev->attached) {
1262 if (devpriv->intr_sd >= 0) {
1263 handled = dio200_handle_read_intr(dev,
1264 dev->subdevices + devpriv->intr_sd);
1269 return IRQ_RETVAL(handled);
1273 * Read an '8254' counter subdevice channel.
1275 static inline unsigned int
1276 dio200_subdev_8254_read_chan(comedi_device * dev, comedi_subdevice * s,
1279 unsigned int i8254_ofs = ((dio200_subdev_8254 *)s->private)->ofs;
1284 dio200_write8(dev, i8254_ofs + i8254_control_reg, val);
1287 val = dio200_read8(dev, i8254_ofs + chan);
1289 val += dio200_read8(dev, i8254_ofs + chan) << 8;
1295 * Write an '8254' counter subdevice channel.
1298 dio200_subdev_8254_write_chan(comedi_device * dev, comedi_subdevice * s,
1299 unsigned int chan, unsigned int count)
1301 unsigned int i8254_ofs = ((dio200_subdev_8254 *)s->private)->ofs;
1304 dio200_write8(dev, i8254_ofs + chan, count & 0xff);
1306 dio200_write8(dev, i8254_ofs + chan, (count >> 8) & 0xff);
1310 * Set mode of an '8254' counter subdevice channel.
1313 dio200_subdev_8254_set_mode(comedi_device * dev, comedi_subdevice * s,
1314 unsigned int chan, unsigned int mode)
1316 unsigned int i8254_ofs = ((dio200_subdev_8254 *)s->private)->ofs;
1320 byte |= 0x30; /* load lsb then msb */
1321 byte |= (mode & 0xf); /* set counter mode and BCD|binary */
1322 dio200_write8(dev, i8254_ofs + i8254_control_reg, byte);
1326 * Read status byte of an '8254' counter subdevice channel.
1328 static inline unsigned int
1329 dio200_subdev_8254_status(comedi_device * dev, comedi_subdevice * s,
1332 unsigned int i8254_ofs = ((dio200_subdev_8254 *)s->private)->ofs;
1334 dio200_write8(dev, i8254_ofs + i8254_control_reg, (0xE0 | 2 << chan));
1335 return dio200_read8(dev, i8254_ofs + chan);
1339 * Handle 'insn_read' for an '8254' counter subdevice.
1342 dio200_subdev_8254_read(comedi_device * dev, comedi_subdevice * s,
1343 comedi_insn * insn, lsampl_t * data)
1345 dio200_subdev_8254 *subpriv = s->private;
1346 int chan = CR_CHAN(insn->chanspec);
1347 unsigned long flags;
1352 comedi_spin_lock_irqsave(&subpriv->spinlock, flags);
1353 data[0] = dio200_subdev_8254_read_chan(dev, s, chan);
1354 comedi_spin_unlock_irqrestore(&subpriv->spinlock, flags);
1360 * Handle 'insn_write' for an '8254' counter subdevice.
1363 dio200_subdev_8254_write(comedi_device * dev, comedi_subdevice * s,
1364 comedi_insn * insn, lsampl_t * data)
1366 dio200_subdev_8254 *subpriv = s->private;
1367 int chan = CR_CHAN(insn->chanspec);
1368 unsigned long flags;
1373 comedi_spin_lock_irqsave(&subpriv->spinlock, flags);
1374 dio200_subdev_8254_write_chan(dev, s, chan, data[0]);
1375 comedi_spin_unlock_irqrestore(&subpriv->spinlock, flags);
1381 * Set gate source for an '8254' counter subdevice channel.
1384 dio200_subdev_8254_set_gate_src(comedi_device * dev, comedi_subdevice *s,
1385 unsigned int counter_number, unsigned int gate_src)
1387 dio200_subdev_8254 *subpriv = s->private;
1390 if (!thislayout->has_clk_gat_sce)
1392 if (counter_number > 2)
1394 if (gate_src > (thislayout->has_enhancements ? 31 : 7))
1397 subpriv->gate_src[counter_number] = gate_src;
1398 byte = GAT_SCE(subpriv->which, counter_number, gate_src);
1399 dio200_write8(dev, subpriv->gat_sce_ofs, byte);
1405 * Get gate source for an '8254' counter subdevice channel.
1408 dio200_subdev_8254_get_gate_src(comedi_device * dev, comedi_subdevice *s,
1409 unsigned int counter_number)
1411 dio200_subdev_8254 *subpriv = s->private;
1413 if (!thislayout->has_clk_gat_sce)
1415 if (counter_number > 2)
1418 return subpriv->gate_src[counter_number];
1422 * Set clock source for an '8254' counter subdevice channel.
1425 dio200_subdev_8254_set_clock_src(comedi_device * dev, comedi_subdevice *s,
1426 unsigned int counter_number, unsigned int clock_src)
1428 dio200_subdev_8254 *subpriv = s->private;
1431 if (!thislayout->has_clk_gat_sce)
1433 if (counter_number > 2)
1435 if (clock_src > (thislayout->has_enhancements ? 31 : 7))
1438 subpriv->clock_src[counter_number] = clock_src;
1439 byte = CLK_SCE(subpriv->which, counter_number, clock_src);
1440 dio200_write8(dev, subpriv->clk_sce_ofs, byte);
1446 * Get clock source for an '8254' counter subdevice channel.
1449 dio200_subdev_8254_get_clock_src(comedi_device * dev, comedi_subdevice *s,
1450 unsigned int counter_number, lsampl_t * period_ns)
1452 dio200_subdev_8254 *subpriv = s->private;
1455 if (!thislayout->has_clk_gat_sce)
1457 if (counter_number > 2)
1460 clock_src = subpriv->clock_src[counter_number];
1461 *period_ns = clock_period[clock_src];
1466 * Handle 'insn_config' for an '8254' counter subdevice.
1469 dio200_subdev_8254_config(comedi_device * dev, comedi_subdevice * s,
1470 comedi_insn * insn, lsampl_t * data)
1472 dio200_subdev_8254 *subpriv = s->private;
1474 int chan = CR_CHAN(insn->chanspec);
1475 unsigned long flags;
1477 comedi_spin_lock_irqsave(&subpriv->spinlock, flags);
1479 case INSN_CONFIG_SET_COUNTER_MODE:
1480 if (data[1] > (I8254_MODE5 | I8254_BINARY))
1483 dio200_subdev_8254_set_mode(dev, s, chan, data[1]);
1485 case INSN_CONFIG_8254_READ_STATUS:
1486 data[1] = dio200_subdev_8254_status(dev, s, chan);
1488 case INSN_CONFIG_SET_GATE_SRC:
1489 ret = dio200_subdev_8254_set_gate_src(dev, s, chan, data[2]);
1493 case INSN_CONFIG_GET_GATE_SRC:
1494 ret = dio200_subdev_8254_get_gate_src(dev, s, chan);
1501 case INSN_CONFIG_SET_CLOCK_SRC:
1502 ret = dio200_subdev_8254_set_clock_src(dev, s, chan, data[1]);
1506 case INSN_CONFIG_GET_CLOCK_SRC:
1507 ret = dio200_subdev_8254_get_clock_src(dev, s, chan, &data[2]);
1518 comedi_spin_unlock_irqrestore(&subpriv->spinlock, flags);
1519 return ret < 0 ? ret : insn->n;
1523 * This function initializes an '8254' counter subdevice.
1525 * offset is the offset to the 8254 chip.
1528 dio200_subdev_8254_init(comedi_device * dev, comedi_subdevice * s,
1529 unsigned int offset)
1531 dio200_subdev_8254 *subpriv;
1534 subpriv = kzalloc(sizeof(*subpriv), GFP_KERNEL);
1536 printk(KERN_ERR "comedi%d: error! out of memory!\n",
1541 s->private = subpriv;
1542 s->type = COMEDI_SUBD_COUNTER;
1543 s->subdev_flags = SDF_WRITABLE | SDF_READABLE;
1545 s->maxdata = 0xFFFF;
1546 s->insn_read = dio200_subdev_8254_read;
1547 s->insn_write = dio200_subdev_8254_write;
1548 s->insn_config = dio200_subdev_8254_config;
1550 spin_lock_init(&subpriv->spinlock);
1551 subpriv->ofs = offset;
1552 if (thislayout->has_clk_gat_sce) {
1553 /* Derive CLK_SCE and GAT_SCE register offsets from
1555 subpriv->clk_sce_ofs =
1556 DIO200_XCLK_SCE + (offset >> 3);
1557 subpriv->gat_sce_ofs =
1558 DIO200_XGAT_SCE + (offset >> 3);
1559 subpriv->which = (offset >> 2) & 1;
1562 /* Initialize channels. */
1563 for (chan = 0; chan < 3; chan++) {
1564 dio200_subdev_8254_set_mode(dev, s, chan,
1565 (I8254_MODE0 | I8254_BINARY));
1566 if (thislayout->has_clk_gat_sce) {
1567 /* Gate source 0 is VCC (logic 1). */
1568 dio200_subdev_8254_set_gate_src(dev, s, chan, 0);
1569 /* Clock source 0 is the dedicated clock input. */
1570 dio200_subdev_8254_set_clock_src(dev, s, chan, 0);
1578 * This function cleans up an '8254' counter subdevice.
1581 dio200_subdev_8254_cleanup(comedi_device * dev, comedi_subdevice * s)
1583 dio200_subdev_8254 *subpriv = s->private;
1591 * This function sets I/O directions for an '8255' DIO subdevice.
1594 dio200_subdev_8255_set_dir(comedi_device * dev, comedi_subdevice * s)
1596 dio200_subdev_8255 *subpriv = s->private;
1600 /* 1 in io_bits indicates output, 1 in config indicates input */
1601 if (!(s->io_bits & 0x0000ff))
1603 if (!(s->io_bits & 0x00ff00))
1605 if (!(s->io_bits & 0x0f0000))
1606 config |= CR_C_LO_IO;
1607 if (!(s->io_bits & 0xf00000))
1608 config |= CR_C_HI_IO;
1610 dio200_write8(dev, subpriv->ofs + 3, config);
1614 * Handle 'insn_bits' for an '8255' DIO subdevice.
1617 dio200_subdev_8255_bits(comedi_device * dev, comedi_subdevice * s,
1618 comedi_insn * insn, lsampl_t * data)
1620 unsigned int i8255_ofs = ((dio200_subdev_8255 *)s->private)->ofs;
1623 s->state &= ~data[0];
1624 s->state |= (data[0] & data[1]);
1626 if (data[0] & 0xff) {
1627 dio200_write8(dev, i8255_ofs, s->state & 0xff);
1629 if (data[0] & 0xff00) {
1630 dio200_write8(dev, i8255_ofs + 1,
1631 (s->state >> 8) & 0xff);
1633 if (data[0] & 0xff0000) {
1634 dio200_write8(dev, i8255_ofs + 2,
1635 (s->state >> 16) & 0xff);
1639 data[1] = dio200_read8(dev, i8255_ofs);
1640 data[1] |= dio200_read8(dev, i8255_ofs + 1) << 8;
1641 data[1] |= dio200_read8(dev, i8255_ofs + 2) << 16;
1647 * Handle 'insn_config' for an '8255' DIO subdevice.
1650 dio200_subdev_8255_config(comedi_device * dev, comedi_subdevice * s,
1651 comedi_insn * insn, lsampl_t * data)
1656 mask = 1 << CR_CHAN(insn->chanspec);
1657 if (mask & 0x0000ff) {
1659 } else if (mask & 0x00ff00) {
1661 } else if (mask & 0x0f0000) {
1668 case INSN_CONFIG_DIO_INPUT:
1669 s->io_bits &= ~bits;
1671 case INSN_CONFIG_DIO_OUTPUT:
1674 case INSN_CONFIG_DIO_QUERY:
1675 data[1] = (s->io_bits & bits) ? COMEDI_OUTPUT : COMEDI_INPUT;
1682 dio200_subdev_8255_set_dir(dev, s);
1688 * This function initializes an '8255' DIO subdevice.
1690 * offset is the offset to the 8255 chip.
1693 dio200_subdev_8255_init(comedi_device * dev, comedi_subdevice * s,
1694 unsigned int offset)
1696 dio200_subdev_8255 *subpriv;
1698 subpriv = kzalloc(sizeof(*subpriv), GFP_KERNEL);
1700 printk(KERN_ERR "comedi%d: error! out of memory!\n",
1705 subpriv->ofs = offset;
1707 s->private = subpriv;
1708 s->type = COMEDI_SUBD_DIO;
1709 s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
1711 s->range_table = &range_digital;
1713 s->insn_bits = dio200_subdev_8255_bits;
1714 s->insn_config = dio200_subdev_8255_config;
1718 dio200_subdev_8255_set_dir(dev, s);
1724 * This function cleans up an '8255' DIO subdevice.
1727 dio200_subdev_8255_cleanup(comedi_device * dev, comedi_subdevice * s)
1729 dio200_subdev_8255 *subpriv = s->private;
1737 * Handle 'insn_read' for a timer subdevice.
1739 #ifdef CONFIG_COMEDI_PCI
1741 dio200_subdev_timer_read(comedi_device * dev, comedi_subdevice * s,
1742 comedi_insn * insn, lsampl_t * data)
1746 for (n = 0; n < insn->n; n++) {
1747 data[n] = dio200_read32(dev, DIO200_TS_COUNT);
1754 * Reset timer subdevice.
1756 #ifdef CONFIG_COMEDI_PCI
1758 dio200_subdev_timer_reset(comedi_device * dev, comedi_subdevice * s)
1762 clock = dio200_read32(dev, DIO200_TS_CONFIG) & TS_CONFIG_CLK_SRC_MASK;
1763 dio200_write32(dev, DIO200_TS_CONFIG, clock | TS_CONFIG_RESET);
1764 dio200_write32(dev, DIO200_TS_CONFIG, clock);
1769 * Get timer subdevice clock source and period.
1771 #ifdef CONFIG_COMEDI_PCI
1773 dio200_subdev_timer_get_clock_src(comedi_device * dev, comedi_subdevice * s,
1774 lsampl_t *src, lsampl_t *period)
1778 clk = dio200_read32(dev, DIO200_TS_CONFIG) & TS_CONFIG_CLK_SRC_MASK;
1780 *period = (clk < ARRAY_SIZE(ts_clock_period))
1781 ? ts_clock_period[clk] : 0;
1786 * Set timer subdevice clock source.
1788 #ifdef CONFIG_COMEDI_PCI
1790 dio200_subdev_timer_set_clock_src(comedi_device * dev, comedi_subdevice * s,
1793 if (src > TS_CONFIG_MAX_CLK_SRC) {
1796 dio200_write32(dev, DIO200_TS_CONFIG, src);
1802 * Handle 'insn_config' for a timer subdevice.
1804 #ifdef CONFIG_COMEDI_PCI
1806 dio200_subdev_timer_config(comedi_device * dev, comedi_subdevice * s,
1807 comedi_insn * insn, lsampl_t * data)
1812 case INSN_CONFIG_RESET:
1813 dio200_subdev_timer_reset(dev, s);
1815 case INSN_CONFIG_SET_CLOCK_SRC:
1816 ret = dio200_subdev_timer_set_clock_src(dev, s, data[1]);
1820 case INSN_CONFIG_GET_CLOCK_SRC:
1821 dio200_subdev_timer_get_clock_src(dev, s, &data[1], &data[2]);
1827 return ret < 0 ? ret : insn->n;
1832 * This function initializes a timer subdevice.
1834 * Uses the timestamp timer registers. There is only one timestamp timer.
1836 #ifdef CONFIG_COMEDI_PCI
1838 dio200_subdev_timer_init(comedi_device * dev, comedi_subdevice * s)
1840 s->type = COMEDI_SUBD_TIMER;
1841 s->subdev_flags = SDF_READABLE | SDF_LSAMPL;
1843 s->maxdata = 0xFFFFFFFF;
1844 s->insn_read = dio200_subdev_timer_read;
1845 s->insn_config = dio200_subdev_timer_config;
1851 * This function cleans up a timer subdevice.
1853 #ifdef CONFIG_COMEDI_PCI
1855 dio200_subdev_timer_cleanup(comedi_device * dev, comedi_subdevice * s)
1857 /* Nothing to do. */
1861 #ifdef CONFIG_COMEDI_PCI
1863 * This function does some special set-up for the PCIe boards
1864 * PCIe215, PCIe236, PCIe296.
1867 dio200_pcie_board_setup(comedi_device * dev)
1869 struct pci_dev *pci_dev = devpriv->pci_dev;
1870 unsigned char __iomem *brbase;
1871 resource_size_t brlen;
1874 * The board uses Altera Cyclone IV with PCI-Express hard IP.
1875 * The FPGA configuration has the PCI-Express Avalon-MM Bridge
1876 * Control registers in PCI BAR 0, offset 0, and the length of
1877 * these registers is 0x4000.
1879 * We need to write 0x80 to the "Avalon-MM to PCI-Express Interrupt
1880 * Enable" register at offset 0x50 to allow generation of PCIe
1881 * interrupts when RXmlrq_i is asserted in the SOPC Builder system.
1883 brlen = pci_resource_len(pci_dev, 0);
1884 if (brlen < 0x4000 ||
1885 !(pci_resource_flags(pci_dev, 0) & IORESOURCE_MEM)) {
1886 printk(KERN_ERR "comedi%d: error! bad PCI region!\n",
1890 brbase = ioremap_nocache(pci_resource_start(pci_dev, 0), brlen);
1892 printk(KERN_ERR "comedi%d: error! failed to map registers!\n",
1896 writel(0x80, brbase + 0x50);
1899 * Enable "enhanced" features of board.
1901 dio200_write8(dev, DIO200_ENHANCE, 1);
1907 * Attach is called by the Comedi core to configure the driver
1908 * for a particular board. If you specified a board_name array
1909 * in the driver structure, dev->board_ptr contains that
1912 static int dio200_attach(comedi_device * dev, comedi_devconfig * it)
1914 comedi_subdevice *s;
1915 unsigned long iobase = 0;
1916 unsigned int irq = 0;
1917 #ifdef CONFIG_COMEDI_PCI
1918 struct pci_dev *pci_dev = NULL;
1919 int bus = 0, slot = 0;
1921 const dio200_layout *layout;
1927 printk(KERN_DEBUG "comedi%d: %s: attach\n", dev->minor,
1928 DIO200_DRIVER_NAME);
1930 if ((ret = alloc_private(dev, sizeof(dio200_private))) < 0) {
1931 printk(KERN_ERR "comedi%d: error! out of memory!\n",
1936 /* Process options. */
1937 switch (thisboard->bustype) {
1939 iobase = it->options[0];
1940 irq = it->options[1];
1943 #ifdef CONFIG_COMEDI_PCI
1945 bus = it->options[0];
1946 slot = it->options[1];
1949 if ((ret = dio200_find_pci(dev, bus, slot, &pci_dev)) < 0)
1951 devpriv->pci_dev = pci_dev;
1956 "comedi%d: %s: BUG! cannot determine board type!\n",
1957 dev->minor, DIO200_DRIVER_NAME);
1962 devpriv->intr_sd = -1;
1963 devpriv->io.regtype = no_regtype;
1964 devpriv->io.regshift = thisboard->mainshift;
1966 /* Enable device and reserve I/O spaces. */
1967 #ifdef CONFIG_COMEDI_PCI
1969 resource_size_t base, len;
1972 ret = comedi_pci_enable(pci_dev, DIO200_DRIVER_NAME);
1975 "comedi%d: error! cannot enable PCI device and request regions!\n",
1979 bar = thisboard->mainbar;
1980 base = pci_resource_start(pci_dev, bar);
1981 len = pci_resource_len(pci_dev, bar);
1982 if (len < thisboard->mainsize) {
1984 "comedi%d: error! PCI region size too small!\n",
1988 if ((pci_resource_flags(pci_dev, bar) & IORESOURCE_MEM) != 0) {
1989 devpriv->io.u.membase = ioremap_nocache(base, len);
1990 if (!devpriv->io.u.membase) {
1992 "comedi%d: error! cannot remap registers!\n",
1996 devpriv->io.regtype = mmio_regtype;
1998 devpriv->io.u.iobase = (unsigned long)base;
1999 devpriv->io.regtype = io_regtype;
2005 ret = dio200_request_region(dev->minor, iobase,
2006 thisboard->mainsize);
2010 devpriv->io.u.iobase = iobase;
2011 devpriv->io.regtype = io_regtype;
2014 switch (thisboard->model) {
2015 #ifdef CONFIG_COMEDI_PCI
2019 ret = dio200_pcie_board_setup(dev);
2029 layout = thislayout;
2030 if ((ret = alloc_subdevices(dev, layout->n_subdevs)) < 0) {
2031 printk(KERN_ERR "comedi%d: error! out of memory!\n",
2036 for (n = 0; n < dev->n_subdevices; n++) {
2037 s = &dev->subdevices[n];
2038 switch (layout->sdtype[n]) {
2040 /* counter subdevice (8254) */
2041 ret = dio200_subdev_8254_init(dev, s,
2048 /* digital i/o subdevice (8255) */
2049 ret = dio200_subdev_8255_init(dev, s,
2056 /* 'INTERRUPT' subdevice */
2058 ret = dio200_subdev_intr_init(dev, s,
2059 DIO200_INT_SCE, layout->sdinfo[n]);
2063 devpriv->intr_sd = n;
2065 s->type = COMEDI_SUBD_UNUSED;
2069 /* timer subdevice */
2070 #ifdef CONFIG_COMEDI_PCI
2071 ret = dio200_subdev_timer_init(dev, s);
2076 s->type = COMEDI_SUBD_UNUSED;
2080 s->type = COMEDI_SUBD_UNUSED;
2085 sdx = devpriv->intr_sd;
2086 if (sdx >= 0 && sdx < dev->n_subdevices) {
2087 dev->read_subdev = &dev->subdevices[sdx];
2090 dev->board_name = thisboard->name;
2093 unsigned long flags = share_irq ? IRQF_SHARED : 0;
2095 if (comedi_request_irq(irq, dio200_interrupt, flags,
2096 DIO200_DRIVER_NAME, dev) >= 0) {
2100 "comedi%d: warning! irq %u unavailable!\n",
2105 printk(KERN_INFO "comedi%d: %s ", dev->minor, dev->board_name);
2106 if (thisboard->bustype == isa_bustype) {
2107 printk("(base %#lx) ", iobase);
2109 #ifdef CONFIG_COMEDI_PCI
2110 printk("(pci %s) ", pci_name(pci_dev));
2114 printk("(irq %u%s) ", irq, (dev->irq ? "" : " UNAVAILABLE"));
2116 printk("(no irq) ");
2119 printk("attached\n");
2125 * _detach is called to deconfigure a device. It should deallocate
2127 * This function is also called when _attach() fails, so it should be
2128 * careful not to release resources that were not necessarily
2129 * allocated by _attach(). dev->private and dev->subdevices are
2130 * deallocated automatically by the core.
2132 static int dio200_detach(comedi_device * dev)
2134 const dio200_layout *layout;
2137 printk(KERN_DEBUG "comedi%d: %s: detach\n", dev->minor,
2138 DIO200_DRIVER_NAME);
2141 comedi_free_irq(dev->irq, dev);
2143 if (dev->subdevices) {
2144 layout = thislayout;
2145 for (n = 0; n < dev->n_subdevices; n++) {
2146 comedi_subdevice *s = &dev->subdevices[n];
2147 switch (layout->sdtype[n]) {
2149 dio200_subdev_8254_cleanup(dev, s);
2152 dio200_subdev_8255_cleanup(dev, s);
2155 dio200_subdev_intr_cleanup(dev, s);
2158 #ifdef CONFIG_COMEDI_PCI
2159 dio200_subdev_timer_cleanup(dev, s);
2168 if (devpriv->io.regtype == mmio_regtype) {
2169 iounmap(devpriv->io.u.membase);
2171 #ifdef CONFIG_COMEDI_PCI
2172 if (devpriv->pci_dev) {
2173 if (devpriv->io.regtype != no_regtype) {
2174 comedi_pci_disable(devpriv->pci_dev);
2176 pci_dev_put(devpriv->pci_dev);
2180 if (devpriv->io.regtype == io_regtype) {
2181 release_region(devpriv->io.u.iobase,
2182 thisboard->mainsize);
2186 if (dev->board_name) {
2187 printk(KERN_INFO "comedi%d: %s removed\n",
2188 dev->minor, dev->board_name);