Staging: comedi: Remove COMEDI_INITCLEANUP macro
[linux-2.6-block.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         spinlock_t spinlock;
464 };
465
466 struct dio200_subdev_intr {
467         unsigned long iobase;
468         spinlock_t spinlock;
469         int active;
470         int has_int_sce;
471         unsigned int valid_isns;
472         unsigned int enabled_isns;
473         unsigned int stopcount;
474         int continuous;
475 };
476
477 /*
478  * The struct comedi_driver structure tells the Comedi core module
479  * which functions to call to configure/deconfigure (attach/detach)
480  * the board, and also about the kernel module that contains
481  * the device code.
482  */
483 static int dio200_attach(struct comedi_device *dev,
484                          struct comedi_devconfig *it);
485 static int dio200_detach(struct comedi_device *dev);
486 static struct comedi_driver driver_amplc_dio200 = {
487         .driver_name = DIO200_DRIVER_NAME,
488         .module = THIS_MODULE,
489         .attach = dio200_attach,
490         .detach = dio200_detach,
491         .board_name = &dio200_boards[0].name,
492         .offset = sizeof(struct dio200_board),
493         .num_names = ARRAY_SIZE(dio200_boards),
494 };
495
496 #ifdef CONFIG_COMEDI_PCI
497 COMEDI_PCI_INITCLEANUP(driver_amplc_dio200, dio200_pci_table);
498 #else
499 static int __init driver_amplc_dio200_init_module(void)
500 {
501         return comedi_driver_register(&driver_amplc_dio200);
502 }
503
504 static void __exit driver_amplc_dio200_cleanup_module(void)
505 {
506         comedi_driver_unregister(&driver_amplc_dio200);
507 }
508
509 module_init(driver_amplc_dio200_init_module);
510 module_exit(driver_amplc_dio200_cleanup_module);
511 #endif
512
513 /*
514  * This function looks for a PCI device matching the requested board name,
515  * bus and slot.
516  */
517 #ifdef CONFIG_COMEDI_PCI
518 static int
519 dio200_find_pci(struct comedi_device *dev, int bus, int slot,
520                 struct pci_dev **pci_dev_p)
521 {
522         struct pci_dev *pci_dev = NULL;
523
524         *pci_dev_p = NULL;
525
526         /* Look for matching PCI device. */
527         for (pci_dev = pci_get_device(PCI_VENDOR_ID_AMPLICON, PCI_ANY_ID, NULL);
528              pci_dev != NULL;
529              pci_dev = pci_get_device(PCI_VENDOR_ID_AMPLICON,
530                                       PCI_ANY_ID, pci_dev)) {
531                 /* If bus/slot specified, check them. */
532                 if (bus || slot) {
533                         if (bus != pci_dev->bus->number
534                             || slot != PCI_SLOT(pci_dev->devfn))
535                                 continue;
536                 }
537                 if (thisboard->model == anypci_model) {
538                         /* Match any supported model. */
539                         int i;
540
541                         for (i = 0; i < ARRAY_SIZE(dio200_boards); i++) {
542                                 if (dio200_boards[i].bustype != pci_bustype)
543                                         continue;
544                                 if (pci_dev->device == dio200_boards[i].devid) {
545                                         /* Change board_ptr to matched board. */
546                                         dev->board_ptr = &dio200_boards[i];
547                                         break;
548                                 }
549                         }
550                         if (i == ARRAY_SIZE(dio200_boards))
551                                 continue;
552                 } else {
553                         /* Match specific model name. */
554                         if (pci_dev->device != thisboard->devid)
555                                 continue;
556                 }
557
558                 /* Found a match. */
559                 *pci_dev_p = pci_dev;
560                 return 0;
561         }
562         /* No match found. */
563         if (bus || slot) {
564                 printk(KERN_ERR
565                        "comedi%d: error! no %s found at pci %02x:%02x!\n",
566                        dev->minor, thisboard->name, bus, slot);
567         } else {
568                 printk(KERN_ERR "comedi%d: error! no %s found!\n",
569                        dev->minor, thisboard->name);
570         }
571         return -EIO;
572 }
573 #endif
574
575 /*
576  * This function checks and requests an I/O region, reporting an error
577  * if there is a conflict.
578  */
579 static int
580 dio200_request_region(unsigned minor, unsigned long from, unsigned long extent)
581 {
582         if (!from || !request_region(from, extent, DIO200_DRIVER_NAME)) {
583                 printk(KERN_ERR "comedi%d: I/O port conflict (%#lx,%lu)!\n",
584                        minor, from, extent);
585                 return -EIO;
586         }
587         return 0;
588 }
589
590 /*
591  * 'insn_bits' function for an 'INTERRUPT' subdevice.
592  */
593 static int
594 dio200_subdev_intr_insn_bits(struct comedi_device *dev,
595                              struct comedi_subdevice *s,
596                              struct comedi_insn *insn, unsigned int *data)
597 {
598         struct dio200_subdev_intr *subpriv = s->private;
599
600         if (subpriv->has_int_sce) {
601                 /* Just read the interrupt status register.  */
602                 data[1] = inb(subpriv->iobase) & subpriv->valid_isns;
603         } else {
604                 /* No interrupt status register. */
605                 data[0] = 0;
606         }
607
608         return 2;
609 }
610
611 /*
612  * Called to stop acquisition for an 'INTERRUPT' subdevice.
613  */
614 static void dio200_stop_intr(struct comedi_device *dev,
615                              struct comedi_subdevice *s)
616 {
617         struct dio200_subdev_intr *subpriv = s->private;
618
619         subpriv->active = 0;
620         subpriv->enabled_isns = 0;
621         if (subpriv->has_int_sce)
622                 outb(0, subpriv->iobase);
623 }
624
625 /*
626  * Called to start acquisition for an 'INTERRUPT' subdevice.
627  */
628 static int dio200_start_intr(struct comedi_device *dev,
629                              struct comedi_subdevice *s)
630 {
631         unsigned int n;
632         unsigned isn_bits;
633         struct dio200_subdev_intr *subpriv = s->private;
634         struct comedi_cmd *cmd = &s->async->cmd;
635         int retval = 0;
636
637         if (!subpriv->continuous && subpriv->stopcount == 0) {
638                 /* An empty acquisition! */
639                 s->async->events |= COMEDI_CB_EOA;
640                 subpriv->active = 0;
641                 retval = 1;
642         } else {
643                 /* Determine interrupt sources to enable. */
644                 isn_bits = 0;
645                 if (cmd->chanlist) {
646                         for (n = 0; n < cmd->chanlist_len; n++)
647                                 isn_bits |= (1U << CR_CHAN(cmd->chanlist[n]));
648                 }
649                 isn_bits &= subpriv->valid_isns;
650                 /* Enable interrupt sources. */
651                 subpriv->enabled_isns = isn_bits;
652                 if (subpriv->has_int_sce)
653                         outb(isn_bits, subpriv->iobase);
654         }
655
656         return retval;
657 }
658
659 /*
660  * Internal trigger function to start acquisition for an 'INTERRUPT' subdevice.
661  */
662 static int
663 dio200_inttrig_start_intr(struct comedi_device *dev, struct comedi_subdevice *s,
664                           unsigned int trignum)
665 {
666         struct dio200_subdev_intr *subpriv;
667         unsigned long flags;
668         int event = 0;
669
670         if (trignum != 0)
671                 return -EINVAL;
672
673         subpriv = s->private;
674
675         spin_lock_irqsave(&subpriv->spinlock, flags);
676         s->async->inttrig = NULL;
677         if (subpriv->active)
678                 event = dio200_start_intr(dev, s);
679
680         spin_unlock_irqrestore(&subpriv->spinlock, flags);
681
682         if (event)
683                 comedi_event(dev, s);
684
685         return 1;
686 }
687
688 /*
689  * This is called from the interrupt service routine to handle a read
690  * scan on an 'INTERRUPT' subdevice.
691  */
692 static int dio200_handle_read_intr(struct comedi_device *dev,
693                                    struct comedi_subdevice *s)
694 {
695         struct dio200_subdev_intr *subpriv = s->private;
696         unsigned triggered;
697         unsigned intstat;
698         unsigned cur_enabled;
699         unsigned int oldevents;
700         unsigned long flags;
701
702         triggered = 0;
703
704         spin_lock_irqsave(&subpriv->spinlock, flags);
705         oldevents = s->async->events;
706         if (subpriv->has_int_sce) {
707                 /*
708                  * Collect interrupt sources that have triggered and disable
709                  * them temporarily.  Loop around until no extra interrupt
710                  * sources have triggered, at which point, the valid part of
711                  * the interrupt status register will read zero, clearing the
712                  * cause of the interrupt.
713                  *
714                  * Mask off interrupt sources already seen to avoid infinite
715                  * loop in case of misconfiguration.
716                  */
717                 cur_enabled = subpriv->enabled_isns;
718                 while ((intstat = (inb(subpriv->iobase) & subpriv->valid_isns
719                                    & ~triggered)) != 0) {
720                         triggered |= intstat;
721                         cur_enabled &= ~triggered;
722                         outb(cur_enabled, subpriv->iobase);
723                 }
724         } else {
725                 /*
726                  * No interrupt status register.  Assume the single interrupt
727                  * source has triggered.
728                  */
729                 triggered = subpriv->enabled_isns;
730         }
731
732         if (triggered) {
733                 /*
734                  * Some interrupt sources have triggered and have been
735                  * temporarily disabled to clear the cause of the interrupt.
736                  *
737                  * Reenable them NOW to minimize the time they are disabled.
738                  */
739                 cur_enabled = subpriv->enabled_isns;
740                 if (subpriv->has_int_sce)
741                         outb(cur_enabled, subpriv->iobase);
742
743                 if (subpriv->active) {
744                         /*
745                          * The command is still active.
746                          *
747                          * Ignore interrupt sources that the command isn't
748                          * interested in (just in case there's a race
749                          * condition).
750                          */
751                         if (triggered & subpriv->enabled_isns) {
752                                 /* Collect scan data. */
753                                 short val;
754                                 unsigned int n, ch, len;
755
756                                 val = 0;
757                                 len = s->async->cmd.chanlist_len;
758                                 for (n = 0; n < len; n++) {
759                                         ch = CR_CHAN(s->async->cmd.chanlist[n]);
760                                         if (triggered & (1U << ch))
761                                                 val |= (1U << n);
762                                 }
763                                 /* Write the scan to the buffer. */
764                                 if (comedi_buf_put(s->async, val)) {
765                                         s->async->events |= (COMEDI_CB_BLOCK |
766                                                              COMEDI_CB_EOS);
767                                 } else {
768                                         /* Error!  Stop acquisition.  */
769                                         dio200_stop_intr(dev, s);
770                                         s->async->events |= COMEDI_CB_ERROR
771                                             | COMEDI_CB_OVERFLOW;
772                                         comedi_error(dev, "buffer overflow");
773                                 }
774
775                                 /* Check for end of acquisition. */
776                                 if (!subpriv->continuous) {
777                                         /* stop_src == TRIG_COUNT */
778                                         if (subpriv->stopcount > 0) {
779                                                 subpriv->stopcount--;
780                                                 if (subpriv->stopcount == 0) {
781                                                         s->async->events |=
782                                                             COMEDI_CB_EOA;
783                                                         dio200_stop_intr(dev,
784                                                                          s);
785                                                 }
786                                         }
787                                 }
788                         }
789                 }
790         }
791         spin_unlock_irqrestore(&subpriv->spinlock, flags);
792
793         if (oldevents != s->async->events)
794                 comedi_event(dev, s);
795
796         return (triggered != 0);
797 }
798
799 /*
800  * 'cancel' function for an 'INTERRUPT' subdevice.
801  */
802 static int dio200_subdev_intr_cancel(struct comedi_device *dev,
803                                      struct comedi_subdevice *s)
804 {
805         struct dio200_subdev_intr *subpriv = s->private;
806         unsigned long flags;
807
808         spin_lock_irqsave(&subpriv->spinlock, flags);
809         if (subpriv->active)
810                 dio200_stop_intr(dev, s);
811
812         spin_unlock_irqrestore(&subpriv->spinlock, flags);
813
814         return 0;
815 }
816
817 /*
818  * 'do_cmdtest' function for an 'INTERRUPT' subdevice.
819  */
820 static int
821 dio200_subdev_intr_cmdtest(struct comedi_device *dev,
822                            struct comedi_subdevice *s, struct comedi_cmd *cmd)
823 {
824         int err = 0;
825         unsigned int tmp;
826
827         /* step 1: make sure trigger sources are trivially valid */
828
829         tmp = cmd->start_src;
830         cmd->start_src &= (TRIG_NOW | TRIG_INT);
831         if (!cmd->start_src || tmp != cmd->start_src)
832                 err++;
833
834         tmp = cmd->scan_begin_src;
835         cmd->scan_begin_src &= TRIG_EXT;
836         if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
837                 err++;
838
839         tmp = cmd->convert_src;
840         cmd->convert_src &= TRIG_NOW;
841         if (!cmd->convert_src || tmp != cmd->convert_src)
842                 err++;
843
844         tmp = cmd->scan_end_src;
845         cmd->scan_end_src &= TRIG_COUNT;
846         if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
847                 err++;
848
849         tmp = cmd->stop_src;
850         cmd->stop_src &= (TRIG_COUNT | TRIG_NONE);
851         if (!cmd->stop_src || tmp != cmd->stop_src)
852                 err++;
853
854         if (err)
855                 return 1;
856
857         /* step 2: make sure trigger sources are unique and mutually
858                    compatible */
859
860         /* these tests are true if more than one _src bit is set */
861         if ((cmd->start_src & (cmd->start_src - 1)) != 0)
862                 err++;
863         if ((cmd->scan_begin_src & (cmd->scan_begin_src - 1)) != 0)
864                 err++;
865         if ((cmd->convert_src & (cmd->convert_src - 1)) != 0)
866                 err++;
867         if ((cmd->scan_end_src & (cmd->scan_end_src - 1)) != 0)
868                 err++;
869         if ((cmd->stop_src & (cmd->stop_src - 1)) != 0)
870                 err++;
871
872         if (err)
873                 return 2;
874
875         /* step 3: make sure arguments are trivially compatible */
876
877         /* cmd->start_src == TRIG_NOW || cmd->start_src == TRIG_INT */
878         if (cmd->start_arg != 0) {
879                 cmd->start_arg = 0;
880                 err++;
881         }
882
883         /* cmd->scan_begin_src == TRIG_EXT */
884         if (cmd->scan_begin_arg != 0) {
885                 cmd->scan_begin_arg = 0;
886                 err++;
887         }
888
889         /* cmd->convert_src == TRIG_NOW */
890         if (cmd->convert_arg != 0) {
891                 cmd->convert_arg = 0;
892                 err++;
893         }
894
895         /* cmd->scan_end_src == TRIG_COUNT */
896         if (cmd->scan_end_arg != cmd->chanlist_len) {
897                 cmd->scan_end_arg = cmd->chanlist_len;
898                 err++;
899         }
900
901         switch (cmd->stop_src) {
902         case TRIG_COUNT:
903                 /* any count allowed */
904                 break;
905         case TRIG_NONE:
906                 if (cmd->stop_arg != 0) {
907                         cmd->stop_arg = 0;
908                         err++;
909                 }
910                 break;
911         default:
912                 break;
913         }
914
915         if (err)
916                 return 3;
917
918         /* step 4: fix up any arguments */
919
920         /* if (err) return 4; */
921
922         return 0;
923 }
924
925 /*
926  * 'do_cmd' function for an 'INTERRUPT' subdevice.
927  */
928 static int dio200_subdev_intr_cmd(struct comedi_device *dev,
929                                   struct comedi_subdevice *s)
930 {
931         struct comedi_cmd *cmd = &s->async->cmd;
932         struct dio200_subdev_intr *subpriv = s->private;
933         unsigned long flags;
934         int event = 0;
935
936         spin_lock_irqsave(&subpriv->spinlock, flags);
937         subpriv->active = 1;
938
939         /* Set up end of acquisition. */
940         switch (cmd->stop_src) {
941         case TRIG_COUNT:
942                 subpriv->continuous = 0;
943                 subpriv->stopcount = cmd->stop_arg;
944                 break;
945         default:
946                 /* TRIG_NONE */
947                 subpriv->continuous = 1;
948                 subpriv->stopcount = 0;
949                 break;
950         }
951
952         /* Set up start of acquisition. */
953         switch (cmd->start_src) {
954         case TRIG_INT:
955                 s->async->inttrig = dio200_inttrig_start_intr;
956                 break;
957         default:
958                 /* TRIG_NOW */
959                 event = dio200_start_intr(dev, s);
960                 break;
961         }
962         spin_unlock_irqrestore(&subpriv->spinlock, flags);
963
964         if (event)
965                 comedi_event(dev, s);
966
967         return 0;
968 }
969
970 /*
971  * This function initializes an 'INTERRUPT' subdevice.
972  */
973 static int
974 dio200_subdev_intr_init(struct comedi_device *dev, struct comedi_subdevice *s,
975                         unsigned long iobase, unsigned valid_isns,
976                         int has_int_sce)
977 {
978         struct dio200_subdev_intr *subpriv;
979
980         subpriv = kzalloc(sizeof(*subpriv), GFP_KERNEL);
981         if (!subpriv) {
982                 printk(KERN_ERR "comedi%d: error! out of memory!\n",
983                        dev->minor);
984                 return -ENOMEM;
985         }
986         subpriv->iobase = iobase;
987         subpriv->has_int_sce = has_int_sce;
988         subpriv->valid_isns = valid_isns;
989         spin_lock_init(&subpriv->spinlock);
990
991         if (has_int_sce)
992                 outb(0, subpriv->iobase);       /* Disable interrupt sources. */
993
994         s->private = subpriv;
995         s->type = COMEDI_SUBD_DI;
996         s->subdev_flags = SDF_READABLE | SDF_CMD_READ;
997         if (has_int_sce) {
998                 s->n_chan = DIO200_MAX_ISNS;
999                 s->len_chanlist = DIO200_MAX_ISNS;
1000         } else {
1001                 /* No interrupt source register.  Support single channel. */
1002                 s->n_chan = 1;
1003                 s->len_chanlist = 1;
1004         }
1005         s->range_table = &range_digital;
1006         s->maxdata = 1;
1007         s->insn_bits = dio200_subdev_intr_insn_bits;
1008         s->do_cmdtest = dio200_subdev_intr_cmdtest;
1009         s->do_cmd = dio200_subdev_intr_cmd;
1010         s->cancel = dio200_subdev_intr_cancel;
1011
1012         return 0;
1013 }
1014
1015 /*
1016  * This function cleans up an 'INTERRUPT' subdevice.
1017  */
1018 static void
1019 dio200_subdev_intr_cleanup(struct comedi_device *dev,
1020                            struct comedi_subdevice *s)
1021 {
1022         struct dio200_subdev_intr *subpriv = s->private;
1023         kfree(subpriv);
1024 }
1025
1026 /*
1027  * Interrupt service routine.
1028  */
1029 static irqreturn_t dio200_interrupt(int irq, void *d)
1030 {
1031         struct comedi_device *dev = d;
1032         int handled;
1033
1034         if (!dev->attached)
1035                 return IRQ_NONE;
1036
1037         if (devpriv->intr_sd >= 0) {
1038                 handled = dio200_handle_read_intr(dev,
1039                                                   dev->subdevices +
1040                                                   devpriv->intr_sd);
1041         } else {
1042                 handled = 0;
1043         }
1044
1045         return IRQ_RETVAL(handled);
1046 }
1047
1048 /*
1049  * Handle 'insn_read' for an '8254' counter subdevice.
1050  */
1051 static int
1052 dio200_subdev_8254_read(struct comedi_device *dev, struct comedi_subdevice *s,
1053                         struct comedi_insn *insn, unsigned int *data)
1054 {
1055         struct dio200_subdev_8254 *subpriv = s->private;
1056         int chan = CR_CHAN(insn->chanspec);
1057         unsigned long flags;
1058
1059         spin_lock_irqsave(&subpriv->spinlock, flags);
1060         data[0] = i8254_read(subpriv->iobase, 0, chan);
1061         spin_unlock_irqrestore(&subpriv->spinlock, flags);
1062
1063         return 1;
1064 }
1065
1066 /*
1067  * Handle 'insn_write' for an '8254' counter subdevice.
1068  */
1069 static int
1070 dio200_subdev_8254_write(struct comedi_device *dev, struct comedi_subdevice *s,
1071                          struct comedi_insn *insn, unsigned int *data)
1072 {
1073         struct dio200_subdev_8254 *subpriv = s->private;
1074         int chan = CR_CHAN(insn->chanspec);
1075         unsigned long flags;
1076
1077         spin_lock_irqsave(&subpriv->spinlock, flags);
1078         i8254_write(subpriv->iobase, 0, chan, data[0]);
1079         spin_unlock_irqrestore(&subpriv->spinlock, flags);
1080
1081         return 1;
1082 }
1083
1084 /*
1085  * Set gate source for an '8254' counter subdevice channel.
1086  */
1087 static int
1088 dio200_set_gate_src(struct dio200_subdev_8254 *subpriv,
1089                     unsigned int counter_number, unsigned int gate_src)
1090 {
1091         unsigned char byte;
1092
1093         if (!subpriv->has_clk_gat_sce)
1094                 return -1;
1095         if (counter_number > 2)
1096                 return -1;
1097         if (gate_src > 7)
1098                 return -1;
1099
1100         subpriv->gate_src[counter_number] = gate_src;
1101         byte = GAT_SCE(subpriv->which, counter_number, gate_src);
1102         outb(byte, subpriv->gat_sce_iobase);
1103
1104         return 0;
1105 }
1106
1107 /*
1108  * Get gate source for an '8254' counter subdevice channel.
1109  */
1110 static int
1111 dio200_get_gate_src(struct dio200_subdev_8254 *subpriv,
1112                     unsigned int counter_number)
1113 {
1114         if (!subpriv->has_clk_gat_sce)
1115                 return -1;
1116         if (counter_number > 2)
1117                 return -1;
1118
1119         return subpriv->gate_src[counter_number];
1120 }
1121
1122 /*
1123  * Set clock source for an '8254' counter subdevice channel.
1124  */
1125 static int
1126 dio200_set_clock_src(struct dio200_subdev_8254 *subpriv,
1127                      unsigned int counter_number, unsigned int clock_src)
1128 {
1129         unsigned char byte;
1130
1131         if (!subpriv->has_clk_gat_sce)
1132                 return -1;
1133         if (counter_number > 2)
1134                 return -1;
1135         if (clock_src > 7)
1136                 return -1;
1137
1138         subpriv->clock_src[counter_number] = clock_src;
1139         byte = CLK_SCE(subpriv->which, counter_number, clock_src);
1140         outb(byte, subpriv->clk_sce_iobase);
1141
1142         return 0;
1143 }
1144
1145 /*
1146  * Get clock source for an '8254' counter subdevice channel.
1147  */
1148 static int
1149 dio200_get_clock_src(struct dio200_subdev_8254 *subpriv,
1150                      unsigned int counter_number, unsigned int *period_ns)
1151 {
1152         unsigned clock_src;
1153
1154         if (!subpriv->has_clk_gat_sce)
1155                 return -1;
1156         if (counter_number > 2)
1157                 return -1;
1158
1159         clock_src = subpriv->clock_src[counter_number];
1160         *period_ns = clock_period[clock_src];
1161         return clock_src;
1162 }
1163
1164 /*
1165  * Handle 'insn_config' for an '8254' counter subdevice.
1166  */
1167 static int
1168 dio200_subdev_8254_config(struct comedi_device *dev, struct comedi_subdevice *s,
1169                           struct comedi_insn *insn, unsigned int *data)
1170 {
1171         struct dio200_subdev_8254 *subpriv = s->private;
1172         int ret = 0;
1173         int chan = CR_CHAN(insn->chanspec);
1174         unsigned long flags;
1175
1176         spin_lock_irqsave(&subpriv->spinlock, flags);
1177         switch (data[0]) {
1178         case INSN_CONFIG_SET_COUNTER_MODE:
1179                 ret = i8254_set_mode(subpriv->iobase, 0, chan, data[1]);
1180                 if (ret < 0)
1181                         ret = -EINVAL;
1182                 break;
1183         case INSN_CONFIG_8254_READ_STATUS:
1184                 data[1] = i8254_status(subpriv->iobase, 0, chan);
1185                 break;
1186         case INSN_CONFIG_SET_GATE_SRC:
1187                 ret = dio200_set_gate_src(subpriv, chan, data[2]);
1188                 if (ret < 0)
1189                         ret = -EINVAL;
1190                 break;
1191         case INSN_CONFIG_GET_GATE_SRC:
1192                 ret = dio200_get_gate_src(subpriv, chan);
1193                 if (ret < 0) {
1194                         ret = -EINVAL;
1195                         break;
1196                 }
1197                 data[2] = ret;
1198                 break;
1199         case INSN_CONFIG_SET_CLOCK_SRC:
1200                 ret = dio200_set_clock_src(subpriv, chan, data[1]);
1201                 if (ret < 0)
1202                         ret = -EINVAL;
1203                 break;
1204         case INSN_CONFIG_GET_CLOCK_SRC:
1205                 ret = dio200_get_clock_src(subpriv, chan, &data[2]);
1206                 if (ret < 0) {
1207                         ret = -EINVAL;
1208                         break;
1209                 }
1210                 data[1] = ret;
1211                 break;
1212         default:
1213                 ret = -EINVAL;
1214                 break;
1215         }
1216         spin_unlock_irqrestore(&subpriv->spinlock, flags);
1217         return ret < 0 ? ret : insn->n;
1218 }
1219
1220 /*
1221  * This function initializes an '8254' counter subdevice.
1222  *
1223  * Note: iobase is the base address of the board, not the subdevice;
1224  * offset is the offset to the 8254 chip.
1225  */
1226 static int
1227 dio200_subdev_8254_init(struct comedi_device *dev, struct comedi_subdevice *s,
1228                         unsigned long iobase, unsigned offset,
1229                         int has_clk_gat_sce)
1230 {
1231         struct dio200_subdev_8254 *subpriv;
1232         unsigned int chan;
1233
1234         subpriv = kzalloc(sizeof(*subpriv), GFP_KERNEL);
1235         if (!subpriv) {
1236                 printk(KERN_ERR "comedi%d: error! out of memory!\n",
1237                        dev->minor);
1238                 return -ENOMEM;
1239         }
1240
1241         s->private = subpriv;
1242         s->type = COMEDI_SUBD_COUNTER;
1243         s->subdev_flags = SDF_WRITABLE | SDF_READABLE;
1244         s->n_chan = 3;
1245         s->maxdata = 0xFFFF;
1246         s->insn_read = dio200_subdev_8254_read;
1247         s->insn_write = dio200_subdev_8254_write;
1248         s->insn_config = dio200_subdev_8254_config;
1249
1250         spin_lock_init(&subpriv->spinlock);
1251         subpriv->iobase = offset + iobase;
1252         subpriv->has_clk_gat_sce = has_clk_gat_sce;
1253         if (has_clk_gat_sce) {
1254                 /* Derive CLK_SCE and GAT_SCE register offsets from
1255                  * 8254 offset. */
1256                 subpriv->clk_sce_iobase =
1257                     DIO200_XCLK_SCE + (offset >> 3) + iobase;
1258                 subpriv->gat_sce_iobase =
1259                     DIO200_XGAT_SCE + (offset >> 3) + iobase;
1260                 subpriv->which = (offset >> 2) & 1;
1261         }
1262
1263         /* Initialize channels. */
1264         for (chan = 0; chan < 3; chan++) {
1265                 i8254_set_mode(subpriv->iobase, 0, chan,
1266                                I8254_MODE0 | I8254_BINARY);
1267                 if (subpriv->has_clk_gat_sce) {
1268                         /* Gate source 0 is VCC (logic 1). */
1269                         dio200_set_gate_src(subpriv, chan, 0);
1270                         /* Clock source 0 is the dedicated clock input. */
1271                         dio200_set_clock_src(subpriv, chan, 0);
1272                 }
1273         }
1274
1275         return 0;
1276 }
1277
1278 /*
1279  * This function cleans up an '8254' counter subdevice.
1280  */
1281 static void
1282 dio200_subdev_8254_cleanup(struct comedi_device *dev,
1283                            struct comedi_subdevice *s)
1284 {
1285         struct dio200_subdev_intr *subpriv = s->private;
1286         kfree(subpriv);
1287 }
1288
1289 /*
1290  * Attach is called by the Comedi core to configure the driver
1291  * for a particular board.  If you specified a board_name array
1292  * in the driver structure, dev->board_ptr contains that
1293  * address.
1294  */
1295 static int dio200_attach(struct comedi_device *dev, struct comedi_devconfig *it)
1296 {
1297         struct comedi_subdevice *s;
1298         unsigned long iobase = 0;
1299         unsigned int irq = 0;
1300 #ifdef CONFIG_COMEDI_PCI
1301         struct pci_dev *pci_dev = NULL;
1302         int bus = 0, slot = 0;
1303 #endif
1304         const struct dio200_layout_struct *layout;
1305         int share_irq = 0;
1306         int sdx;
1307         unsigned n;
1308         int ret;
1309
1310         printk(KERN_DEBUG "comedi%d: %s: attach\n", dev->minor,
1311                DIO200_DRIVER_NAME);
1312
1313         ret = alloc_private(dev, sizeof(struct dio200_private));
1314         if (ret < 0) {
1315                 printk(KERN_ERR "comedi%d: error! out of memory!\n",
1316                        dev->minor);
1317                 return ret;
1318         }
1319
1320         /* Process options. */
1321         switch (thisboard->bustype) {
1322         case isa_bustype:
1323                 iobase = it->options[0];
1324                 irq = it->options[1];
1325                 share_irq = 0;
1326                 break;
1327 #ifdef CONFIG_COMEDI_PCI
1328         case pci_bustype:
1329                 bus = it->options[0];
1330                 slot = it->options[1];
1331                 share_irq = 1;
1332
1333                 ret = dio200_find_pci(dev, bus, slot, &pci_dev);
1334                 if (ret < 0)
1335                         return ret;
1336                 devpriv->pci_dev = pci_dev;
1337                 break;
1338 #endif
1339         default:
1340                 printk(KERN_ERR
1341                        "comedi%d: %s: BUG! cannot determine board type!\n",
1342                        dev->minor, DIO200_DRIVER_NAME);
1343                 return -EINVAL;
1344                 break;
1345         }
1346
1347         devpriv->intr_sd = -1;
1348
1349         /* Enable device and reserve I/O spaces. */
1350 #ifdef CONFIG_COMEDI_PCI
1351         if (pci_dev) {
1352                 ret = comedi_pci_enable(pci_dev, DIO200_DRIVER_NAME);
1353                 if (ret < 0) {
1354                         printk(KERN_ERR
1355                                "comedi%d: error! cannot enable PCI device and request regions!\n",
1356                                dev->minor);
1357                         return ret;
1358                 }
1359                 iobase = pci_resource_start(pci_dev, 2);
1360                 irq = pci_dev->irq;
1361         } else
1362 #endif
1363         {
1364                 ret = dio200_request_region(dev->minor, iobase, DIO200_IO_SIZE);
1365                 if (ret < 0)
1366                         return ret;
1367         }
1368         dev->iobase = iobase;
1369
1370         layout = thislayout;
1371
1372         ret = alloc_subdevices(dev, layout->n_subdevs);
1373         if (ret < 0) {
1374                 printk(KERN_ERR "comedi%d: error! out of memory!\n",
1375                        dev->minor);
1376                 return ret;
1377         }
1378
1379         for (n = 0; n < dev->n_subdevices; n++) {
1380                 s = &dev->subdevices[n];
1381                 switch (layout->sdtype[n]) {
1382                 case sd_8254:
1383                         /* counter subdevice (8254) */
1384                         ret = dio200_subdev_8254_init(dev, s, iobase,
1385                                                       layout->sdinfo[n],
1386                                                       layout->has_clk_gat_sce);
1387                         if (ret < 0)
1388                                 return ret;
1389
1390                         break;
1391                 case sd_8255:
1392                         /* digital i/o subdevice (8255) */
1393                         ret = subdev_8255_init(dev, s, NULL,
1394                                                iobase + layout->sdinfo[n]);
1395                         if (ret < 0)
1396                                 return ret;
1397
1398                         break;
1399                 case sd_intr:
1400                         /* 'INTERRUPT' subdevice */
1401                         if (irq) {
1402                                 ret = dio200_subdev_intr_init(dev, s,
1403                                                               iobase +
1404                                                               DIO200_INT_SCE,
1405                                                               layout->sdinfo[n],
1406                                                               layout->
1407                                                               has_int_sce);
1408                                 if (ret < 0)
1409                                         return ret;
1410
1411                                 devpriv->intr_sd = n;
1412                         } else {
1413                                 s->type = COMEDI_SUBD_UNUSED;
1414                         }
1415                         break;
1416                 default:
1417                         s->type = COMEDI_SUBD_UNUSED;
1418                         break;
1419                 }
1420         }
1421
1422         sdx = devpriv->intr_sd;
1423         if (sdx >= 0 && sdx < dev->n_subdevices)
1424                 dev->read_subdev = &dev->subdevices[sdx];
1425
1426         dev->board_name = thisboard->name;
1427
1428         if (irq) {
1429                 unsigned long flags = share_irq ? IRQF_SHARED : 0;
1430
1431                 if (request_irq(irq, dio200_interrupt, flags,
1432                                 DIO200_DRIVER_NAME, dev) >= 0) {
1433                         dev->irq = irq;
1434                 } else {
1435                         printk(KERN_WARNING
1436                                "comedi%d: warning! irq %u unavailable!\n",
1437                                dev->minor, irq);
1438                 }
1439         }
1440
1441         printk(KERN_INFO "comedi%d: %s ", dev->minor, dev->board_name);
1442         if (thisboard->bustype == isa_bustype) {
1443                 printk("(base %#lx) ", iobase);
1444         } else {
1445 #ifdef CONFIG_COMEDI_PCI
1446                 printk("(pci %s) ", pci_name(pci_dev));
1447 #endif
1448         }
1449         if (irq)
1450                 printk("(irq %u%s) ", irq, (dev->irq ? "" : " UNAVAILABLE"));
1451         else
1452                 printk("(no irq) ");
1453
1454         printk("attached\n");
1455
1456         return 1;
1457 }
1458
1459 /*
1460  * _detach is called to deconfigure a device.  It should deallocate
1461  * resources.
1462  * This function is also called when _attach() fails, so it should be
1463  * careful not to release resources that were not necessarily
1464  * allocated by _attach().  dev->private and dev->subdevices are
1465  * deallocated automatically by the core.
1466  */
1467 static int dio200_detach(struct comedi_device *dev)
1468 {
1469         const struct dio200_layout_struct *layout;
1470         unsigned n;
1471
1472         printk(KERN_DEBUG "comedi%d: %s: detach\n", dev->minor,
1473                DIO200_DRIVER_NAME);
1474
1475         if (dev->irq)
1476                 free_irq(dev->irq, dev);
1477         if (dev->subdevices) {
1478                 layout = thislayout;
1479                 for (n = 0; n < dev->n_subdevices; n++) {
1480                         struct comedi_subdevice *s = &dev->subdevices[n];
1481                         switch (layout->sdtype[n]) {
1482                         case sd_8254:
1483                                 dio200_subdev_8254_cleanup(dev, s);
1484                                 break;
1485                         case sd_8255:
1486                                 subdev_8255_cleanup(dev, s);
1487                                 break;
1488                         case sd_intr:
1489                                 dio200_subdev_intr_cleanup(dev, s);
1490                                 break;
1491                         default:
1492                                 break;
1493                         }
1494                 }
1495         }
1496         if (devpriv) {
1497 #ifdef CONFIG_COMEDI_PCI
1498                 if (devpriv->pci_dev) {
1499                         if (dev->iobase)
1500                                 comedi_pci_disable(devpriv->pci_dev);
1501                         pci_dev_put(devpriv->pci_dev);
1502                 } else
1503 #endif
1504                 {
1505                         if (dev->iobase)
1506                                 release_region(dev->iobase, DIO200_IO_SIZE);
1507                 }
1508         }
1509         if (dev->board_name)
1510                 printk(KERN_INFO "comedi%d: %s removed\n",
1511                        dev->minor, dev->board_name);
1512
1513         return 0;
1514 }
1515
1516 MODULE_AUTHOR("Comedi http://www.comedi.org");
1517 MODULE_DESCRIPTION("Comedi low-level driver");
1518 MODULE_LICENSE("GPL");