2 comedi/drivers/amplc_pci224.c
3 Driver for Amplicon PCI224 and PCI234 AO boards.
5 Copyright (C) 2005 MEV Ltd. <http://www.mev.co.uk/>
7 COMEDI - Linux Control and Measurement Device Interface
8 Copyright (C) 1998,2000 David A. Schleef <ds@schleef.org>
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.
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.
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.
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
37 - ao_do_cmd mode with the following sources:
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
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
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.
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
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
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].
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
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].
86 Passing a zero for an option is the same as leaving it unspecified.
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.
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
106 #include <linux/interrupt.h>
107 #include <linux/slab.h>
109 #include "../comedidev.h"
111 #include "comedi_pci.h"
113 #include "comedi_fc.h"
116 #define DRIVER_NAME "amplc_pci224"
121 #define PCI_VENDOR_ID_AMPLICON 0x14dc
122 #define PCI_DEVICE_ID_AMPLICON_PCI224 0x0007
123 #define PCI_DEVICE_ID_AMPLICON_PCI234 0x0008
124 #define PCI_DEVICE_ID_INVALID 0xffff
127 * PCI224/234 i/o space 1 (PCIBAR2) registers.
129 #define PCI224_IO1_SIZE 0x20 /* Size of i/o space 1 (8-bit registers) */
130 #define PCI224_Z2_CT0 0x14 /* 82C54 counter/timer 0 */
131 #define PCI224_Z2_CT1 0x15 /* 82C54 counter/timer 1 */
132 #define PCI224_Z2_CT2 0x16 /* 82C54 counter/timer 2 */
133 #define PCI224_Z2_CTC 0x17 /* 82C54 counter/timer control word */
134 #define PCI224_ZCLK_SCE 0x1A /* Group Z Clock Configuration Register */
135 #define PCI224_ZGAT_SCE 0x1D /* Group Z Gate Configuration Register */
136 #define PCI224_INT_SCE 0x1E /* ISR Interrupt source mask register */
137 /* /Interrupt status */
140 * PCI224/234 i/o space 2 (PCIBAR3) 16-bit registers.
142 #define PCI224_IO2_SIZE 0x10 /* Size of i/o space 2 (16-bit registers). */
143 #define PCI224_DACDATA 0x00 /* (w-o) DAC FIFO data. */
144 #define PCI224_SOFTTRIG 0x00 /* (r-o) DAC software scan trigger. */
145 #define PCI224_DACCON 0x02 /* (r/w) DAC status/configuration. */
146 #define PCI224_FIFOSIZ 0x04 /* (w-o) FIFO size for wraparound mode. */
147 #define PCI224_DACCEN 0x06 /* (w-o) DAC channel enable register. */
152 /* (r/w) Scan trigger. */
153 #define PCI224_DACCON_TRIG_MASK (7 << 0)
154 #define PCI224_DACCON_TRIG_NONE (0 << 0) /* none */
155 #define PCI224_DACCON_TRIG_SW (1 << 0) /* software trig */
156 #define PCI224_DACCON_TRIG_EXTP (2 << 0) /* ext +ve edge */
157 #define PCI224_DACCON_TRIG_EXTN (3 << 0) /* ext -ve edge */
158 #define PCI224_DACCON_TRIG_Z2CT0 (4 << 0) /* Z2 CT0 out */
159 #define PCI224_DACCON_TRIG_Z2CT1 (5 << 0) /* Z2 CT1 out */
160 #define PCI224_DACCON_TRIG_Z2CT2 (6 << 0) /* Z2 CT2 out */
161 /* (r/w) Polarity (PCI224 only, PCI234 always bipolar!). */
162 #define PCI224_DACCON_POLAR_MASK (1 << 3)
163 #define PCI224_DACCON_POLAR_UNI (0 << 3) /* range [0,Vref] */
164 #define PCI224_DACCON_POLAR_BI (1 << 3) /* range [-Vref,Vref] */
165 /* (r/w) Internal Vref (PCI224 only, when LK1 in position 1-2). */
166 #define PCI224_DACCON_VREF_MASK (3 << 4)
167 #define PCI224_DACCON_VREF_1_25 (0 << 4) /* Vref = 1.25V */
168 #define PCI224_DACCON_VREF_2_5 (1 << 4) /* Vref = 2.5V */
169 #define PCI224_DACCON_VREF_5 (2 << 4) /* Vref = 5V */
170 #define PCI224_DACCON_VREF_10 (3 << 4) /* Vref = 10V */
171 /* (r/w) Wraparound mode enable (to play back stored waveform). */
172 #define PCI224_DACCON_FIFOWRAP (1 << 7)
173 /* (r/w) FIFO enable. It MUST be set! */
174 #define PCI224_DACCON_FIFOENAB (1 << 8)
175 /* (r/w) FIFO interrupt trigger level (most values are not very useful). */
176 #define PCI224_DACCON_FIFOINTR_MASK (7 << 9)
177 #define PCI224_DACCON_FIFOINTR_EMPTY (0 << 9) /* when empty */
178 #define PCI224_DACCON_FIFOINTR_NEMPTY (1 << 9) /* when not empty */
179 #define PCI224_DACCON_FIFOINTR_NHALF (2 << 9) /* when not half full */
180 #define PCI224_DACCON_FIFOINTR_HALF (3 << 9) /* when half full */
181 #define PCI224_DACCON_FIFOINTR_NFULL (4 << 9) /* when not full */
182 #define PCI224_DACCON_FIFOINTR_FULL (5 << 9) /* when full */
183 /* (r-o) FIFO fill level. */
184 #define PCI224_DACCON_FIFOFL_MASK (7 << 12)
185 #define PCI224_DACCON_FIFOFL_EMPTY (1 << 12) /* 0 */
186 #define PCI224_DACCON_FIFOFL_ONETOHALF (0 << 12) /* [1,2048] */
187 #define PCI224_DACCON_FIFOFL_HALFTOFULL (4 << 12) /* [2049,4095] */
188 #define PCI224_DACCON_FIFOFL_FULL (6 << 12) /* 4096 */
189 /* (r-o) DAC busy flag. */
190 #define PCI224_DACCON_BUSY (1 << 15)
191 /* (w-o) FIFO reset. */
192 #define PCI224_DACCON_FIFORESET (1 << 12)
193 /* (w-o) Global reset (not sure what it does). */
194 #define PCI224_DACCON_GLOBALRESET (1 << 13)
199 #define PCI224_FIFO_SIZE 4096
202 * DAC FIFO guaranteed minimum room available, depending on reported fill level.
203 * The maximum room available depends on the reported fill level and how much
206 #define PCI224_FIFO_ROOM_EMPTY PCI224_FIFO_SIZE
207 #define PCI224_FIFO_ROOM_ONETOHALF (PCI224_FIFO_SIZE / 2)
208 #define PCI224_FIFO_ROOM_HALFTOFULL 1
209 #define PCI224_FIFO_ROOM_FULL 0
212 * Counter/timer clock input configuration sources.
214 #define CLK_CLK 0 /* reserved (channel-specific clock) */
215 #define CLK_10MHZ 1 /* internal 10 MHz clock */
216 #define CLK_1MHZ 2 /* internal 1 MHz clock */
217 #define CLK_100KHZ 3 /* internal 100 kHz clock */
218 #define CLK_10KHZ 4 /* internal 10 kHz clock */
219 #define CLK_1KHZ 5 /* internal 1 kHz clock */
220 #define CLK_OUTNM1 6 /* output of channel-1 modulo total */
221 #define CLK_EXT 7 /* external clock */
222 /* Macro to construct clock input configuration register value. */
223 #define CLK_CONFIG(chan, src) ((((chan) & 3) << 3) | ((src) & 7))
224 /* Timebases in ns. */
225 #define TIMEBASE_10MHZ 100
226 #define TIMEBASE_1MHZ 1000
227 #define TIMEBASE_100KHZ 10000
228 #define TIMEBASE_10KHZ 100000
229 #define TIMEBASE_1KHZ 1000000
232 * Counter/timer gate input configuration sources.
234 #define GAT_VCC 0 /* VCC (i.e. enabled) */
235 #define GAT_GND 1 /* GND (i.e. disabled) */
236 #define GAT_EXT 2 /* reserved (external gate input) */
237 #define GAT_NOUTNM2 3 /* inverted output of channel-2 modulo total */
238 /* Macro to construct gate input configuration register value. */
239 #define GAT_CONFIG(chan, src) ((((chan) & 3) << 3) | ((src) & 7))
242 * Summary of CLK_OUTNM1 and GAT_NOUTNM2 connections for PCI224 and PCI234:
244 * Channel's Channel's
245 * clock input gate input
246 * Channel CLK_OUTNM1 GAT_NOUTNM2
247 * ------- ---------- -----------
248 * Z2-CT0 Z2-CT2-OUT /Z2-CT1-OUT
249 * Z2-CT1 Z2-CT0-OUT /Z2-CT2-OUT
250 * Z2-CT2 Z2-CT1-OUT /Z2-CT0-OUT
254 * Interrupt enable/status bits
256 #define PCI224_INTR_EXT 0x01 /* rising edge on external input */
257 #define PCI224_INTR_DAC 0x04 /* DAC (FIFO) interrupt */
258 #define PCI224_INTR_Z2CT1 0x20 /* rising edge on Z2-CT1 output */
260 #define PCI224_INTR_EDGE_BITS (PCI224_INTR_EXT | PCI224_INTR_Z2CT1)
261 #define PCI224_INTR_LEVEL_BITS PCI224_INTR_DACFIFO
267 /* Combine old and new bits. */
268 #define COMBINE(old, new, mask) (((old) & ~(mask)) | ((new) & (mask)))
270 /* A generic null function pointer value. */
273 /* Current CPU. XXX should this be hard_smp_processor_id()? */
274 #define THISCPU smp_processor_id()
276 /* State bits for use with atomic bit operations. */
277 #define AO_CMD_STARTED 0
283 /* The software selectable internal ranges for PCI224 (option[2] == 0). */
284 static const struct comedi_lrange range_pci224_internal = {
298 static const unsigned short hwrange_pci224_internal[8] = {
299 PCI224_DACCON_POLAR_BI | PCI224_DACCON_VREF_10,
300 PCI224_DACCON_POLAR_BI | PCI224_DACCON_VREF_5,
301 PCI224_DACCON_POLAR_BI | PCI224_DACCON_VREF_2_5,
302 PCI224_DACCON_POLAR_BI | PCI224_DACCON_VREF_1_25,
303 PCI224_DACCON_POLAR_UNI | PCI224_DACCON_VREF_10,
304 PCI224_DACCON_POLAR_UNI | PCI224_DACCON_VREF_5,
305 PCI224_DACCON_POLAR_UNI | PCI224_DACCON_VREF_2_5,
306 PCI224_DACCON_POLAR_UNI | PCI224_DACCON_VREF_1_25,
309 /* The software selectable external ranges for PCI224 (option[2] == 1). */
310 static const struct comedi_lrange range_pci224_external = {
313 RANGE_ext(-1, 1), /* bipolar [-Vref,+Vref] */
314 RANGE_ext(0, 1), /* unipolar [0,+Vref] */
318 static const unsigned short hwrange_pci224_external[2] = {
319 PCI224_DACCON_POLAR_BI,
320 PCI224_DACCON_POLAR_UNI,
323 /* The hardware selectable Vref*2 external range for PCI234
324 * (option[2] == 1, option[3+n] == 0). */
325 static const struct comedi_lrange range_pci234_ext2 = {
332 /* The hardware selectable Vref external range for PCI234
333 * (option[2] == 1, option[3+n] == 1). */
334 static const struct comedi_lrange range_pci234_ext = {
341 /* This serves for all the PCI234 ranges. */
342 static const unsigned short hwrange_pci234[1] = {
343 PCI224_DACCON_POLAR_BI, /* bipolar - hardware ignores it! */
347 * Board descriptions.
350 enum pci224_model { any_model, pci224_model, pci234_model };
352 struct pci224_board {
354 unsigned short devid;
355 enum pci224_model model;
356 unsigned int ao_chans;
357 unsigned int ao_bits;
360 static const struct pci224_board pci224_boards[] = {
363 .devid = PCI_DEVICE_ID_AMPLICON_PCI224,
364 .model = pci224_model,
370 .devid = PCI_DEVICE_ID_AMPLICON_PCI234,
371 .model = pci234_model,
377 .devid = PCI_DEVICE_ID_INVALID,
378 .model = any_model, /* wildcard */
383 * Useful for shorthand access to the particular board structure
385 #define thisboard ((struct pci224_board *)dev->board_ptr)
387 /* this structure is for data unique to this hardware driver. If
388 several hardware drivers keep similar information in this structure,
389 feel free to suggest moving the variable to the struct comedi_device struct. */
390 struct pci224_private {
391 struct pci_dev *pci_dev; /* PCI device */
392 const unsigned short *hwrange;
393 unsigned long iobase1;
395 spinlock_t ao_spinlock;
396 unsigned int *ao_readback;
398 unsigned char *ao_scan_order;
401 unsigned short daccon;
402 unsigned int cached_div1;
403 unsigned int cached_div2;
404 unsigned int ao_stop_count;
405 short ao_stop_continuous;
406 unsigned short ao_enab; /* max 16 channels so 'short' will do */
407 unsigned char intsce;
410 #define devpriv ((struct pci224_private *)dev->private)
413 * Called from the 'insn_write' function to perform a single write.
416 pci224_ao_set_data(struct comedi_device *dev, int chan, int range,
419 unsigned short mangled;
421 /* Store unmangled data for readback. */
422 devpriv->ao_readback[chan] = data;
423 /* Enable the channel. */
424 outw(1 << chan, dev->iobase + PCI224_DACCEN);
425 /* Set range and reset FIFO. */
426 devpriv->daccon = COMBINE(devpriv->daccon, devpriv->hwrange[range],
427 (PCI224_DACCON_POLAR_MASK |
428 PCI224_DACCON_VREF_MASK));
429 outw(devpriv->daccon | PCI224_DACCON_FIFORESET,
430 dev->iobase + PCI224_DACCON);
432 * Mangle the data. The hardware expects:
433 * - bipolar: 16-bit 2's complement
434 * - unipolar: 16-bit unsigned
436 mangled = (unsigned short)data << (16 - thisboard->ao_bits);
437 if ((devpriv->daccon & PCI224_DACCON_POLAR_MASK) ==
438 PCI224_DACCON_POLAR_BI) {
441 /* Write mangled data to the FIFO. */
442 outw(mangled, dev->iobase + PCI224_DACDATA);
443 /* Trigger the conversion. */
444 inw(dev->iobase + PCI224_SOFTTRIG);
448 * 'insn_write' function for AO subdevice.
451 pci224_ao_insn_write(struct comedi_device *dev, struct comedi_subdevice *s,
452 struct comedi_insn *insn, unsigned int *data)
457 /* Unpack channel and range. */
458 chan = CR_CHAN(insn->chanspec);
459 range = CR_RANGE(insn->chanspec);
461 /* Writing a list of values to an AO channel is probably not
462 * very useful, but that's how the interface is defined. */
463 for (i = 0; i < insn->n; i++)
464 pci224_ao_set_data(dev, chan, range, data[i]);
470 * 'insn_read' function for AO subdevice.
472 * N.B. The value read will not be valid if the DAC channel has
473 * never been written successfully since the device was attached
474 * or since the channel has been used by an AO streaming write
478 pci224_ao_insn_read(struct comedi_device *dev, struct comedi_subdevice *s,
479 struct comedi_insn *insn, unsigned int *data)
484 chan = CR_CHAN(insn->chanspec);
486 for (i = 0; i < insn->n; i++)
487 data[i] = devpriv->ao_readback[chan];
494 * Just a wrapper for the inline function 'i8253_cascade_ns_to_timer'.
497 pci224_cascade_ns_to_timer(int osc_base, unsigned int *d1, unsigned int *d2,
498 unsigned int *nanosec, int round_mode)
500 i8253_cascade_ns_to_timer(osc_base, d1, d2, nanosec, round_mode);
504 * Kills a command running on the AO subdevice.
506 static void pci224_ao_stop(struct comedi_device *dev,
507 struct comedi_subdevice *s)
511 if (!test_and_clear_bit(AO_CMD_STARTED, &devpriv->state))
515 spin_lock_irqsave(&devpriv->ao_spinlock, flags);
516 /* Kill the interrupts. */
518 outb(0, devpriv->iobase1 + PCI224_INT_SCE);
520 * Interrupt routine may or may not be running. We may or may not
521 * have been called from the interrupt routine (directly or
522 * indirectly via a comedi_events() callback routine). It's highly
523 * unlikely that we've been called from some other interrupt routine
524 * but who knows what strange things coders get up to!
526 * If the interrupt routine is currently running, wait for it to
527 * finish, unless we appear to have been called via the interrupt
530 while (devpriv->intr_running && devpriv->intr_cpuid != THISCPU) {
531 spin_unlock_irqrestore(&devpriv->ao_spinlock, flags);
532 spin_lock_irqsave(&devpriv->ao_spinlock, flags);
534 spin_unlock_irqrestore(&devpriv->ao_spinlock, flags);
535 /* Reconfigure DAC for insn_write usage. */
536 outw(0, dev->iobase + PCI224_DACCEN); /* Disable channels. */
537 devpriv->daccon = COMBINE(devpriv->daccon,
538 PCI224_DACCON_TRIG_SW |
539 PCI224_DACCON_FIFOINTR_EMPTY,
540 PCI224_DACCON_TRIG_MASK |
541 PCI224_DACCON_FIFOINTR_MASK);
542 outw(devpriv->daccon | PCI224_DACCON_FIFORESET,
543 dev->iobase + PCI224_DACCON);
547 * Handles start of acquisition for the AO subdevice.
549 static void pci224_ao_start(struct comedi_device *dev,
550 struct comedi_subdevice *s)
552 struct comedi_cmd *cmd = &s->async->cmd;
555 set_bit(AO_CMD_STARTED, &devpriv->state);
556 if (!devpriv->ao_stop_continuous && devpriv->ao_stop_count == 0) {
557 /* An empty acquisition! */
558 pci224_ao_stop(dev, s);
559 s->async->events |= COMEDI_CB_EOA;
560 comedi_event(dev, s);
562 /* Enable interrupts. */
563 spin_lock_irqsave(&devpriv->ao_spinlock, flags);
564 if (cmd->stop_src == TRIG_EXT)
565 devpriv->intsce = PCI224_INTR_EXT | PCI224_INTR_DAC;
567 devpriv->intsce = PCI224_INTR_DAC;
569 outb(devpriv->intsce, devpriv->iobase1 + PCI224_INT_SCE);
570 spin_unlock_irqrestore(&devpriv->ao_spinlock, flags);
575 * Handles interrupts from the DAC FIFO.
577 static void pci224_ao_handle_fifo(struct comedi_device *dev,
578 struct comedi_subdevice *s)
580 struct comedi_cmd *cmd = &s->async->cmd;
581 unsigned int num_scans;
583 unsigned short dacstat;
585 unsigned int bytes_per_scan;
587 if (cmd->chanlist_len) {
588 bytes_per_scan = cmd->chanlist_len * sizeof(short);
590 /* Shouldn't get here! */
591 bytes_per_scan = sizeof(short);
593 /* Determine number of scans available in buffer. */
594 num_scans = comedi_buf_read_n_available(s->async) / bytes_per_scan;
595 if (!devpriv->ao_stop_continuous) {
596 /* Fixed number of scans. */
597 if (num_scans > devpriv->ao_stop_count)
598 num_scans = devpriv->ao_stop_count;
602 /* Determine how much room is in the FIFO (in samples). */
603 dacstat = inw(dev->iobase + PCI224_DACCON);
604 switch (dacstat & PCI224_DACCON_FIFOFL_MASK) {
605 case PCI224_DACCON_FIFOFL_EMPTY:
606 room = PCI224_FIFO_ROOM_EMPTY;
607 if (!devpriv->ao_stop_continuous && devpriv->ao_stop_count == 0) {
608 /* FIFO empty at end of counted acquisition. */
609 pci224_ao_stop(dev, s);
610 s->async->events |= COMEDI_CB_EOA;
611 comedi_event(dev, s);
615 case PCI224_DACCON_FIFOFL_ONETOHALF:
616 room = PCI224_FIFO_ROOM_ONETOHALF;
618 case PCI224_DACCON_FIFOFL_HALFTOFULL:
619 room = PCI224_FIFO_ROOM_HALFTOFULL;
622 room = PCI224_FIFO_ROOM_FULL;
625 if (room >= PCI224_FIFO_ROOM_ONETOHALF) {
626 /* FIFO is less than half-full. */
627 if (num_scans == 0) {
628 /* Nothing left to put in the FIFO. */
629 pci224_ao_stop(dev, s);
630 s->async->events |= COMEDI_CB_OVERFLOW;
631 printk(KERN_ERR "comedi%d: "
632 "AO buffer underrun\n", dev->minor);
635 /* Determine how many new scans can be put in the FIFO. */
636 if (cmd->chanlist_len)
637 room /= cmd->chanlist_len;
639 /* Determine how many scans to process. */
640 if (num_scans > room)
644 for (n = 0; n < num_scans; n++) {
645 cfc_read_array_from_buffer(s, &devpriv->ao_scan_vals[0],
647 for (i = 0; i < cmd->chanlist_len; i++) {
648 outw(devpriv->ao_scan_vals[devpriv->ao_scan_order[i]],
649 dev->iobase + PCI224_DACDATA);
652 if (!devpriv->ao_stop_continuous) {
653 devpriv->ao_stop_count -= num_scans;
654 if (devpriv->ao_stop_count == 0) {
656 * Change FIFO interrupt trigger level to wait
657 * until FIFO is empty.
659 devpriv->daccon = COMBINE(devpriv->daccon,
660 PCI224_DACCON_FIFOINTR_EMPTY,
661 PCI224_DACCON_FIFOINTR_MASK);
662 outw(devpriv->daccon, dev->iobase + PCI224_DACCON);
665 if ((devpriv->daccon & PCI224_DACCON_TRIG_MASK) ==
666 PCI224_DACCON_TRIG_NONE) {
670 * This is the initial DAC FIFO interrupt at the
671 * start of the acquisition. The DAC's scan trigger
672 * has been set to 'none' up until now.
674 * Now that data has been written to the FIFO, the
675 * DAC's scan trigger source can be set to the
678 * BUG: The first scan will be triggered immediately
679 * if the scan trigger source is at logic level 1.
681 if (cmd->scan_begin_src == TRIG_TIMER) {
682 trig = PCI224_DACCON_TRIG_Z2CT0;
684 /* cmd->scan_begin_src == TRIG_EXT */
685 if (cmd->scan_begin_arg & CR_INVERT)
686 trig = PCI224_DACCON_TRIG_EXTN;
688 trig = PCI224_DACCON_TRIG_EXTP;
691 devpriv->daccon = COMBINE(devpriv->daccon, trig,
692 PCI224_DACCON_TRIG_MASK);
693 outw(devpriv->daccon, dev->iobase + PCI224_DACCON);
695 if (s->async->events)
696 comedi_event(dev, s);
701 * Internal trigger function to start acquisition on AO subdevice.
704 pci224_ao_inttrig_start(struct comedi_device *dev, struct comedi_subdevice *s,
705 unsigned int trignum)
710 s->async->inttrig = NULLFUNC;
711 pci224_ao_start(dev, s);
716 #define MAX_SCAN_PERIOD 0xFFFFFFFFU
717 #define MIN_SCAN_PERIOD 2500
718 #define CONVERT_PERIOD 625
721 * 'do_cmdtest' function for AO subdevice.
724 pci224_ao_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
725 struct comedi_cmd *cmd)
730 /* Step 1: make sure trigger sources are trivially valid. */
732 tmp = cmd->start_src;
733 cmd->start_src &= TRIG_INT | TRIG_EXT;
734 if (!cmd->start_src || tmp != cmd->start_src)
737 tmp = cmd->scan_begin_src;
738 cmd->scan_begin_src &= TRIG_EXT | TRIG_TIMER;
739 if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
742 tmp = cmd->convert_src;
743 cmd->convert_src &= TRIG_NOW;
744 if (!cmd->convert_src || tmp != cmd->convert_src)
747 tmp = cmd->scan_end_src;
748 cmd->scan_end_src &= TRIG_COUNT;
749 if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
753 cmd->stop_src &= TRIG_COUNT | TRIG_EXT | TRIG_NONE;
754 if (!cmd->stop_src || tmp != cmd->stop_src)
760 /* Step 2: make sure trigger sources are unique and mutually
763 /* these tests are true if more than one _src bit is set */
764 if ((cmd->start_src & (cmd->start_src - 1)) != 0)
766 if ((cmd->scan_begin_src & (cmd->scan_begin_src - 1)) != 0)
768 if ((cmd->convert_src & (cmd->convert_src - 1)) != 0)
770 if ((cmd->scan_end_src & (cmd->scan_end_src - 1)) != 0)
772 if ((cmd->stop_src & (cmd->stop_src - 1)) != 0)
775 /* There's only one external trigger signal (which makes these
776 * tests easier). Only one thing can use it. */
778 if (cmd->start_src & TRIG_EXT)
780 if (cmd->scan_begin_src & TRIG_EXT)
782 if (cmd->stop_src & TRIG_EXT)
790 /* Step 3: make sure arguments are trivially compatible. */
792 switch (cmd->start_src) {
794 if (cmd->start_arg != 0) {
800 /* Force to external trigger 0. */
801 if ((cmd->start_arg & ~CR_FLAGS_MASK) != 0) {
802 cmd->start_arg = COMBINE(cmd->start_arg, 0,
806 /* The only flag allowed is CR_EDGE, which is ignored. */
807 if ((cmd->start_arg & CR_FLAGS_MASK & ~CR_EDGE) != 0) {
808 cmd->start_arg = COMBINE(cmd->start_arg, 0,
809 CR_FLAGS_MASK & ~CR_EDGE);
815 switch (cmd->scan_begin_src) {
817 if (cmd->scan_begin_arg > MAX_SCAN_PERIOD) {
818 cmd->scan_begin_arg = MAX_SCAN_PERIOD;
821 tmp = cmd->chanlist_len * CONVERT_PERIOD;
822 if (tmp < MIN_SCAN_PERIOD)
823 tmp = MIN_SCAN_PERIOD;
825 if (cmd->scan_begin_arg < tmp) {
826 cmd->scan_begin_arg = tmp;
831 /* Force to external trigger 0. */
832 if ((cmd->scan_begin_arg & ~CR_FLAGS_MASK) != 0) {
833 cmd->scan_begin_arg = COMBINE(cmd->scan_begin_arg, 0,
837 /* Only allow flags CR_EDGE and CR_INVERT. Ignore CR_EDGE. */
838 if ((cmd->scan_begin_arg & CR_FLAGS_MASK &
839 ~(CR_EDGE | CR_INVERT)) != 0) {
840 cmd->scan_begin_arg = COMBINE(cmd->scan_begin_arg, 0,
841 CR_FLAGS_MASK & ~(CR_EDGE
849 /* cmd->convert_src == TRIG_NOW */
850 if (cmd->convert_arg != 0) {
851 cmd->convert_arg = 0;
855 /* cmd->scan_end_arg == TRIG_COUNT */
856 if (cmd->scan_end_arg != cmd->chanlist_len) {
857 cmd->scan_end_arg = cmd->chanlist_len;
861 switch (cmd->stop_src) {
863 /* Any count allowed. */
866 /* Force to external trigger 0. */
867 if ((cmd->stop_arg & ~CR_FLAGS_MASK) != 0) {
868 cmd->stop_arg = COMBINE(cmd->stop_arg, 0,
872 /* The only flag allowed is CR_EDGE, which is ignored. */
873 if ((cmd->stop_arg & CR_FLAGS_MASK & ~CR_EDGE) != 0) {
874 cmd->stop_arg = COMBINE(cmd->stop_arg, 0,
875 CR_FLAGS_MASK & ~CR_EDGE);
879 if (cmd->stop_arg != 0) {
889 /* Step 4: fix up any arguments. */
891 if (cmd->scan_begin_src == TRIG_TIMER) {
892 unsigned int div1, div2, round;
893 int round_mode = cmd->flags & TRIG_ROUND_MASK;
895 tmp = cmd->scan_begin_arg;
896 /* Check whether to use a single timer. */
897 switch (round_mode) {
898 case TRIG_ROUND_NEAREST:
900 round = TIMEBASE_10MHZ / 2;
902 case TRIG_ROUND_DOWN:
906 round = TIMEBASE_10MHZ - 1;
909 /* Be careful to avoid overflow! */
910 div2 = cmd->scan_begin_arg / TIMEBASE_10MHZ;
911 div2 += (round + cmd->scan_begin_arg % TIMEBASE_10MHZ) /
913 if (div2 <= 0x10000) {
914 /* A single timer will suffice. */
917 cmd->scan_begin_arg = div2 * TIMEBASE_10MHZ;
918 if (cmd->scan_begin_arg < div2 ||
919 cmd->scan_begin_arg < TIMEBASE_10MHZ) {
921 cmd->scan_begin_arg = MAX_SCAN_PERIOD;
924 /* Use two timers. */
925 div1 = devpriv->cached_div1;
926 div2 = devpriv->cached_div2;
927 pci224_cascade_ns_to_timer(TIMEBASE_10MHZ, &div1, &div2,
928 &cmd->scan_begin_arg,
930 devpriv->cached_div1 = div1;
931 devpriv->cached_div2 = div2;
933 if (tmp != cmd->scan_begin_arg)
941 /* Step 5: check channel list. */
943 if (cmd->chanlist && (cmd->chanlist_len > 0)) {
945 enum { range_err = 1, dupchan_err = 2, };
951 * Check all channels have the same range index. Don't care
952 * about analogue reference, as we can't configure it.
954 * Check the list has no duplicate channels.
956 range = CR_RANGE(cmd->chanlist[0]);
959 for (n = 0; n < cmd->chanlist_len; n++) {
960 ch = CR_CHAN(cmd->chanlist[n]);
961 if (tmp & (1U << ch))
962 errors |= dupchan_err;
965 if (CR_RANGE(cmd->chanlist[n]) != range)
970 if (errors & dupchan_err) {
971 DPRINTK("comedi%d: " DRIVER_NAME
973 "entries in chanlist must contain no "
974 "duplicate channels\n", dev->minor);
976 if (errors & range_err) {
977 DPRINTK("comedi%d: " DRIVER_NAME
979 "entries in chanlist must all have "
980 "the same range index\n", dev->minor);
993 * 'do_cmd' function for AO subdevice.
995 static int pci224_ao_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
997 struct comedi_cmd *cmd = &s->async->cmd;
1002 unsigned long flags;
1004 /* Cannot handle null/empty chanlist. */
1005 if (cmd->chanlist == NULL || cmd->chanlist_len == 0)
1009 /* Determine which channels are enabled and their load order. */
1010 devpriv->ao_enab = 0;
1012 for (i = 0; i < cmd->chanlist_len; i++) {
1013 ch = CR_CHAN(cmd->chanlist[i]);
1014 devpriv->ao_enab |= 1U << ch;
1016 for (j = 0; j < cmd->chanlist_len; j++) {
1017 if (CR_CHAN(cmd->chanlist[j]) < ch)
1021 devpriv->ao_scan_order[rank] = i;
1024 /* Set enabled channels. */
1025 outw(devpriv->ao_enab, dev->iobase + PCI224_DACCEN);
1027 /* Determine range and polarity. All channels the same. */
1028 range = CR_RANGE(cmd->chanlist[0]);
1031 * Set DAC range and polarity.
1032 * Set DAC scan trigger source to 'none'.
1033 * Set DAC FIFO interrupt trigger level to 'not half full'.
1036 * N.B. DAC FIFO interrupts are currently disabled.
1038 devpriv->daccon = COMBINE(devpriv->daccon,
1040 hwrange[range] | PCI224_DACCON_TRIG_NONE |
1041 PCI224_DACCON_FIFOINTR_NHALF),
1042 (PCI224_DACCON_POLAR_MASK |
1043 PCI224_DACCON_VREF_MASK |
1044 PCI224_DACCON_TRIG_MASK |
1045 PCI224_DACCON_FIFOINTR_MASK));
1046 outw(devpriv->daccon | PCI224_DACCON_FIFORESET,
1047 dev->iobase + PCI224_DACCON);
1049 if (cmd->scan_begin_src == TRIG_TIMER) {
1050 unsigned int div1, div2, round;
1051 unsigned int ns = cmd->scan_begin_arg;
1052 int round_mode = cmd->flags & TRIG_ROUND_MASK;
1054 /* Check whether to use a single timer. */
1055 switch (round_mode) {
1056 case TRIG_ROUND_NEAREST:
1058 round = TIMEBASE_10MHZ / 2;
1060 case TRIG_ROUND_DOWN:
1064 round = TIMEBASE_10MHZ - 1;
1067 /* Be careful to avoid overflow! */
1068 div2 = cmd->scan_begin_arg / TIMEBASE_10MHZ;
1069 div2 += (round + cmd->scan_begin_arg % TIMEBASE_10MHZ) /
1071 if (div2 <= 0x10000) {
1072 /* A single timer will suffice. */
1076 div1 = 1; /* Flag that single timer to be used. */
1078 /* Use two timers. */
1079 div1 = devpriv->cached_div1;
1080 div2 = devpriv->cached_div2;
1081 pci224_cascade_ns_to_timer(TIMEBASE_10MHZ, &div1, &div2,
1086 * The output of timer Z2-0 will be used as the scan trigger
1089 /* Make sure Z2-0 is gated on. */
1090 outb(GAT_CONFIG(0, GAT_VCC),
1091 devpriv->iobase1 + PCI224_ZGAT_SCE);
1093 /* Not cascading. Z2-0 needs 10 MHz clock. */
1094 outb(CLK_CONFIG(0, CLK_10MHZ),
1095 devpriv->iobase1 + PCI224_ZCLK_SCE);
1097 /* Cascading with Z2-2. */
1098 /* Make sure Z2-2 is gated on. */
1099 outb(GAT_CONFIG(2, GAT_VCC),
1100 devpriv->iobase1 + PCI224_ZGAT_SCE);
1101 /* Z2-2 needs 10 MHz clock. */
1102 outb(CLK_CONFIG(2, CLK_10MHZ),
1103 devpriv->iobase1 + PCI224_ZCLK_SCE);
1104 /* Load Z2-2 mode (2) and counter (div1). */
1105 i8254_load(devpriv->iobase1 + PCI224_Z2_CT0, 0,
1107 /* Z2-0 is clocked from Z2-2's output. */
1108 outb(CLK_CONFIG(0, CLK_OUTNM1),
1109 devpriv->iobase1 + PCI224_ZCLK_SCE);
1111 /* Load Z2-0 mode (2) and counter (div2). */
1112 i8254_load(devpriv->iobase1 + PCI224_Z2_CT0, 0, 0, div2, 2);
1116 * Sort out end of acquisition.
1118 switch (cmd->stop_src) {
1120 /* Fixed number of scans. */
1121 devpriv->ao_stop_continuous = 0;
1122 devpriv->ao_stop_count = cmd->stop_arg;
1125 /* Continuous scans. */
1126 devpriv->ao_stop_continuous = 1;
1127 devpriv->ao_stop_count = 0;
1132 * Sort out start of acquisition.
1134 switch (cmd->start_src) {
1136 spin_lock_irqsave(&devpriv->ao_spinlock, flags);
1137 s->async->inttrig = &pci224_ao_inttrig_start;
1138 spin_unlock_irqrestore(&devpriv->ao_spinlock, flags);
1141 /* Enable external interrupt trigger to start acquisition. */
1142 spin_lock_irqsave(&devpriv->ao_spinlock, flags);
1143 devpriv->intsce |= PCI224_INTR_EXT;
1144 outb(devpriv->intsce, devpriv->iobase1 + PCI224_INT_SCE);
1145 spin_unlock_irqrestore(&devpriv->ao_spinlock, flags);
1153 * 'cancel' function for AO subdevice.
1155 static int pci224_ao_cancel(struct comedi_device *dev,
1156 struct comedi_subdevice *s)
1158 pci224_ao_stop(dev, s);
1163 * 'munge' data for AO command.
1166 pci224_ao_munge(struct comedi_device *dev, struct comedi_subdevice *s,
1167 void *data, unsigned int num_bytes, unsigned int chan_index)
1169 struct comedi_async *async = s->async;
1170 short *array = data;
1171 unsigned int length = num_bytes / sizeof(*array);
1172 unsigned int offset;
1176 /* The hardware expects 16-bit numbers. */
1177 shift = 16 - thisboard->ao_bits;
1178 /* Channels will be all bipolar or all unipolar. */
1179 if ((devpriv->hwrange[CR_RANGE(async->cmd.chanlist[0])] &
1180 PCI224_DACCON_POLAR_MASK) == PCI224_DACCON_POLAR_UNI) {
1187 /* Munge the data. */
1188 for (i = 0; i < length; i++)
1189 array[i] = (array[i] << shift) - offset;
1194 * Interrupt handler.
1196 static irqreturn_t pci224_interrupt(int irq, void *d)
1198 struct comedi_device *dev = d;
1199 struct comedi_subdevice *s = &dev->subdevices[0];
1200 struct comedi_cmd *cmd;
1201 unsigned char intstat, valid_intstat;
1202 unsigned char curenab;
1204 unsigned long flags;
1206 intstat = inb(devpriv->iobase1 + PCI224_INT_SCE) & 0x3F;
1209 spin_lock_irqsave(&devpriv->ao_spinlock, flags);
1210 valid_intstat = devpriv->intsce & intstat;
1211 /* Temporarily disable interrupt sources. */
1212 curenab = devpriv->intsce & ~intstat;
1213 outb(curenab, devpriv->iobase1 + PCI224_INT_SCE);
1214 devpriv->intr_running = 1;
1215 devpriv->intr_cpuid = THISCPU;
1216 spin_unlock_irqrestore(&devpriv->ao_spinlock, flags);
1217 if (valid_intstat != 0) {
1218 cmd = &s->async->cmd;
1219 if (valid_intstat & PCI224_INTR_EXT) {
1220 devpriv->intsce &= ~PCI224_INTR_EXT;
1221 if (cmd->start_src == TRIG_EXT)
1222 pci224_ao_start(dev, s);
1223 else if (cmd->stop_src == TRIG_EXT)
1224 pci224_ao_stop(dev, s);
1227 if (valid_intstat & PCI224_INTR_DAC)
1228 pci224_ao_handle_fifo(dev, s);
1231 /* Reenable interrupt sources. */
1232 spin_lock_irqsave(&devpriv->ao_spinlock, flags);
1233 if (curenab != devpriv->intsce) {
1234 outb(devpriv->intsce,
1235 devpriv->iobase1 + PCI224_INT_SCE);
1237 devpriv->intr_running = 0;
1238 spin_unlock_irqrestore(&devpriv->ao_spinlock, flags);
1240 return IRQ_RETVAL(retval);
1244 * This function looks for a board matching the supplied PCI device.
1246 static const struct pci224_board
1247 *pci224_find_pci_board(struct pci_dev *pci_dev)
1251 for (i = 0; i < ARRAY_SIZE(pci224_boards); i++)
1252 if (pci_dev->device == pci224_boards[i].devid)
1253 return &pci224_boards[i];
1258 * This function looks for a PCI device matching the requested board name,
1262 pci224_find_pci(struct comedi_device *dev, int bus, int slot,
1263 struct pci_dev **pci_dev_p)
1265 struct pci_dev *pci_dev = NULL;
1269 /* Look for matching PCI device. */
1270 for (pci_dev = pci_get_device(PCI_VENDOR_ID_AMPLICON, PCI_ANY_ID, NULL);
1272 pci_dev = pci_get_device(PCI_VENDOR_ID_AMPLICON, PCI_ANY_ID,
1274 /* If bus/slot specified, check them. */
1276 if (bus != pci_dev->bus->number
1277 || slot != PCI_SLOT(pci_dev->devfn))
1280 if (thisboard->model == any_model) {
1281 /* Match any supported model. */
1282 const struct pci224_board *board_ptr;
1283 board_ptr = pci224_find_pci_board(pci_dev);
1284 if (board_ptr == NULL)
1286 /* Change board_ptr to matched board. */
1287 dev->board_ptr = board_ptr;
1289 /* Match specific model name. */
1290 if (thisboard->devid != pci_dev->device)
1294 /* Found a match. */
1295 *pci_dev_p = pci_dev;
1298 /* No match found. */
1300 printk(KERN_ERR "comedi%d: error! "
1301 "no %s found at pci %02x:%02x!\n",
1302 dev->minor, thisboard->name, bus, slot);
1304 printk(KERN_ERR "comedi%d: error! no %s found!\n",
1305 dev->minor, thisboard->name);
1311 * Common part of attach and attach_pci.
1313 static int pci224_attach_common(struct comedi_device *dev,
1314 struct pci_dev *pci_dev, int *options)
1316 struct comedi_subdevice *s;
1321 devpriv->pci_dev = pci_dev;
1322 ret = comedi_pci_enable(pci_dev, DRIVER_NAME);
1325 "comedi%d: error! cannot enable PCI device "
1326 "and request regions!\n", dev->minor);
1329 spin_lock_init(&devpriv->ao_spinlock);
1331 devpriv->iobase1 = pci_resource_start(pci_dev, 2);
1332 dev->iobase = pci_resource_start(pci_dev, 3);
1335 /* Allocate readback buffer for AO channels. */
1336 devpriv->ao_readback = kmalloc(sizeof(devpriv->ao_readback[0]) *
1337 thisboard->ao_chans, GFP_KERNEL);
1338 if (!devpriv->ao_readback)
1342 /* Allocate buffer to hold values for AO channel scan. */
1343 devpriv->ao_scan_vals = kmalloc(sizeof(devpriv->ao_scan_vals[0]) *
1344 thisboard->ao_chans, GFP_KERNEL);
1345 if (!devpriv->ao_scan_vals)
1349 /* Allocate buffer to hold AO channel scan order. */
1350 devpriv->ao_scan_order = kmalloc(sizeof(devpriv->ao_scan_order[0]) *
1351 thisboard->ao_chans, GFP_KERNEL);
1352 if (!devpriv->ao_scan_order)
1356 /* Disable interrupt sources. */
1357 devpriv->intsce = 0;
1358 outb(0, devpriv->iobase1 + PCI224_INT_SCE);
1360 /* Initialize the DAC hardware. */
1361 outw(PCI224_DACCON_GLOBALRESET, dev->iobase + PCI224_DACCON);
1362 outw(0, dev->iobase + PCI224_DACCEN);
1363 outw(0, dev->iobase + PCI224_FIFOSIZ);
1364 devpriv->daccon = (PCI224_DACCON_TRIG_SW | PCI224_DACCON_POLAR_BI |
1365 PCI224_DACCON_FIFOENAB |
1366 PCI224_DACCON_FIFOINTR_EMPTY);
1367 outw(devpriv->daccon | PCI224_DACCON_FIFORESET,
1368 dev->iobase + PCI224_DACCON);
1370 /* Allocate subdevices. There is only one! */
1371 ret = alloc_subdevices(dev, 1);
1373 printk(KERN_ERR "comedi%d: error! out of memory!\n",
1378 s = dev->subdevices + 0;
1379 /* Analog output subdevice. */
1380 s->type = COMEDI_SUBD_AO;
1381 s->subdev_flags = SDF_WRITABLE | SDF_GROUND | SDF_CMD_WRITE;
1382 s->n_chan = thisboard->ao_chans;
1383 s->maxdata = (1 << thisboard->ao_bits) - 1;
1384 s->insn_write = &pci224_ao_insn_write;
1385 s->insn_read = &pci224_ao_insn_read;
1386 s->len_chanlist = s->n_chan;
1388 dev->write_subdev = s;
1389 s->do_cmd = &pci224_ao_cmd;
1390 s->do_cmdtest = &pci224_ao_cmdtest;
1391 s->cancel = &pci224_ao_cancel;
1392 s->munge = &pci224_ao_munge;
1394 /* Sort out channel range options. */
1395 if (thisboard->model == pci234_model) {
1396 /* PCI234 range options. */
1397 const struct comedi_lrange **range_table_list;
1399 s->range_table_list = range_table_list =
1400 kmalloc(sizeof(struct comedi_lrange *) * s->n_chan,
1402 if (!s->range_table_list)
1406 for (n = 2; n < 3 + s->n_chan; n++) {
1407 if (options[n] < 0 || options[n] > 1) {
1409 "comedi%d: %s: warning! bad options[%u]=%d\n",
1410 dev->minor, DRIVER_NAME, n,
1415 for (n = 0; n < s->n_chan; n++) {
1416 if (n < COMEDI_NDEVCONFOPTS - 3 && options &&
1417 options[3 + n] == 1) {
1418 if (options[2] == 1)
1419 range_table_list[n] = &range_pci234_ext;
1421 range_table_list[n] = &range_bipolar5;
1424 if (options && options[2] == 1) {
1425 range_table_list[n] =
1428 range_table_list[n] = &range_bipolar10;
1432 devpriv->hwrange = hwrange_pci234;
1434 /* PCI224 range options. */
1435 if (options && options[2] == 1) {
1436 s->range_table = &range_pci224_external;
1437 devpriv->hwrange = hwrange_pci224_external;
1439 if (options && options[2] != 0) {
1440 printk(KERN_WARNING "comedi%d: %s: warning! "
1441 "bad options[2]=%d\n",
1442 dev->minor, DRIVER_NAME, options[2]);
1444 s->range_table = &range_pci224_internal;
1445 devpriv->hwrange = hwrange_pci224_internal;
1449 dev->board_name = thisboard->name;
1452 ret = request_irq(irq, pci224_interrupt, IRQF_SHARED,
1455 printk(KERN_ERR "comedi%d: error! "
1456 "unable to allocate irq %u\n", dev->minor, irq);
1463 printk(KERN_INFO "comedi%d: %s ", dev->minor, dev->board_name);
1464 printk("(pci %s) ", pci_name(pci_dev));
1466 printk("(irq %u%s) ", irq, (dev->irq ? "" : " UNAVAILABLE"));
1468 printk("(no irq) ");
1471 printk("attached\n");
1476 static int pci224_attach(struct comedi_device *dev, struct comedi_devconfig *it)
1478 struct pci_dev *pci_dev;
1482 printk(KERN_DEBUG "comedi%d: %s: attach\n", dev->minor, DRIVER_NAME);
1484 bus = it->options[0];
1485 slot = it->options[1];
1486 ret = alloc_private(dev, sizeof(struct pci224_private));
1488 printk(KERN_ERR "comedi%d: error! out of memory!\n",
1493 ret = pci224_find_pci(dev, bus, slot, &pci_dev);
1497 return pci224_attach_common(dev, pci_dev, it->options);
1501 pci224_attach_pci(struct comedi_device *dev, struct pci_dev *pci_dev)
1505 printk(KERN_DEBUG "comedi%d: %s: attach_pci %s\n", dev->minor,
1506 DRIVER_NAME, pci_name(pci_dev));
1508 ret = alloc_private(dev, sizeof(struct pci224_private));
1510 printk(KERN_ERR "comedi%d: error! out of memory!\n",
1515 dev->board_ptr = pci224_find_pci_board(pci_dev);
1516 if (dev->board_ptr == NULL) {
1518 "comedi%d: %s: BUG! cannot determine board type!\n",
1519 dev->minor, DRIVER_NAME);
1522 return pci224_attach_common(dev, pci_dev, NULL);
1525 static void pci224_detach(struct comedi_device *dev)
1528 free_irq(dev->irq, dev);
1529 if (dev->subdevices) {
1530 struct comedi_subdevice *s;
1532 s = dev->subdevices + 0;
1534 kfree(s->range_table_list);
1537 kfree(devpriv->ao_readback);
1538 kfree(devpriv->ao_scan_vals);
1539 kfree(devpriv->ao_scan_order);
1540 if (devpriv->pci_dev) {
1542 comedi_pci_disable(devpriv->pci_dev);
1543 pci_dev_put(devpriv->pci_dev);
1548 static struct comedi_driver amplc_pci224_driver = {
1549 .driver_name = "amplc_pci224",
1550 .module = THIS_MODULE,
1551 .attach = pci224_attach,
1552 .detach = pci224_detach,
1553 .attach_pci = pci224_attach_pci,
1554 .board_name = &pci224_boards[0].name,
1555 .offset = sizeof(struct pci224_board),
1556 .num_names = ARRAY_SIZE(pci224_boards),
1559 static int __devinit amplc_pci224_pci_probe(struct pci_dev *dev,
1560 const struct pci_device_id
1563 return comedi_pci_auto_config(dev, &lc_pci224_driver);
1566 static void __devexit amplc_pci224_pci_remove(struct pci_dev *dev)
1568 comedi_pci_auto_unconfig(dev);
1571 static DEFINE_PCI_DEVICE_TABLE(amplc_pci224_pci_table) = {
1572 { PCI_DEVICE(PCI_VENDOR_ID_AMPLICON, PCI_DEVICE_ID_AMPLICON_PCI224) },
1573 { PCI_DEVICE(PCI_VENDOR_ID_AMPLICON, PCI_DEVICE_ID_AMPLICON_PCI234) },
1576 MODULE_DEVICE_TABLE(pci, amplc_pci224_pci_table);
1578 static struct pci_driver amplc_pci224_pci_driver = {
1579 .name = "amplc_pci224",
1580 .id_table = amplc_pci224_pci_table,
1581 .probe = amplc_pci224_pci_probe,
1582 .remove = __devexit_p(amplc_pci224_pci_remove),
1584 module_comedi_pci_driver(amplc_pci224_driver, amplc_pci224_pci_driver);
1586 MODULE_AUTHOR("Comedi http://www.comedi.org");
1587 MODULE_DESCRIPTION("Comedi low-level driver");
1588 MODULE_LICENSE("GPL");