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