2 comedi/drivers/amplc_dio200.c
3 Driver for Amplicon PC272E and PCI272 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 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.
28 Driver: amplc_dio200.o
29 Description: Amplicon PC272E, PCI272
30 Author: Ian Abbott <abbotti@mev.co.uk>
31 Devices: [Amplicon] PC212E (pc212e), PC214E (pc214e), PC215E (pc215e),
32 PCI215 (pci215), PC218E (pc218e), PC272E (pc272e), PCI272 (pci272)
33 Updated: Fri, 07 Oct 2005 16:59:59 +0100
36 Configuration options - PC212E, PC214E, PC215E, PC218E, PC272E:
37 [0] - I/O port base address
38 [1] - IRQ (optional, but commands won't work without it)
40 Configuration options - PCI215, PCI272:
41 [0] - PCI bus of device (optional)
42 [1] - PCI slot of device (optional)
43 If bus/slot is not specified, the first available PCI device will
46 Passing a zero for an option is the same as leaving it unspecified.
51 PC218E PC212E PC215E/PCI215
52 ------------- ------------- -------------
56 2 CTR-Y1 CTR-Y2 CTR-Z1
57 3 CTR-Y2 CTR-Z1 CTR-Z2
58 4 CTR-Z1 CTR-Z2 INTERRUPT
63 ------------- -------------
68 3 INTERRUPT* INTERRUPT
71 Each PPI is a 8255 chip providing 24 DIO channels. The DIO channels
72 are configurable as inputs or outputs in four groups:
74 Port A - channels 0 to 7
75 Port B - channels 8 to 15
76 Port CL - channels 16 to 19
77 Port CH - channels 20 to 23
79 Only mode 0 of the 8255 chips is supported.
81 Each CTR is a 8254 chip providing 3 16-bit counter channels. Each
82 channel is configured individually with INSN_CONFIG instructions. The
83 specific type of configuration instruction is specified in data[0].
84 Some configuration instructions expect an additional parameter in
85 data[1]; others return a value in data[1]. The following configuration
86 instructions are supported:
88 INSN_CONFIG_8254_SET_MODE. Sets the counter channel's mode and
89 BCD/binary setting specified in data[1].
91 INSN_CONFIG_8254_READ_STATUS. Reads the status register value for the
92 counter channel into data[1].
94 INSN_CONFIG_SET_CLOCK_SRC. Sets the counter channel's clock source as
95 specified in data[1] (this is a hardware-specific value). Not
96 supported on PC214E. For the other boards, valid clock sources are
99 0. CLK n, the counter channel's dedicated CLK input from the SK1
100 connector. (N.B. for other values, the counter channel's CLKn
101 pin on the SK1 connector is an output!)
102 1. Internal 10 MHz clock.
103 2. Internal 1 MHz clock.
104 3. Internal 100 kHz clock.
105 4. Internal 10 kHz clock.
106 5. Internal 1 kHz clock.
107 6. OUT n-1, the output of counter channel n-1 (see note 1 below).
108 7. Ext Clock, the counter chip's dedicated Ext Clock input from
109 the SK1 connector. This pin is shared by all three counter
110 channels on the chip.
112 INSN_CONFIG_GET_CLOCK_SRC. Returns the counter channel's current
113 clock source in data[1].
115 INSN_CONFIG_SET_GATE_SRC. Sets the counter channel's gate source as
116 specified in data[1] (this is a hardware-specific value). Not
117 supported on PC214E. For the other boards, valid gate sources are 0
120 0. VCC (internal +5V d.c.), i.e. gate permanently enabled.
121 1. GND (internal 0V d.c.), i.e. gate permanently disabled.
122 2. GAT n, the counter channel's dedicated GAT input from the SK1
123 connector. (N.B. for other values, the counter channel's GATn
124 pin on the SK1 connector is an output!)
125 3. /OUT n-2, the inverted output of counter channel n-2 (see note
132 INSN_CONFIG_GET_GATE_SRC. Returns the counter channel's current gate
135 Clock and gate interconnection notes:
137 1. Clock source OUT n-1 is the output of the preceding channel on the
138 same counter subdevice if n > 0, or the output of channel 2 on the
139 preceding counter subdevice (see note 3) if n = 0.
141 2. Gate source /OUT n-2 is the inverted output of channel 0 on the
142 same counter subdevice if n = 2, or the inverted output of channel n+1
143 on the preceding counter subdevice (see note 3) if n < 2.
145 3. The counter subdevices are connected in a ring, so the highest
146 counter subdevice precedes the lowest.
148 The 'INTERRUPT' subdevice pretends to be a digital input subdevice. The
149 digital inputs come from the interrupt status register. The number of
150 channels matches the number of interrupt sources. The PC214E does not
151 have an interrupt status register; see notes on 'INTERRUPT SOURCES'
157 PC218E PC212E PC215E/PCI215
158 ------------- ------------- -------------
160 0 CTR-X1-OUT PPI-X-C0 PPI-X-C0
161 1 CTR-X2-OUT PPI-X-C3 PPI-X-C3
162 2 CTR-Y1-OUT CTR-Y1-OUT PPI-Y-C0
163 3 CTR-Y2-OUT CTR-Y2-OUT PPI-Y-C3
164 4 CTR-Z1-OUT CTR-Z1-OUT CTR-Z1-OUT
165 5 CTR-Z2-OUT CTR-Z2-OUT CTR-Z2-OUT
168 ------------- -------------
177 When an interrupt source is enabled in the interrupt source enable
178 register, a rising edge on the source signal latches the corresponding
179 bit to 1 in the interrupt status register.
181 When the interrupt status register value as a whole (actually, just the
182 6 least significant bits) goes from zero to non-zero, the board will
183 generate an interrupt. For level-triggered hardware interrupts (PCI
184 card), the interrupt will remain asserted until the interrupt status
185 register is cleared to zero. For edge-triggered hardware interrupts
186 (ISA card), no further interrupts will occur until the interrupt status
187 register is cleared to zero. To clear a bit to zero in the interrupt
188 status register, the corresponding interrupt source must be disabled
189 in the interrupt source enable register (there is no separate interrupt
192 The PC214E does not have an interrupt source enable register or an
193 interrupt status register; its 'INTERRUPT' subdevice has a single
194 channel and its interrupt source is selected by the position of jumper
200 The driver supports a read streaming acquisition command on the
201 'INTERRUPT' subdevice. The channel list selects the interrupt sources
202 to be enabled. All channels will be sampled together (convert_src ==
203 TRIG_NOW). The scan begins a short time after the hardware interrupt
204 occurs, subject to interrupt latencies (scan_begin_src == TRIG_EXT,
205 scan_begin_arg == 0). The value read from the interrupt status register
206 is packed into a sampl_t value, one bit per requested channel, in the
207 order they appear in the channel list.
210 #include <linux/comedidev.h>
212 #include <linux/pci.h>
217 #define DIO200_DRIVER_NAME "amplc_dio200"
220 /* #define PCI_VENDOR_ID_AMPLICON 0x14dc */
221 #define PCI_DEVICE_ID_AMPLICON_PCI272 0x000a
222 #define PCI_DEVICE_ID_AMPLICON_PCI215 0x000b
224 /* 200 series registers */
225 #define DIO200_IO_SIZE 0x20
226 #define DIO200_XCLK_SCE 0x18 /* Group X clock selection register */
227 #define DIO200_YCLK_SCE 0x19 /* Group Y clock selection register */
228 #define DIO200_ZCLK_SCE 0x1a /* Group Z clock selection register */
229 #define DIO200_XGAT_SCE 0x1b /* Group X gate selection register */
230 #define DIO200_YGAT_SCE 0x1c /* Group Y gate selection register */
231 #define DIO200_ZGAT_SCE 0x1d /* Group Z gate selection register */
232 #define DIO200_INT_SCE 0x1e /* Interrupt enable/status register */
235 * Macros for constructing value for DIO_200_?CLK_SCE and
236 * DIO_200_?GAT_SCE registers:
238 * 'which' is: 0 for CTR-X1, CTR-Y1, CTR-Z1; 1 for CTR-X2, CTR-Y2 or CTR-Z2.
239 * 'chan' is the channel: 0, 1 or 2.
240 * 'source' is the signal source: 0 to 7.
242 #define CLK_SCE(which, chan, source) (((which) << 5) | ((chan) << 3) | (source))
243 #define GAT_SCE(which, chan, source) (((which) << 5) | ((chan) << 3) | (source))
246 * Board descriptions.
249 enum dio200_bustype { isa_bustype, pci_bustype };
254 pc215e_model, pci215_model,
256 pc272e_model, pci272_model
267 typedef struct dio200_board_struct {
269 enum dio200_bustype bustype;
270 enum dio200_model model;
271 enum dio200_layout layout;
274 static dio200_board dio200_boards[] = {
277 bustype: isa_bustype,
279 layout: pc212_layout,
283 bustype: isa_bustype,
285 layout: pc214_layout,
289 bustype: isa_bustype,
291 layout: pc215_layout,
295 bustype: pci_bustype,
297 layout: pc215_layout,
301 bustype: isa_bustype,
303 layout: pc218_layout,
307 bustype: isa_bustype,
309 layout: pc272_layout,
313 bustype: pci_bustype,
315 layout: pc272_layout,
320 * Layout descriptions - some ISA and PCI board descriptions share the same
324 enum dio200_sdtype { sd_none, sd_intr, sd_8255, sd_8254 };
326 #define DIO200_MAX_SUBDEVS 7
327 #define DIO200_MAX_ISNS 6
329 typedef struct dio200_layout_struct {
330 unsigned short n_subdevs; /* number of subdevices */
331 unsigned char sdtype[DIO200_MAX_SUBDEVS]; /* enum dio200_sdtype */
332 unsigned char sdinfo[DIO200_MAX_SUBDEVS]; /* depends on sdtype */
333 char has_int_sce; /* has interrupt enable/status register */
334 char has_clk_gat_sce; /* has clock/gate selection registers */
337 static dio200_layout dio200_layouts[] = {
340 sdtype: { sd_8255, sd_8254, sd_8254, sd_8254, sd_8254, sd_intr },
341 sdinfo: { 0x00, 0x08, 0x0C, 0x10, 0x14, 0x3F },
347 sdtype: { sd_8255, sd_8255, sd_8254, sd_intr },
348 sdinfo: { 0x00, 0x08, 0x10, 0x01 },
354 sdtype: { sd_8255, sd_8255, sd_8254, sd_8254, sd_intr },
355 sdinfo: { 0x00, 0x08, 0x10, 0x14, 0x3F },
361 sdtype: { sd_8254, sd_8254, sd_8255, sd_8254, sd_8254, sd_intr },
362 sdinfo: { 0x00, 0x04, 0x08, 0x0C, 0x10, 0x14, 0x3F },
368 sdtype: { sd_8255, sd_8255, sd_8255, sd_intr },
369 sdinfo: { 0x00, 0x08, 0x10, 0x3F },
379 static struct pci_device_id dio200_pci_table[] __devinitdata = {
380 { PCI_VENDOR_ID_AMPLICON, PCI_DEVICE_ID_AMPLICON_PCI215,
381 PCI_ANY_ID, PCI_ANY_ID, 0, 0, pci215_model },
382 { PCI_VENDOR_ID_AMPLICON, PCI_DEVICE_ID_AMPLICON_PCI272,
383 PCI_ANY_ID, PCI_ANY_ID, 0, 0, pci272_model },
386 MODULE_DEVICE_TABLE(pci, dio200_pci_table);
389 * Useful for shorthand access to the particular board structure
391 #define thisboard ((dio200_board *)dev->board_ptr)
392 #define thislayout (&dio200_layouts[((dio200_board *)dev->board_ptr)->layout])
394 /* this structure is for data unique to this hardware driver. If
395 several hardware drivers keep similar information in this structure,
396 feel free to suggest moving the variable to the comedi_device struct. */
398 struct pci_dev *pci_dev; /* PCI device */
402 #define devpriv ((dio200_private *)dev->private)
405 unsigned long iobase; /* Counter base address */
406 unsigned long clk_sce_iobase; /* CLK_SCE base address */
407 unsigned long gat_sce_iobase; /* GAT_SCE base address */
408 int which; /* Bit 5 of CLK_SCE or GAT_SCE */
410 unsigned clock_src[3]; /* Current clock sources */
411 unsigned gate_src[3]; /* Current gate sources */
412 } dio200_subdev_8254;
415 unsigned long iobase;
419 unsigned int valid_isns;
420 unsigned int enabled_isns;
421 unsigned int stopcount;
423 } dio200_subdev_intr;
427 * The comedi_driver structure tells the Comedi core module
428 * which functions to call to configure/deconfigure (attach/detach)
429 * the board, and also about the kernel module that contains
432 static int dio200_attach(comedi_device *dev,comedi_devconfig *it);
433 static int dio200_detach(comedi_device *dev);
434 static comedi_driver driver_amplc_dio200 = {
435 driver_name: DIO200_DRIVER_NAME,
437 attach: dio200_attach,
438 detach: dio200_detach,
439 board_name: dio200_boards,
440 offset: sizeof(dio200_board),
441 num_names: sizeof(dio200_boards) / sizeof(dio200_board),
443 COMEDI_INITCLEANUP(driver_amplc_dio200);
446 * This function looks for a PCI device matching the requested board name,
450 dio200_find_pci(comedi_device *dev, int bus, int slot,
451 struct pci_dev **pci_dev_p)
453 struct pci_dev *pci_dev = NULL;
454 struct pci_device_id *pci_id;
458 /* Look for PCI table entry for this model. */
459 for (pci_id = dio200_pci_table; pci_id->vendor != 0; pci_id++) {
460 if (pci_id->driver_data == thisboard->model)
463 if (pci_id->vendor == 0) {
464 printk(KERN_ERR "comedi%d: %s: BUG! cannot determine board type!\n",
465 dev->minor, DIO200_DRIVER_NAME);
469 /* Look for matching PCI device. */
470 for(pci_dev = pci_get_device(pci_id->vendor, pci_id->device, NULL);
472 pci_dev = pci_get_device(pci_id->vendor,
473 pci_id->device, pci_dev)) {
474 /* If bus/slot specified, check them. */
476 if (bus != pci_dev->bus->number
477 || slot != PCI_SLOT(pci_dev->devfn))
481 if (pci_id->subvendor != PCI_ANY_ID) {
482 if (pci_dev->subsystem_vendor != pci_id->subvendor)
485 if (pci_id->subdevice != PCI_ANY_ID) {
486 if (pci_dev->subsystem_device != pci_id->subdevice)
490 if (((pci_dev->class ^ pci_id->class) & pci_id->class_mask) != 0)
494 *pci_dev_p = pci_dev;
497 /* No match found. */
499 printk(KERN_ERR "comedi%d: error! no %s found at pci %02x:%02x!\n",
500 dev->minor, thisboard->name,
503 printk(KERN_ERR "comedi%d: error! no %s found!\n",
504 dev->minor, thisboard->name);
510 * This function checks and requests an I/O region, reporting an error
511 * if there is a conflict.
514 dio200_request_region(unsigned minor, unsigned long from, unsigned long extent)
516 if (!from || !request_region(from, extent, DIO200_DRIVER_NAME)) {
517 printk(KERN_ERR "comedi%d: I/O port conflict (%#lx,%lu)!\n",
518 minor, from, extent);
525 * 'insn_bits' function for an 'INTERRUPT' subdevice.
528 dio200_subdev_intr_insn_bits(comedi_device *dev, comedi_subdevice *s,
529 comedi_insn *insn, lsampl_t *data)
531 dio200_subdev_intr *subpriv = s->private;
533 if (subpriv->has_int_sce) {
534 /* Just read the interrupt status register. */
535 data[1] = inb(subpriv->iobase) & subpriv->valid_isns;
537 /* No interrupt status register. */
545 * Called to stop acquisition for an 'INTERRUPT' subdevice.
548 dio200_stop_intr(comedi_device *dev, comedi_subdevice *s)
550 dio200_subdev_intr *subpriv = s->private;
552 s->async->inttrig = 0;
554 subpriv->enabled_isns = 0;
555 if (subpriv->has_int_sce) {
556 outb(0, subpriv->iobase);
561 * Called to start acquisition for an 'INTERRUPT' subdevice.
564 dio200_start_intr(comedi_device *dev, comedi_subdevice *s)
568 dio200_subdev_intr *subpriv = s->private;
569 comedi_cmd *cmd = &s->async->cmd;
572 if (!subpriv->continuous && subpriv->stopcount == 0) {
573 /* An empty acquisition! */
574 s->async->events |= COMEDI_CB_EOA;
578 /* Determine interrupt sources to enable. */
581 for (n = 0; n < cmd->chanlist_len; n++) {
582 isn_bits |= (1U << CR_CHAN(cmd->chanlist[n]));
585 isn_bits &= subpriv->valid_isns;
586 /* Enable interrupt sources. */
587 subpriv->enabled_isns = isn_bits;
588 if (subpriv->has_int_sce) {
589 outb(isn_bits, subpriv->iobase);
597 * Internal trigger function to start acquisition for an 'INTERRUPT' subdevice.
600 dio200_inttrig_start_intr(comedi_device *dev, comedi_subdevice *s,
601 unsigned int trignum)
603 dio200_subdev_intr *subpriv;
607 if (trignum != 0) return -EINVAL;
609 subpriv = s->private;
611 comedi_spin_lock_irqsave(&subpriv->spinlock, flags);
612 s->async->inttrig = 0;
613 if (subpriv->active) {
614 event = dio200_start_intr(dev, s);
616 comedi_spin_unlock_irqrestore(&subpriv->spinlock, flags);
619 comedi_event(dev, s, s->async->events);
626 * This is called from the interrupt service routine to handle a read
627 * scan on an 'INTERRUPT' subdevice.
630 dio200_handle_read_intr(comedi_device *dev, comedi_subdevice *s)
632 dio200_subdev_intr *subpriv = s->private;
635 unsigned cur_enabled;
636 unsigned int oldevents;
641 comedi_spin_lock_irqsave(&subpriv->spinlock, flags);
642 oldevents = s->async->events;
643 if (subpriv->has_int_sce) {
645 * Collect interrupt sources that have triggered and disable
646 * them temporarily. Loop around until no extra interrupt
647 * sources have triggered, at which point, the valid part of
648 * the interrupt status register will read zero, clearing the
649 * cause of the interrupt.
651 * Mask off interrupt sources already seen to avoid infinite
652 * loop in case of misconfiguration.
654 cur_enabled = subpriv->enabled_isns;
655 while ((intstat = (inb(subpriv->iobase) & subpriv->valid_isns
656 & ~triggered)) != 0) {
657 triggered |= intstat;
658 cur_enabled &= ~triggered;
659 outb(cur_enabled, subpriv->iobase);
663 * No interrupt status register. Assume the single interrupt
664 * source has triggered.
666 triggered = subpriv->enabled_isns;
671 * Some interrupt sources have triggered and have been
672 * temporarily disabled to clear the cause of the interrupt.
674 * Reenable them NOW to minimize the time they are disabled.
676 cur_enabled = subpriv->enabled_isns;
677 if (subpriv->has_int_sce) {
678 outb(cur_enabled, subpriv->iobase);
681 if (subpriv->active) {
683 * The command is still active.
685 * Ignore interrupt sources that the command isn't
686 * interested in (just in case there's a race
689 if (triggered & subpriv->enabled_isns) {
690 /* Collect scan data. */
692 unsigned int n, ch, len;
695 len = s->async->cmd.chanlist_len;
696 for (n = 0; n < len; n++) {
697 ch = CR_CHAN(s->async->cmd.chanlist[n]);
698 if (triggered & (1U << ch)) {
702 /* Write the scan to the buffer. */
703 if (comedi_buf_put(s->async, val)) {
704 s->async->events |= (COMEDI_CB_BLOCK |
707 /* Error! Stop acquisition. */
708 dio200_stop_intr(dev, s);
711 /* Check for end of acquisition. */
712 if (!subpriv->continuous) {
713 /* stop_src == TRIG_COUNT */
714 if (subpriv->stopcount > 0) {
715 subpriv->stopcount--;
716 if (subpriv->stopcount == 0) {
719 dio200_stop_intr(dev, s);
726 comedi_spin_unlock_irqrestore(&subpriv->spinlock, flags);
728 if (oldevents != s->async->events) {
729 comedi_event(dev, s, s->async->events);
732 return (triggered != 0);
736 * 'cancel' function for an 'INTERRUPT' subdevice.
739 dio200_subdev_intr_cancel(comedi_device *dev, comedi_subdevice *s)
741 dio200_subdev_intr *subpriv = s->private;
744 comedi_spin_lock_irqsave(&subpriv->spinlock, flags);
745 if (subpriv->active) {
746 dio200_stop_intr(dev, s);
748 comedi_spin_unlock_irqrestore(&subpriv->spinlock, flags);
754 * 'do_cmdtest' function for an 'INTERRUPT' subdevice.
757 dio200_subdev_intr_cmdtest(comedi_device *dev, comedi_subdevice *s,
763 /* step 1: make sure trigger sources are trivially valid */
765 tmp = cmd->start_src;
766 cmd->start_src &= (TRIG_NOW | TRIG_INT);
767 if (!cmd->start_src || tmp != cmd->start_src) err++;
769 tmp = cmd->scan_begin_src;
770 cmd->scan_begin_src &= TRIG_EXT;
771 if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src) err++;
773 tmp = cmd->convert_src;
774 cmd->convert_src &= TRIG_NOW;
775 if (!cmd->convert_src || tmp != cmd->convert_src) err++;
777 tmp = cmd->scan_end_src;
778 cmd->scan_end_src &= TRIG_COUNT;
779 if (!cmd->scan_end_src || tmp != cmd->scan_end_src) err++;
782 cmd->stop_src &= (TRIG_COUNT | TRIG_NONE);
783 if (!cmd->stop_src || tmp != cmd->stop_src) err++;
787 /* step 2: make sure trigger sources are unique and mutually compatible */
789 /* these tests are true if more than one _src bit is set */
790 if ((cmd->start_src & (cmd->start_src - 1)) != 0) err++;
791 if ((cmd->scan_begin_src & (cmd->scan_begin_src - 1)) != 0) err++;
792 if ((cmd->convert_src & (cmd->convert_src - 1)) != 0) err++;
793 if ((cmd->scan_end_src & (cmd->scan_end_src - 1)) != 0) err++;
794 if ((cmd->stop_src & (cmd->stop_src - 1)) != 0) err++;
798 /* step 3: make sure arguments are trivially compatible */
800 /* cmd->start_src == TRIG_NOW || cmd->start_src == TRIG_INT */
801 if (cmd->start_arg != 0) {
806 /* cmd->scan_begin_src == TRIG_EXT */
807 if (cmd->scan_begin_arg != 0) {
808 cmd->scan_begin_arg = 0;
812 /* cmd->convert_src == TRIG_NOW */
813 if (cmd->convert_arg != 0) {
814 cmd->convert_arg = 0;
818 /* cmd->scan_end_src == TRIG_COUNT */
819 if (cmd->scan_end_arg != cmd->chanlist_len) {
820 cmd->scan_end_arg = cmd->chanlist_len;
824 switch (cmd->stop_src) {
826 /* any count allowed */
829 if (cmd->stop_arg != 0) {
840 /* step 4: fix up any arguments */
842 /* if (err) return 4; */
848 * 'do_cmd' function for an 'INTERRUPT' subdevice.
851 dio200_subdev_intr_cmd(comedi_device *dev, comedi_subdevice *s)
853 comedi_cmd *cmd = &s->async->cmd;
854 dio200_subdev_intr *subpriv = s->private;
858 comedi_spin_lock_irqsave(&subpriv->spinlock, flags);
861 /* Set up end of acquisition. */
862 switch (cmd->stop_src) {
864 subpriv->continuous = 0;
865 subpriv->stopcount = cmd->stop_arg;
869 subpriv->continuous = 1;
870 subpriv->stopcount = 0;
874 /* Set up start of acquisition. */
875 switch (cmd->start_src) {
877 s->async->inttrig = dio200_inttrig_start_intr;
881 event = dio200_start_intr(dev, s);
884 comedi_spin_unlock_irqrestore(&subpriv->spinlock, flags);
887 comedi_event(dev, s, s->async->events);
894 * This function initializes an 'INTERRUPT' subdevice.
897 dio200_subdev_intr_init(comedi_device *dev, comedi_subdevice *s,
898 unsigned long iobase, unsigned valid_isns, int has_int_sce)
900 dio200_subdev_intr *subpriv;
902 subpriv = kmalloc(sizeof(*subpriv), GFP_KERNEL);
904 printk(KERN_ERR "comedi%d: error! out of memory!\n", dev->minor);
907 memset(subpriv, 0, sizeof(*subpriv));
908 subpriv->iobase = iobase;
909 subpriv->has_int_sce = has_int_sce;
910 subpriv->valid_isns = valid_isns;
911 spin_lock_init(&subpriv->spinlock);
914 outb(0, subpriv->iobase); /* Disable interrupt sources. */
917 s->private = subpriv;
918 s->type = COMEDI_SUBD_DI;
919 s->subdev_flags = SDF_READABLE;
921 s->n_chan = DIO200_MAX_ISNS;
922 s->len_chanlist = DIO200_MAX_ISNS;
924 /* No interrupt source register. Support single channel. */
928 s->range_table = &range_digital;
930 s->insn_bits = dio200_subdev_intr_insn_bits;
931 s->do_cmdtest = dio200_subdev_intr_cmdtest;
932 s->do_cmd = dio200_subdev_intr_cmd;
933 s->cancel = dio200_subdev_intr_cancel;
939 * This function cleans up an 'INTERRUPT' subdevice.
942 dio200_subdev_intr_cleanup(comedi_device *dev, comedi_subdevice *s)
944 dio200_subdev_intr *subpriv = s->private;
952 * Interrupt service routine.
955 dio200_interrupt(int irq, void *d, struct pt_regs *regs)
957 comedi_device *dev=d;
960 if (devpriv->intr_sd >= 0) {
961 handled = dio200_handle_read_intr(dev,
962 dev->subdevices + devpriv->intr_sd);
967 return IRQ_RETVAL(handled);
971 * Handle 'insn_read' for an '8254' counter subdevice.
974 dio200_subdev_8254_read(comedi_device *dev, comedi_subdevice *s,
975 comedi_insn *insn, lsampl_t *data)
977 dio200_subdev_8254 *subpriv = s->private;
978 int chan = CR_CHAN(insn->chanspec);
980 data[0] = i8254_read(subpriv->iobase, chan);
986 * Handle 'insn_write' for an '8254' counter subdevice.
989 dio200_subdev_8254_write(comedi_device *dev, comedi_subdevice *s,
990 comedi_insn *insn, lsampl_t *data)
992 dio200_subdev_8254 *subpriv = s->private;
993 int chan = CR_CHAN(insn->chanspec);
995 i8254_write(subpriv->iobase, chan, data[0]);
1001 * Set gate source for an '8254' counter subdevice channel.
1004 dio200_set_gate_src(dio200_subdev_8254 *subpriv, unsigned int counter_number,
1005 unsigned int gate_src)
1009 if (!subpriv->has_clk_gat_sce) return -1;
1010 if (counter_number > 2) return -1;
1011 if (gate_src > 7) return -1;
1013 subpriv->gate_src[counter_number] = gate_src;
1014 byte = GAT_SCE(subpriv->which, counter_number, gate_src);
1015 outb(byte, subpriv->gat_sce_iobase);
1021 * Get gate source for an '8254' counter subdevice channel.
1024 dio200_get_gate_src(dio200_subdev_8254 *subpriv, unsigned int counter_number)
1026 if (!subpriv->has_clk_gat_sce) return -1;
1027 if (counter_number > 2) return -1;
1029 return subpriv->gate_src[counter_number];
1033 * Set clock source for an '8254' counter subdevice channel.
1036 dio200_set_clock_src(dio200_subdev_8254 *subpriv, unsigned int counter_number,
1037 unsigned int clock_src)
1041 if (!subpriv->has_clk_gat_sce) return -1;
1042 if (counter_number > 2) return -1;
1043 if (clock_src > 7) return -1;
1045 subpriv->clock_src[counter_number] = clock_src;
1046 byte = CLK_SCE(subpriv->which, counter_number, clock_src);
1047 outb(byte, subpriv->clk_sce_iobase);
1053 * Get clock source for an '8254' counter subdevice channel.
1056 dio200_get_clock_src(dio200_subdev_8254 *subpriv, unsigned int counter_number)
1058 if (!subpriv->has_clk_gat_sce) return -1;
1059 if (counter_number > 2) return -1;
1061 return subpriv->clock_src[counter_number];
1065 * Handle 'insn_config' for an '8254' counter subdevice.
1068 dio200_subdev_8254_config(comedi_device *dev, comedi_subdevice *s,
1069 comedi_insn *insn, lsampl_t *data)
1071 dio200_subdev_8254 *subpriv = s->private;
1073 int chan = CR_CHAN(insn->chanspec);
1075 if (insn->n != 2) return -EINVAL;
1078 case INSN_CONFIG_8254_SET_MODE:
1079 ret = i8254_set_mode(subpriv->iobase, chan, data[1]);
1080 if (ret < 0) return -EINVAL;
1082 case INSN_CONFIG_8254_READ_STATUS:
1083 data[1] = i8254_status(subpriv->iobase, chan);
1085 case INSN_CONFIG_SET_GATE_SRC:
1086 ret = dio200_set_gate_src(subpriv, chan, data[1]);
1087 if (ret < 0) return -EINVAL;
1089 case INSN_CONFIG_GET_GATE_SRC:
1090 ret = dio200_get_gate_src(subpriv, chan);
1091 if (ret < 0) return -EINVAL;
1094 case INSN_CONFIG_SET_CLOCK_SRC:
1095 ret = dio200_set_clock_src(subpriv, chan, data[1]);
1096 if (ret < 0) return -EINVAL;
1098 case INSN_CONFIG_GET_CLOCK_SRC:
1099 ret = dio200_get_clock_src(subpriv, chan);
1100 if (ret < 0) return -EINVAL;
1111 * This function initializes an '8254' counter subdevice.
1113 * Note: iobase is the base address of the board, not the subdevice;
1114 * offset is the offset to the 8254 chip.
1117 dio200_subdev_8254_init(comedi_device *dev, comedi_subdevice *s,
1118 unsigned long iobase, unsigned offset, int has_clk_gat_sce)
1120 dio200_subdev_8254 *subpriv;
1123 subpriv = kmalloc(sizeof(*subpriv), GFP_KERNEL);
1125 printk(KERN_ERR "comedi%d: error! out of memory!\n", dev->minor);
1128 memset(subpriv, 0, sizeof(*subpriv));
1130 s->private = subpriv;
1131 s->type = COMEDI_SUBD_COUNTER;
1132 s->subdev_flags = SDF_WRITABLE | SDF_READABLE;
1134 s->maxdata = 0xFFFF;
1135 s->insn_read = dio200_subdev_8254_read;
1136 s->insn_write = dio200_subdev_8254_write;
1137 s->insn_config = dio200_subdev_8254_config;
1139 subpriv->iobase = offset + iobase;
1140 subpriv->has_clk_gat_sce = has_clk_gat_sce;
1141 if (has_clk_gat_sce) {
1142 /* Derive CLK_SCE and GAT_SCE register offsets from
1144 subpriv->clk_sce_iobase =
1145 DIO200_XCLK_SCE + (offset >> 3) + iobase;
1146 subpriv->gat_sce_iobase =
1147 DIO200_XGAT_SCE + (offset >> 3) + iobase;
1148 subpriv->which = (offset >> 2) & 1;
1151 /* Initialize channels. */
1152 for (chan = 0; chan < 3; chan++) {
1153 i8254_set_mode(subpriv->iobase, chan,
1154 I8254_MODE0 | I8254_BINARY);
1155 if (subpriv->has_clk_gat_sce) {
1156 /* Gate source 0 is VCC (logic 1). */
1157 dio200_set_gate_src(subpriv, chan, 0);
1158 /* Clock source 0 is the dedicated clock input. */
1159 dio200_set_clock_src(subpriv, chan, 0);
1167 * This function cleans up an '8254' counter subdevice.
1170 dio200_subdev_8254_cleanup(comedi_device *dev, comedi_subdevice *s)
1172 dio200_subdev_intr *subpriv = s->private;
1180 * Attach is called by the Comedi core to configure the driver
1181 * for a particular board. If you specified a board_name array
1182 * in the driver structure, dev->board_ptr contains that
1186 dio200_attach(comedi_device *dev,comedi_devconfig *it)
1188 comedi_subdevice *s;
1189 struct pci_dev *pci_dev = NULL;
1190 int iobase = 0, irq = 0;
1191 int bus = 0, slot = 0;
1192 dio200_layout *layout;
1198 printk(KERN_DEBUG "comedi%d: %s: attach\n", dev->minor,
1199 DIO200_DRIVER_NAME);
1201 /* Process options. */
1202 switch (thisboard->bustype) {
1204 iobase = it->options[0];
1205 irq = it->options[1];
1209 bus = it->options[0];
1210 slot = it->options[1];
1213 if ((ret=dio200_find_pci(dev, bus, slot, &pci_dev)) < 0)
1217 printk(KERN_ERR "comedi%d: %s: BUG! cannot determine board type!\n",
1218 dev->minor, DIO200_DRIVER_NAME);
1223 if ((ret=alloc_private(dev,sizeof(dio200_private))) < 0) {
1224 printk(KERN_ERR "comedi%d: error! out of memory!\n", dev->minor);
1226 pci_dev_put(pci_dev);
1231 devpriv->intr_sd = -1;
1233 /* Enable device and reserve I/O spaces. */
1235 ret = pci_enable_device(pci_dev);
1237 printk(KERN_ERR "comedi%d: error! cannot enable PCI device!\n",
1239 pci_dev_put(pci_dev);
1242 iobase = pci_resource_start(pci_dev, 2);
1244 ret = pci_request_regions(pci_dev, DIO200_DRIVER_NAME);
1246 printk(KERN_ERR "comedi%d: I/O port conflict (PCI)!\n",
1248 pci_dev_put(pci_dev);
1251 devpriv->pci_dev = pci_dev;
1253 ret = dio200_request_region(dev->minor, iobase, DIO200_IO_SIZE);
1258 dev->iobase = iobase;
1260 layout = thislayout;
1261 if ((ret=alloc_subdevices(dev, layout->n_subdevs)) < 0) {
1262 printk(KERN_ERR "comedi%d: error! out of memory!\n", dev->minor);
1266 for (n = 0; n < dev->n_subdevices; n++) {
1267 s = &dev->subdevices[n];
1268 switch (layout->sdtype[n]) {
1270 /* counter subdevice (8254) */
1271 ret = dio200_subdev_8254_init(dev, s, iobase,
1273 layout->has_clk_gat_sce);
1279 /* digital i/o subdevice (8255) */
1280 ret = subdev_8255_init(dev, s, 0,
1281 iobase + layout->sdinfo[n]);
1287 /* 'INTERRUPT' subdevice */
1289 ret = dio200_subdev_intr_init(dev, s,
1290 iobase + DIO200_INT_SCE,
1292 layout->has_int_sce);
1296 devpriv->intr_sd = n;
1298 s->type = COMEDI_SUBD_UNUSED;
1302 s->type = COMEDI_SUBD_UNUSED;
1307 sdx = devpriv->intr_sd;
1308 if (sdx >= 0 && sdx < dev->n_subdevices) {
1309 dev->read_subdev = &dev->subdevices[sdx];
1312 dev->board_name = thisboard->name;
1315 unsigned long flags = share_irq ? SA_SHIRQ : 0;
1317 if (comedi_request_irq(irq, dio200_interrupt, flags,
1318 DIO200_DRIVER_NAME, dev) >= 0) {
1321 printk(KERN_WARNING "comedi%d: warning! irq %d unavailable!\n",
1326 printk(KERN_INFO "comedi%d: %s ", dev->minor, dev->board_name);
1327 if (thisboard->bustype == isa_bustype) {
1328 printk("(base %#x) ", iobase);
1330 printk("(pci %02x:%02x.%x) ", pci_dev->bus->number,
1331 PCI_SLOT(pci_dev->devfn),
1332 PCI_FUNC(pci_dev->devfn));
1335 printk("(irq %d%s) ", irq, (dev->irq ? "" : " UNAVAILABLE"));
1337 printk("(no irq) ");
1340 printk("attached\n");
1346 * _detach is called to deconfigure a device. It should deallocate
1348 * This function is also called when _attach() fails, so it should be
1349 * careful not to release resources that were not necessarily
1350 * allocated by _attach(). dev->private and dev->subdevices are
1351 * deallocated automatically by the core.
1354 dio200_detach(comedi_device *dev)
1356 dio200_layout *layout;
1359 printk(KERN_DEBUG "comedi%d: %s: detach\n", dev->minor,
1360 DIO200_DRIVER_NAME);
1363 comedi_free_irq(dev->irq, dev);
1365 if (dev->subdevices) {
1366 layout = thislayout;
1367 for (n = 0; n < dev->n_subdevices; n++) {
1368 comedi_subdevice *s = &dev->subdevices[n];
1369 switch (layout->sdtype[n]) {
1371 dio200_subdev_8254_cleanup(dev, s);
1374 subdev_8255_cleanup(dev, s);
1377 dio200_subdev_intr_cleanup(dev, s);
1385 if (devpriv->pci_dev) {
1386 pci_release_regions(devpriv->pci_dev);
1387 pci_disable_device(devpriv->pci_dev);
1388 pci_dev_put(devpriv->pci_dev);
1389 } else if (dev->iobase) {
1390 release_region(dev->iobase, DIO200_IO_SIZE);
1393 if (dev->board_name) {
1394 printk(KERN_INFO "comedi%d: %s removed\n",
1395 dev->minor, dev->board_name);