ae06b6ff6177cb772f4df40fd8d32a76f6c181ef
[comedi.git] / comedi / drivers / amplc_dio200.c
1 /*
2     comedi/drivers/amplc_dio200.c
3     Driver for various Amplicon 200 series 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-2012 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), PCIe215 (pcie215 or amplc_dio200),
33   PC218E (pc218e), PCIe236 (pcie236 or amplc_dio200), PC272E (pc272e),
34   PCI272 (pci272 or amplc_dio200), PCIe296 (pcie296 or amplc_dio200)
35 Updated: Wed, 16 May 2012 13:57:58 +0100
36 Status: works
37
38 Configuration options - PC212E, PC214E, PC215E, PC218E, PC272E:
39   [0] - I/O port base address
40   [1] - IRQ (optional, but commands won't work without it)
41
42 Configuration options - PCI215, PCIe215, PCIe236, PCI272, PCIe296:
43   [0] - PCI bus of device (optional)
44   [1] - PCI slot of device (optional)
45   If bus/slot is not specified, the first available PCI device will
46   be used.
47
48 Passing a zero for an option is the same as leaving it unspecified.
49
50 SUBDEVICES
51
52                     PC212E         PC214E      PC215E/PCI215
53                  -------------  -------------  -------------
54   Subdevices           6              4              5
55    0                 PPI-X          PPI-X          PPI-X
56    1                 CTR-Y1         PPI-Y          PPI-Y
57    2                 CTR-Y2         CTR-Z1*        CTR-Z1
58    3                 CTR-Z1       INTERRUPT*       CTR-Z2
59    4                 CTR-Z2                      INTERRUPT
60    5               INTERRUPT
61
62                     PCIe215        PC218E         PCIe236
63                  -------------  -------------  -------------
64   Subdevices           8              7              8
65    0                 PPI-X          CTR-X1         PPI-X
66    1                 UNUSED         CTR-X2         UNUSED
67    2                 PPI-Y          CTR-Y1         UNUSED
68    3                 UNUSED         CTR-Y2         UNUSED
69    4                 CTR-Z1         CTR-Z1         CTR-Z1
70    5                 CTR-Z2         CTR-Z2         CTR-Z2
71    6                 TIMER        INTERRUPT        TIMER
72    7               INTERRUPT                     INTERRUPT
73
74                  PC272E/PCI272     PCIe296
75                  -------------  -------------
76   Subdevices           4              8
77    0                 PPI-X          PPI-X1
78    1                 PPI-Y          PPI-X2
79    2                 PPI-Z          PPI-Y1
80    3               INTERRUPT        PPI-Y2
81    4                                CTR-Z1
82    5                                CTR-Z2
83    6                                TIMER
84    7                              INTERRUPT
85
86 Each PPI is a 8255 chip providing 24 DIO channels.  The DIO channels
87 are configurable as inputs or outputs in four groups:
88
89   Port A  - channels  0 to  7
90   Port B  - channels  8 to 15
91   Port CL - channels 16 to 19
92   Port CH - channels 20 to 23
93
94 Only mode 0 of the 8255 chips is supported.
95
96 Each CTR is a 8254 chip providing 3 16-bit counter channels.  Each
97 channel is configured individually with INSN_CONFIG instructions.  The
98 specific type of configuration instruction is specified in data[0].
99 Some configuration instructions expect an additional parameter in
100 data[1]; others return a value in data[1].  The following configuration
101 instructions are supported:
102
103   INSN_CONFIG_SET_COUNTER_MODE.  Sets the counter channel's mode and
104     BCD/binary setting specified in data[1].
105
106   INSN_CONFIG_8254_READ_STATUS.  Reads the status register value for the
107     counter channel into data[1].
108
109   INSN_CONFIG_SET_CLOCK_SRC.  Sets the counter channel's clock source as
110     specified in data[1] (this is a hardware-specific value).  Not
111     supported on PC214E.  For the other boards, valid clock sources are
112     0 to 7 as follows:
113
114       0.  CLK n, the counter channel's dedicated CLK input from the SK1
115         connector.  (N.B. for other values, the counter channel's CLKn
116         pin on the SK1 connector is an output!)
117       1.  Internal 10 MHz clock.
118       2.  Internal 1 MHz clock.
119       3.  Internal 100 kHz clock.
120       4.  Internal 10 kHz clock.
121       5.  Internal 1 kHz clock.
122       6.  OUT n-1, the output of counter channel n-1 (see note 1 below).
123       7.  Ext Clock, the counter chip's dedicated Ext Clock input from
124         the SK1 connector.  This pin is shared by all three counter
125         channels on the chip.
126
127   INSN_CONFIG_GET_CLOCK_SRC.  Returns the counter channel's current
128     clock source in data[1].  For internal clock sources, data[2] is set
129     to the period in ns.
130
131   INSN_CONFIG_SET_GATE_SRC.  Sets the counter channel's gate source as
132     specified in data[2] (this is a hardware-specific value).  Not
133     supported on PC214E.  For the other boards, valid gate sources are 0
134     to 7 as follows:
135
136       0.  VCC (internal +5V d.c.), i.e. gate permanently enabled.
137       1.  GND (internal 0V d.c.), i.e. gate permanently disabled.
138       2.  GAT n, the counter channel's dedicated GAT input from the SK1
139         connector.  (N.B. for other values, the counter channel's GATn
140         pin on the SK1 connector is an output!)
141       3.  /OUT n-2, the inverted output of counter channel n-2 (see note
142         2 below).
143       4.  Reserved.
144       5.  Reserved.
145       6.  Reserved.
146       7.  Reserved.
147
148   INSN_CONFIG_GET_GATE_SRC.  Returns the counter channel's current gate
149     source in data[2].
150
151 Clock and gate interconnection notes:
152
153   1.  Clock source OUT n-1 is the output of the preceding channel on the
154   same counter subdevice if n > 0, or the output of channel 2 on the
155   preceding counter subdevice (see note 3) if n = 0.
156
157   2.  Gate source /OUT n-2 is the inverted output of channel 0 on the
158   same counter subdevice if n = 2, or the inverted output of channel n+1
159   on the preceding counter subdevice (see note 3) if n < 2.
160
161   3.  The counter subdevices are connected in a ring, so the highest
162   counter subdevice precedes the lowest.
163
164 The 'TIMER' subdevice is a free-running 32-bit timer subdevice.
165
166 The 'INTERRUPT' subdevice pretends to be a digital input subdevice.  The
167 digital inputs come from the interrupt status register.  The number of
168 channels matches the number of interrupt sources.  The PC214E does not
169 have an interrupt status register; see notes on 'INTERRUPT SOURCES'
170 below.
171
172 INTERRUPT SOURCES
173
174                     PC212E         PC214E      PC215E/PCI215
175                  -------------  -------------  -------------
176   Sources              6              1              6
177    0               PPI-X-C0       JUMPER-J5      PPI-X-C0
178    1               PPI-X-C3                      PPI-X-C3
179    2              CTR-Y1-OUT                     PPI-Y-C0
180    3              CTR-Y2-OUT                     PPI-Y-C3
181    4              CTR-Z1-OUT                    CTR-Z1-OUT
182    5              CTR-Z2-OUT                    CTR-Z2-OUT
183
184                     PCIe215        PC218E         PCIe236
185                  -------------  -------------  -------------
186   Sources              6              6              6
187    0               PPI-X-C0      CTR-X1-OUT      PPI-X-C0
188    1               PPI-X-C3      CTR-X2-OUT      PPI-X-C3
189    2               PPI-Y-C0      CTR-Y1-OUT       unused
190    3               PPI-Y-C3      CTR-Y2-OUT       unused
191    4              CTR-Z1-OUT     CTR-Z1-OUT     CTR-Z1-OUT
192    5              CTR-Z2-OUT     CTR-Z2-OUT     CTR-Z2-OUT
193
194                  PC272E/PCI272     PCIe296
195                  -------------  -------------
196   Sources              6              6
197    0               PPI-X-C0       PPI-X1-C0
198    1               PPI-X-C3       PPI-X1-C3
199    2               PPI-Y-C0       PPI-Y1-C0
200    3               PPI-Y-C3       PPI-Y2-C3
201    4               PPI-Z-C0      CTR-Z1-OUT
202    5               PPI-Z-C3      CTR-Z2-OUT
203
204 When an interrupt source is enabled in the interrupt source enable
205 register, a rising edge on the source signal latches the corresponding
206 bit to 1 in the interrupt status register.
207
208 When the interrupt status register value as a whole (actually, just the
209 6 least significant bits) goes from zero to non-zero, the board will
210 generate an interrupt.  For level-triggered hardware interrupts (PCI
211 card), the interrupt will remain asserted until the interrupt status
212 register is cleared to zero.  For edge-triggered hardware interrupts
213 (ISA card), no further interrupts will occur until the interrupt status
214 register is cleared to zero.  To clear a bit to zero in the interrupt
215 status register, the corresponding interrupt source must be disabled
216 in the interrupt source enable register (there is no separate interrupt
217 clear register).
218
219 The PC214E does not have an interrupt source enable register or an
220 interrupt status register; its 'INTERRUPT' subdevice has a single
221 channel and its interrupt source is selected by the position of jumper
222 J5.
223
224 COMMANDS
225
226 The driver supports a read streaming acquisition command on the
227 'INTERRUPT' subdevice.  The channel list selects the interrupt sources
228 to be enabled.  All channels will be sampled together (convert_src ==
229 TRIG_NOW).  The scan begins a short time after the hardware interrupt
230 occurs, subject to interrupt latencies (scan_begin_src == TRIG_EXT,
231 scan_begin_arg == 0).  The value read from the interrupt status register
232 is packed into a sampl_t value, one bit per requested channel, in the
233 order they appear in the channel list.
234 */
235
236 #include <linux/comedidev.h>
237
238 #include "comedi_pci.h"
239
240 #include "8255.h"
241 #include "8253.h"
242
243 #define DIO200_DRIVER_NAME      "amplc_dio200"
244
245 /* PCI IDs */
246 /* #define PCI_VENDOR_ID_AMPLICON 0x14dc */
247 #define PCI_DEVICE_ID_AMPLICON_PCI272 0x000a
248 #define PCI_DEVICE_ID_AMPLICON_PCI215 0x000b
249 #define PCI_DEVICE_ID_AMPLICON_PCIE236 0x0011
250 #define PCI_DEVICE_ID_AMPLICON_PCIE215 0x0012
251 #define PCI_DEVICE_ID_AMPLICON_PCIE296 0x0014
252 #define PCI_DEVICE_ID_INVALID 0xffff
253
254 /* 8255 control register bits */
255 #define CR_C_LO_IO      0x01
256 #define CR_B_IO         0x02
257 #define CR_B_MODE       0x04
258 #define CR_C_HI_IO      0x08
259 #define CR_A_IO         0x10
260 #define CR_A_MODE(a)    ((a)<<5)
261 #define CR_CW           0x80
262
263 /* 200 series registers */
264 #define DIO200_IO_SIZE          0x20
265 #define DIO200_PCIE_IO_SIZE     0x4000
266 #define DIO200_XCLK_SCE         0x18    /* Group X clock selection register */
267 #define DIO200_YCLK_SCE         0x19    /* Group Y clock selection register */
268 #define DIO200_ZCLK_SCE         0x1a    /* Group Z clock selection register */
269 #define DIO200_XGAT_SCE         0x1b    /* Group X gate selection register */
270 #define DIO200_YGAT_SCE         0x1c    /* Group Y gate selection register */
271 #define DIO200_ZGAT_SCE         0x1d    /* Group Z gate selection register */
272 #define DIO200_INT_SCE          0x1e    /* Interrupt enable/status register */
273
274 /*
275  * Macros for constructing value for DIO_200_?CLK_SCE and
276  * DIO_200_?GAT_SCE registers:
277  *
278  * 'which' is: 0 for CTR-X1, CTR-Y1, CTR-Z1; 1 for CTR-X2, CTR-Y2 or CTR-Z2.
279  * 'chan' is the channel: 0, 1 or 2.
280  * 'source' is the signal source: 0 to 7.
281  */
282 #define CLK_SCE(which, chan, source) (((which) << 5) | ((chan) << 3) | (source))
283 #define GAT_SCE(which, chan, source) (((which) << 5) | ((chan) << 3) | (source))
284
285 /*
286  * Periods of the internal clock sources in nanoseconds.
287  */
288 static const unsigned clock_period[8] = {
289         0,                      /* dedicated clock input/output pin */
290         100,                    /* 10 MHz */
291         1000,                   /* 1 MHz */
292         10000,                  /* 100 kHz */
293         100000,                 /* 10 kHz */
294         1000000,                /* 1 kHz */
295         0,                      /* OUT N-1 */
296         0                       /* group clock input pin */
297 };
298
299 /*
300  * Register region.
301  */
302 enum dio200_regtype { no_regtype, io_regtype, mmio_regtype };
303 struct dio200_region {
304         union {
305                 unsigned long iobase;           /* I/O base address */
306                 unsigned char __iomem *membase; /* Mapped MMIO base address */
307         } u;
308         unsigned char regtype;
309         unsigned char regshift;
310 };
311
312 /*
313  * Board descriptions.
314  */
315
316 enum dio200_bustype { isa_bustype, pci_bustype };
317
318 enum dio200_model {
319         pc212e_model,
320         pc214e_model,
321         pc215e_model, pci215_model, pcie215_model,
322         pc218e_model,
323         pcie236_model,
324         pc272e_model, pci272_model,
325         pcie296_model,
326         anypci_model
327 };
328
329 enum dio200_layout {
330         pc212_layout,
331         pc214_layout,
332         pc215_layout,
333         pc218_layout,
334         pc272_layout,
335 #ifdef CONFIG_COMEDI_PCI
336         pcie215_layout,
337         pcie236_layout,
338         pcie296_layout,
339 #endif
340         num_layouts
341 };
342
343 typedef struct dio200_board_struct {
344         const char *name;
345         unsigned short devid;
346         enum dio200_bustype bustype;
347         enum dio200_model model;
348         enum dio200_layout layout;
349         unsigned char mainbar;
350         unsigned char mainshift;
351         unsigned int mainsize;
352 } dio200_board;
353
354 static const dio200_board dio200_boards[] = {
355         {
356               name:     "pc212e",
357               bustype:  isa_bustype,
358               model:    pc212e_model,
359               layout:   pc212_layout,
360               mainsize: DIO200_IO_SIZE,
361                 },
362         {
363               name:     "pc214e",
364               bustype:  isa_bustype,
365               model:    pc214e_model,
366               layout:   pc214_layout,
367               mainsize: DIO200_IO_SIZE,
368                 },
369         {
370               name:     "pc215e",
371               bustype:  isa_bustype,
372               model:    pc215e_model,
373               layout:   pc215_layout,
374               mainsize: DIO200_IO_SIZE,
375                 },
376 #ifdef CONFIG_COMEDI_PCI
377         {
378               name:     "pci215",
379               devid:    PCI_DEVICE_ID_AMPLICON_PCI215,
380               bustype:  pci_bustype,
381               model:    pci215_model,
382               layout:   pc215_layout,
383               mainsize: DIO200_IO_SIZE,
384               mainbar:  2,
385                 },
386 #endif
387 #ifdef CONFIG_COMEDI_PCI
388         {
389               name:     "pcie215",
390               devid:    PCI_DEVICE_ID_AMPLICON_PCIE215,
391               bustype:  pci_bustype,
392               model:    pcie215_model,
393               layout:   pcie215_layout,
394               mainsize: DIO200_PCIE_IO_SIZE,
395               mainbar:  1,
396               mainshift: 3,
397                 },
398 #endif
399         {
400               name:     "pc218e",
401               bustype:  isa_bustype,
402               model:    pc218e_model,
403               layout:   pc218_layout,
404               mainsize: DIO200_IO_SIZE,
405                 },
406 #ifdef CONFIG_COMEDI_PCI
407         {
408               name:     "pcie236",
409               devid:    PCI_DEVICE_ID_AMPLICON_PCIE236,
410               bustype:  pci_bustype,
411               model:    pcie236_model,
412               layout:   pcie236_layout,
413               mainsize: DIO200_PCIE_IO_SIZE,
414               mainbar:  1,
415               mainshift: 3,
416                 },
417 #endif
418         {
419               name:     "pc272e",
420               bustype:  isa_bustype,
421               model:    pc272e_model,
422               layout:   pc272_layout,
423               mainsize: DIO200_IO_SIZE,
424                 },
425 #ifdef CONFIG_COMEDI_PCI
426         {
427               name:     "pci272",
428               devid:    PCI_DEVICE_ID_AMPLICON_PCI272,
429               bustype:  pci_bustype,
430               model:    pci272_model,
431               layout:   pc272_layout,
432               mainsize: DIO200_IO_SIZE,
433               mainbar:  2,
434                 },
435 #endif
436 #ifdef CONFIG_COMEDI_PCI
437         {
438               name:     "pcie296",
439               devid:    PCI_DEVICE_ID_AMPLICON_PCIE296,
440               bustype:  pci_bustype,
441               model:    pcie296_model,
442               layout:   pcie296_layout,
443               mainsize: DIO200_PCIE_IO_SIZE,
444               mainbar:  1,
445               mainshift: 3,
446                 },
447 #endif
448 #ifdef CONFIG_COMEDI_PCI
449         {
450               name:     DIO200_DRIVER_NAME,
451               devid:    PCI_DEVICE_ID_INVALID,
452               bustype:  pci_bustype,
453               model:    anypci_model,   /* wildcard */
454                 },
455 #endif
456 };
457
458 /*
459  * Layout descriptions - some ISA and PCI board descriptions share the same
460  * layout.
461  */
462
463 enum dio200_sdtype { sd_none, sd_intr, sd_8255, sd_8254, sd_timer };
464
465 #define DIO200_MAX_SUBDEVS      8
466 #define DIO200_MAX_ISNS         6
467
468 typedef struct dio200_layout_struct {
469         unsigned short n_subdevs;       /* number of subdevices */
470         unsigned char sdtype[DIO200_MAX_SUBDEVS];       /* enum dio200_sdtype */
471         unsigned char sdinfo[DIO200_MAX_SUBDEVS];       /* depends on sdtype */
472         char has_int_sce;       /* has interrupt enable/status register */
473         char has_clk_gat_sce;   /* has clock/gate selection registers */
474 } dio200_layout;
475
476 static const dio200_layout dio200_layouts[] = {
477         [pc212_layout] = {
478               n_subdevs:6,
479               sdtype:   {sd_8255, sd_8254, sd_8254, sd_8254,
480                                         sd_8254,
481                                 sd_intr},
482               sdinfo:   {0x00, 0x08, 0x0C, 0x10, 0x14,
483                                 0x3F},
484               has_int_sce:1,
485               has_clk_gat_sce:1,
486                 },
487         [pc214_layout] = {
488               n_subdevs:4,
489               sdtype:   {sd_8255, sd_8255, sd_8254,
490                                 sd_intr},
491               sdinfo:   {0x00, 0x08, 0x10, 0x01},
492               has_int_sce:0,
493               has_clk_gat_sce:0,
494                 },
495         [pc215_layout] = {
496               n_subdevs:5,
497               sdtype:   {sd_8255, sd_8255, sd_8254,
498                                         sd_8254,
499                                 sd_intr},
500               sdinfo:   {0x00, 0x08, 0x10, 0x14, 0x3F},
501               has_int_sce:1,
502               has_clk_gat_sce:1,
503                 },
504         [pc218_layout] = {
505               n_subdevs:7,
506               sdtype:   {sd_8254, sd_8254, sd_8255, sd_8254,
507                                         sd_8254,
508                                 sd_intr},
509               sdinfo:   {0x00, 0x04, 0x08, 0x0C, 0x10,
510                                         0x14,
511                                 0x3F},
512               has_int_sce:1,
513               has_clk_gat_sce:1,
514                 },
515         [pc272_layout] = {
516               n_subdevs:4,
517               sdtype:   {sd_8255, sd_8255, sd_8255,
518                                 sd_intr},
519               sdinfo:   {0x00, 0x08, 0x10, 0x3F},
520               has_int_sce:1,
521               has_clk_gat_sce:0,
522                 },
523 #ifdef CONFIG_COMEDI_PCI
524         [pcie215_layout] = {
525               n_subdevs:8,
526               sdtype:   {sd_8255, sd_none, sd_8255, sd_none, sd_8254, sd_8254,
527                                 sd_timer, sd_intr},
528               sdinfo:   {0x00, 0x00, 0x08, 0x00, 0x10, 0x14, 0x00, 0x3F},
529               has_int_sce:1,
530               has_clk_gat_sce:1,
531                 },
532         [pcie236_layout] = {
533               n_subdevs:8,
534               sdtype:   {sd_8255, sd_none, sd_none, sd_none, sd_8254, sd_8254,
535                                 sd_timer, sd_intr},
536               sdinfo:   {0x00, 0x00, 0x00, 0x00, 0x10, 0x14, 0x00, 0x3F},
537               has_int_sce:1,
538               has_clk_gat_sce:1,
539                 },
540         [pcie296_layout] = {
541               n_subdevs:8,
542               sdtype:   {sd_8255, sd_8255, sd_8255, sd_8255, sd_8254, sd_8254,
543                                 sd_timer, sd_intr},
544               sdinfo:   {0x00, 0x04, 0x08, 0x0C, 0x10, 0x14, 0x00, 0x3F},
545               has_int_sce:1,
546               has_clk_gat_sce:1,
547                 },
548 #endif
549 };
550
551 /*
552  * PCI driver table.
553  */
554
555 #ifdef CONFIG_COMEDI_PCI
556 static DEFINE_PCI_DEVICE_TABLE(dio200_pci_table) = {
557         {PCI_VENDOR_ID_AMPLICON, PCI_DEVICE_ID_AMPLICON_PCI215,
558                 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
559         {PCI_VENDOR_ID_AMPLICON, PCI_DEVICE_ID_AMPLICON_PCI272,
560                 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
561         {PCI_VENDOR_ID_AMPLICON, PCI_DEVICE_ID_AMPLICON_PCIE236,
562                 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
563         {PCI_VENDOR_ID_AMPLICON, PCI_DEVICE_ID_AMPLICON_PCIE215,
564                 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
565         {PCI_VENDOR_ID_AMPLICON, PCI_DEVICE_ID_AMPLICON_PCIE296,
566                 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
567         {0}
568 };
569
570 MODULE_DEVICE_TABLE(pci, dio200_pci_table);
571 #endif /* CONFIG_COMEDI_PCI */
572
573 /*
574  * Useful for shorthand access to the particular board structure
575  */
576 #define thisboard ((const dio200_board *)dev->board_ptr)
577 #define thislayout (&dio200_layouts[((dio200_board *)dev->board_ptr)->layout])
578
579 /* this structure is for data unique to this hardware driver.  If
580    several hardware drivers keep similar information in this structure,
581    feel free to suggest moving the variable to the comedi_device struct.  */
582 typedef struct {
583 #ifdef CONFIG_COMEDI_PCI
584         struct pci_dev *pci_dev;        /* PCI device */
585 #endif
586         struct dio200_region io;        /* Register region */
587         int intr_sd;
588 } dio200_private;
589
590 #define devpriv ((dio200_private *)dev->private)
591
592 typedef struct {
593         unsigned int ofs;               /* Counter base offset */
594         unsigned int clk_sce_ofs;       /* CLK_SCE base offset */
595         unsigned int gat_sce_ofs;       /* GAT_SCE base offset */
596         int which;                      /* Bit 5 of CLK_SCE or GAT_SCE */
597         unsigned int clock_src[3];      /* Current clock sources */
598         unsigned int gate_src[3];       /* Current gate sources */
599         spinlock_t spinlock;
600 } dio200_subdev_8254;
601
602 typedef struct {
603         unsigned int ofs;               /* DIO base offset */
604 } dio200_subdev_8255;
605
606 typedef struct {
607         unsigned int ofs;
608         spinlock_t spinlock;
609         int active;
610         unsigned int valid_isns;
611         unsigned int enabled_isns;
612         unsigned int stopcount;
613         int continuous;
614 } dio200_subdev_intr;
615
616 /*
617  * The comedi_driver structure tells the Comedi core module
618  * which functions to call to configure/deconfigure (attach/detach)
619  * the board, and also about the kernel module that contains
620  * the device code.
621  */
622 static int dio200_attach(comedi_device * dev, comedi_devconfig * it);
623 static int dio200_detach(comedi_device * dev);
624 static comedi_driver driver_amplc_dio200 = {
625       driver_name:DIO200_DRIVER_NAME,
626       module:THIS_MODULE,
627       attach:dio200_attach,
628       detach:dio200_detach,
629       board_name:&dio200_boards[0].name,
630       offset:sizeof(dio200_board),
631       num_names:sizeof(dio200_boards) / sizeof(dio200_board),
632 };
633
634 #ifdef CONFIG_COMEDI_PCI
635 COMEDI_PCI_INITCLEANUP(driver_amplc_dio200, dio200_pci_table);
636 #else
637 COMEDI_INITCLEANUP(driver_amplc_dio200);
638 #endif
639
640 /*
641  * Read 8-bit register.
642  */
643 static unsigned char dio200_read8(comedi_device * dev, unsigned int offset)
644 {
645         offset <<= devpriv->io.regshift;
646         if (devpriv->io.regtype == io_regtype)
647                 return inb(devpriv->io.u.iobase + offset);
648         else
649                 return readb(devpriv->io.u.membase + offset);
650 }
651
652 /*
653  * Write 8-bit register.
654  */
655 static void dio200_write8(comedi_device * dev, unsigned int offset,
656                 unsigned char val)
657 {
658         offset <<= devpriv->io.regshift;
659         if (devpriv->io.regtype == io_regtype)
660                 outb(val, devpriv->io.u.iobase + offset);
661         else
662                 writeb(val, devpriv->io.u.membase + offset);
663 }
664
665 /*
666  * This function looks for a PCI device matching the requested board name,
667  * bus and slot.
668  */
669 #ifdef CONFIG_COMEDI_PCI
670 static int
671 dio200_find_pci(comedi_device * dev, int bus, int slot,
672         struct pci_dev **pci_dev_p)
673 {
674         struct pci_dev *pci_dev = NULL;
675
676         *pci_dev_p = NULL;
677
678         /* Look for matching PCI device. */
679         for (pci_dev = pci_get_device(PCI_VENDOR_ID_AMPLICON, PCI_ANY_ID, NULL);
680                 pci_dev != NULL;
681                 pci_dev = pci_get_device(PCI_VENDOR_ID_AMPLICON,
682                         PCI_ANY_ID, pci_dev)) {
683                 /* If bus/slot specified, check them. */
684                 if (bus || slot) {
685                         if (bus != pci_dev->bus->number
686                                 || slot != PCI_SLOT(pci_dev->devfn))
687                                 continue;
688                 }
689                 if (thisboard->model == anypci_model) {
690                         /* Match any supported model. */
691                         int i;
692
693                         for (i = 0; i < ARRAY_SIZE(dio200_boards); i++) {
694                                 if (dio200_boards[i].bustype != pci_bustype)
695                                         continue;
696                                 if (pci_dev->device == dio200_boards[i].devid) {
697                                         /* Change board_ptr to matched board. */
698                                         dev->board_ptr = &dio200_boards[i];
699                                         break;
700                                 }
701                         }
702                         if (i == ARRAY_SIZE(dio200_boards))
703                                 continue;
704                 } else {
705                         /* Match specific model name. */
706                         if (pci_dev->device != thisboard->devid)
707                                 continue;
708                 }
709
710                 /* Found a match. */
711                 *pci_dev_p = pci_dev;
712                 return 0;
713         }
714         /* No match found. */
715         if (bus || slot) {
716                 printk(KERN_ERR
717                         "comedi%d: error! no %s found at pci %02x:%02x!\n",
718                         dev->minor, thisboard->name, bus, slot);
719         } else {
720                 printk(KERN_ERR "comedi%d: error! no %s found!\n",
721                         dev->minor, thisboard->name);
722         }
723         return -EIO;
724 }
725 #endif
726
727 /*
728  * This function checks and requests an I/O region, reporting an error
729  * if there is a conflict.
730  */
731 static int
732 dio200_request_region(unsigned minor, unsigned long from, unsigned long extent)
733 {
734         if (!from || !request_region(from, extent, DIO200_DRIVER_NAME)) {
735                 printk(KERN_ERR "comedi%d: I/O port conflict (%#lx,%lu)!\n",
736                         minor, from, extent);
737                 return -EIO;
738         }
739         return 0;
740 }
741
742 /*
743  * 'insn_bits' function for an 'INTERRUPT' subdevice.
744  */
745 static int
746 dio200_subdev_intr_insn_bits(comedi_device * dev, comedi_subdevice * s,
747         comedi_insn * insn, lsampl_t * data)
748 {
749         dio200_subdev_intr *subpriv = s->private;
750
751         if (thislayout->has_int_sce) {
752                 /* Just read the interrupt status register.  */
753                 data[1] = dio200_read8(dev, subpriv->ofs) & subpriv->valid_isns;
754         } else {
755                 /* No interrupt status register. */
756                 data[0] = 0;
757         }
758
759         return 2;
760 }
761
762 /*
763  * Called to stop acquisition for an 'INTERRUPT' subdevice.
764  */
765 static void dio200_stop_intr(comedi_device * dev, comedi_subdevice * s)
766 {
767         dio200_subdev_intr *subpriv = s->private;
768
769         subpriv->active = 0;
770         subpriv->enabled_isns = 0;
771         if (thislayout->has_int_sce) {
772                 dio200_write8(dev, subpriv->ofs, 0);
773         }
774 }
775
776 /*
777  * Called to start acquisition for an 'INTERRUPT' subdevice.
778  */
779 static int dio200_start_intr(comedi_device * dev, comedi_subdevice * s)
780 {
781         unsigned int n;
782         unsigned isn_bits;
783         dio200_subdev_intr *subpriv = s->private;
784         comedi_cmd *cmd = &s->async->cmd;
785         int retval = 0;
786
787         if (!subpriv->continuous && subpriv->stopcount == 0) {
788                 /* An empty acquisition! */
789                 s->async->events |= COMEDI_CB_EOA;
790                 subpriv->active = 0;
791                 retval = 1;
792         } else {
793                 /* Determine interrupt sources to enable. */
794                 isn_bits = 0;
795                 if (cmd->chanlist) {
796                         for (n = 0; n < cmd->chanlist_len; n++) {
797                                 isn_bits |= (1U << CR_CHAN(cmd->chanlist[n]));
798                         }
799                 }
800                 isn_bits &= subpriv->valid_isns;
801                 /* Enable interrupt sources. */
802                 subpriv->enabled_isns = isn_bits;
803                 if (thislayout->has_int_sce) {
804                         dio200_write8(dev, subpriv->ofs, isn_bits);
805                 }
806         }
807
808         return retval;
809 }
810
811 /*
812  * Internal trigger function to start acquisition for an 'INTERRUPT' subdevice.
813  */
814 static int
815 dio200_inttrig_start_intr(comedi_device * dev, comedi_subdevice * s,
816         unsigned int trignum)
817 {
818         dio200_subdev_intr *subpriv;
819         unsigned long flags;
820         int event = 0;
821
822         if (trignum != 0)
823                 return -EINVAL;
824
825         subpriv = s->private;
826
827         comedi_spin_lock_irqsave(&subpriv->spinlock, flags);
828         s->async->inttrig = 0;
829         if (subpriv->active) {
830                 event = dio200_start_intr(dev, s);
831         }
832         comedi_spin_unlock_irqrestore(&subpriv->spinlock, flags);
833
834         if (event) {
835                 comedi_event(dev, s);
836         }
837
838         return 1;
839 }
840
841 /*
842  * This is called from the interrupt service routine to handle a read
843  * scan on an 'INTERRUPT' subdevice.
844  */
845 static int dio200_handle_read_intr(comedi_device * dev, comedi_subdevice * s)
846 {
847         dio200_subdev_intr *subpriv = s->private;
848         unsigned triggered;
849         unsigned intstat;
850         unsigned cur_enabled;
851         unsigned int oldevents;
852         unsigned long flags;
853         unsigned int int_sce_ofs;
854
855         int_sce_ofs = subpriv->ofs;
856         triggered = 0;
857
858         comedi_spin_lock_irqsave(&subpriv->spinlock, flags);
859         oldevents = s->async->events;
860         if (thislayout->has_int_sce) {
861                 /*
862                  * Collect interrupt sources that have triggered and disable
863                  * them temporarily.  Loop around until no extra interrupt
864                  * sources have triggered, at which point, the valid part of
865                  * the interrupt status register will read zero, clearing the
866                  * cause of the interrupt.
867                  *
868                  * Mask off interrupt sources already seen to avoid infinite
869                  * loop in case of misconfiguration.
870                  */
871                 cur_enabled = subpriv->enabled_isns;
872                 while ((intstat = (dio200_read8(dev, int_sce_ofs)
873                                         & subpriv->valid_isns & ~triggered))
874                                 != 0) {
875                         triggered |= intstat;
876                         cur_enabled &= ~triggered;
877                         dio200_write8(dev, int_sce_ofs, cur_enabled);
878                 }
879         } else {
880                 /*
881                  * No interrupt status register.  Assume the single interrupt
882                  * source has triggered.
883                  */
884                 triggered = subpriv->enabled_isns;
885         }
886
887         if (triggered) {
888                 /*
889                  * Some interrupt sources have triggered and have been
890                  * temporarily disabled to clear the cause of the interrupt.
891                  *
892                  * Reenable them NOW to minimize the time they are disabled.
893                  */
894                 cur_enabled = subpriv->enabled_isns;
895                 if (thislayout->has_int_sce) {
896                         dio200_write8(dev, int_sce_ofs, cur_enabled);
897                 }
898
899                 if (subpriv->active) {
900                         /*
901                          * The command is still active.
902                          *
903                          * Ignore interrupt sources that the command isn't
904                          * interested in (just in case there's a race
905                          * condition).
906                          */
907                         if (triggered & subpriv->enabled_isns) {
908                                 /* Collect scan data. */
909                                 sampl_t val;
910                                 unsigned int n, ch, len;
911
912                                 val = 0;
913                                 len = s->async->cmd.chanlist_len;
914                                 for (n = 0; n < len; n++) {
915                                         ch = CR_CHAN(s->async->cmd.chanlist[n]);
916                                         if (triggered & (1U << ch)) {
917                                                 val |= (1U << n);
918                                         }
919                                 }
920                                 /* Write the scan to the buffer. */
921                                 if (comedi_buf_put(s->async, val)) {
922                                         s->async->events |= (COMEDI_CB_BLOCK |
923                                                 COMEDI_CB_EOS);
924                                 } else {
925                                         /* Error!  Stop acquisition.  */
926                                         dio200_stop_intr(dev, s);
927                                         s->async->events |= COMEDI_CB_ERROR
928                                                 | COMEDI_CB_OVERFLOW;
929                                         comedi_error(dev, "buffer overflow");
930                                 }
931
932                                 /* Check for end of acquisition. */
933                                 if (!subpriv->continuous) {
934                                         /* stop_src == TRIG_COUNT */
935                                         if (subpriv->stopcount > 0) {
936                                                 subpriv->stopcount--;
937                                                 if (subpriv->stopcount == 0) {
938                                                         s->async->events |=
939                                                                 COMEDI_CB_EOA;
940                                                         dio200_stop_intr(dev,
941                                                                 s);
942                                                 }
943                                         }
944                                 }
945                         }
946                 }
947         }
948         comedi_spin_unlock_irqrestore(&subpriv->spinlock, flags);
949
950         if (oldevents != s->async->events) {
951                 comedi_event(dev, s);
952         }
953
954         return (triggered != 0);
955 }
956
957 /*
958  * 'cancel' function for an 'INTERRUPT' subdevice.
959  */
960 static int dio200_subdev_intr_cancel(comedi_device * dev, comedi_subdevice * s)
961 {
962         dio200_subdev_intr *subpriv = s->private;
963         unsigned long flags;
964
965         comedi_spin_lock_irqsave(&subpriv->spinlock, flags);
966         if (subpriv->active) {
967                 dio200_stop_intr(dev, s);
968         }
969         comedi_spin_unlock_irqrestore(&subpriv->spinlock, flags);
970
971         return 0;
972 }
973
974 /*
975  * 'do_cmdtest' function for an 'INTERRUPT' subdevice.
976  */
977 static int
978 dio200_subdev_intr_cmdtest(comedi_device * dev, comedi_subdevice * s,
979         comedi_cmd * cmd)
980 {
981         int err = 0;
982         unsigned int tmp;
983
984         /* step 1: make sure trigger sources are trivially valid */
985
986         tmp = cmd->start_src;
987         cmd->start_src &= (TRIG_NOW | TRIG_INT);
988         if (!cmd->start_src || tmp != cmd->start_src)
989                 err++;
990
991         tmp = cmd->scan_begin_src;
992         cmd->scan_begin_src &= TRIG_EXT;
993         if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
994                 err++;
995
996         tmp = cmd->convert_src;
997         cmd->convert_src &= TRIG_NOW;
998         if (!cmd->convert_src || tmp != cmd->convert_src)
999                 err++;
1000
1001         tmp = cmd->scan_end_src;
1002         cmd->scan_end_src &= TRIG_COUNT;
1003         if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
1004                 err++;
1005
1006         tmp = cmd->stop_src;
1007         cmd->stop_src &= (TRIG_COUNT | TRIG_NONE);
1008         if (!cmd->stop_src || tmp != cmd->stop_src)
1009                 err++;
1010
1011         if (err)
1012                 return 1;
1013
1014         /* step 2: make sure trigger sources are unique and mutually compatible */
1015
1016         /* these tests are true if more than one _src bit is set */
1017         if ((cmd->start_src & (cmd->start_src - 1)) != 0)
1018                 err++;
1019         if ((cmd->scan_begin_src & (cmd->scan_begin_src - 1)) != 0)
1020                 err++;
1021         if ((cmd->convert_src & (cmd->convert_src - 1)) != 0)
1022                 err++;
1023         if ((cmd->scan_end_src & (cmd->scan_end_src - 1)) != 0)
1024                 err++;
1025         if ((cmd->stop_src & (cmd->stop_src - 1)) != 0)
1026                 err++;
1027
1028         if (err)
1029                 return 2;
1030
1031         /* step 3: make sure arguments are trivially compatible */
1032
1033         /* cmd->start_src == TRIG_NOW || cmd->start_src == TRIG_INT */
1034         if (cmd->start_arg != 0) {
1035                 cmd->start_arg = 0;
1036                 err++;
1037         }
1038
1039         /* cmd->scan_begin_src == TRIG_EXT */
1040         if (cmd->scan_begin_arg != 0) {
1041                 cmd->scan_begin_arg = 0;
1042                 err++;
1043         }
1044
1045         /* cmd->convert_src == TRIG_NOW */
1046         if (cmd->convert_arg != 0) {
1047                 cmd->convert_arg = 0;
1048                 err++;
1049         }
1050
1051         /* cmd->scan_end_src == TRIG_COUNT */
1052         if (cmd->scan_end_arg != cmd->chanlist_len) {
1053                 cmd->scan_end_arg = cmd->chanlist_len;
1054                 err++;
1055         }
1056
1057         switch (cmd->stop_src) {
1058         case TRIG_COUNT:
1059                 /* any count allowed */
1060                 break;
1061         case TRIG_NONE:
1062                 if (cmd->stop_arg != 0) {
1063                         cmd->stop_arg = 0;
1064                         err++;
1065                 }
1066                 break;
1067         default:
1068                 break;
1069         }
1070
1071         if (err)
1072                 return 3;
1073
1074         /* step 4: fix up any arguments */
1075
1076         /* if (err) return 4; */
1077
1078         return 0;
1079 }
1080
1081 /*
1082  * 'do_cmd' function for an 'INTERRUPT' subdevice.
1083  */
1084 static int dio200_subdev_intr_cmd(comedi_device * dev, comedi_subdevice * s)
1085 {
1086         comedi_cmd *cmd = &s->async->cmd;
1087         dio200_subdev_intr *subpriv = s->private;
1088         unsigned long flags;
1089         int event = 0;
1090
1091         comedi_spin_lock_irqsave(&subpriv->spinlock, flags);
1092         subpriv->active = 1;
1093
1094         /* Set up end of acquisition. */
1095         switch (cmd->stop_src) {
1096         case TRIG_COUNT:
1097                 subpriv->continuous = 0;
1098                 subpriv->stopcount = cmd->stop_arg;
1099                 break;
1100         default:
1101                 /* TRIG_NONE */
1102                 subpriv->continuous = 1;
1103                 subpriv->stopcount = 0;
1104                 break;
1105         }
1106
1107         /* Set up start of acquisition. */
1108         switch (cmd->start_src) {
1109         case TRIG_INT:
1110                 s->async->inttrig = dio200_inttrig_start_intr;
1111                 break;
1112         default:
1113                 /* TRIG_NOW */
1114                 event = dio200_start_intr(dev, s);
1115                 break;
1116         }
1117         comedi_spin_unlock_irqrestore(&subpriv->spinlock, flags);
1118
1119         if (event) {
1120                 comedi_event(dev, s);
1121         }
1122
1123         return 0;
1124 }
1125
1126 /*
1127  * This function initializes an 'INTERRUPT' subdevice.
1128  */
1129 static int
1130 dio200_subdev_intr_init(comedi_device * dev, comedi_subdevice * s,
1131         unsigned int offset, unsigned valid_isns)
1132 {
1133         dio200_subdev_intr *subpriv;
1134
1135         subpriv = kzalloc(sizeof(*subpriv), GFP_KERNEL);
1136         if (!subpriv) {
1137                 printk(KERN_ERR "comedi%d: error! out of memory!\n",
1138                         dev->minor);
1139                 return -ENOMEM;
1140         }
1141         subpriv->ofs = offset;
1142         subpriv->valid_isns = valid_isns;
1143         spin_lock_init(&subpriv->spinlock);
1144
1145         if (thislayout->has_int_sce) {
1146                 /* Disable interrupt sources. */
1147                 dio200_write8(dev, subpriv->ofs, 0);
1148         }
1149
1150         s->private = subpriv;
1151         s->type = COMEDI_SUBD_DI;
1152         s->subdev_flags = SDF_READABLE | SDF_CMD_READ;
1153         if (thislayout->has_int_sce) {
1154                 s->n_chan = DIO200_MAX_ISNS;
1155                 s->len_chanlist = DIO200_MAX_ISNS;
1156         } else {
1157                 /* No interrupt source register.  Support single channel. */
1158                 s->n_chan = 1;
1159                 s->len_chanlist = 1;
1160         }
1161         s->range_table = &range_digital;
1162         s->maxdata = 1;
1163         s->insn_bits = dio200_subdev_intr_insn_bits;
1164         s->do_cmdtest = dio200_subdev_intr_cmdtest;
1165         s->do_cmd = dio200_subdev_intr_cmd;
1166         s->cancel = dio200_subdev_intr_cancel;
1167
1168         return 0;
1169 }
1170
1171 /*
1172  * This function cleans up an 'INTERRUPT' subdevice.
1173  */
1174 static void
1175 dio200_subdev_intr_cleanup(comedi_device * dev, comedi_subdevice * s)
1176 {
1177         dio200_subdev_intr *subpriv = s->private;
1178
1179         if (subpriv) {
1180                 kfree(subpriv);
1181         }
1182 }
1183
1184 /*
1185  * Interrupt service routine.
1186  */
1187 static irqreturn_t dio200_interrupt(int irq, void *d PT_REGS_ARG)
1188 {
1189         comedi_device *dev = d;
1190         int handled;
1191
1192         if (!dev->attached) {
1193                 return IRQ_NONE;
1194         }
1195
1196         if (devpriv->intr_sd >= 0) {
1197                 handled = dio200_handle_read_intr(dev,
1198                         dev->subdevices + devpriv->intr_sd);
1199         } else {
1200                 handled = 0;
1201         }
1202
1203         return IRQ_RETVAL(handled);
1204 }
1205
1206 /*
1207  * Read an '8254' counter subdevice channel.
1208  */
1209 static inline unsigned int
1210 dio200_subdev_8254_read_chan(comedi_device * dev, comedi_subdevice * s,
1211         unsigned int chan)
1212 {
1213         unsigned int i8254_ofs = ((dio200_subdev_8254 *)s->private)->ofs;
1214         unsigned int val;
1215
1216         /* latch counter */
1217         val = chan << 6;
1218         dio200_write8(dev, i8254_ofs + i8254_control_reg, val);
1219
1220         /* read lsb */
1221         val = dio200_read8(dev, i8254_ofs + chan);
1222         /* read msb */
1223         val += dio200_read8(dev, i8254_ofs + chan) << 8;
1224
1225         return val;
1226 }
1227
1228 /*
1229  * Write an '8254' counter subdevice channel.
1230  */
1231 static inline void
1232 dio200_subdev_8254_write_chan(comedi_device * dev, comedi_subdevice * s,
1233         unsigned int chan, unsigned int count)
1234 {
1235         unsigned int i8254_ofs = ((dio200_subdev_8254 *)s->private)->ofs;
1236
1237         /* write lsb */
1238         dio200_write8(dev, i8254_ofs + chan, count & 0xff);
1239         /* write msb */
1240         dio200_write8(dev, i8254_ofs + chan, (count >> 8) & 0xff);
1241 }
1242
1243 /*
1244  * Set mode of an '8254' counter subdevice channel.
1245  */
1246 static inline void
1247 dio200_subdev_8254_set_mode(comedi_device * dev, comedi_subdevice * s,
1248         unsigned int chan, unsigned int mode)
1249 {
1250         unsigned int i8254_ofs = ((dio200_subdev_8254 *)s->private)->ofs;
1251         unsigned int byte;
1252
1253         byte = chan << 6;
1254         byte |= 0x30;           /* load lsb then msb */
1255         byte |= (mode & 0xf);   /* set counter mode and BCD|binary */
1256         dio200_write8(dev, i8254_ofs + i8254_control_reg, byte);
1257 }
1258
1259 /*
1260  * Read status byte of an '8254' counter subdevice channel.
1261  */
1262 static inline unsigned int
1263 dio200_subdev_8254_status(comedi_device * dev, comedi_subdevice * s,
1264         unsigned int chan)
1265 {
1266         unsigned int i8254_ofs = ((dio200_subdev_8254 *)s->private)->ofs;
1267
1268         dio200_write8(dev, i8254_ofs + i8254_control_reg, (0xE0 | 2 << chan));
1269         return dio200_read8(dev, i8254_ofs + chan);
1270 }
1271
1272 /*
1273  * Handle 'insn_read' for an '8254' counter subdevice.
1274  */
1275 static int
1276 dio200_subdev_8254_read(comedi_device * dev, comedi_subdevice * s,
1277         comedi_insn * insn, lsampl_t * data)
1278 {
1279         dio200_subdev_8254 *subpriv = s->private;
1280         int chan = CR_CHAN(insn->chanspec);
1281         unsigned long flags;
1282
1283         if (insn->n == 0)
1284                 return 0;
1285
1286         comedi_spin_lock_irqsave(&subpriv->spinlock, flags);
1287         data[0] = dio200_subdev_8254_read_chan(dev, s, chan);
1288         comedi_spin_unlock_irqrestore(&subpriv->spinlock, flags);
1289
1290         return 1;
1291 }
1292
1293 /*
1294  * Handle 'insn_write' for an '8254' counter subdevice.
1295  */
1296 static int
1297 dio200_subdev_8254_write(comedi_device * dev, comedi_subdevice * s,
1298         comedi_insn * insn, lsampl_t * data)
1299 {
1300         dio200_subdev_8254 *subpriv = s->private;
1301         int chan = CR_CHAN(insn->chanspec);
1302         unsigned long flags;
1303
1304         if (insn->n == 0)
1305                 return 0;
1306
1307         comedi_spin_lock_irqsave(&subpriv->spinlock, flags);
1308         dio200_subdev_8254_write_chan(dev, s, chan, data[0]);
1309         comedi_spin_unlock_irqrestore(&subpriv->spinlock, flags);
1310
1311         return 1;
1312 }
1313
1314 /*
1315  * Set gate source for an '8254' counter subdevice channel.
1316  */
1317 static int
1318 dio200_subdev_8254_set_gate_src(comedi_device * dev, comedi_subdevice *s,
1319         unsigned int counter_number, unsigned int gate_src)
1320 {
1321         dio200_subdev_8254 *subpriv = s->private;
1322         unsigned char byte;
1323
1324         if (!thislayout->has_clk_gat_sce)
1325                 return -1;
1326         if (counter_number > 2)
1327                 return -1;
1328         if (gate_src > 7)
1329                 return -1;
1330
1331         subpriv->gate_src[counter_number] = gate_src;
1332         byte = GAT_SCE(subpriv->which, counter_number, gate_src);
1333         dio200_write8(dev, subpriv->gat_sce_ofs, byte);
1334
1335         return 0;
1336 }
1337
1338 /*
1339  * Get gate source for an '8254' counter subdevice channel.
1340  */
1341 static int
1342 dio200_subdev_8254_get_gate_src(comedi_device * dev, comedi_subdevice *s,
1343         unsigned int counter_number)
1344 {
1345         dio200_subdev_8254 *subpriv = s->private;
1346
1347         if (!thislayout->has_clk_gat_sce)
1348                 return -1;
1349         if (counter_number > 2)
1350                 return -1;
1351
1352         return subpriv->gate_src[counter_number];
1353 }
1354
1355 /*
1356  * Set clock source for an '8254' counter subdevice channel.
1357  */
1358 static int
1359 dio200_subdev_8254_set_clock_src(comedi_device * dev, comedi_subdevice *s,
1360         unsigned int counter_number, unsigned int clock_src)
1361 {
1362         dio200_subdev_8254 *subpriv = s->private;
1363         unsigned char byte;
1364
1365         if (!thislayout->has_clk_gat_sce)
1366                 return -1;
1367         if (counter_number > 2)
1368                 return -1;
1369         if (clock_src > 7)
1370                 return -1;
1371
1372         subpriv->clock_src[counter_number] = clock_src;
1373         byte = CLK_SCE(subpriv->which, counter_number, clock_src);
1374         dio200_write8(dev, subpriv->clk_sce_ofs, byte);
1375
1376         return 0;
1377 }
1378
1379 /*
1380  * Get clock source for an '8254' counter subdevice channel.
1381  */
1382 static int
1383 dio200_subdev_8254_get_clock_src(comedi_device * dev, comedi_subdevice *s,
1384         unsigned int counter_number, lsampl_t * period_ns)
1385 {
1386         dio200_subdev_8254 *subpriv = s->private;
1387         unsigned clock_src;
1388
1389         if (!thislayout->has_clk_gat_sce)
1390                 return -1;
1391         if (counter_number > 2)
1392                 return -1;
1393
1394         clock_src = subpriv->clock_src[counter_number];
1395         *period_ns = clock_period[clock_src];
1396         return clock_src;
1397 }
1398
1399 /*
1400  * Handle 'insn_config' for an '8254' counter subdevice.
1401  */
1402 static int
1403 dio200_subdev_8254_config(comedi_device * dev, comedi_subdevice * s,
1404         comedi_insn * insn, lsampl_t * data)
1405 {
1406         dio200_subdev_8254 *subpriv = s->private;
1407         int ret = 0;
1408         int chan = CR_CHAN(insn->chanspec);
1409         unsigned long flags;
1410
1411         comedi_spin_lock_irqsave(&subpriv->spinlock, flags);
1412         switch (data[0]) {
1413         case INSN_CONFIG_SET_COUNTER_MODE:
1414                 if (data[1] > (I8254_MODE5 | I8254_BINARY))
1415                         ret = -EINVAL;
1416                 else
1417                         dio200_subdev_8254_set_mode(dev, s, chan, data[1]);
1418                 break;
1419         case INSN_CONFIG_8254_READ_STATUS:
1420                 data[1] = dio200_subdev_8254_status(dev, s, chan);
1421                 break;
1422         case INSN_CONFIG_SET_GATE_SRC:
1423                 ret = dio200_subdev_8254_set_gate_src(dev, s, chan, data[2]);
1424                 if (ret < 0)
1425                         ret = -EINVAL;
1426                 break;
1427         case INSN_CONFIG_GET_GATE_SRC:
1428                 ret = dio200_subdev_8254_get_gate_src(dev, s, chan);
1429                 if (ret < 0) {
1430                         ret = -EINVAL;
1431                         break;
1432                 }
1433                 data[2] = ret;
1434                 break;
1435         case INSN_CONFIG_SET_CLOCK_SRC:
1436                 ret = dio200_subdev_8254_set_clock_src(dev, s, chan, data[1]);
1437                 if (ret < 0)
1438                         ret = -EINVAL;
1439                 break;
1440         case INSN_CONFIG_GET_CLOCK_SRC:
1441                 ret = dio200_subdev_8254_get_clock_src(dev, s, chan, &data[2]);
1442                 if (ret < 0) {
1443                         ret = -EINVAL;
1444                         break;
1445                 }
1446                 data[1] = ret;
1447                 break;
1448         default:
1449                 ret = -EINVAL;
1450                 break;
1451         }
1452         comedi_spin_unlock_irqrestore(&subpriv->spinlock, flags);
1453         return ret < 0 ? ret : insn->n;
1454 }
1455
1456 /*
1457  * This function initializes an '8254' counter subdevice.
1458  *
1459  * offset is the offset to the 8254 chip.
1460  */
1461 static int
1462 dio200_subdev_8254_init(comedi_device * dev, comedi_subdevice * s,
1463         unsigned int offset)
1464 {
1465         dio200_subdev_8254 *subpriv;
1466         unsigned int chan;
1467
1468         subpriv = kzalloc(sizeof(*subpriv), GFP_KERNEL);
1469         if (!subpriv) {
1470                 printk(KERN_ERR "comedi%d: error! out of memory!\n",
1471                         dev->minor);
1472                 return -ENOMEM;
1473         }
1474
1475         s->private = subpriv;
1476         s->type = COMEDI_SUBD_COUNTER;
1477         s->subdev_flags = SDF_WRITABLE | SDF_READABLE;
1478         s->n_chan = 3;
1479         s->maxdata = 0xFFFF;
1480         s->insn_read = dio200_subdev_8254_read;
1481         s->insn_write = dio200_subdev_8254_write;
1482         s->insn_config = dio200_subdev_8254_config;
1483
1484         spin_lock_init(&subpriv->spinlock);
1485         subpriv->ofs = offset;
1486         if (thislayout->has_clk_gat_sce) {
1487                 /* Derive CLK_SCE and GAT_SCE register offsets from
1488                  * 8254 offset. */
1489                 subpriv->clk_sce_ofs =
1490                         DIO200_XCLK_SCE + (offset >> 3);
1491                 subpriv->gat_sce_ofs =
1492                         DIO200_XGAT_SCE + (offset >> 3);
1493                 subpriv->which = (offset >> 2) & 1;
1494         }
1495
1496         /* Initialize channels. */
1497         for (chan = 0; chan < 3; chan++) {
1498                 dio200_subdev_8254_set_mode(dev, s, chan,
1499                         (I8254_MODE0 | I8254_BINARY));
1500                 if (thislayout->has_clk_gat_sce) {
1501                         /* Gate source 0 is VCC (logic 1). */
1502                         dio200_subdev_8254_set_gate_src(dev, s, chan, 0);
1503                         /* Clock source 0 is the dedicated clock input. */
1504                         dio200_subdev_8254_set_clock_src(dev, s, chan, 0);
1505                 }
1506         }
1507
1508         return 0;
1509 }
1510
1511 /*
1512  * This function cleans up an '8254' counter subdevice.
1513  */
1514 static void
1515 dio200_subdev_8254_cleanup(comedi_device * dev, comedi_subdevice * s)
1516 {
1517         dio200_subdev_8254 *subpriv = s->private;
1518
1519         if (subpriv) {
1520                 kfree(subpriv);
1521         }
1522 }
1523
1524 /*
1525  * This function sets I/O directions for an '8255' DIO subdevice.
1526  */
1527 static void
1528 dio200_subdev_8255_set_dir(comedi_device * dev, comedi_subdevice * s)
1529 {
1530         dio200_subdev_8255 *subpriv = s->private;
1531         int config;
1532
1533         config = CR_CW;
1534         /* 1 in io_bits indicates output, 1 in config indicates input */
1535         if (!(s->io_bits & 0x0000ff))
1536                 config |= CR_A_IO;
1537         if (!(s->io_bits & 0x00ff00))
1538                 config |= CR_B_IO;
1539         if (!(s->io_bits & 0x0f0000))
1540                 config |= CR_C_LO_IO;
1541         if (!(s->io_bits & 0xf00000))
1542                 config |= CR_C_HI_IO;
1543
1544         dio200_write8(dev, subpriv->ofs + 3, config);
1545 }
1546
1547 /*
1548  * Handle 'insn_bits' for an '8255' DIO subdevice.
1549  */
1550 static int
1551 dio200_subdev_8255_bits(comedi_device * dev, comedi_subdevice * s,
1552         comedi_insn * insn, lsampl_t * data)
1553 {
1554         unsigned int i8255_ofs = ((dio200_subdev_8255 *)s->private)->ofs;
1555
1556         if (data[0]) {
1557                 s->state &= ~data[0];
1558                 s->state |= (data[0] & data[1]);
1559
1560                 if (data[0] & 0xff) {
1561                         dio200_write8(dev, i8255_ofs, s->state & 0xff);
1562                 }
1563                 if (data[0] & 0xff00) {
1564                         dio200_write8(dev, i8255_ofs + 1,
1565                                 (s->state >> 8) & 0xff);
1566                 }
1567                 if (data[0] & 0xff0000) {
1568                         dio200_write8(dev, i8255_ofs + 2,
1569                                 (s->state >> 16) & 0xff);
1570                 }
1571         }
1572
1573         data[1] = dio200_read8(dev, i8255_ofs);
1574         data[1] |= dio200_read8(dev, i8255_ofs + 1) << 8;
1575         data[1] |= dio200_read8(dev, i8255_ofs + 2) << 16;
1576
1577         return 2;
1578 }
1579
1580 /*
1581  * Handle 'insn_config' for an '8255' DIO subdevice.
1582  */
1583 static int
1584 dio200_subdev_8255_config(comedi_device * dev, comedi_subdevice * s,
1585         comedi_insn * insn, lsampl_t * data)
1586 {
1587         unsigned int mask;
1588         unsigned int bits;
1589
1590         mask = 1 << CR_CHAN(insn->chanspec);
1591         if (mask & 0x0000ff) {
1592                 bits = 0x0000ff;
1593         } else if (mask & 0x00ff00) {
1594                 bits = 0x00ff00;
1595         } else if (mask & 0x0f0000) {
1596                 bits = 0x0f0000;
1597         } else {
1598                 bits = 0xf00000;
1599         }
1600
1601         switch (data[0]) {
1602         case INSN_CONFIG_DIO_INPUT:
1603                 s->io_bits &= ~bits;
1604                 break;
1605         case INSN_CONFIG_DIO_OUTPUT:
1606                 s->io_bits |= bits;
1607                 break;
1608         case INSN_CONFIG_DIO_QUERY:
1609                 data[1] = (s->io_bits & bits) ? COMEDI_OUTPUT : COMEDI_INPUT;
1610                 return insn->n;
1611                 break;
1612         default:
1613                 return -EINVAL;
1614         }
1615
1616         dio200_subdev_8255_set_dir(dev, s);
1617
1618         return 1;
1619 }
1620
1621 /*
1622  * This function initializes an '8255' DIO subdevice.
1623  *
1624  * offset is the offset to the 8255 chip.
1625  */
1626 static int
1627 dio200_subdev_8255_init(comedi_device * dev, comedi_subdevice * s,
1628         unsigned int offset)
1629 {
1630         dio200_subdev_8255 *subpriv;
1631
1632         subpriv = kzalloc(sizeof(*subpriv), GFP_KERNEL);
1633         if (!subpriv) {
1634                 printk(KERN_ERR "comedi%d: error! out of memory!\n",
1635                         dev->minor);
1636                 return -ENOMEM;
1637         }
1638
1639         subpriv->ofs = offset;
1640
1641         s->private = subpriv;
1642         s->type = COMEDI_SUBD_DIO;
1643         s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
1644         s->n_chan = 24;
1645         s->range_table = &range_digital;
1646         s->maxdata = 1;
1647         s->insn_bits = dio200_subdev_8255_bits;
1648         s->insn_config = dio200_subdev_8255_config;
1649
1650         s->state = 0;
1651         s->io_bits = 0;
1652         dio200_subdev_8255_set_dir(dev, s);
1653
1654         return 0;
1655 }
1656
1657 /*
1658  * This function cleans up an '8255' DIO subdevice.
1659  */
1660 static void
1661 dio200_subdev_8255_cleanup(comedi_device * dev, comedi_subdevice * s)
1662 {
1663         dio200_subdev_8255 *subpriv = s->private;
1664
1665         if (subpriv) {
1666                 kfree(subpriv);
1667         }
1668 }
1669
1670 #ifdef CONFIG_COMEDI_PCI
1671 /*
1672  * This function does some special set-up for the PCIe boards
1673  * PCIe215, PCIe236, PCIe296.
1674  */
1675 static int
1676 dio200_pcie_board_setup(comedi_device * dev)
1677 {
1678         struct pci_dev *pci_dev = devpriv->pci_dev;
1679         unsigned char __iomem *brbase;
1680         resource_size_t brlen;
1681
1682         /*
1683          * The board uses Altera Cyclone IV with PCI-Express hard IP.
1684          * The FPGA configuration has the PCI-Express Avalon-MM Bridge
1685          * Control registers in PCI BAR 0, offset 0, and the length of
1686          * these registers is 0x4000.
1687          *
1688          * We need to write 0x80 to the "Avalon-MM to PCI-Express Interrupt
1689          * Enable" register at offset 0x50 to allow generation of PCIe
1690          * interrupts when RXmlrq_i is asserted in the SOPC Builder system.
1691          */
1692         brlen = pci_resource_len(pci_dev, 0);
1693         if (brlen < 0x4000 ||
1694                         !(pci_resource_flags(pci_dev, 0) & IORESOURCE_MEM)) {
1695                 printk(KERN_ERR "comedi%d: error! bad PCI region!\n",
1696                         dev->minor);
1697                 return -EINVAL;
1698         }
1699         brbase = ioremap_nocache(pci_resource_start(pci_dev, 0), brlen);
1700         if (!brbase) {
1701                 printk(KERN_ERR "comedi%d: error! failed to map registers!\n",
1702                         dev->minor);
1703                 return -ENOMEM;
1704         }
1705         writel(0x80, brbase + 0x50);
1706         iounmap(brbase);
1707         return 0;
1708 }
1709 #endif
1710
1711 /*
1712  * Attach is called by the Comedi core to configure the driver
1713  * for a particular board.  If you specified a board_name array
1714  * in the driver structure, dev->board_ptr contains that
1715  * address.
1716  */
1717 static int dio200_attach(comedi_device * dev, comedi_devconfig * it)
1718 {
1719         comedi_subdevice *s;
1720         unsigned long iobase = 0;
1721         unsigned int irq = 0;
1722 #ifdef CONFIG_COMEDI_PCI
1723         struct pci_dev *pci_dev = NULL;
1724         int bus = 0, slot = 0;
1725 #endif
1726         const dio200_layout *layout;
1727         int share_irq = 0;
1728         int sdx;
1729         unsigned n;
1730         int ret;
1731
1732         printk(KERN_DEBUG "comedi%d: %s: attach\n", dev->minor,
1733                 DIO200_DRIVER_NAME);
1734
1735         if ((ret = alloc_private(dev, sizeof(dio200_private))) < 0) {
1736                 printk(KERN_ERR "comedi%d: error! out of memory!\n",
1737                         dev->minor);
1738                 return ret;
1739         }
1740
1741         /* Process options. */
1742         switch (thisboard->bustype) {
1743         case isa_bustype:
1744                 iobase = it->options[0];
1745                 irq = it->options[1];
1746                 share_irq = 0;
1747                 break;
1748 #ifdef CONFIG_COMEDI_PCI
1749         case pci_bustype:
1750                 bus = it->options[0];
1751                 slot = it->options[1];
1752                 share_irq = 1;
1753
1754                 if ((ret = dio200_find_pci(dev, bus, slot, &pci_dev)) < 0)
1755                         return ret;
1756                 devpriv->pci_dev = pci_dev;
1757                 break;
1758 #endif
1759         default:
1760                 printk(KERN_ERR
1761                         "comedi%d: %s: BUG! cannot determine board type!\n",
1762                         dev->minor, DIO200_DRIVER_NAME);
1763                 return -EINVAL;
1764                 break;
1765         }
1766
1767         devpriv->intr_sd = -1;
1768         devpriv->io.regtype = no_regtype;
1769         devpriv->io.regshift = thisboard->mainshift;
1770
1771         /* Enable device and reserve I/O spaces. */
1772 #ifdef CONFIG_COMEDI_PCI
1773         if (pci_dev) {
1774                 resource_size_t base, len;
1775                 unsigned int bar;
1776
1777                 ret = comedi_pci_enable(pci_dev, DIO200_DRIVER_NAME);
1778                 if (ret < 0) {
1779                         printk(KERN_ERR
1780                                 "comedi%d: error! cannot enable PCI device and request regions!\n",
1781                                 dev->minor);
1782                         return ret;
1783                 }
1784                 bar = thisboard->mainbar;
1785                 base = pci_resource_start(pci_dev, bar);
1786                 len = pci_resource_len(pci_dev, bar);
1787                 if (len < thisboard->mainsize) {
1788                         printk(KERN_ERR
1789                                 "comedi%d: error! PCI region size too small!\n",
1790                                 dev->minor);
1791                         return -EINVAL;
1792                 }
1793                 if ((pci_resource_flags(pci_dev, bar) & IORESOURCE_MEM) != 0) {
1794                         devpriv->io.u.membase = ioremap_nocache(base, len);
1795                         if (!devpriv->io.u.membase) {
1796                                 printk(KERN_ERR
1797                                         "comedi%d: error! cannot remap registers!\n",
1798                                         dev->minor);
1799                                 return -ENOMEM;
1800                         }
1801                         devpriv->io.regtype = mmio_regtype;
1802                 } else {
1803                         devpriv->io.u.iobase = (unsigned long)base;
1804                         devpriv->io.regtype = io_regtype;
1805                 }
1806                 irq = pci_dev->irq;
1807         } else
1808 #endif
1809         {
1810                 ret = dio200_request_region(dev->minor, iobase,
1811                         thisboard->mainsize);
1812                 if (ret < 0) {
1813                         return ret;
1814                 }
1815                 devpriv->io.u.iobase = iobase;
1816                 devpriv->io.regtype = io_regtype;
1817         }
1818
1819         switch (thisboard->model) {
1820 #ifdef CONFIG_COMEDI_PCI
1821         case pcie215_model:
1822         case pcie236_model:
1823         case pcie296_model:
1824                 ret = dio200_pcie_board_setup(dev);
1825                 if (ret < 0) {
1826                         return ret;
1827                 }
1828                 break;
1829 #endif
1830         default:
1831                 break;
1832         }
1833
1834         layout = thislayout;
1835         if ((ret = alloc_subdevices(dev, layout->n_subdevs)) < 0) {
1836                 printk(KERN_ERR "comedi%d: error! out of memory!\n",
1837                         dev->minor);
1838                 return ret;
1839         }
1840
1841         for (n = 0; n < dev->n_subdevices; n++) {
1842                 s = &dev->subdevices[n];
1843                 switch (layout->sdtype[n]) {
1844                 case sd_8254:
1845                         /* counter subdevice (8254) */
1846                         ret = dio200_subdev_8254_init(dev, s,
1847                                 layout->sdinfo[n]);
1848                         if (ret < 0) {
1849                                 return ret;
1850                         }
1851                         break;
1852                 case sd_8255:
1853                         /* digital i/o subdevice (8255) */
1854                         ret = dio200_subdev_8255_init(dev, s,
1855                                 layout->sdinfo[n]);
1856                         if (ret < 0) {
1857                                 return ret;
1858                         }
1859                         break;
1860                 case sd_intr:
1861                         /* 'INTERRUPT' subdevice */
1862                         if (irq) {
1863                                 ret = dio200_subdev_intr_init(dev, s,
1864                                         DIO200_INT_SCE, layout->sdinfo[n]);
1865                                 if (ret < 0) {
1866                                         return ret;
1867                                 }
1868                                 devpriv->intr_sd = n;
1869                         } else {
1870                                 s->type = COMEDI_SUBD_UNUSED;
1871                         }
1872                         break;
1873                 case sd_timer:
1874                         /* TODO.  Fall-thru to default for now. */
1875                 default:
1876                         s->type = COMEDI_SUBD_UNUSED;
1877                         break;
1878                 }
1879         }
1880
1881         sdx = devpriv->intr_sd;
1882         if (sdx >= 0 && sdx < dev->n_subdevices) {
1883                 dev->read_subdev = &dev->subdevices[sdx];
1884         }
1885
1886         dev->board_name = thisboard->name;
1887
1888         if (irq) {
1889                 unsigned long flags = share_irq ? IRQF_SHARED : 0;
1890
1891                 if (comedi_request_irq(irq, dio200_interrupt, flags,
1892                                 DIO200_DRIVER_NAME, dev) >= 0) {
1893                         dev->irq = irq;
1894                 } else {
1895                         printk(KERN_WARNING
1896                                 "comedi%d: warning! irq %u unavailable!\n",
1897                                 dev->minor, irq);
1898                 }
1899         }
1900
1901         printk(KERN_INFO "comedi%d: %s ", dev->minor, dev->board_name);
1902         if (thisboard->bustype == isa_bustype) {
1903                 printk("(base %#lx) ", iobase);
1904         } else {
1905 #ifdef CONFIG_COMEDI_PCI
1906                 printk("(pci %s) ", pci_name(pci_dev));
1907 #endif
1908         }
1909         if (irq) {
1910                 printk("(irq %u%s) ", irq, (dev->irq ? "" : " UNAVAILABLE"));
1911         } else {
1912                 printk("(no irq) ");
1913         }
1914
1915         printk("attached\n");
1916
1917         return 1;
1918 }
1919
1920 /*
1921  * _detach is called to deconfigure a device.  It should deallocate
1922  * resources.
1923  * This function is also called when _attach() fails, so it should be
1924  * careful not to release resources that were not necessarily
1925  * allocated by _attach().  dev->private and dev->subdevices are
1926  * deallocated automatically by the core.
1927  */
1928 static int dio200_detach(comedi_device * dev)
1929 {
1930         const dio200_layout *layout;
1931         unsigned n;
1932
1933         printk(KERN_DEBUG "comedi%d: %s: detach\n", dev->minor,
1934                 DIO200_DRIVER_NAME);
1935
1936         if (dev->irq) {
1937                 comedi_free_irq(dev->irq, dev);
1938         }
1939         if (dev->subdevices) {
1940                 layout = thislayout;
1941                 for (n = 0; n < dev->n_subdevices; n++) {
1942                         comedi_subdevice *s = &dev->subdevices[n];
1943                         switch (layout->sdtype[n]) {
1944                         case sd_8254:
1945                                 dio200_subdev_8254_cleanup(dev, s);
1946                                 break;
1947                         case sd_8255:
1948                                 dio200_subdev_8255_cleanup(dev, s);
1949                                 break;
1950                         case sd_intr:
1951                                 dio200_subdev_intr_cleanup(dev, s);
1952                                 break;
1953                         default:
1954                                 break;
1955                         }
1956                 }
1957         }
1958         if (devpriv) {
1959                 if (devpriv->io.regtype == mmio_regtype) {
1960                         iounmap(devpriv->io.u.membase);
1961                 }
1962 #ifdef CONFIG_COMEDI_PCI
1963                 if (devpriv->pci_dev) {
1964                         if (devpriv->io.regtype != no_regtype) {
1965                                 comedi_pci_disable(devpriv->pci_dev);
1966                         }
1967                         pci_dev_put(devpriv->pci_dev);
1968                 } else
1969 #endif
1970                 {
1971                         if (devpriv->io.regtype == io_regtype) {
1972                                 release_region(devpriv->io.u.iobase,
1973                                         thisboard->mainsize);
1974                         }
1975                 }
1976         }
1977         if (dev->board_name) {
1978                 printk(KERN_INFO "comedi%d: %s removed\n",
1979                         dev->minor, dev->board_name);
1980         }
1981
1982         return 0;
1983 }