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