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