Constified ranges, board structures, and miscellaneous data.
[comedi.git] / comedi / drivers / amplc_pci224.c
1 /*
2     comedi/drivers/amplc_pci224.c
3     Driver for Amplicon PCI224 and PCI234 AO boards.
4
5     Copyright (C) 2005 MEV Ltd. <http://www.mev.co.uk/>
6
7     COMEDI - Linux Control and Measurement Device Interface
8     Copyright (C) 1998,2000 David A. Schleef <ds@schleef.org>
9
10     This program is free software; you can redistribute it and/or modify
11     it under the terms of the GNU General Public License as published by
12     the Free Software Foundation; either version 2 of the License, or
13     (at your option) any later version.
14
15     This program is distributed in the hope that it will be useful,
16     but WITHOUT ANY WARRANTY; without even the implied warranty of
17     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18     GNU General Public License for more details.
19
20     You should have received a copy of the GNU General Public License
21     along with this program; if not, write to the Free Software
22     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23
24 */
25 /*
26 Driver: amplc_pci224.o
27 Description: Amplicon PCI224, PCI234
28 Author: Ian Abbott <abbotti@mev.co.uk>
29 Devices: [Amplicon] PCI224 (pci224), PCI234 (pci234)
30 Updated: Thu, 24 Feb 2005 12:29:26 +0000
31 Status: works, but see caveats
32
33 Supports:
34
35   - ao_insn read/write
36   - ao_do_cmd mode with the following sources:
37
38     - start_src         TRIG_INT        TRIG_EXT
39     - scan_begin_src    TRIG_TIMER      TRIG_EXT
40     - convert_src       TRIG_NOW
41     - scan_end_src      TRIG_COUNT
42     - stop_src          TRIG_COUNT      TRIG_EXT        TRIG_NONE
43
44     The channel list must contain at least one channel with no repeated
45     channels.  The scan end count must equal the number of channels in
46     the channel list.
47
48     There is only one external trigger source so only one of start_src,
49     scan_begin_src or stop_src may use TRIG_EXT.
50
51 Configuration options - PCI224:
52   [0] - PCI bus of device (optional).
53   [1] - PCI slot of device (optional).
54           If bus/slot is not specified, the first available PCI device
55           will be used.
56   [2] - Select available ranges according to jumper LK1.  All channels
57         are set to the same range:
58         0=Jumper position 1-2 (factory default), 4 software-selectable
59           internal voltage references, giving 4 bipolar and 4 unipolar
60           ranges:
61             [-10V,+10V], [-5V,+5V], [-2.5V,+2.5V], [-1.25V,+1.25V],
62             [0,+10V], [0,+5V], [0,+2.5V], [0,1.25V].
63         1=Jumper position 2-3, 1 external voltage reference, giving
64           1 bipolar and 1 unipolar range:
65             [-Vext,+Vext], [0,+Vext].
66
67 Configuration options - PCI234:
68   [0] - PCI bus of device (optional).
69   [1] - PCI slot of device (optional).
70           If bus/slot is not specified, the first available PCI device
71           will be used.
72   [2] - Select internal or external voltage reference according to
73         jumper LK1.  This affects all channels:
74         0=Jumper position 1-2 (factory default), Vref=5V internal.
75         1=Jumper position 2-3, Vref=Vext external.
76   [3] - Select channel 0 range according to jumper LK2:
77         0=Jumper position 2-3 (factory default), range [-2*Vref,+2*Vref]
78           (10V bipolar when options[2]=0).
79         1=Jumper position 1-2, range [-Vref,+Vref]
80           (5V bipolar when options[2]=0).
81   [4] - Select channel 1 range according to jumper LK3: cf. options[3].
82   [5] - Select channel 2 range according to jumper LK4: cf. options[3].
83   [6] - Select channel 3 range according to jumper LK5: cf. options[3].
84
85 Passing a zero for an option is the same as leaving it unspecified.
86
87 Caveats:
88
89   1) All channels on the PCI224 share the same range.  Any change to the
90      range as a result of insn_write or a streaming command will affect
91      the output voltages of all channels, including those not specified
92      by the instruction or command.
93
94   2) For the analog output command,  the first scan may be triggered
95      falsely at the start of acquisition.  This occurs when the DAC scan
96      trigger source is switched from 'none' to 'timer' (scan_begin_src =
97      TRIG_TIMER) or 'external' (scan_begin_src == TRIG_EXT) at the start
98      of acquisition and the trigger source is at logic level 1 at the
99      time of the switch.  This is very likely for TRIG_TIMER.  For
100      TRIG_EXT, it depends on the state of the external line and whether
101      the CR_INVERT flag has been set.  The remaining scans are triggered
102      correctly.
103 */
104
105 #include <linux/comedidev.h>
106
107 #include <linux/pci.h>
108
109 #include "comedi_fc.h"
110 #include "8253.h"
111
112 #define DRIVER_NAME     "amplc_pci224"
113
114 /*
115  * PCI IDs.
116  */
117 /* #define PCI_VENDOR_ID_AMPLICON 0x14dc */
118 #define PCI_DEVICE_ID_AMPLICON_PCI224 0x0007
119 #define PCI_DEVICE_ID_AMPLICON_PCI234 0x0008
120
121 /*
122  * PCI224/234 i/o space 1 (PCIBAR2) registers.
123  */
124 #define PCI224_IO1_SIZE 0x20    /* Size of i/o space 1 (8-bit registers) */
125 #define PCI224_Z2_CT0   0x14    /* 82C54 counter/timer 0 */
126 #define PCI224_Z2_CT1   0x15    /* 82C54 counter/timer 1 */
127 #define PCI224_Z2_CT2   0x16    /* 82C54 counter/timer 2 */
128 #define PCI224_Z2_CTC   0x17    /* 82C54 counter/timer control word */
129 #define PCI224_ZCLK_SCE 0x1A    /* Group Z Clock Configuration Register */
130 #define PCI224_ZGAT_SCE 0x1D    /* Group Z Gate Configuration Register */
131 #define PCI224_INT_SCE  0x1E    /* ISR Interrupt source mask register/Interrupt status */
132
133 /*
134  * PCI224/234 i/o space 2 (PCIBAR3) 16-bit registers.
135  */
136 #define PCI224_IO2_SIZE 0x10    /* Size of i/o space 2 (16-bit registers). */
137 #define PCI224_DACDATA  0x00    /* (w-o) DAC FIFO data. */
138 #define PCI224_SOFTTRIG 0x00    /* (r-o) DAC software scan trigger. */
139 #define PCI224_DACCON   0x02    /* (r/w) DAC status/configuration. */
140 #define PCI224_FIFOSIZ  0x04    /* (w-o) FIFO size for wraparound mode. */
141 #define PCI224_DACCEN   0x06    /* (w-o) DAC channel enable register. */
142
143 /*
144  * DACCON values.
145  */
146 /* (r/w) Scan trigger. */
147 #define PCI224_DACCON_TRIG_MASK         (7 << 0)
148 #define PCI224_DACCON_TRIG_NONE         (0 << 0)        /* none */
149 #define PCI224_DACCON_TRIG_SW           (1 << 0)        /* software trig */
150 #define PCI224_DACCON_TRIG_EXTP         (2 << 0)        /* ext +ve edge */
151 #define PCI224_DACCON_TRIG_EXTN         (3 << 0)        /* ext -ve edge */
152 #define PCI224_DACCON_TRIG_Z2CT0        (4 << 0)        /* Z2 CT0 out */
153 #define PCI224_DACCON_TRIG_Z2CT1        (5 << 0)        /* Z2 CT1 out */
154 #define PCI224_DACCON_TRIG_Z2CT2        (6 << 0)        /* Z2 CT2 out */
155 /* (r/w) Polarity (PCI224 only, PCI234 always bipolar!). */
156 #define PCI224_DACCON_POLAR_MASK        (1 << 3)
157 #define PCI224_DACCON_POLAR_UNI         (0 << 3)        /* range [0,Vref] */
158 #define PCI224_DACCON_POLAR_BI          (1 << 3)        /* range [-Vref,+Vref]*/
159 /* (r/w) Internal Vref (PCI224 only, when LK1 in position 1-2). */
160 #define PCI224_DACCON_VREF_MASK         (3 << 4)
161 #define PCI224_DACCON_VREF_1_25         (0 << 4)        /* Vref = 1.25V */
162 #define PCI224_DACCON_VREF_2_5          (1 << 4)        /* Vref = 2.5V */
163 #define PCI224_DACCON_VREF_5            (2 << 4)        /* Vref = 5V */
164 #define PCI224_DACCON_VREF_10           (3 << 4)        /* Vref = 10V */
165 /* (r/w) Wraparound mode enable (to play back stored waveform). */
166 #define PCI224_DACCON_FIFOWRAP          (1 << 7)
167 /* (r/w) FIFO enable.  It MUST be set! */
168 #define PCI224_DACCON_FIFOENAB          (1 << 8)
169 /* (r/w) FIFO interrupt trigger level (most values are not very useful). */
170 #define PCI224_DACCON_FIFOINTR_MASK     (7 << 9)
171 #define PCI224_DACCON_FIFOINTR_EMPTY    (0 << 9)        /* when empty */
172 #define PCI224_DACCON_FIFOINTR_NEMPTY   (1 << 9)        /* when not empty */
173 #define PCI224_DACCON_FIFOINTR_NHALF    (2 << 9)        /* when not half full */
174 #define PCI224_DACCON_FIFOINTR_HALF     (3 << 9)        /* when half full */
175 #define PCI224_DACCON_FIFOINTR_NFULL    (4 << 9)        /* when not full */
176 #define PCI224_DACCON_FIFOINTR_FULL     (5 << 9)        /* when full */
177 /* (r-o) FIFO fill level. */
178 #define PCI224_DACCON_FIFOFL_MASK       (7 << 12)
179 #define PCI224_DACCON_FIFOFL_EMPTY      (1 << 12)       /* 0 */
180 #define PCI224_DACCON_FIFOFL_ONETOHALF  (0 << 12)       /* [1,2048] */
181 #define PCI224_DACCON_FIFOFL_HALFTOFULL (4 << 12)       /* [2049,4095] */
182 #define PCI224_DACCON_FIFOFL_FULL       (6 << 12)       /* 4096 */
183 /* (r-o) DAC busy flag. */
184 #define PCI224_DACCON_BUSY              (1 << 15)
185 /* (w-o) FIFO reset. */
186 #define PCI224_DACCON_FIFORESET         (1 << 12)
187 /* (w-o) Global reset (not sure what it does). */
188 #define PCI224_DACCON_GLOBALRESET       (1 << 13)
189
190 /*
191  * DAC FIFO size.
192  */
193 #define PCI224_FIFO_SIZE        4096
194
195 /*
196  * DAC FIFO guaranteed minimum room available, depending on reported fill level.
197  * The maximum room available depends on the reported fill level and how much
198  * has been written!
199  */
200 #define PCI224_FIFO_ROOM_EMPTY          PCI224_FIFO_SIZE
201 #define PCI224_FIFO_ROOM_ONETOHALF      (PCI224_FIFO_SIZE / 2)
202 #define PCI224_FIFO_ROOM_HALFTOFULL     1
203 #define PCI224_FIFO_ROOM_FULL           0
204
205 /*
206  * Counter/timer clock input configuration sources.
207  */
208 #define CLK_CLK         0       /* reserved (channel-specific clock) */
209 #define CLK_10MHZ       1       /* internal 10 MHz clock */
210 #define CLK_1MHZ        2       /* internal 1 MHz clock */
211 #define CLK_100KHZ      3       /* internal 100 kHz clock */
212 #define CLK_10KHZ       4       /* internal 10 kHz clock */
213 #define CLK_1KHZ        5       /* internal 1 kHz clock */
214 #define CLK_OUTNM1      6       /* output of channel-1 modulo total */
215 #define CLK_EXT         7       /* external clock */
216 /* Macro to construct clock input configuration register value. */
217 #define CLK_CONFIG(chan, src)   ((((chan) & 3) << 3) | ((src) & 7))
218 /* Timebases in ns. */
219 #define TIMEBASE_10MHZ          100
220 #define TIMEBASE_1MHZ           1000
221 #define TIMEBASE_100KHZ         10000
222 #define TIMEBASE_10KHZ          100000
223 #define TIMEBASE_1KHZ           1000000
224
225 /*
226  * Counter/timer gate input configuration sources.
227  */
228 #define GAT_VCC         0       /* VCC (i.e. enabled) */
229 #define GAT_GND         1       /* GND (i.e. disabled) */
230 #define GAT_EXT         2       /* reserved (external gate input) */
231 #define GAT_NOUTNM2     3       /* inverted output of channel-2 modulo total */
232 /* Macro to construct gate input configuration register value. */
233 #define GAT_CONFIG(chan, src)   ((((chan) & 3) << 3) | ((src) & 7))
234
235 /*
236  * Summary of CLK_OUTNM1 and GAT_NOUTNM2 connections for PCI224 and PCI234:
237  *
238  *              Channel's       Channel's
239  *              clock input     gate input
240  * Channel      CLK_OUTNM1      GAT_NOUTNM2
241  * -------      ----------      -----------
242  * Z2-CT0       Z2-CT2-OUT      /Z2-CT1-OUT
243  * Z2-CT1       Z2-CT0-OUT      /Z2-CT2-OUT
244  * Z2-CT2       Z2-CT1-OUT      /Z2-CT0-OUT
245  */
246
247 /*
248  * Interrupt enable/status bits
249  */
250 #define PCI224_INTR_EXT         0x01    /* rising edge on external input */
251 #define PCI224_INTR_DAC         0x04    /* DAC (FIFO) interrupt */
252 #define PCI224_INTR_Z2CT1       0x20    /* rising edge on Z2-CT1 output */
253
254 #define PCI224_INTR_EDGE_BITS   (PCI224_INTR_EXT | PCI224_INTR_Z2CT1)
255 #define PCI224_INTR_LEVEL_BITS  PCI224_INTR_DACFIFO
256
257 /*
258  * Handy macros.
259  */
260
261 /* Combine old and new bits. */
262 #define COMBINE(old, new, mask) (((old) & ~(mask)) | ((new) & (mask)))
263
264 /* A generic null function pointer value.  */
265 #define NULLFUNC        0
266
267 /* Current CPU.  XXX should this be hard_smp_processor_id()? */
268 #define THISCPU         smp_processor_id()
269
270 /*
271  * Range tables.
272  */
273
274 /* The software selectable internal ranges for PCI224 (option[2] == 0). */
275 static const comedi_lrange range_pci224_internal = {
276         8,
277         {
278                 BIP_RANGE(10),
279                 BIP_RANGE(5),
280                 BIP_RANGE(2.5),
281                 BIP_RANGE(1.25),
282                 UNI_RANGE(10),
283                 UNI_RANGE(5),
284                 UNI_RANGE(2.5),
285                 UNI_RANGE(1.25),
286         }
287 };
288
289 static const unsigned short hwrange_pci224_internal[8] = {
290         PCI224_DACCON_POLAR_BI | PCI224_DACCON_VREF_10,
291         PCI224_DACCON_POLAR_BI | PCI224_DACCON_VREF_5,
292         PCI224_DACCON_POLAR_BI | PCI224_DACCON_VREF_2_5,
293         PCI224_DACCON_POLAR_BI | PCI224_DACCON_VREF_1_25,
294         PCI224_DACCON_POLAR_UNI | PCI224_DACCON_VREF_10,
295         PCI224_DACCON_POLAR_UNI | PCI224_DACCON_VREF_5,
296         PCI224_DACCON_POLAR_UNI | PCI224_DACCON_VREF_2_5,
297         PCI224_DACCON_POLAR_UNI | PCI224_DACCON_VREF_1_25,
298 };
299
300 /* The software selectable external ranges for PCI224 (option[2] == 1). */
301 static const comedi_lrange range_pci224_external = {
302         2,
303         {
304                 RANGE_ext(-1, 1),       /* bipolar [-Vref,+Vref] */
305                 RANGE_ext(0, 1),        /* unipolar [0,+Vref] */
306         }
307 };
308
309 static const unsigned short hwrange_pci224_external[2] = {
310         PCI224_DACCON_POLAR_BI,
311         PCI224_DACCON_POLAR_UNI,
312 };
313
314 /* The hardware selectable Vref*2 external range for PCI234
315  * (option[2] == 1, option[3+n] == 0). */
316 static const comedi_lrange range_pci234_ext2 = {
317         1,
318         {
319                 RANGE_ext(-2, 2),
320         }
321 };
322
323 /* The hardware selectable Vref external range for PCI234
324  * (option[2] == 1, option[3+n] == 1). */
325 static const comedi_lrange range_pci234_ext = {
326         1,
327         {
328                 RANGE_ext(-1, 1),
329         }
330 };
331
332 /* This serves for all the PCI234 ranges. */
333 static const unsigned short hwrange_pci234[1] = {
334         PCI224_DACCON_POLAR_BI,         /* bipolar - hardware ignores it! */
335 };
336
337
338 /*
339  * Board descriptions.
340  */
341
342 enum pci224_model       { pci224_model, pci234_model };
343
344 typedef struct pci224_board_struct {
345         const char *name;
346         enum pci224_model model;
347         unsigned int ao_chans;
348         unsigned int ao_bits;
349 } pci224_board;
350
351 static const pci224_board pci224_boards[] = {
352         {
353         name:           "pci224",
354         model:          pci224_model,
355         ao_chans:       16,
356         ao_bits:        12,
357         },
358         {
359         name:           "pci234",
360         model:          pci234_model,
361         ao_chans:       4,
362         ao_bits:        16,
363         },
364 };
365
366 /*
367  * PCI driver table.
368  */
369
370 static struct pci_device_id pci224_pci_table[] __devinitdata = {
371         { PCI_VENDOR_ID_AMPLICON, PCI_DEVICE_ID_AMPLICON_PCI224,
372           PCI_ANY_ID, PCI_ANY_ID, 0, 0, pci224_model },
373         { PCI_VENDOR_ID_AMPLICON, PCI_DEVICE_ID_AMPLICON_PCI234,
374           PCI_ANY_ID, PCI_ANY_ID, 0, 0, pci234_model },
375         { 0 }
376 };
377 MODULE_DEVICE_TABLE(pci, pci224_pci_table);
378
379 /*
380  * Useful for shorthand access to the particular board structure
381  */
382 #define thisboard ((pci224_board *)dev->board_ptr)
383
384 /* this structure is for data unique to this hardware driver.  If
385    several hardware drivers keep similar information in this structure,
386    feel free to suggest moving the variable to the comedi_device struct.  */
387 typedef struct {
388         struct pci_dev *pci_dev;        /* PCI device */
389         const unsigned short *hwrange;
390         unsigned long iobase1;
391         spinlock_t ao_spinlock;
392         lsampl_t *ao_readback;
393         sampl_t *ao_scan_vals;
394         unsigned char *ao_scan_order;
395         int intr_cpuid;
396         short intr_running;
397         short ao_cmd_running;
398         unsigned short daccon;
399         unsigned int cached_div1;
400         unsigned int cached_div2;
401         unsigned int ao_stop_count;
402         short ao_stop_continuous;
403         unsigned short ao_enab; /* max 16 channels so 'short' will do */
404         unsigned char intsce;
405 } pci224_private;
406
407 #define devpriv ((pci224_private *)dev->private)
408
409 /*
410  * The comedi_driver structure tells the Comedi core module
411  * which functions to call to configure/deconfigure (attach/detach)
412  * the board, and also about the kernel module that contains
413  * the device code.
414  */
415 static int pci224_attach(comedi_device *dev,comedi_devconfig *it);
416 static int pci224_detach(comedi_device *dev);
417 static comedi_driver driver_amplc_pci224 = {
418         driver_name:    DRIVER_NAME,
419         module:         THIS_MODULE,
420         attach:         pci224_attach,
421         detach:         pci224_detach,
422         board_name:     &pci224_boards[0].name,
423         offset:         sizeof(pci224_board),
424         num_names:      sizeof(pci224_boards) / sizeof(pci224_board),
425 };
426 COMEDI_INITCLEANUP(driver_amplc_pci224);
427
428 /*
429  * Called from the 'insn_write' function to perform a single write.
430  */
431 static void
432 pci224_ao_set_data(comedi_device *dev, int chan, int range, lsampl_t data)
433 {
434         unsigned short mangled;
435
436         /* Store unmangled data for readback. */
437         devpriv->ao_readback[chan] = data;
438         /* Enable the channel. */
439         outw(1 << chan, dev->iobase + PCI224_DACCEN);
440         /* Set range and reset FIFO. */
441         devpriv->daccon = COMBINE(devpriv->daccon, devpriv->hwrange[range],
442                         (PCI224_DACCON_POLAR_MASK | PCI224_DACCON_VREF_MASK));
443         outw(devpriv->daccon | PCI224_DACCON_FIFORESET,
444                         dev->iobase + PCI224_DACCON);
445         /*
446          * Mangle the data.  The hardware expects:
447          * - bipolar: 16-bit 2's complement
448          * - unipolar: 16-bit unsigned
449          */
450         mangled = (unsigned short)data << (16 - thisboard->ao_bits);
451         if ((devpriv->daccon & PCI224_DACCON_POLAR_MASK) ==
452                         PCI224_DACCON_POLAR_BI) {
453                 mangled ^= 0x8000;
454         }
455         /* Write mangled data to the FIFO. */
456         outw(mangled, dev->iobase + PCI224_DACDATA);
457         /* Trigger the conversion. */
458         inw(dev->iobase + PCI224_SOFTTRIG);
459 }
460
461 /*
462  * 'insn_write' function for AO subdevice.
463  */
464 static int
465 pci224_ao_insn_write(comedi_device *dev, comedi_subdevice *s,
466                 comedi_insn *insn, lsampl_t *data)
467 {
468         int retval;
469         int i;
470         int chan, range;
471
472         /* Unpack channel and range. */
473         chan = CR_CHAN(insn->chanspec);
474         range = CR_RANGE(insn->chanspec);
475
476         if (devpriv->ao_cmd_running) {
477                 retval = -EBUSY;
478         } else {
479                 /* Writing a list of values to an AO channel is probably not
480                  * very useful, but that's how the interface is defined. */
481                 for (i = 0; i < insn->n; i++) {
482                         pci224_ao_set_data(dev, chan, range, data[i]);
483                 }
484                 retval = i;
485         }
486         return retval;
487 }
488
489 /*
490  * 'insn_read' function for AO subdevice.
491  *
492  * N.B. The value read will not be valid if the DAC channel has
493  * never been written successfully since the device was attached
494  * or since the channel has been used by an AO streaming write
495  * command.
496  */
497 static int
498 pci224_ao_insn_read(comedi_device *dev, comedi_subdevice *s,
499                 comedi_insn *insn, lsampl_t *data)
500 {
501         int i;
502         int chan;
503
504         chan = CR_CHAN(insn->chanspec);
505
506         for (i = 0; i < insn->n; i++) {
507                 data[i] = devpriv->ao_readback[chan];
508         }
509
510         return i;
511 }
512
513 /*
514  * Just a wrapper for the inline function 'i8253_cascade_ns_to_timer'.
515  */
516 static void
517 pci224_cascade_ns_to_timer(int osc_base, unsigned int *d1, unsigned int *d2,
518                 unsigned int *nanosec, int round_mode)
519 {
520         i8253_cascade_ns_to_timer(osc_base, d1, d2, nanosec, round_mode);
521 }
522
523 /*
524  * Kills a command running on the AO subdevice.
525  */
526 static void
527 pci224_ao_stop(comedi_device *dev, comedi_subdevice *s)
528 {
529         unsigned long flags;
530
531         comedi_spin_lock_irqsave(&devpriv->ao_spinlock, flags);
532         /* Turn off the internal trigger. */
533         s->async->inttrig = NULLFUNC;
534         /* Kill the interrupts. */
535         devpriv->intsce = 0;
536         outb(0, devpriv->iobase1 + PCI224_INT_SCE);
537         /*
538          * Interrupt routine may or may not be running.  We may or may not
539          * have been called from the interrupt routine (directly or
540          * indirectly via a comedi_events() callback routine).  It's highly
541          * unlikely that we've been called from some other interrupt routine
542          * but who knows what strange things coders get up to!
543          *
544          * If the interrupt routine is currently running, wait for it to
545          * finish, unless we appear to have been called via the interrupt
546          * routine.
547          */
548         while (devpriv->intr_running &&
549                         devpriv->intr_cpuid != THISCPU) {
550                 comedi_spin_unlock_irqrestore(&devpriv->ao_spinlock, flags);
551                 comedi_spin_lock_irqsave(&devpriv->ao_spinlock, flags);
552         }
553         comedi_spin_unlock_irqrestore(&devpriv->ao_spinlock, flags);
554         /* Reconfigure DAC for insn_write usage. */
555         outw(0, dev->iobase + PCI224_DACCEN);   /* Disable channels. */
556         devpriv->daccon = COMBINE(devpriv->daccon,
557                         PCI224_DACCON_TRIG_SW | PCI224_DACCON_FIFOINTR_EMPTY,
558                         PCI224_DACCON_TRIG_MASK | PCI224_DACCON_FIFOINTR_MASK);
559         outw(devpriv->daccon | PCI224_DACCON_FIFORESET,
560                         dev->iobase + PCI224_DACCON);
561         /* No longer running AO command. */
562         devpriv->ao_cmd_running = 0;
563 }
564
565 /*
566  * Handles start of acquisition for the AO subdevice.
567  */
568 static void
569 pci224_ao_start(comedi_device *dev, comedi_subdevice *s)
570 {
571         comedi_cmd *cmd = &s->async->cmd;
572         unsigned long flags;
573
574         if (!devpriv->ao_stop_continuous && devpriv->ao_stop_count == 0) {
575                 /* An empty acquisition! */
576                 pci224_ao_stop(dev, s);
577                 s->async->events |= COMEDI_CB_EOA;
578                 comedi_event(dev, s, s->async->events);
579         } else {
580                 /* Enable interrupts. */
581                 comedi_spin_lock_irqsave(&devpriv->ao_spinlock, flags);
582                 if (cmd->stop_src == TRIG_EXT) {
583                         devpriv->intsce = PCI224_INTR_EXT | PCI224_INTR_DAC;
584                 } else {
585                         devpriv->intsce = PCI224_INTR_DAC;
586                 }
587                 outb(devpriv->intsce, devpriv->iobase1 + PCI224_INT_SCE);
588                 comedi_spin_unlock_irqrestore(&devpriv->ao_spinlock, flags);
589         }
590 }
591
592 /*
593  * Handles interrupts from the DAC FIFO.
594  */
595 static void
596 pci224_ao_handle_fifo(comedi_device *dev, comedi_subdevice *s)
597 {
598         comedi_cmd *cmd = &s->async->cmd;
599         unsigned int num_scans;
600         unsigned int room;
601         unsigned short dacstat;
602         unsigned int i, n;
603         unsigned int bytes_per_scan;
604
605         if (cmd->chanlist_len) {
606                 bytes_per_scan = cmd->chanlist_len * sizeof(sampl_t);
607         } else {
608                 /* Shouldn't get here! */
609                 bytes_per_scan = sizeof(sampl_t);
610         }
611         /* Determine number of scans available in buffer. */
612         num_scans = comedi_buf_read_n_available(s->async) / bytes_per_scan;
613         if (!devpriv->ao_stop_continuous) {
614                 /* Fixed number of scans. */
615                 if (num_scans > devpriv->ao_stop_count) {
616                         num_scans = devpriv->ao_stop_count;
617                 }
618         }
619
620         /* Determine how much room is in the FIFO (in samples). */
621         dacstat = inw(dev->iobase + PCI224_DACCON);
622         switch (dacstat & PCI224_DACCON_FIFOFL_MASK) {
623         case PCI224_DACCON_FIFOFL_EMPTY:
624                 room = PCI224_FIFO_ROOM_EMPTY;
625                 if (!devpriv->ao_stop_continuous &&
626                                 devpriv->ao_stop_count == 0) {
627                         /* FIFO empty at end of counted acquisition. */
628                         pci224_ao_stop(dev, s);
629                         s->async->events |= COMEDI_CB_EOA;
630                 }
631                 break;
632         case PCI224_DACCON_FIFOFL_ONETOHALF:
633                 room = PCI224_FIFO_ROOM_ONETOHALF;
634                 break;
635         case PCI224_DACCON_FIFOFL_HALFTOFULL:
636                 room = PCI224_FIFO_ROOM_HALFTOFULL;
637                 break;
638         default:
639                 room = PCI224_FIFO_ROOM_FULL;
640                 break;
641         }
642         if (devpriv->ao_cmd_running) {
643                 if (room >= PCI224_FIFO_ROOM_ONETOHALF) {
644                         /* FIFO is less than half-full. */
645                         if (num_scans == 0) {
646                                 /* Nothing left to put in the FIFO. */
647                                 pci224_ao_stop(dev, s);
648                                 s->async->events |= COMEDI_CB_OVERFLOW;
649                                 rt_printk(KERN_ERR "comedi%d: "
650                                                 "AO buffer underrun\n",
651                                                 dev->minor);
652                         }
653                 }
654                 /* Determine how many new scans can be put in the FIFO. */
655                 if (cmd->chanlist_len) {
656                         room /= cmd->chanlist_len;
657                 }
658                 /* Determine how many scans to process. */
659                 if (num_scans > room) {
660                         num_scans = room;
661                 }
662                 /* Process scans. */
663                 for (n = 0; n < num_scans; n++) {
664                         cfc_read_array_from_buffer(s, &devpriv->ao_scan_vals[0],
665                                         bytes_per_scan);
666                         for (i = 0; i < cmd->chanlist_len; i++) {
667                                 outw(devpriv->ao_scan_vals[devpriv->ao_scan_order[i]],
668                                                 dev->iobase + PCI224_DACDATA);
669                         }
670                 }
671                 if (!devpriv->ao_stop_continuous) {
672                         devpriv->ao_stop_count -= num_scans;
673                         if (devpriv->ao_stop_count == 0) {
674                                 /*
675                                  * Change FIFO interrupt trigger level to wait
676                                  * until FIFO is empty.
677                                  */
678                                 devpriv->daccon = COMBINE(devpriv->daccon,
679                                                 PCI224_DACCON_FIFOINTR_EMPTY,
680                                                 PCI224_DACCON_FIFOINTR_MASK);
681                                 outw(devpriv->daccon,
682                                                 dev->iobase + PCI224_DACCON);
683                         }
684                 }
685                 if ((devpriv->daccon & PCI224_DACCON_TRIG_MASK) ==
686                                 PCI224_DACCON_TRIG_NONE) {
687                         unsigned short trig;
688
689                         /*
690                          * This is the initial DAC FIFO interrupt at the
691                          * start of the acquisition.  The DAC's scan trigger
692                          * has been set to 'none' up until now.
693                          *
694                          * Now that data has been written to the FIFO, the
695                          * DAC's scan trigger source can be set to the
696                          * correct value.
697                          *
698                          * BUG: The first scan will be triggered immediately
699                          * if the scan trigger source is at logic level 1.
700                          */
701                         if (cmd->scan_begin_src == TRIG_TIMER) {
702                                 trig = PCI224_DACCON_TRIG_Z2CT0;
703                         } else {
704                                 /* cmd->scan_begin_src == TRIG_EXT */
705                                 if (cmd->scan_begin_arg & CR_INVERT) {
706                                         trig = PCI224_DACCON_TRIG_EXTN;
707                                 } else {
708                                         trig = PCI224_DACCON_TRIG_EXTP;
709                                 }
710                         }
711                         devpriv->daccon = COMBINE(devpriv->daccon, trig,
712                                         PCI224_DACCON_TRIG_MASK);
713                         outw(devpriv->daccon, dev->iobase + PCI224_DACCON);
714                 }
715         }
716         if (s->async->events) {
717                 comedi_event(dev, s, s->async->events);
718         }
719 }
720
721 /*
722  * Internal trigger function to start acquisition on AO subdevice.
723  */
724 static int
725 pci224_ao_inttrig_start(comedi_device *dev, comedi_subdevice *s,
726                 unsigned int trignum)
727 {
728         unsigned long flags;
729
730         if (trignum != 0) return -EINVAL;
731
732         comedi_spin_lock_irqsave(&devpriv->ao_spinlock, flags);
733         if (s->async->inttrig) {
734                 s->async->inttrig = NULLFUNC;
735                 comedi_spin_unlock_irqrestore(&devpriv->ao_spinlock, flags);
736                 if (devpriv->ao_cmd_running) {
737                         pci224_ao_start(dev, s);
738                 }
739         } else {
740                 comedi_spin_unlock_irqrestore(&devpriv->ao_spinlock, flags);
741         }
742
743         return 1;
744 }
745
746 #define MAX_SCAN_PERIOD         0xFFFFFFFFU
747 #define MIN_SCAN_PERIOD         2500
748 #define CONVERT_PERIOD          625
749
750 /*
751  * 'do_cmdtest' function for AO subdevice.
752  */
753 static int
754 pci224_ao_cmdtest(comedi_device *dev, comedi_subdevice *s, comedi_cmd *cmd)
755 {
756         int err = 0;
757         unsigned int tmp;
758
759         /* Step 1: make sure trigger sources are trivially valid. */
760
761         tmp = cmd->start_src;
762         cmd->start_src &= TRIG_INT | TRIG_EXT;
763         if (!cmd->start_src || tmp != cmd->start_src) err++;
764
765         tmp = cmd->scan_begin_src;
766         cmd->scan_begin_src &= TRIG_EXT | TRIG_TIMER;
767         if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src) err++;
768
769         tmp = cmd->convert_src;
770         cmd->convert_src &= TRIG_NOW;
771         if (!cmd->convert_src || tmp != cmd->convert_src) err++;
772
773         tmp = cmd->scan_end_src;
774         cmd->scan_end_src &= TRIG_COUNT;
775         if (!cmd->scan_end_src || tmp != cmd->scan_end_src) err++;
776
777         tmp = cmd->stop_src;
778         cmd->stop_src &= TRIG_COUNT | TRIG_EXT | TRIG_NONE;
779         if (!cmd->stop_src || tmp != cmd->stop_src) err++;
780
781         if (err) return 1;
782
783         /* Step 2: make sure trigger sources are unique and mutually
784          * compatible. */
785
786         /* these tests are true if more than one _src bit is set */
787         if ((cmd->start_src & (cmd->start_src - 1)) != 0) err++;
788         if ((cmd->scan_begin_src & (cmd->scan_begin_src - 1)) != 0) err++;
789         if ((cmd->convert_src & (cmd->convert_src - 1)) != 0) err++;
790         if ((cmd->scan_end_src & (cmd->scan_end_src - 1)) != 0) err++;
791         if ((cmd->stop_src & (cmd->stop_src - 1)) != 0) err++;
792
793         /* There's only one external trigger signal (which makes these
794          * tests easier).  Only one thing can use it. */
795         tmp = 0;
796         if (cmd->start_src & TRIG_EXT) tmp++;
797         if (cmd->scan_begin_src & TRIG_EXT) tmp++;
798         if (cmd->stop_src & TRIG_EXT) tmp++;
799         if (tmp > 1) err++;
800
801         if (err) return 2;
802
803         /* Step 3: make sure arguments are trivially compatible. */
804
805         switch (cmd->start_src) {
806         case TRIG_INT:
807                 if (cmd->start_arg != 0) {
808                         cmd->start_arg = 0;
809                         err++;
810                 }
811                 break;
812         case TRIG_EXT:
813                 /* Force to external trigger 0. */
814                 if ((cmd->start_arg & ~CR_FLAGS_MASK) != 0) {
815                         cmd->start_arg = COMBINE(cmd->start_arg, 0,
816                                         ~CR_FLAGS_MASK);
817                         err++;
818                 }
819                 /* The only flag allowed is CR_EDGE, which is ignored. */
820                 if ((cmd->start_arg & CR_FLAGS_MASK & ~CR_EDGE) != 0) {
821                         cmd->start_arg = COMBINE(cmd->start_arg, 0,
822                                         CR_FLAGS_MASK & ~CR_EDGE);
823                 }
824                 break;
825         }
826
827         switch (cmd->scan_begin_src) {
828         case TRIG_TIMER:
829                 if (cmd->scan_begin_arg > MAX_SCAN_PERIOD) {
830                         cmd->scan_begin_arg = MAX_SCAN_PERIOD;
831                         err++;
832                 }
833                 tmp = cmd->chanlist_len * CONVERT_PERIOD;
834                 if (tmp < MIN_SCAN_PERIOD) {
835                         tmp = MIN_SCAN_PERIOD;
836                 }
837                 if (cmd->scan_begin_arg < tmp) {
838                         cmd->scan_begin_arg = tmp;
839                         err++;
840                 }
841                 break;
842         case TRIG_EXT:
843                 /* Force to external trigger 0. */
844                 if ((cmd->scan_begin_arg & ~CR_FLAGS_MASK) != 0) {
845                         cmd->scan_begin_arg = COMBINE(cmd->scan_begin_arg, 0,
846                                         ~CR_FLAGS_MASK);
847                         err++;
848                 }
849                 /* Only allow flags CR_EDGE and CR_INVERT.  Ignore CR_EDGE. */
850                 if ((cmd->scan_begin_arg & CR_FLAGS_MASK &
851                                         ~(CR_EDGE | CR_INVERT)) != 0) {
852                         cmd->scan_begin_arg = COMBINE(cmd->scan_begin_arg, 0,
853                                         CR_FLAGS_MASK & ~(CR_EDGE | CR_INVERT));
854                 }
855                 break;
856         }
857
858         /* cmd->convert_src == TRIG_NOW */
859         if (cmd->convert_arg != 0) {
860                 cmd->convert_arg = 0;
861                 err++;
862         }
863
864         /* cmd->scan_end_arg == TRIG_COUNT */
865         if (cmd->scan_end_arg != cmd->chanlist_len) {
866                 cmd->scan_end_arg = cmd->chanlist_len;
867                 err++;
868         }
869
870         switch (cmd->stop_src) {
871         case TRIG_COUNT:
872                 /* Any count allowed. */
873                 break;
874         case TRIG_EXT:
875                 /* Force to external trigger 0. */
876                 if ((cmd->stop_arg & ~CR_FLAGS_MASK) != 0) {
877                         cmd->stop_arg = COMBINE(cmd->stop_arg, 0,
878                                         ~CR_FLAGS_MASK);
879                         err++;
880                 }
881                 /* The only flag allowed is CR_EDGE, which is ignored. */
882                 if ((cmd->stop_arg & CR_FLAGS_MASK & ~CR_EDGE) != 0) {
883                         cmd->stop_arg = COMBINE(cmd->stop_arg, 0,
884                                         CR_FLAGS_MASK & ~CR_EDGE);
885                 }
886                 break;
887         case TRIG_NONE:
888                 if (cmd->stop_arg != 0) {
889                         cmd->stop_arg = 0;
890                         err++;
891                 }
892                 break;
893         }
894
895         if (err) return 3;
896
897         /* Step 4: fix up any arguments. */
898
899         if (cmd->scan_begin_src == TRIG_TIMER) {
900                 unsigned int div1, div2, round;
901                 int round_mode = cmd->flags & TRIG_ROUND_MASK;
902
903                 tmp = cmd->scan_begin_arg;
904                 /* Check whether to use a single timer. */
905                 switch (round_mode) {
906                 case TRIG_ROUND_NEAREST:
907                 default:
908                         round = TIMEBASE_10MHZ / 2;
909                         break;
910                 case TRIG_ROUND_DOWN:
911                         round = 0;
912                         break;
913                 case TRIG_ROUND_UP:
914                         round = TIMEBASE_10MHZ - 1;
915                         break;
916                 }
917                 /* Be careful to avoid overflow! */
918                 div2 = cmd->scan_begin_arg / TIMEBASE_10MHZ;
919                 div2 += (round + cmd->scan_begin_arg % TIMEBASE_10MHZ) /
920                         TIMEBASE_10MHZ;
921                 if (div2 <= 0x10000) {
922                         /* A single timer will suffice. */
923                         if (div2 < 2) div2 = 2;
924                         cmd->scan_begin_arg = div2 * TIMEBASE_10MHZ;
925                         if (cmd->scan_begin_arg < div2 ||
926                                         cmd->scan_begin_arg < TIMEBASE_10MHZ) {
927                                 /* Overflow! */
928                                 cmd->scan_begin_arg = MAX_SCAN_PERIOD;
929                         }
930                 } else {
931                         /* Use two timers. */
932                         div1 = devpriv->cached_div1;
933                         div2 = devpriv->cached_div2;
934                         pci224_cascade_ns_to_timer(TIMEBASE_10MHZ, &div1, &div2,
935                                         &cmd->scan_begin_arg, round_mode);
936                         devpriv->cached_div1 = div1;
937                         devpriv->cached_div2 = div2;
938                 }
939                 if (tmp != cmd->scan_begin_arg) {
940                         err++;
941                 }
942         }
943
944         if (err) return 4;
945
946         /* Step 5: check channel list. */
947
948         if (cmd->chanlist && cmd->chanlist_len > 0) {
949                 unsigned int range;
950                 enum { range_err = 1, dupchan_err = 2, };
951                 unsigned errors;
952                 unsigned int n;
953                 unsigned int ch;
954
955                 /*
956                  * Check all channels have the same range index.  Don't care
957                  * about analogue reference, as we can't configure it.
958                  *
959                  * Check the list has no duplicate channels.
960                  */
961                 range = CR_RANGE(cmd->chanlist[0]);
962                 errors = 0;
963                 tmp = 0;
964                 for (n = 0; n < cmd->chanlist_len; n++) {
965                         ch = CR_CHAN(cmd->chanlist[n]);
966                         if (tmp & (1U << ch)) {
967                                 errors |= dupchan_err;
968                         }
969                         tmp |= (1U << ch);
970                         if (CR_RANGE(cmd->chanlist[n]) != range) {
971                                 errors |= range_err;
972                         }
973                 }
974                 if (errors) {
975                         if (errors & dupchan_err) {
976                                 comedi_error(dev, "entries in chanlist must "
977                                                 "contain no duplicate "
978                                                 "channels\n");
979                         }
980                         if (errors & range_err) {
981                                 comedi_error(dev, "entries in chanlist must "
982                                                 "all have the same range "
983                                                 "index\n");
984                         }
985                         err++;
986                 }
987         } else {
988                 /* cmd->chanlist == NULL || cmd->chanlist_len == 0 */
989                 err++;
990         }
991
992         if (err) return 5;
993
994         return 0;
995 }
996
997 /*
998  * 'do_cmd' function for AO subdevice.
999  */
1000 static int
1001 pci224_ao_cmd(comedi_device *dev, comedi_subdevice *s)
1002 {
1003         comedi_cmd *cmd = &s->async->cmd;
1004         int range;
1005         unsigned int i, j;
1006         unsigned int ch;
1007         unsigned int rank;
1008         unsigned long flags;
1009
1010         /* Cannot handle null/empty chanlist. */
1011         if (cmd->chanlist == NULL || cmd->chanlist_len == 0) {
1012                 return -EINVAL;
1013         }
1014
1015         devpriv->ao_cmd_running = 1;
1016
1017         /* Determine which channels are enabled and their load order.  */
1018         devpriv->ao_enab = 0;
1019
1020         for (i = 0; i < cmd->chanlist_len; i++) {
1021                 ch = CR_CHAN(cmd->chanlist[i]);
1022                 devpriv->ao_enab |= 1U << ch;
1023                 rank = 0;
1024                 for (j = 0; j < cmd->chanlist_len; j++) {
1025                         if (CR_CHAN(cmd->chanlist[j]) < ch) {
1026                                 rank++;
1027                         }
1028                 }
1029                 devpriv->ao_scan_order[rank] = i;
1030         }
1031
1032         /* Set enabled channels. */
1033         outw(devpriv->ao_enab, dev->iobase + PCI224_DACCEN);
1034
1035         /* Determine range and polarity.  All channels the same.  */
1036         range = CR_RANGE(cmd->chanlist[0]);
1037
1038         /*
1039          * Set DAC range and polarity.
1040          * Set DAC scan trigger source to 'none'.
1041          * Set DAC FIFO interrupt trigger level to 'not half full'.
1042          * Reset DAC FIFO.
1043          *
1044          * N.B. DAC FIFO interrupts are currently disabled.
1045          */
1046         devpriv->daccon = COMBINE(devpriv->daccon,
1047                         (devpriv->hwrange[range] | PCI224_DACCON_TRIG_NONE |
1048                          PCI224_DACCON_FIFOINTR_NHALF),
1049                         (PCI224_DACCON_POLAR_MASK | PCI224_DACCON_VREF_MASK |
1050                          PCI224_DACCON_TRIG_MASK | PCI224_DACCON_FIFOINTR_MASK));
1051         outw(devpriv->daccon | PCI224_DACCON_FIFORESET,
1052                         dev->iobase + PCI224_DACCON);
1053
1054         if (cmd->scan_begin_src == TRIG_TIMER) {
1055                 unsigned int div1, div2, round;
1056                 unsigned int ns = cmd->scan_begin_arg;
1057                 int round_mode = cmd->flags & TRIG_ROUND_MASK;
1058
1059                 /* Check whether to use a single timer. */
1060                 switch (round_mode) {
1061                 case TRIG_ROUND_NEAREST:
1062                 default:
1063                         round = TIMEBASE_10MHZ / 2;
1064                         break;
1065                 case TRIG_ROUND_DOWN:
1066                         round = 0;
1067                         break;
1068                 case TRIG_ROUND_UP:
1069                         round = TIMEBASE_10MHZ - 1;
1070                         break;
1071                 }
1072                 /* Be careful to avoid overflow! */
1073                 div2 = cmd->scan_begin_arg / TIMEBASE_10MHZ;
1074                 div2 += (round + cmd->scan_begin_arg % TIMEBASE_10MHZ) /
1075                         TIMEBASE_10MHZ;
1076                 if (div2 <= 0x10000) {
1077                         /* A single timer will suffice. */
1078                         if (div2 < 2) div2 = 2;
1079                         div2 &= 0xffff;
1080                         div1 = 1;       /* Flag that single timer to be used. */
1081                 } else {
1082                         /* Use two timers. */
1083                         div1 = devpriv->cached_div1;
1084                         div2 = devpriv->cached_div2;
1085                         pci224_cascade_ns_to_timer(TIMEBASE_10MHZ, &div1, &div2,
1086                                         &ns, round_mode);
1087                 }
1088
1089                 /*
1090                  * The output of timer Z2-0 will be used as the scan trigger
1091                  * source.
1092                  */
1093                 /* Make sure Z2-0 is gated on.  */
1094                 outb(GAT_CONFIG(0, GAT_VCC),
1095                                 devpriv->iobase1 + PCI224_ZGAT_SCE);
1096                 if (div1 == 1) {
1097                         /* Not cascading.  Z2-0 needs 10 MHz clock. */
1098                         outb(CLK_CONFIG(0, CLK_10MHZ),
1099                                         devpriv->iobase1 + PCI224_ZCLK_SCE);
1100                 } else {
1101                         /* Cascading with Z2-2. */
1102                         /* Make sure Z2-2 is gated on.  */
1103                         outb(GAT_CONFIG(2, GAT_VCC),
1104                                         devpriv->iobase1 + PCI224_ZGAT_SCE);
1105                         /* Z2-2 needs 10 MHz clock. */
1106                         outb(CLK_CONFIG(2, CLK_10MHZ),
1107                                         devpriv->iobase1 + PCI224_ZCLK_SCE);
1108                         /* Load Z2-2 mode (2) and counter (div1). */
1109                         i8254_load(devpriv->iobase1 + PCI224_Z2_CT0,
1110                                         2, div1, 2);
1111                         /* Z2-0 is clocked from Z2-2's output. */
1112                         outb(CLK_CONFIG(0, CLK_OUTNM1),
1113                                         devpriv->iobase1 + PCI224_ZCLK_SCE);
1114                 }
1115                 /* Load Z2-0 mode (2) and counter (div2). */
1116                 i8254_load(devpriv->iobase1 + PCI224_Z2_CT0, 0, div2, 2);
1117         }
1118
1119         /*
1120          * Sort out end of acquisition.
1121          */
1122         switch (cmd->stop_src) {
1123         case TRIG_COUNT:
1124                 /* Fixed number of scans.  */
1125                 devpriv->ao_stop_continuous = 0;
1126                 devpriv->ao_stop_count = cmd->stop_arg;
1127                 break;
1128         default:
1129                 /* Continuous scans. */
1130                 devpriv->ao_stop_continuous = 1;
1131                 devpriv->ao_stop_count = 0;
1132                 break;
1133         }
1134
1135         /*
1136          * Sort out start of acquisition.
1137          */
1138         switch (cmd->start_src) {
1139         case TRIG_INT:
1140                 comedi_spin_lock_irqsave(&devpriv->ao_spinlock, flags);
1141                 s->async->inttrig = &pci224_ao_inttrig_start;
1142                 comedi_spin_unlock_irqrestore(&devpriv->ao_spinlock, flags);
1143                 break;
1144         case TRIG_EXT:
1145                 /* Enable external interrupt trigger to start acquisition. */
1146                 comedi_spin_lock_irqsave(&devpriv->ao_spinlock, flags);
1147                 devpriv->intsce |= PCI224_INTR_EXT;
1148                 outb(devpriv->intsce, devpriv->iobase1 + PCI224_INT_SCE);
1149                 comedi_spin_unlock_irqrestore(&devpriv->ao_spinlock, flags);
1150                 break;
1151         }
1152
1153         return 0;
1154 }
1155
1156 /*
1157  * 'cancel' function for AO subdevice.
1158  */
1159 static int
1160 pci224_ao_cancel(comedi_device *dev, comedi_subdevice *s)
1161 {
1162         if (devpriv->ao_cmd_running) {
1163                 pci224_ao_stop(dev, s);
1164         }
1165         return 0;
1166 }
1167
1168 /*
1169  * 'munge' data for AO command.
1170  */
1171 static void
1172 pci224_ao_munge(comedi_device *dev, comedi_subdevice *s, void *data,
1173                 unsigned int num_bytes, unsigned int chan_index)
1174 {
1175         comedi_async *async = s->async;
1176         sampl_t *array = data;
1177         unsigned int length = num_bytes / sizeof(*array);
1178         unsigned int offset;
1179         unsigned int shift;
1180         unsigned int i;
1181
1182         /* The hardware expects 16-bit numbers. */
1183         shift = 16 - thisboard->ao_bits;
1184         /* Channels will be all bipolar or all unipolar. */
1185         if ((devpriv->hwrange[CR_RANGE(async->cmd.chanlist[0])] &
1186                                 PCI224_DACCON_POLAR_MASK) ==
1187                         PCI224_DACCON_POLAR_UNI) {
1188                 /* Unipolar */
1189                 offset = 0;
1190         } else {
1191                 /* Bipolar */
1192                 offset = 32768;
1193         }
1194         /* Munge the data. */
1195         for (i = 0; i < length; i++) {
1196                 array[i] = (array[i] << shift) - offset;
1197         }
1198 }
1199
1200 /*
1201  * Interrupt handler.
1202  */
1203 static irqreturn_t
1204 pci224_interrupt(int irq, void *d PT_REGS_ARG)
1205 {
1206         comedi_device *dev = d;
1207         comedi_subdevice *s = &dev->subdevices[0];
1208         comedi_cmd *cmd;
1209         unsigned char intstat, valid_intstat;
1210         unsigned char curenab;
1211         int retval = 0;
1212         unsigned long flags;
1213
1214         intstat = inb(devpriv->iobase1 + PCI224_INT_SCE) & 0x3F;
1215         if (intstat) {
1216                 retval = 1;
1217                 comedi_spin_lock_irqsave(&devpriv->ao_spinlock, flags);
1218                 valid_intstat = devpriv->intsce & intstat;
1219                 /* Temporarily disable interrupt sources. */
1220                 curenab = devpriv->intsce & ~intstat;
1221                 outb(curenab, devpriv->iobase1 + PCI224_INT_SCE);
1222                 devpriv->intr_running = 1;
1223                 devpriv->intr_cpuid = THISCPU;
1224                 comedi_spin_unlock_irqrestore(&devpriv->ao_spinlock, flags);
1225                 if (s->async && devpriv->ao_cmd_running) {
1226                         cmd = &s->async->cmd;
1227                         if (valid_intstat & PCI224_INTR_EXT) {
1228                                 devpriv->intsce &= ~PCI224_INTR_EXT;
1229                                 if (cmd->start_src == TRIG_EXT) {
1230                                         pci224_ao_start(dev, s);
1231                                 } else if (cmd->stop_src == TRIG_EXT) {
1232                                         pci224_ao_stop(dev, s);
1233                                 }
1234                         }
1235                         if (valid_intstat & PCI224_INTR_DAC) {
1236                                 pci224_ao_handle_fifo(dev, s);
1237                         }
1238                 }
1239                 /* Reenable interrupt sources. */
1240                 comedi_spin_lock_irqsave(&devpriv->ao_spinlock, flags);
1241                 if (curenab != devpriv->intsce) {
1242                         outb(devpriv->intsce, devpriv->iobase1 + PCI224_INT_SCE);
1243                 }
1244                 devpriv->intr_running = 0;
1245                 comedi_spin_unlock_irqrestore(&devpriv->ao_spinlock, flags);
1246         }
1247         return IRQ_RETVAL(retval);
1248 }
1249
1250 /*
1251  * This function looks for a PCI device matching the requested board name,
1252  * bus and slot.
1253  */
1254 static int
1255 pci224_find_pci(comedi_device *dev, int bus, int slot,
1256                 struct pci_dev **pci_dev_p)
1257 {
1258         struct pci_dev *pci_dev = NULL;
1259         struct pci_device_id *pci_id;
1260
1261         *pci_dev_p = NULL;
1262
1263         /* Look for PCI table entry for this model. */
1264         for (pci_id = pci224_pci_table; pci_id->vendor != 0; pci_id++) {
1265                 if (pci_id->driver_data == thisboard->model)
1266                         break;
1267         }
1268         if (pci_id->vendor == 0) {
1269                 printk(KERN_ERR "comedi%d: %s: BUG! "
1270                                 "cannot determine board type!\n",
1271                                 dev->minor, DRIVER_NAME);
1272                 return -EINVAL;
1273         }
1274
1275         /* Look for matching PCI device. */
1276         for(pci_dev = pci_get_device(pci_id->vendor, pci_id->device, NULL);
1277                         pci_dev != NULL ;
1278                         pci_dev = pci_get_device(pci_id->vendor,
1279                                 pci_id->device, pci_dev)) {
1280                 /* If bus/slot specified, check them. */
1281                 if (bus || slot) {
1282                         if (bus != pci_dev->bus->number
1283                                         || slot != PCI_SLOT(pci_dev->devfn))
1284                                 continue;
1285                 }
1286 #if 0
1287                 if (pci_id->subvendor != PCI_ANY_ID) {
1288                         if (pci_dev->subsystem_vendor != pci_id->subvendor)
1289                                 continue;
1290                 }
1291                 if (pci_id->subdevice != PCI_ANY_ID) {
1292                         if (pci_dev->subsystem_device != pci_id->subdevice)
1293                                 continue;
1294                 }
1295 #endif
1296                 if (((pci_dev->class ^ pci_id->class) & pci_id->class_mask) != 0)
1297                         continue;
1298
1299                 /* Found a match. */
1300                 *pci_dev_p = pci_dev;
1301                 return 0;
1302         }
1303         /* No match found. */
1304         if (bus || slot) {
1305                 printk(KERN_ERR "comedi%d: error! "
1306                                 "no %s found at pci %02x:%02x!\n",
1307                                 dev->minor, thisboard->name,
1308                                 bus, slot);
1309         } else {
1310                 printk(KERN_ERR "comedi%d: error! no %s found!\n",
1311                                 dev->minor, thisboard->name);
1312         }
1313         return -EIO;
1314 }
1315
1316 /*
1317  * Attach is called by the Comedi core to configure the driver
1318  * for a particular board.  If you specified a board_name array
1319  * in the driver structure, dev->board_ptr contains that
1320  * address.
1321  */
1322 static int
1323 pci224_attach(comedi_device *dev,comedi_devconfig *it)
1324 {
1325         comedi_subdevice *s;
1326         struct pci_dev *pci_dev;
1327         unsigned int irq;
1328         int bus = 0, slot = 0;
1329         unsigned n;
1330         int ret;
1331
1332         printk(KERN_DEBUG "comedi%d: %s: attach\n", dev->minor,
1333                         DRIVER_NAME);
1334
1335         bus = it->options[0];
1336         slot = it->options[1];
1337         if ((ret=alloc_private(dev,sizeof(pci224_private))) < 0) {
1338                 printk(KERN_ERR "comedi%d: error! out of memory!\n",
1339                                 dev->minor);
1340                 return ret;
1341         }
1342         if ((ret=pci224_find_pci(dev, bus, slot, &pci_dev)) < 0)
1343                 return ret;
1344         devpriv->pci_dev = pci_dev;
1345
1346         if ((ret=pci_enable_device(pci_dev)) < 0) {
1347                 printk(KERN_ERR "comedi%d: error! cannot enable PCI device!\n",
1348                                 dev->minor);
1349                 return ret;
1350         }
1351         if (pci_request_regions(pci_dev, DRIVER_NAME)) {
1352                 printk(KERN_ERR "comedi%d: error! cannot allocate PCI regions!\n",
1353                                 dev->minor);
1354                 return -EIO;
1355         }
1356         spin_lock_init(&devpriv->ao_spinlock);
1357
1358         devpriv->iobase1 = pci_resource_start(pci_dev, 2);
1359         dev->iobase = pci_resource_start(pci_dev, 3);
1360         irq = pci_dev->irq;
1361
1362         /* Allocate readback buffer for AO channels. */
1363         devpriv->ao_readback = kmalloc(sizeof(devpriv->ao_readback[0]) *
1364                         thisboard->ao_chans, GFP_KERNEL);
1365         if (!devpriv->ao_readback) {
1366                 return -ENOMEM;
1367         }
1368
1369         /* Allocate buffer to hold values for AO channel scan. */
1370         devpriv->ao_scan_vals = kmalloc(sizeof(devpriv->ao_scan_vals[0]) *
1371                         thisboard->ao_chans, GFP_KERNEL);
1372         if (!devpriv->ao_scan_vals) {
1373                 return -ENOMEM;
1374         }
1375
1376         /* Allocate buffer to hold AO channel scan order. */
1377         devpriv->ao_scan_order = kmalloc(sizeof(devpriv->ao_scan_order[0]) *
1378                         thisboard->ao_chans, GFP_KERNEL);
1379         if (!devpriv->ao_scan_order) {
1380                 return -ENOMEM;
1381         }
1382
1383         /* Disable interrupt sources. */
1384         devpriv->intsce = 0;
1385         outb(0, devpriv->iobase1 + PCI224_INT_SCE);
1386
1387         /* Initialize the DAC hardware. */
1388         outw(PCI224_DACCON_GLOBALRESET, dev->iobase + PCI224_DACCON);
1389         outw(0, dev->iobase + PCI224_DACCEN);
1390         outw(0, dev->iobase + PCI224_FIFOSIZ);
1391         devpriv->daccon = (PCI224_DACCON_TRIG_SW | PCI224_DACCON_POLAR_BI |
1392                         PCI224_DACCON_FIFOENAB | PCI224_DACCON_FIFOINTR_EMPTY);
1393         outw(devpriv->daccon | PCI224_DACCON_FIFORESET,
1394                         dev->iobase + PCI224_DACCON);
1395
1396         /* Allocate subdevices.  There is only one!  */
1397         if ((ret=alloc_subdevices(dev, 1)) < 0) {
1398                 printk(KERN_ERR "comedi%d: error! out of memory!\n",
1399                                 dev->minor);
1400                 return ret;
1401         }
1402
1403         s = dev->subdevices + 0;
1404         /* Analog output subdevice. */
1405         s->type = COMEDI_SUBD_AO;
1406         s->subdev_flags = SDF_WRITABLE | SDF_GROUND | SDF_CMD_WRITE;
1407         s->n_chan = thisboard->ao_chans;
1408         s->maxdata = (1 << thisboard->ao_bits) - 1;
1409         s->insn_write = &pci224_ao_insn_write;
1410         s->insn_read = &pci224_ao_insn_read;
1411         s->len_chanlist = s->n_chan;
1412
1413         dev->write_subdev = s;
1414         s->do_cmd = &pci224_ao_cmd;
1415         s->do_cmdtest = &pci224_ao_cmdtest;
1416         s->cancel = &pci224_ao_cancel;
1417         s->munge = &pci224_ao_munge;
1418
1419         /* Sort out channel range options. */
1420         if (thisboard->model == pci234_model) {
1421                 /* PCI234 range options. */
1422                 const comedi_lrange **range_table_list;
1423
1424                 s->range_table_list = range_table_list = kmalloc(
1425                                 sizeof(comedi_lrange *) * s->n_chan,
1426                                 GFP_KERNEL);
1427                 if (!s->range_table_list) {
1428                         return -ENOMEM;
1429                 }
1430                 for (n = 2; n < 3 + s->n_chan; n++) {
1431                         if (it->options[n] < 0 || it->options[n] > 1) {
1432                                 printk(KERN_WARNING "comedi%d: %s: warning! "
1433                                                 "bad options[%u]=%d\n",
1434                                                 dev->minor, DRIVER_NAME, n,
1435                                                 it->options[n]);
1436                         }
1437                 }
1438                 for (n = 0; n < s->n_chan; n++) {
1439                         if (n < COMEDI_NDEVCONFOPTS - 3 &&
1440                                         it->options[3+n] == 1) {
1441                                 if (it->options[2] == 1) {
1442                                         range_table_list[n] =
1443                                                 &range_pci234_ext;
1444                                 } else {
1445                                         range_table_list[n] =
1446                                                 &range_bipolar5;
1447                                 }
1448                         } else {
1449                                 if (it->options[2] == 1) {
1450                                         range_table_list[n] =
1451                                                 &range_pci234_ext2;
1452                                 } else {
1453                                         range_table_list[n] =
1454                                                 &range_bipolar10;
1455                                 }
1456                         }
1457                 }
1458                 devpriv->hwrange = hwrange_pci234;
1459         } else {
1460                 /* PCI224 range options. */
1461                 if (it->options[2] == 1) {
1462                         s->range_table = &range_pci224_external;
1463                         devpriv->hwrange = hwrange_pci224_external;
1464                 } else {
1465                         if (it->options[2] != 0) {
1466                                 printk(KERN_WARNING "comedi%d: %s: warning! "
1467                                                 "bad options[2]=%d\n",
1468                                                 dev->minor, DRIVER_NAME,
1469                                                 it->options[2]);
1470                         }
1471                         s->range_table = &range_pci224_internal;
1472                         devpriv->hwrange = hwrange_pci224_internal;
1473                 }
1474         }
1475
1476         dev->board_name = thisboard->name;
1477
1478         if (irq) {
1479                 ret = comedi_request_irq(irq, pci224_interrupt, IRQF_SHARED,
1480                                 DRIVER_NAME, dev);
1481                 if (ret < 0) {
1482                         printk(KERN_ERR "comedi%d: error! "
1483                                         "unable to allocate irq %u\n",
1484                                         dev->minor, irq);
1485                         return ret;
1486                 } else {
1487                         dev->irq = irq;
1488                 }
1489         }
1490
1491         printk(KERN_INFO "comedi%d: %s ", dev->minor, dev->board_name);
1492         printk("(pci %s) ", pci_name(pci_dev));
1493         if (irq) {
1494                 printk("(irq %u%s) ", irq, (dev->irq ? "" : " UNAVAILABLE"));
1495         } else {
1496                 printk("(no irq) ");
1497         }
1498
1499         printk("attached\n");
1500
1501         return 1;
1502 }
1503
1504 /*
1505  * _detach is called to deconfigure a device.  It should deallocate
1506  * resources.
1507  * This function is also called when _attach() fails, so it should be
1508  * careful not to release resources that were not necessarily
1509  * allocated by _attach().  dev->private and dev->subdevices are
1510  * deallocated automatically by the core.
1511  */
1512 static int
1513 pci224_detach(comedi_device *dev)
1514 {
1515         printk(KERN_DEBUG "comedi%d: %s: detach\n", dev->minor, DRIVER_NAME);
1516
1517         if (dev->irq) {
1518                 comedi_free_irq(dev->irq, dev);
1519         }
1520         if (dev->subdevices) {
1521                 comedi_subdevice *s;
1522
1523                 s = dev->subdevices + 0;
1524                 /* AO subdevice */
1525                 if (s->range_table_list) {
1526                         kfree(s->range_table_list);
1527                 }
1528         }
1529         if (devpriv) {
1530                 if (devpriv->ao_readback) {
1531                         kfree(devpriv->ao_readback);
1532                 }
1533                 if (devpriv->ao_scan_vals) {
1534                         kfree(devpriv->ao_scan_vals);
1535                 }
1536                 if (devpriv->ao_scan_order) {
1537                         kfree(devpriv->ao_scan_order);
1538                 }
1539                 if (devpriv->pci_dev) {
1540                         if(dev->iobase)
1541                         {
1542                                 pci_release_regions(devpriv->pci_dev);
1543                                 pci_disable_device(devpriv->pci_dev);
1544                         }
1545                         pci_dev_put(devpriv->pci_dev);
1546                 }
1547         }
1548         if (dev->board_name) {
1549                 printk(KERN_INFO "comedi%d: %s removed\n",
1550                                 dev->minor, dev->board_name);
1551         }
1552
1553         return 0;
1554 }
1555