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