fc960ef5962994af560226bcac064c74fc07d5c5
[comedi.git] / comedi / drivers / amplc_dio200.c
1 /*
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.)
6
7     Copyright (C) 2005 MEV Ltd. <http://www.mev.co.uk/>
8
9     COMEDI - Linux Control and Measurement Device Interface
10     Copyright (C) 1998,2000 David A. Schleef <ds@schleef.org>
11
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.
16
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.
21
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.
25
26 */
27 /*
28 Driver: amplc_dio200
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), PC218E (pc218e), PC272E (pc272e),
33   PCI272 (pci272 or amplc_dio200)
34 Updated: Wed, 22 Oct 2008 13:36:02 +0100
35 Status: works
36
37 Configuration options - PC212E, PC214E, PC215E, PC218E, PC272E:
38   [0] - I/O port base address
39   [1] - IRQ (optional, but commands won't work without it)
40
41 Configuration options - PCI215, PCI272:
42   [0] - PCI bus of device (optional)
43   [1] - PCI slot of device (optional)
44   If bus/slot is not specified, the first available PCI device will
45   be used.
46
47 Passing a zero for an option is the same as leaving it unspecified.
48
49 SUBDEVICES
50
51                     PC218E         PC212E      PC215E/PCI215
52                  -------------  -------------  -------------
53   Subdevices           7              6              5
54    0                 CTR-X1         PPI-X          PPI-X
55    1                 CTR-X2         CTR-Y1         PPI-Y
56    2                 CTR-Y1         CTR-Y2         CTR-Z1
57    3                 CTR-Y2         CTR-Z1         CTR-Z2
58    4                 CTR-Z1         CTR-Z2       INTERRUPT
59    5                 CTR-Z2       INTERRUPT
60    6               INTERRUPT
61
62                     PC214E      PC272E/PCI272
63                  -------------  -------------
64   Subdevices           4              4
65    0                 PPI-X          PPI-X
66    1                 PPI-Y          PPI-Y
67    2                 CTR-Z1*        PPI-Z
68    3               INTERRUPT*     INTERRUPT
69
70 Each PPI is a 8255 chip providing 24 DIO channels.  The DIO channels
71 are configurable as inputs or outputs in four groups:
72
73   Port A  - channels  0 to  7
74   Port B  - channels  8 to 15
75   Port CL - channels 16 to 19
76   Port CH - channels 20 to 23
77
78 Only mode 0 of the 8255 chips is supported.
79
80 Each CTR is a 8254 chip providing 3 16-bit counter channels.  Each
81 channel is configured individually with INSN_CONFIG instructions.  The
82 specific type of configuration instruction is specified in data[0].
83 Some configuration instructions expect an additional parameter in
84 data[1]; others return a value in data[1].  The following configuration
85 instructions are supported:
86
87   INSN_CONFIG_SET_COUNTER_MODE.  Sets the counter channel's mode and
88     BCD/binary setting specified in data[1].
89
90   INSN_CONFIG_8254_READ_STATUS.  Reads the status register value for the
91     counter channel into data[1].
92
93   INSN_CONFIG_SET_CLOCK_SRC.  Sets the counter channel's clock source as
94     specified in data[1] (this is a hardware-specific value).  Not
95     supported on PC214E.  For the other boards, valid clock sources are
96     0 to 7 as follows:
97
98       0.  CLK n, the counter channel's dedicated CLK input from the SK1
99         connector.  (N.B. for other values, the counter channel's CLKn
100         pin on the SK1 connector is an output!)
101       1.  Internal 10 MHz clock.
102       2.  Internal 1 MHz clock.
103       3.  Internal 100 kHz clock.
104       4.  Internal 10 kHz clock.
105       5.  Internal 1 kHz clock.
106       6.  OUT n-1, the output of counter channel n-1 (see note 1 below).
107       7.  Ext Clock, the counter chip's dedicated Ext Clock input from
108         the SK1 connector.  This pin is shared by all three counter
109         channels on the chip.
110
111   INSN_CONFIG_GET_CLOCK_SRC.  Returns the counter channel's current
112     clock source in data[1].  For internal clock sources, data[2] is set
113     to the period in ns.
114
115   INSN_CONFIG_SET_GATE_SRC.  Sets the counter channel's gate source as
116     specified in data[2] (this is a hardware-specific value).  Not
117     supported on PC214E.  For the other boards, valid gate sources are 0
118     to 7 as follows:
119
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
126         2 below).
127       4.  Reserved.
128       5.  Reserved.
129       6.  Reserved.
130       7.  Reserved.
131
132   INSN_CONFIG_GET_GATE_SRC.  Returns the counter channel's current gate
133     source in data[2].
134
135 Clock and gate interconnection notes:
136
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.
140
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.
144
145   3.  The counter subdevices are connected in a ring, so the highest
146   counter subdevice precedes the lowest.
147
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'
152 below.
153
154 INTERRUPT SOURCES
155
156                     PC218E         PC212E      PC215E/PCI215
157                  -------------  -------------  -------------
158   Sources              6              6              6
159    0              CTR-X1-OUT      PPI-X-C0       PPI-X-C0
160    1              CTR-X2-OUT      PPI-X-C3       PPI-X-C3
161    2              CTR-Y1-OUT     CTR-Y1-OUT      PPI-Y-C0
162    3              CTR-Y2-OUT     CTR-Y2-OUT      PPI-Y-C3
163    4              CTR-Z1-OUT     CTR-Z1-OUT     CTR-Z1-OUT
164    5              CTR-Z2-OUT     CTR-Z2-OUT     CTR-Z2-OUT
165
166                     PC214E      PC272E/PCI272
167                  -------------  -------------
168   Sources              1              6
169    0               JUMPER-J5      PPI-X-C0
170    1                              PPI-X-C3
171    2                              PPI-Y-C0
172    3                              PPI-Y-C3
173    4                              PPI-Z-C0
174    5                              PPI-Z-C3
175
176 When an interrupt source is enabled in the interrupt source enable
177 register, a rising edge on the source signal latches the corresponding
178 bit to 1 in the interrupt status register.
179
180 When the interrupt status register value as a whole (actually, just the
181 6 least significant bits) goes from zero to non-zero, the board will
182 generate an interrupt.  For level-triggered hardware interrupts (PCI
183 card), the interrupt will remain asserted until the interrupt status
184 register is cleared to zero.  For edge-triggered hardware interrupts
185 (ISA card), no further interrupts will occur until the interrupt status
186 register is cleared to zero.  To clear a bit to zero in the interrupt
187 status register, the corresponding interrupt source must be disabled
188 in the interrupt source enable register (there is no separate interrupt
189 clear register).
190
191 The PC214E does not have an interrupt source enable register or an
192 interrupt status register; its 'INTERRUPT' subdevice has a single
193 channel and its interrupt source is selected by the position of jumper
194 J5.
195
196 COMMANDS
197
198 The driver supports a read streaming acquisition command on the
199 'INTERRUPT' subdevice.  The channel list selects the interrupt sources
200 to be enabled.  All channels will be sampled together (convert_src ==
201 TRIG_NOW).  The scan begins a short time after the hardware interrupt
202 occurs, subject to interrupt latencies (scan_begin_src == TRIG_EXT,
203 scan_begin_arg == 0).  The value read from the interrupt status register
204 is packed into a sampl_t value, one bit per requested channel, in the
205 order they appear in the channel list.
206 */
207
208 #include <linux/comedidev.h>
209
210 #include "comedi_pci.h"
211
212 #include "8255.h"
213 #include "8253.h"
214
215 #define DIO200_DRIVER_NAME      "amplc_dio200"
216
217 /* PCI IDs */
218 /* #define PCI_VENDOR_ID_AMPLICON 0x14dc */
219 #define PCI_DEVICE_ID_AMPLICON_PCI272 0x000a
220 #define PCI_DEVICE_ID_AMPLICON_PCI215 0x000b
221 #define PCI_DEVICE_ID_INVALID 0xffff
222
223 /* 200 series registers */
224 #define DIO200_IO_SIZE          0x20
225 #define DIO200_XCLK_SCE         0x18    /* Group X clock selection register */
226 #define DIO200_YCLK_SCE         0x19    /* Group Y clock selection register */
227 #define DIO200_ZCLK_SCE         0x1a    /* Group Z clock selection register */
228 #define DIO200_XGAT_SCE         0x1b    /* Group X gate selection register */
229 #define DIO200_YGAT_SCE         0x1c    /* Group Y gate selection register */
230 #define DIO200_ZGAT_SCE         0x1d    /* Group Z gate selection register */
231 #define DIO200_INT_SCE          0x1e    /* Interrupt enable/status register */
232
233 /*
234  * Macros for constructing value for DIO_200_?CLK_SCE and
235  * DIO_200_?GAT_SCE registers:
236  *
237  * 'which' is: 0 for CTR-X1, CTR-Y1, CTR-Z1; 1 for CTR-X2, CTR-Y2 or CTR-Z2.
238  * 'chan' is the channel: 0, 1 or 2.
239  * 'source' is the signal source: 0 to 7.
240  */
241 #define CLK_SCE(which, chan, source) (((which) << 5) | ((chan) << 3) | (source))
242 #define GAT_SCE(which, chan, source) (((which) << 5) | ((chan) << 3) | (source))
243
244 /*
245  * Periods of the internal clock sources in nanoseconds.
246  */
247 static const unsigned clock_period[8] = {
248         0,                      /* dedicated clock input/output pin */
249         100,                    /* 10 MHz */
250         1000,                   /* 1 MHz */
251         10000,                  /* 100 kHz */
252         100000,                 /* 10 kHz */
253         1000000,                /* 1 kHz */
254         0,                      /* OUT N-1 */
255         0                       /* group clock input pin */
256 };
257
258 /*
259  * Board descriptions.
260  */
261
262 enum dio200_bustype { isa_bustype, pci_bustype };
263
264 enum dio200_model {
265         pc212e_model,
266         pc214e_model,
267         pc215e_model, pci215_model,
268         pc218e_model,
269         pc272e_model, pci272_model,
270         anypci_model
271 };
272
273 enum dio200_layout {
274         pc212_layout,
275         pc214_layout,
276         pc215_layout,
277         pc218_layout,
278         pc272_layout
279 };
280
281 typedef struct dio200_board_struct {
282         const char *name;
283         unsigned short devid;
284         enum dio200_bustype bustype;
285         enum dio200_model model;
286         enum dio200_layout layout;
287 } dio200_board;
288
289 static const dio200_board dio200_boards[] = {
290         {
291               name:     "pc212e",
292               bustype:  isa_bustype,
293               model:    pc212e_model,
294               layout:   pc212_layout,
295                 },
296         {
297               name:     "pc214e",
298               bustype:  isa_bustype,
299               model:    pc214e_model,
300               layout:   pc214_layout,
301                 },
302         {
303               name:     "pc215e",
304               bustype:  isa_bustype,
305               model:    pc215e_model,
306               layout:   pc215_layout,
307                 },
308 #ifdef CONFIG_COMEDI_PCI
309         {
310               name:     "pci215",
311               devid:    PCI_DEVICE_ID_AMPLICON_PCI215,
312               bustype:  pci_bustype,
313               model:    pci215_model,
314               layout:   pc215_layout,
315                 },
316 #endif
317         {
318               name:     "pc218e",
319               bustype:  isa_bustype,
320               model:    pc218e_model,
321               layout:   pc218_layout,
322                 },
323         {
324               name:     "pc272e",
325               bustype:  isa_bustype,
326               model:    pc272e_model,
327               layout:   pc272_layout,
328                 },
329 #ifdef CONFIG_COMEDI_PCI
330         {
331               name:     "pci272",
332               devid:    PCI_DEVICE_ID_AMPLICON_PCI272,
333               bustype:  pci_bustype,
334               model:    pci272_model,
335               layout:   pc272_layout,
336                 },
337 #endif
338 #ifdef CONFIG_COMEDI_PCI
339         {
340               name:     DIO200_DRIVER_NAME,
341               devid:    PCI_DEVICE_ID_INVALID,
342               bustype:  pci_bustype,
343               model:    anypci_model,   /* wildcard */
344                 },
345 #endif
346 };
347
348 /*
349  * Layout descriptions - some ISA and PCI board descriptions share the same
350  * layout.
351  */
352
353 enum dio200_sdtype { sd_none, sd_intr, sd_8255, sd_8254 };
354
355 #define DIO200_MAX_SUBDEVS      7
356 #define DIO200_MAX_ISNS         6
357
358 typedef struct dio200_layout_struct {
359         unsigned short n_subdevs;       /* number of subdevices */
360         unsigned char sdtype[DIO200_MAX_SUBDEVS];       /* enum dio200_sdtype */
361         unsigned char sdinfo[DIO200_MAX_SUBDEVS];       /* depends on sdtype */
362         char has_int_sce;       /* has interrupt enable/status register */
363         char has_clk_gat_sce;   /* has clock/gate selection registers */
364 } dio200_layout;
365
366 static const dio200_layout dio200_layouts[] = {
367         [pc212_layout] = {
368               n_subdevs:6,
369               sdtype:   {sd_8255, sd_8254, sd_8254, sd_8254,
370                                         sd_8254,
371                                 sd_intr},
372               sdinfo:   {0x00, 0x08, 0x0C, 0x10, 0x14,
373                                 0x3F},
374               has_int_sce:1,
375               has_clk_gat_sce:1,
376                 },
377         [pc214_layout] = {
378               n_subdevs:4,
379               sdtype:   {sd_8255, sd_8255, sd_8254,
380                                 sd_intr},
381               sdinfo:   {0x00, 0x08, 0x10, 0x01},
382               has_int_sce:0,
383               has_clk_gat_sce:0,
384                 },
385         [pc215_layout] = {
386               n_subdevs:5,
387               sdtype:   {sd_8255, sd_8255, sd_8254,
388                                         sd_8254,
389                                 sd_intr},
390               sdinfo:   {0x00, 0x08, 0x10, 0x14, 0x3F},
391               has_int_sce:1,
392               has_clk_gat_sce:1,
393                 },
394         [pc218_layout] = {
395               n_subdevs:7,
396               sdtype:   {sd_8254, sd_8254, sd_8255, sd_8254,
397                                         sd_8254,
398                                 sd_intr},
399               sdinfo:   {0x00, 0x04, 0x08, 0x0C, 0x10,
400                                         0x14,
401                                 0x3F},
402               has_int_sce:1,
403               has_clk_gat_sce:1,
404                 },
405         [pc272_layout] = {
406               n_subdevs:4,
407               sdtype:   {sd_8255, sd_8255, sd_8255,
408                                 sd_intr},
409               sdinfo:   {0x00, 0x08, 0x10, 0x3F},
410               has_int_sce:1,
411               has_clk_gat_sce:0,
412                 },
413 };
414
415 /*
416  * PCI driver table.
417  */
418
419 #ifdef CONFIG_COMEDI_PCI
420 static DEFINE_PCI_DEVICE_TABLE(dio200_pci_table) = {
421         {PCI_VENDOR_ID_AMPLICON, PCI_DEVICE_ID_AMPLICON_PCI215,
422                 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
423         {PCI_VENDOR_ID_AMPLICON, PCI_DEVICE_ID_AMPLICON_PCI272,
424                 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
425         {0}
426 };
427
428 MODULE_DEVICE_TABLE(pci, dio200_pci_table);
429 #endif /* CONFIG_COMEDI_PCI */
430
431 /*
432  * Useful for shorthand access to the particular board structure
433  */
434 #define thisboard ((const dio200_board *)dev->board_ptr)
435 #define thislayout (&dio200_layouts[((dio200_board *)dev->board_ptr)->layout])
436
437 /* this structure is for data unique to this hardware driver.  If
438    several hardware drivers keep similar information in this structure,
439    feel free to suggest moving the variable to the comedi_device struct.  */
440 typedef struct {
441 #ifdef CONFIG_COMEDI_PCI
442         struct pci_dev *pci_dev;        /* PCI device */
443 #endif
444         int intr_sd;
445 } dio200_private;
446
447 #define devpriv ((dio200_private *)dev->private)
448
449 typedef struct {
450         unsigned long iobase;   /* Counter base address */
451         unsigned long clk_sce_iobase;   /* CLK_SCE base address */
452         unsigned long gat_sce_iobase;   /* GAT_SCE base address */
453         int which;              /* Bit 5 of CLK_SCE or GAT_SCE */
454         int has_clk_gat_sce;
455         unsigned clock_src[3];  /* Current clock sources */
456         unsigned gate_src[3];   /* Current gate sources */
457         spinlock_t spinlock;
458 } dio200_subdev_8254;
459
460 typedef struct {
461         unsigned long iobase;
462         spinlock_t spinlock;
463         int active;
464         int has_int_sce;
465         unsigned int valid_isns;
466         unsigned int enabled_isns;
467         unsigned int stopcount;
468         int continuous;
469 } dio200_subdev_intr;
470
471 /*
472  * The comedi_driver structure tells the Comedi core module
473  * which functions to call to configure/deconfigure (attach/detach)
474  * the board, and also about the kernel module that contains
475  * the device code.
476  */
477 static int dio200_attach(comedi_device * dev, comedi_devconfig * it);
478 static int dio200_detach(comedi_device * dev);
479 static comedi_driver driver_amplc_dio200 = {
480       driver_name:DIO200_DRIVER_NAME,
481       module:THIS_MODULE,
482       attach:dio200_attach,
483       detach:dio200_detach,
484       board_name:&dio200_boards[0].name,
485       offset:sizeof(dio200_board),
486       num_names:sizeof(dio200_boards) / sizeof(dio200_board),
487 };
488
489 #ifdef CONFIG_COMEDI_PCI
490 COMEDI_PCI_INITCLEANUP(driver_amplc_dio200, dio200_pci_table);
491 #else
492 COMEDI_INITCLEANUP(driver_amplc_dio200);
493 #endif
494
495 /*
496  * This function looks for a PCI device matching the requested board name,
497  * bus and slot.
498  */
499 #ifdef CONFIG_COMEDI_PCI
500 static int
501 dio200_find_pci(comedi_device * dev, int bus, int slot,
502         struct pci_dev **pci_dev_p)
503 {
504         struct pci_dev *pci_dev = NULL;
505
506         *pci_dev_p = NULL;
507
508         /* Look for matching PCI device. */
509         for (pci_dev = pci_get_device(PCI_VENDOR_ID_AMPLICON, PCI_ANY_ID, NULL);
510                 pci_dev != NULL;
511                 pci_dev = pci_get_device(PCI_VENDOR_ID_AMPLICON,
512                         PCI_ANY_ID, pci_dev)) {
513                 /* If bus/slot specified, check them. */
514                 if (bus || slot) {
515                         if (bus != pci_dev->bus->number
516                                 || slot != PCI_SLOT(pci_dev->devfn))
517                                 continue;
518                 }
519                 if (thisboard->model == anypci_model) {
520                         /* Match any supported model. */
521                         int i;
522
523                         for (i = 0; i < ARRAY_SIZE(dio200_boards); i++) {
524                                 if (dio200_boards[i].bustype != pci_bustype)
525                                         continue;
526                                 if (pci_dev->device == dio200_boards[i].devid) {
527                                         /* Change board_ptr to matched board. */
528                                         dev->board_ptr = &dio200_boards[i];
529                                         break;
530                                 }
531                         }
532                         if (i == ARRAY_SIZE(dio200_boards))
533                                 continue;
534                 } else {
535                         /* Match specific model name. */
536                         if (pci_dev->device != thisboard->devid)
537                                 continue;
538                 }
539
540                 /* Found a match. */
541                 *pci_dev_p = pci_dev;
542                 return 0;
543         }
544         /* No match found. */
545         if (bus || slot) {
546                 printk(KERN_ERR
547                         "comedi%d: error! no %s found at pci %02x:%02x!\n",
548                         dev->minor, thisboard->name, bus, slot);
549         } else {
550                 printk(KERN_ERR "comedi%d: error! no %s found!\n",
551                         dev->minor, thisboard->name);
552         }
553         return -EIO;
554 }
555 #endif
556
557 /*
558  * This function checks and requests an I/O region, reporting an error
559  * if there is a conflict.
560  */
561 static int
562 dio200_request_region(unsigned minor, unsigned long from, unsigned long extent)
563 {
564         if (!from || !request_region(from, extent, DIO200_DRIVER_NAME)) {
565                 printk(KERN_ERR "comedi%d: I/O port conflict (%#lx,%lu)!\n",
566                         minor, from, extent);
567                 return -EIO;
568         }
569         return 0;
570 }
571
572 /*
573  * 'insn_bits' function for an 'INTERRUPT' subdevice.
574  */
575 static int
576 dio200_subdev_intr_insn_bits(comedi_device * dev, comedi_subdevice * s,
577         comedi_insn * insn, lsampl_t * data)
578 {
579         dio200_subdev_intr *subpriv = s->private;
580
581         if (subpriv->has_int_sce) {
582                 /* Just read the interrupt status register.  */
583                 data[1] = inb(subpriv->iobase) & subpriv->valid_isns;
584         } else {
585                 /* No interrupt status register. */
586                 data[0] = 0;
587         }
588
589         return 2;
590 }
591
592 /*
593  * Called to stop acquisition for an 'INTERRUPT' subdevice.
594  */
595 static void dio200_stop_intr(comedi_device * dev, comedi_subdevice * s)
596 {
597         dio200_subdev_intr *subpriv = s->private;
598
599         subpriv->active = 0;
600         subpriv->enabled_isns = 0;
601         if (subpriv->has_int_sce) {
602                 outb(0, subpriv->iobase);
603         }
604 }
605
606 /*
607  * Called to start acquisition for an 'INTERRUPT' subdevice.
608  */
609 static int dio200_start_intr(comedi_device * dev, comedi_subdevice * s)
610 {
611         unsigned int n;
612         unsigned isn_bits;
613         dio200_subdev_intr *subpriv = s->private;
614         comedi_cmd *cmd = &s->async->cmd;
615         int retval = 0;
616
617         if (!subpriv->continuous && subpriv->stopcount == 0) {
618                 /* An empty acquisition! */
619                 s->async->events |= COMEDI_CB_EOA;
620                 subpriv->active = 0;
621                 retval = 1;
622         } else {
623                 /* Determine interrupt sources to enable. */
624                 isn_bits = 0;
625                 if (cmd->chanlist) {
626                         for (n = 0; n < cmd->chanlist_len; n++) {
627                                 isn_bits |= (1U << CR_CHAN(cmd->chanlist[n]));
628                         }
629                 }
630                 isn_bits &= subpriv->valid_isns;
631                 /* Enable interrupt sources. */
632                 subpriv->enabled_isns = isn_bits;
633                 if (subpriv->has_int_sce) {
634                         outb(isn_bits, subpriv->iobase);
635                 }
636         }
637
638         return retval;
639 }
640
641 /*
642  * Internal trigger function to start acquisition for an 'INTERRUPT' subdevice.
643  */
644 static int
645 dio200_inttrig_start_intr(comedi_device * dev, comedi_subdevice * s,
646         unsigned int trignum)
647 {
648         dio200_subdev_intr *subpriv;
649         unsigned long flags;
650         int event = 0;
651
652         if (trignum != 0)
653                 return -EINVAL;
654
655         subpriv = s->private;
656
657         comedi_spin_lock_irqsave(&subpriv->spinlock, flags);
658         s->async->inttrig = 0;
659         if (subpriv->active) {
660                 event = dio200_start_intr(dev, s);
661         }
662         comedi_spin_unlock_irqrestore(&subpriv->spinlock, flags);
663
664         if (event) {
665                 comedi_event(dev, s);
666         }
667
668         return 1;
669 }
670
671 /*
672  * This is called from the interrupt service routine to handle a read
673  * scan on an 'INTERRUPT' subdevice.
674  */
675 static int dio200_handle_read_intr(comedi_device * dev, comedi_subdevice * s)
676 {
677         dio200_subdev_intr *subpriv = s->private;
678         unsigned triggered;
679         unsigned intstat;
680         unsigned cur_enabled;
681         unsigned int oldevents;
682         unsigned long flags;
683
684         triggered = 0;
685
686         comedi_spin_lock_irqsave(&subpriv->spinlock, flags);
687         oldevents = s->async->events;
688         if (subpriv->has_int_sce) {
689                 /*
690                  * Collect interrupt sources that have triggered and disable
691                  * them temporarily.  Loop around until no extra interrupt
692                  * sources have triggered, at which point, the valid part of
693                  * the interrupt status register will read zero, clearing the
694                  * cause of the interrupt.
695                  *
696                  * Mask off interrupt sources already seen to avoid infinite
697                  * loop in case of misconfiguration.
698                  */
699                 cur_enabled = subpriv->enabled_isns;
700                 while ((intstat = (inb(subpriv->iobase) & subpriv->valid_isns
701                                         & ~triggered)) != 0) {
702                         triggered |= intstat;
703                         cur_enabled &= ~triggered;
704                         outb(cur_enabled, subpriv->iobase);
705                 }
706         } else {
707                 /*
708                  * No interrupt status register.  Assume the single interrupt
709                  * source has triggered.
710                  */
711                 triggered = subpriv->enabled_isns;
712         }
713
714         if (triggered) {
715                 /*
716                  * Some interrupt sources have triggered and have been
717                  * temporarily disabled to clear the cause of the interrupt.
718                  *
719                  * Reenable them NOW to minimize the time they are disabled.
720                  */
721                 cur_enabled = subpriv->enabled_isns;
722                 if (subpriv->has_int_sce) {
723                         outb(cur_enabled, subpriv->iobase);
724                 }
725
726                 if (subpriv->active) {
727                         /*
728                          * The command is still active.
729                          *
730                          * Ignore interrupt sources that the command isn't
731                          * interested in (just in case there's a race
732                          * condition).
733                          */
734                         if (triggered & subpriv->enabled_isns) {
735                                 /* Collect scan data. */
736                                 sampl_t val;
737                                 unsigned int n, ch, len;
738
739                                 val = 0;
740                                 len = s->async->cmd.chanlist_len;
741                                 for (n = 0; n < len; n++) {
742                                         ch = CR_CHAN(s->async->cmd.chanlist[n]);
743                                         if (triggered & (1U << ch)) {
744                                                 val |= (1U << n);
745                                         }
746                                 }
747                                 /* Write the scan to the buffer. */
748                                 if (comedi_buf_put(s->async, val)) {
749                                         s->async->events |= (COMEDI_CB_BLOCK |
750                                                 COMEDI_CB_EOS);
751                                 } else {
752                                         /* Error!  Stop acquisition.  */
753                                         dio200_stop_intr(dev, s);
754                                         s->async->events |= COMEDI_CB_ERROR
755                                                 | COMEDI_CB_OVERFLOW;
756                                         comedi_error(dev, "buffer overflow");
757                                 }
758
759                                 /* Check for end of acquisition. */
760                                 if (!subpriv->continuous) {
761                                         /* stop_src == TRIG_COUNT */
762                                         if (subpriv->stopcount > 0) {
763                                                 subpriv->stopcount--;
764                                                 if (subpriv->stopcount == 0) {
765                                                         s->async->events |=
766                                                                 COMEDI_CB_EOA;
767                                                         dio200_stop_intr(dev,
768                                                                 s);
769                                                 }
770                                         }
771                                 }
772                         }
773                 }
774         }
775         comedi_spin_unlock_irqrestore(&subpriv->spinlock, flags);
776
777         if (oldevents != s->async->events) {
778                 comedi_event(dev, s);
779         }
780
781         return (triggered != 0);
782 }
783
784 /*
785  * 'cancel' function for an 'INTERRUPT' subdevice.
786  */
787 static int dio200_subdev_intr_cancel(comedi_device * dev, comedi_subdevice * s)
788 {
789         dio200_subdev_intr *subpriv = s->private;
790         unsigned long flags;
791
792         comedi_spin_lock_irqsave(&subpriv->spinlock, flags);
793         if (subpriv->active) {
794                 dio200_stop_intr(dev, s);
795         }
796         comedi_spin_unlock_irqrestore(&subpriv->spinlock, flags);
797
798         return 0;
799 }
800
801 /*
802  * 'do_cmdtest' function for an 'INTERRUPT' subdevice.
803  */
804 static int
805 dio200_subdev_intr_cmdtest(comedi_device * dev, comedi_subdevice * s,
806         comedi_cmd * cmd)
807 {
808         int err = 0;
809         unsigned int tmp;
810
811         /* step 1: make sure trigger sources are trivially valid */
812
813         tmp = cmd->start_src;
814         cmd->start_src &= (TRIG_NOW | TRIG_INT);
815         if (!cmd->start_src || tmp != cmd->start_src)
816                 err++;
817
818         tmp = cmd->scan_begin_src;
819         cmd->scan_begin_src &= TRIG_EXT;
820         if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
821                 err++;
822
823         tmp = cmd->convert_src;
824         cmd->convert_src &= TRIG_NOW;
825         if (!cmd->convert_src || tmp != cmd->convert_src)
826                 err++;
827
828         tmp = cmd->scan_end_src;
829         cmd->scan_end_src &= TRIG_COUNT;
830         if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
831                 err++;
832
833         tmp = cmd->stop_src;
834         cmd->stop_src &= (TRIG_COUNT | TRIG_NONE);
835         if (!cmd->stop_src || tmp != cmd->stop_src)
836                 err++;
837
838         if (err)
839                 return 1;
840
841         /* step 2: make sure trigger sources are unique and mutually compatible */
842
843         /* these tests are true if more than one _src bit is set */
844         if ((cmd->start_src & (cmd->start_src - 1)) != 0)
845                 err++;
846         if ((cmd->scan_begin_src & (cmd->scan_begin_src - 1)) != 0)
847                 err++;
848         if ((cmd->convert_src & (cmd->convert_src - 1)) != 0)
849                 err++;
850         if ((cmd->scan_end_src & (cmd->scan_end_src - 1)) != 0)
851                 err++;
852         if ((cmd->stop_src & (cmd->stop_src - 1)) != 0)
853                 err++;
854
855         if (err)
856                 return 2;
857
858         /* step 3: make sure arguments are trivially compatible */
859
860         /* cmd->start_src == TRIG_NOW || cmd->start_src == TRIG_INT */
861         if (cmd->start_arg != 0) {
862                 cmd->start_arg = 0;
863                 err++;
864         }
865
866         /* cmd->scan_begin_src == TRIG_EXT */
867         if (cmd->scan_begin_arg != 0) {
868                 cmd->scan_begin_arg = 0;
869                 err++;
870         }
871
872         /* cmd->convert_src == TRIG_NOW */
873         if (cmd->convert_arg != 0) {
874                 cmd->convert_arg = 0;
875                 err++;
876         }
877
878         /* cmd->scan_end_src == TRIG_COUNT */
879         if (cmd->scan_end_arg != cmd->chanlist_len) {
880                 cmd->scan_end_arg = cmd->chanlist_len;
881                 err++;
882         }
883
884         switch (cmd->stop_src) {
885         case TRIG_COUNT:
886                 /* any count allowed */
887                 break;
888         case TRIG_NONE:
889                 if (cmd->stop_arg != 0) {
890                         cmd->stop_arg = 0;
891                         err++;
892                 }
893                 break;
894         default:
895                 break;
896         }
897
898         if (err)
899                 return 3;
900
901         /* step 4: fix up any arguments */
902
903         /* if (err) return 4; */
904
905         return 0;
906 }
907
908 /*
909  * 'do_cmd' function for an 'INTERRUPT' subdevice.
910  */
911 static int dio200_subdev_intr_cmd(comedi_device * dev, comedi_subdevice * s)
912 {
913         comedi_cmd *cmd = &s->async->cmd;
914         dio200_subdev_intr *subpriv = s->private;
915         unsigned long flags;
916         int event = 0;
917
918         comedi_spin_lock_irqsave(&subpriv->spinlock, flags);
919         subpriv->active = 1;
920
921         /* Set up end of acquisition. */
922         switch (cmd->stop_src) {
923         case TRIG_COUNT:
924                 subpriv->continuous = 0;
925                 subpriv->stopcount = cmd->stop_arg;
926                 break;
927         default:
928                 /* TRIG_NONE */
929                 subpriv->continuous = 1;
930                 subpriv->stopcount = 0;
931                 break;
932         }
933
934         /* Set up start of acquisition. */
935         switch (cmd->start_src) {
936         case TRIG_INT:
937                 s->async->inttrig = dio200_inttrig_start_intr;
938                 break;
939         default:
940                 /* TRIG_NOW */
941                 event = dio200_start_intr(dev, s);
942                 break;
943         }
944         comedi_spin_unlock_irqrestore(&subpriv->spinlock, flags);
945
946         if (event) {
947                 comedi_event(dev, s);
948         }
949
950         return 0;
951 }
952
953 /*
954  * This function initializes an 'INTERRUPT' subdevice.
955  */
956 static int
957 dio200_subdev_intr_init(comedi_device * dev, comedi_subdevice * s,
958         unsigned long iobase, unsigned valid_isns, int has_int_sce)
959 {
960         dio200_subdev_intr *subpriv;
961
962         subpriv = kzalloc(sizeof(*subpriv), GFP_KERNEL);
963         if (!subpriv) {
964                 printk(KERN_ERR "comedi%d: error! out of memory!\n",
965                         dev->minor);
966                 return -ENOMEM;
967         }
968         subpriv->iobase = iobase;
969         subpriv->has_int_sce = has_int_sce;
970         subpriv->valid_isns = valid_isns;
971         spin_lock_init(&subpriv->spinlock);
972
973         if (has_int_sce) {
974                 outb(0, subpriv->iobase);       /* Disable interrupt sources. */
975         }
976
977         s->private = subpriv;
978         s->type = COMEDI_SUBD_DI;
979         s->subdev_flags = SDF_READABLE | SDF_CMD_READ;
980         if (has_int_sce) {
981                 s->n_chan = DIO200_MAX_ISNS;
982                 s->len_chanlist = DIO200_MAX_ISNS;
983         } else {
984                 /* No interrupt source register.  Support single channel. */
985                 s->n_chan = 1;
986                 s->len_chanlist = 1;
987         }
988         s->range_table = &range_digital;
989         s->maxdata = 1;
990         s->insn_bits = dio200_subdev_intr_insn_bits;
991         s->do_cmdtest = dio200_subdev_intr_cmdtest;
992         s->do_cmd = dio200_subdev_intr_cmd;
993         s->cancel = dio200_subdev_intr_cancel;
994
995         return 0;
996 }
997
998 /*
999  * This function cleans up an 'INTERRUPT' subdevice.
1000  */
1001 static void
1002 dio200_subdev_intr_cleanup(comedi_device * dev, comedi_subdevice * s)
1003 {
1004         dio200_subdev_intr *subpriv = s->private;
1005
1006         if (subpriv) {
1007                 kfree(subpriv);
1008         }
1009 }
1010
1011 /*
1012  * Interrupt service routine.
1013  */
1014 static irqreturn_t dio200_interrupt(int irq, void *d PT_REGS_ARG)
1015 {
1016         comedi_device *dev = d;
1017         int handled;
1018
1019         if (!dev->attached) {
1020                 return IRQ_NONE;
1021         }
1022
1023         if (devpriv->intr_sd >= 0) {
1024                 handled = dio200_handle_read_intr(dev,
1025                         dev->subdevices + devpriv->intr_sd);
1026         } else {
1027                 handled = 0;
1028         }
1029
1030         return IRQ_RETVAL(handled);
1031 }
1032
1033 /*
1034  * Handle 'insn_read' for an '8254' counter subdevice.
1035  */
1036 static int
1037 dio200_subdev_8254_read(comedi_device * dev, comedi_subdevice * s,
1038         comedi_insn * insn, lsampl_t * data)
1039 {
1040         dio200_subdev_8254 *subpriv = s->private;
1041         int chan = CR_CHAN(insn->chanspec);
1042         unsigned long flags;
1043
1044         if (insn->n == 0)
1045                 return 0;
1046
1047         comedi_spin_lock_irqsave(&subpriv->spinlock, flags);
1048         data[0] = i8254_read(subpriv->iobase, 0, chan);
1049         comedi_spin_unlock_irqrestore(&subpriv->spinlock, flags);
1050
1051         return 1;
1052 }
1053
1054 /*
1055  * Handle 'insn_write' for an '8254' counter subdevice.
1056  */
1057 static int
1058 dio200_subdev_8254_write(comedi_device * dev, comedi_subdevice * s,
1059         comedi_insn * insn, lsampl_t * data)
1060 {
1061         dio200_subdev_8254 *subpriv = s->private;
1062         int chan = CR_CHAN(insn->chanspec);
1063         unsigned long flags;
1064
1065         if (insn->n == 0)
1066                 return 0;
1067
1068         comedi_spin_lock_irqsave(&subpriv->spinlock, flags);
1069         i8254_write(subpriv->iobase, 0, chan, data[0]);
1070         comedi_spin_unlock_irqrestore(&subpriv->spinlock, flags);
1071
1072         return 1;
1073 }
1074
1075 /*
1076  * Set gate source for an '8254' counter subdevice channel.
1077  */
1078 static int
1079 dio200_set_gate_src(dio200_subdev_8254 * subpriv, unsigned int counter_number,
1080         unsigned int gate_src)
1081 {
1082         unsigned char byte;
1083
1084         if (!subpriv->has_clk_gat_sce)
1085                 return -1;
1086         if (counter_number > 2)
1087                 return -1;
1088         if (gate_src > 7)
1089                 return -1;
1090
1091         subpriv->gate_src[counter_number] = gate_src;
1092         byte = GAT_SCE(subpriv->which, counter_number, gate_src);
1093         outb(byte, subpriv->gat_sce_iobase);
1094
1095         return 0;
1096 }
1097
1098 /*
1099  * Get gate source for an '8254' counter subdevice channel.
1100  */
1101 static int
1102 dio200_get_gate_src(dio200_subdev_8254 * subpriv, unsigned int counter_number)
1103 {
1104         if (!subpriv->has_clk_gat_sce)
1105                 return -1;
1106         if (counter_number > 2)
1107                 return -1;
1108
1109         return subpriv->gate_src[counter_number];
1110 }
1111
1112 /*
1113  * Set clock source for an '8254' counter subdevice channel.
1114  */
1115 static int
1116 dio200_set_clock_src(dio200_subdev_8254 * subpriv, unsigned int counter_number,
1117         unsigned int clock_src)
1118 {
1119         unsigned char byte;
1120
1121         if (!subpriv->has_clk_gat_sce)
1122                 return -1;
1123         if (counter_number > 2)
1124                 return -1;
1125         if (clock_src > 7)
1126                 return -1;
1127
1128         subpriv->clock_src[counter_number] = clock_src;
1129         byte = CLK_SCE(subpriv->which, counter_number, clock_src);
1130         outb(byte, subpriv->clk_sce_iobase);
1131
1132         return 0;
1133 }
1134
1135 /*
1136  * Get clock source for an '8254' counter subdevice channel.
1137  */
1138 static int
1139 dio200_get_clock_src(dio200_subdev_8254 * subpriv, unsigned int counter_number,
1140         lsampl_t * period_ns)
1141 {
1142         unsigned clock_src;
1143
1144         if (!subpriv->has_clk_gat_sce)
1145                 return -1;
1146         if (counter_number > 2)
1147                 return -1;
1148
1149         clock_src = subpriv->clock_src[counter_number];
1150         *period_ns = clock_period[clock_src];
1151         return clock_src;
1152 }
1153
1154 /*
1155  * Handle 'insn_config' for an '8254' counter subdevice.
1156  */
1157 static int
1158 dio200_subdev_8254_config(comedi_device * dev, comedi_subdevice * s,
1159         comedi_insn * insn, lsampl_t * data)
1160 {
1161         dio200_subdev_8254 *subpriv = s->private;
1162         int ret = 0;
1163         int chan = CR_CHAN(insn->chanspec);
1164         unsigned long flags;
1165
1166         comedi_spin_lock_irqsave(&subpriv->spinlock, flags);
1167         switch (data[0]) {
1168         case INSN_CONFIG_SET_COUNTER_MODE:
1169                 ret = i8254_set_mode(subpriv->iobase, 0, chan, data[1]);
1170                 if (ret < 0)
1171                         ret = -EINVAL;
1172                 break;
1173         case INSN_CONFIG_8254_READ_STATUS:
1174                 data[1] = i8254_status(subpriv->iobase, 0, chan);
1175                 break;
1176         case INSN_CONFIG_SET_GATE_SRC:
1177                 ret = dio200_set_gate_src(subpriv, chan, data[2]);
1178                 if (ret < 0)
1179                         ret = -EINVAL;
1180                 break;
1181         case INSN_CONFIG_GET_GATE_SRC:
1182                 ret = dio200_get_gate_src(subpriv, chan);
1183                 if (ret < 0) {
1184                         ret = -EINVAL;
1185                         break;
1186                 }
1187                 data[2] = ret;
1188                 break;
1189         case INSN_CONFIG_SET_CLOCK_SRC:
1190                 ret = dio200_set_clock_src(subpriv, chan, data[1]);
1191                 if (ret < 0)
1192                         ret = -EINVAL;
1193                 break;
1194         case INSN_CONFIG_GET_CLOCK_SRC:
1195                 ret = dio200_get_clock_src(subpriv, chan, &data[2]);
1196                 if (ret < 0) {
1197                         ret = -EINVAL;
1198                         break;
1199                 }
1200                 data[1] = ret;
1201                 break;
1202         default:
1203                 ret = -EINVAL;
1204                 break;
1205         }
1206         comedi_spin_unlock_irqrestore(&subpriv->spinlock, flags);
1207         return ret < 0 ? ret : insn->n;
1208 }
1209
1210 /*
1211  * This function initializes an '8254' counter subdevice.
1212  *
1213  * Note: iobase is the base address of the board, not the subdevice;
1214  * offset is the offset to the 8254 chip.
1215  */
1216 static int
1217 dio200_subdev_8254_init(comedi_device * dev, comedi_subdevice * s,
1218         unsigned long iobase, unsigned offset, int has_clk_gat_sce)
1219 {
1220         dio200_subdev_8254 *subpriv;
1221         unsigned int chan;
1222
1223         subpriv = kzalloc(sizeof(*subpriv), GFP_KERNEL);
1224         if (!subpriv) {
1225                 printk(KERN_ERR "comedi%d: error! out of memory!\n",
1226                         dev->minor);
1227                 return -ENOMEM;
1228         }
1229
1230         s->private = subpriv;
1231         s->type = COMEDI_SUBD_COUNTER;
1232         s->subdev_flags = SDF_WRITABLE | SDF_READABLE;
1233         s->n_chan = 3;
1234         s->maxdata = 0xFFFF;
1235         s->insn_read = dio200_subdev_8254_read;
1236         s->insn_write = dio200_subdev_8254_write;
1237         s->insn_config = dio200_subdev_8254_config;
1238
1239         spin_lock_init(&subpriv->spinlock);
1240         subpriv->iobase = offset + iobase;
1241         subpriv->has_clk_gat_sce = has_clk_gat_sce;
1242         if (has_clk_gat_sce) {
1243                 /* Derive CLK_SCE and GAT_SCE register offsets from
1244                  * 8254 offset. */
1245                 subpriv->clk_sce_iobase =
1246                         DIO200_XCLK_SCE + (offset >> 3) + iobase;
1247                 subpriv->gat_sce_iobase =
1248                         DIO200_XGAT_SCE + (offset >> 3) + iobase;
1249                 subpriv->which = (offset >> 2) & 1;
1250         }
1251
1252         /* Initialize channels. */
1253         for (chan = 0; chan < 3; chan++) {
1254                 i8254_set_mode(subpriv->iobase, 0, chan,
1255                         I8254_MODE0 | I8254_BINARY);
1256                 if (subpriv->has_clk_gat_sce) {
1257                         /* Gate source 0 is VCC (logic 1). */
1258                         dio200_set_gate_src(subpriv, chan, 0);
1259                         /* Clock source 0 is the dedicated clock input. */
1260                         dio200_set_clock_src(subpriv, chan, 0);
1261                 }
1262         }
1263
1264         return 0;
1265 }
1266
1267 /*
1268  * This function cleans up an '8254' counter subdevice.
1269  */
1270 static void
1271 dio200_subdev_8254_cleanup(comedi_device * dev, comedi_subdevice * s)
1272 {
1273         dio200_subdev_intr *subpriv = s->private;
1274
1275         if (subpriv) {
1276                 kfree(subpriv);
1277         }
1278 }
1279
1280 /*
1281  * Attach is called by the Comedi core to configure the driver
1282  * for a particular board.  If you specified a board_name array
1283  * in the driver structure, dev->board_ptr contains that
1284  * address.
1285  */
1286 static int dio200_attach(comedi_device * dev, comedi_devconfig * it)
1287 {
1288         comedi_subdevice *s;
1289         unsigned long iobase = 0;
1290         unsigned int irq = 0;
1291 #ifdef CONFIG_COMEDI_PCI
1292         struct pci_dev *pci_dev = NULL;
1293         int bus = 0, slot = 0;
1294 #endif
1295         const dio200_layout *layout;
1296         int share_irq = 0;
1297         int sdx;
1298         unsigned n;
1299         int ret;
1300
1301         printk(KERN_DEBUG "comedi%d: %s: attach\n", dev->minor,
1302                 DIO200_DRIVER_NAME);
1303
1304         if ((ret = alloc_private(dev, sizeof(dio200_private))) < 0) {
1305                 printk(KERN_ERR "comedi%d: error! out of memory!\n",
1306                         dev->minor);
1307                 return ret;
1308         }
1309
1310         /* Process options. */
1311         switch (thisboard->bustype) {
1312         case isa_bustype:
1313                 iobase = it->options[0];
1314                 irq = it->options[1];
1315                 share_irq = 0;
1316                 break;
1317 #ifdef CONFIG_COMEDI_PCI
1318         case pci_bustype:
1319                 bus = it->options[0];
1320                 slot = it->options[1];
1321                 share_irq = 1;
1322
1323                 if ((ret = dio200_find_pci(dev, bus, slot, &pci_dev)) < 0)
1324                         return ret;
1325                 devpriv->pci_dev = pci_dev;
1326                 break;
1327 #endif
1328         default:
1329                 printk(KERN_ERR
1330                         "comedi%d: %s: BUG! cannot determine board type!\n",
1331                         dev->minor, DIO200_DRIVER_NAME);
1332                 return -EINVAL;
1333                 break;
1334         }
1335
1336         devpriv->intr_sd = -1;
1337
1338         /* Enable device and reserve I/O spaces. */
1339 #ifdef CONFIG_COMEDI_PCI
1340         if (pci_dev) {
1341                 ret = comedi_pci_enable(pci_dev, DIO200_DRIVER_NAME);
1342                 if (ret < 0) {
1343                         printk(KERN_ERR
1344                                 "comedi%d: error! cannot enable PCI device and request regions!\n",
1345                                 dev->minor);
1346                         return ret;
1347                 }
1348                 iobase = pci_resource_start(pci_dev, 2);
1349                 irq = pci_dev->irq;
1350         } else
1351 #endif
1352         {
1353                 ret = dio200_request_region(dev->minor, iobase, DIO200_IO_SIZE);
1354                 if (ret < 0) {
1355                         return ret;
1356                 }
1357         }
1358         dev->iobase = iobase;
1359
1360         layout = thislayout;
1361         if ((ret = alloc_subdevices(dev, layout->n_subdevs)) < 0) {
1362                 printk(KERN_ERR "comedi%d: error! out of memory!\n",
1363                         dev->minor);
1364                 return ret;
1365         }
1366
1367         for (n = 0; n < dev->n_subdevices; n++) {
1368                 s = &dev->subdevices[n];
1369                 switch (layout->sdtype[n]) {
1370                 case sd_8254:
1371                         /* counter subdevice (8254) */
1372                         ret = dio200_subdev_8254_init(dev, s, iobase,
1373                                 layout->sdinfo[n], layout->has_clk_gat_sce);
1374                         if (ret < 0) {
1375                                 return ret;
1376                         }
1377                         break;
1378                 case sd_8255:
1379                         /* digital i/o subdevice (8255) */
1380                         ret = subdev_8255_init(dev, s, 0,
1381                                 iobase + layout->sdinfo[n]);
1382                         if (ret < 0) {
1383                                 return ret;
1384                         }
1385                         break;
1386                 case sd_intr:
1387                         /* 'INTERRUPT' subdevice */
1388                         if (irq) {
1389                                 ret = dio200_subdev_intr_init(dev, s,
1390                                         iobase + DIO200_INT_SCE,
1391                                         layout->sdinfo[n], layout->has_int_sce);
1392                                 if (ret < 0) {
1393                                         return ret;
1394                                 }
1395                                 devpriv->intr_sd = n;
1396                         } else {
1397                                 s->type = COMEDI_SUBD_UNUSED;
1398                         }
1399                         break;
1400                 default:
1401                         s->type = COMEDI_SUBD_UNUSED;
1402                         break;
1403                 }
1404         }
1405
1406         sdx = devpriv->intr_sd;
1407         if (sdx >= 0 && sdx < dev->n_subdevices) {
1408                 dev->read_subdev = &dev->subdevices[sdx];
1409         }
1410
1411         dev->board_name = thisboard->name;
1412
1413         if (irq) {
1414                 unsigned long flags = share_irq ? IRQF_SHARED : 0;
1415
1416                 if (comedi_request_irq(irq, dio200_interrupt, flags,
1417                                 DIO200_DRIVER_NAME, dev) >= 0) {
1418                         dev->irq = irq;
1419                 } else {
1420                         printk(KERN_WARNING
1421                                 "comedi%d: warning! irq %u unavailable!\n",
1422                                 dev->minor, irq);
1423                 }
1424         }
1425
1426         printk(KERN_INFO "comedi%d: %s ", dev->minor, dev->board_name);
1427         if (thisboard->bustype == isa_bustype) {
1428                 printk("(base %#lx) ", iobase);
1429         } else {
1430 #ifdef CONFIG_COMEDI_PCI
1431                 printk("(pci %s) ", pci_name(pci_dev));
1432 #endif
1433         }
1434         if (irq) {
1435                 printk("(irq %u%s) ", irq, (dev->irq ? "" : " UNAVAILABLE"));
1436         } else {
1437                 printk("(no irq) ");
1438         }
1439
1440         printk("attached\n");
1441
1442         return 1;
1443 }
1444
1445 /*
1446  * _detach is called to deconfigure a device.  It should deallocate
1447  * resources.
1448  * This function is also called when _attach() fails, so it should be
1449  * careful not to release resources that were not necessarily
1450  * allocated by _attach().  dev->private and dev->subdevices are
1451  * deallocated automatically by the core.
1452  */
1453 static int dio200_detach(comedi_device * dev)
1454 {
1455         const dio200_layout *layout;
1456         unsigned n;
1457
1458         printk(KERN_DEBUG "comedi%d: %s: detach\n", dev->minor,
1459                 DIO200_DRIVER_NAME);
1460
1461         if (dev->irq) {
1462                 comedi_free_irq(dev->irq, dev);
1463         }
1464         if (dev->subdevices) {
1465                 layout = thislayout;
1466                 for (n = 0; n < dev->n_subdevices; n++) {
1467                         comedi_subdevice *s = &dev->subdevices[n];
1468                         switch (layout->sdtype[n]) {
1469                         case sd_8254:
1470                                 dio200_subdev_8254_cleanup(dev, s);
1471                                 break;
1472                         case sd_8255:
1473                                 subdev_8255_cleanup(dev, s);
1474                                 break;
1475                         case sd_intr:
1476                                 dio200_subdev_intr_cleanup(dev, s);
1477                                 break;
1478                         default:
1479                                 break;
1480                         }
1481                 }
1482         }
1483         if (devpriv) {
1484 #ifdef CONFIG_COMEDI_PCI
1485                 if (devpriv->pci_dev) {
1486                         if (dev->iobase) {
1487                                 comedi_pci_disable(devpriv->pci_dev);
1488                         }
1489                         pci_dev_put(devpriv->pci_dev);
1490                 } else
1491 #endif
1492                 {
1493                         if (dev->iobase) {
1494                                 release_region(dev->iobase, DIO200_IO_SIZE);
1495                         }
1496                 }
1497         }
1498         if (dev->board_name) {
1499                 printk(KERN_INFO "comedi%d: %s removed\n",
1500                         dev->minor, dev->board_name);
1501         }
1502
1503         return 0;
1504 }