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