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_fc.h"
114 #define DRIVER_NAME "amplc_pci224"
119 #define PCI_VENDOR_ID_AMPLICON 0x14dc
120 #define PCI_DEVICE_ID_AMPLICON_PCI224 0x0007
121 #define PCI_DEVICE_ID_AMPLICON_PCI234 0x0008
122 #define PCI_DEVICE_ID_INVALID 0xffff
125 * PCI224/234 i/o space 1 (PCIBAR2) registers.
127 #define PCI224_IO1_SIZE 0x20 /* Size of i/o space 1 (8-bit registers) */
128 #define PCI224_Z2_CT0 0x14 /* 82C54 counter/timer 0 */
129 #define PCI224_Z2_CT1 0x15 /* 82C54 counter/timer 1 */
130 #define PCI224_Z2_CT2 0x16 /* 82C54 counter/timer 2 */
131 #define PCI224_Z2_CTC 0x17 /* 82C54 counter/timer control word */
132 #define PCI224_ZCLK_SCE 0x1A /* Group Z Clock Configuration Register */
133 #define PCI224_ZGAT_SCE 0x1D /* Group Z Gate Configuration Register */
134 #define PCI224_INT_SCE 0x1E /* ISR Interrupt source mask register */
135 /* /Interrupt status */
138 * PCI224/234 i/o space 2 (PCIBAR3) 16-bit registers.
140 #define PCI224_IO2_SIZE 0x10 /* Size of i/o space 2 (16-bit registers). */
141 #define PCI224_DACDATA 0x00 /* (w-o) DAC FIFO data. */
142 #define PCI224_SOFTTRIG 0x00 /* (r-o) DAC software scan trigger. */
143 #define PCI224_DACCON 0x02 /* (r/w) DAC status/configuration. */
144 #define PCI224_FIFOSIZ 0x04 /* (w-o) FIFO size for wraparound mode. */
145 #define PCI224_DACCEN 0x06 /* (w-o) DAC channel enable register. */
150 /* (r/w) Scan trigger. */
151 #define PCI224_DACCON_TRIG_MASK (7 << 0)
152 #define PCI224_DACCON_TRIG_NONE (0 << 0) /* none */
153 #define PCI224_DACCON_TRIG_SW (1 << 0) /* software trig */
154 #define PCI224_DACCON_TRIG_EXTP (2 << 0) /* ext +ve edge */
155 #define PCI224_DACCON_TRIG_EXTN (3 << 0) /* ext -ve edge */
156 #define PCI224_DACCON_TRIG_Z2CT0 (4 << 0) /* Z2 CT0 out */
157 #define PCI224_DACCON_TRIG_Z2CT1 (5 << 0) /* Z2 CT1 out */
158 #define PCI224_DACCON_TRIG_Z2CT2 (6 << 0) /* Z2 CT2 out */
159 /* (r/w) Polarity (PCI224 only, PCI234 always bipolar!). */
160 #define PCI224_DACCON_POLAR_MASK (1 << 3)
161 #define PCI224_DACCON_POLAR_UNI (0 << 3) /* range [0,Vref] */
162 #define PCI224_DACCON_POLAR_BI (1 << 3) /* range [-Vref,Vref] */
163 /* (r/w) Internal Vref (PCI224 only, when LK1 in position 1-2). */
164 #define PCI224_DACCON_VREF_MASK (3 << 4)
165 #define PCI224_DACCON_VREF_1_25 (0 << 4) /* Vref = 1.25V */
166 #define PCI224_DACCON_VREF_2_5 (1 << 4) /* Vref = 2.5V */
167 #define PCI224_DACCON_VREF_5 (2 << 4) /* Vref = 5V */
168 #define PCI224_DACCON_VREF_10 (3 << 4) /* Vref = 10V */
169 /* (r/w) Wraparound mode enable (to play back stored waveform). */
170 #define PCI224_DACCON_FIFOWRAP (1 << 7)
171 /* (r/w) FIFO enable. It MUST be set! */
172 #define PCI224_DACCON_FIFOENAB (1 << 8)
173 /* (r/w) FIFO interrupt trigger level (most values are not very useful). */
174 #define PCI224_DACCON_FIFOINTR_MASK (7 << 9)
175 #define PCI224_DACCON_FIFOINTR_EMPTY (0 << 9) /* when empty */
176 #define PCI224_DACCON_FIFOINTR_NEMPTY (1 << 9) /* when not empty */
177 #define PCI224_DACCON_FIFOINTR_NHALF (2 << 9) /* when not half full */
178 #define PCI224_DACCON_FIFOINTR_HALF (3 << 9) /* when half full */
179 #define PCI224_DACCON_FIFOINTR_NFULL (4 << 9) /* when not full */
180 #define PCI224_DACCON_FIFOINTR_FULL (5 << 9) /* when full */
181 /* (r-o) FIFO fill level. */
182 #define PCI224_DACCON_FIFOFL_MASK (7 << 12)
183 #define PCI224_DACCON_FIFOFL_EMPTY (1 << 12) /* 0 */
184 #define PCI224_DACCON_FIFOFL_ONETOHALF (0 << 12) /* [1,2048] */
185 #define PCI224_DACCON_FIFOFL_HALFTOFULL (4 << 12) /* [2049,4095] */
186 #define PCI224_DACCON_FIFOFL_FULL (6 << 12) /* 4096 */
187 /* (r-o) DAC busy flag. */
188 #define PCI224_DACCON_BUSY (1 << 15)
189 /* (w-o) FIFO reset. */
190 #define PCI224_DACCON_FIFORESET (1 << 12)
191 /* (w-o) Global reset (not sure what it does). */
192 #define PCI224_DACCON_GLOBALRESET (1 << 13)
197 #define PCI224_FIFO_SIZE 4096
200 * DAC FIFO guaranteed minimum room available, depending on reported fill level.
201 * The maximum room available depends on the reported fill level and how much
204 #define PCI224_FIFO_ROOM_EMPTY PCI224_FIFO_SIZE
205 #define PCI224_FIFO_ROOM_ONETOHALF (PCI224_FIFO_SIZE / 2)
206 #define PCI224_FIFO_ROOM_HALFTOFULL 1
207 #define PCI224_FIFO_ROOM_FULL 0
210 * Counter/timer clock input configuration sources.
212 #define CLK_CLK 0 /* reserved (channel-specific clock) */
213 #define CLK_10MHZ 1 /* internal 10 MHz clock */
214 #define CLK_1MHZ 2 /* internal 1 MHz clock */
215 #define CLK_100KHZ 3 /* internal 100 kHz clock */
216 #define CLK_10KHZ 4 /* internal 10 kHz clock */
217 #define CLK_1KHZ 5 /* internal 1 kHz clock */
218 #define CLK_OUTNM1 6 /* output of channel-1 modulo total */
219 #define CLK_EXT 7 /* external clock */
220 /* Macro to construct clock input configuration register value. */
221 #define CLK_CONFIG(chan, src) ((((chan) & 3) << 3) | ((src) & 7))
222 /* Timebases in ns. */
223 #define TIMEBASE_10MHZ 100
224 #define TIMEBASE_1MHZ 1000
225 #define TIMEBASE_100KHZ 10000
226 #define TIMEBASE_10KHZ 100000
227 #define TIMEBASE_1KHZ 1000000
230 * Counter/timer gate input configuration sources.
232 #define GAT_VCC 0 /* VCC (i.e. enabled) */
233 #define GAT_GND 1 /* GND (i.e. disabled) */
234 #define GAT_EXT 2 /* reserved (external gate input) */
235 #define GAT_NOUTNM2 3 /* inverted output of channel-2 modulo total */
236 /* Macro to construct gate input configuration register value. */
237 #define GAT_CONFIG(chan, src) ((((chan) & 3) << 3) | ((src) & 7))
240 * Summary of CLK_OUTNM1 and GAT_NOUTNM2 connections for PCI224 and PCI234:
242 * Channel's Channel's
243 * clock input gate input
244 * Channel CLK_OUTNM1 GAT_NOUTNM2
245 * ------- ---------- -----------
246 * Z2-CT0 Z2-CT2-OUT /Z2-CT1-OUT
247 * Z2-CT1 Z2-CT0-OUT /Z2-CT2-OUT
248 * Z2-CT2 Z2-CT1-OUT /Z2-CT0-OUT
252 * Interrupt enable/status bits
254 #define PCI224_INTR_EXT 0x01 /* rising edge on external input */
255 #define PCI224_INTR_DAC 0x04 /* DAC (FIFO) interrupt */
256 #define PCI224_INTR_Z2CT1 0x20 /* rising edge on Z2-CT1 output */
258 #define PCI224_INTR_EDGE_BITS (PCI224_INTR_EXT | PCI224_INTR_Z2CT1)
259 #define PCI224_INTR_LEVEL_BITS PCI224_INTR_DACFIFO
265 /* Combine old and new bits. */
266 #define COMBINE(old, new, mask) (((old) & ~(mask)) | ((new) & (mask)))
268 /* Current CPU. XXX should this be hard_smp_processor_id()? */
269 #define THISCPU smp_processor_id()
271 /* State bits for use with atomic bit operations. */
272 #define AO_CMD_STARTED 0
278 /* The software selectable internal ranges for PCI224 (option[2] == 0). */
279 static const struct comedi_lrange range_pci224_internal = {
293 static const unsigned short hwrange_pci224_internal[8] = {
294 PCI224_DACCON_POLAR_BI | PCI224_DACCON_VREF_10,
295 PCI224_DACCON_POLAR_BI | PCI224_DACCON_VREF_5,
296 PCI224_DACCON_POLAR_BI | PCI224_DACCON_VREF_2_5,
297 PCI224_DACCON_POLAR_BI | PCI224_DACCON_VREF_1_25,
298 PCI224_DACCON_POLAR_UNI | PCI224_DACCON_VREF_10,
299 PCI224_DACCON_POLAR_UNI | PCI224_DACCON_VREF_5,
300 PCI224_DACCON_POLAR_UNI | PCI224_DACCON_VREF_2_5,
301 PCI224_DACCON_POLAR_UNI | PCI224_DACCON_VREF_1_25,
304 /* The software selectable external ranges for PCI224 (option[2] == 1). */
305 static const struct comedi_lrange range_pci224_external = {
308 RANGE_ext(-1, 1), /* bipolar [-Vref,+Vref] */
309 RANGE_ext(0, 1), /* unipolar [0,+Vref] */
313 static const unsigned short hwrange_pci224_external[2] = {
314 PCI224_DACCON_POLAR_BI,
315 PCI224_DACCON_POLAR_UNI,
318 /* The hardware selectable Vref*2 external range for PCI234
319 * (option[2] == 1, option[3+n] == 0). */
320 static const struct comedi_lrange range_pci234_ext2 = {
327 /* The hardware selectable Vref external range for PCI234
328 * (option[2] == 1, option[3+n] == 1). */
329 static const struct comedi_lrange range_pci234_ext = {
336 /* This serves for all the PCI234 ranges. */
337 static const unsigned short hwrange_pci234[1] = {
338 PCI224_DACCON_POLAR_BI, /* bipolar - hardware ignores it! */
342 * Board descriptions.
345 enum pci224_model { any_model, pci224_model, pci234_model };
347 struct pci224_board {
349 unsigned short devid;
350 enum pci224_model model;
351 unsigned int ao_chans;
352 unsigned int ao_bits;
355 static const struct pci224_board pci224_boards[] = {
358 .devid = PCI_DEVICE_ID_AMPLICON_PCI224,
359 .model = pci224_model,
365 .devid = PCI_DEVICE_ID_AMPLICON_PCI234,
366 .model = pci234_model,
372 .devid = PCI_DEVICE_ID_INVALID,
373 .model = any_model, /* wildcard */
377 /* this structure is for data unique to this hardware driver. If
378 several hardware drivers keep similar information in this structure,
379 feel free to suggest moving the variable to the struct comedi_device struct. */
380 struct pci224_private {
381 struct pci_dev *pci_dev; /* PCI device */
382 const unsigned short *hwrange;
383 unsigned long iobase1;
385 spinlock_t ao_spinlock;
386 unsigned int *ao_readback;
388 unsigned char *ao_scan_order;
391 unsigned short daccon;
392 unsigned int cached_div1;
393 unsigned int cached_div2;
394 unsigned int ao_stop_count;
395 short ao_stop_continuous;
396 unsigned short ao_enab; /* max 16 channels so 'short' will do */
397 unsigned char intsce;
401 * Called from the 'insn_write' function to perform a single write.
404 pci224_ao_set_data(struct comedi_device *dev, int chan, int range,
407 const struct pci224_board *thisboard = comedi_board(dev);
408 struct pci224_private *devpriv = dev->private;
409 unsigned short mangled;
411 /* Store unmangled data for readback. */
412 devpriv->ao_readback[chan] = data;
413 /* Enable the channel. */
414 outw(1 << chan, dev->iobase + PCI224_DACCEN);
415 /* Set range and reset FIFO. */
416 devpriv->daccon = COMBINE(devpriv->daccon, devpriv->hwrange[range],
417 (PCI224_DACCON_POLAR_MASK |
418 PCI224_DACCON_VREF_MASK));
419 outw(devpriv->daccon | PCI224_DACCON_FIFORESET,
420 dev->iobase + PCI224_DACCON);
422 * Mangle the data. The hardware expects:
423 * - bipolar: 16-bit 2's complement
424 * - unipolar: 16-bit unsigned
426 mangled = (unsigned short)data << (16 - thisboard->ao_bits);
427 if ((devpriv->daccon & PCI224_DACCON_POLAR_MASK) ==
428 PCI224_DACCON_POLAR_BI) {
431 /* Write mangled data to the FIFO. */
432 outw(mangled, dev->iobase + PCI224_DACDATA);
433 /* Trigger the conversion. */
434 inw(dev->iobase + PCI224_SOFTTRIG);
438 * 'insn_write' function for AO subdevice.
441 pci224_ao_insn_write(struct comedi_device *dev, struct comedi_subdevice *s,
442 struct comedi_insn *insn, unsigned int *data)
447 /* Unpack channel and range. */
448 chan = CR_CHAN(insn->chanspec);
449 range = CR_RANGE(insn->chanspec);
451 /* Writing a list of values to an AO channel is probably not
452 * very useful, but that's how the interface is defined. */
453 for (i = 0; i < insn->n; i++)
454 pci224_ao_set_data(dev, chan, range, data[i]);
460 * 'insn_read' function for AO subdevice.
462 * N.B. The value read will not be valid if the DAC channel has
463 * never been written successfully since the device was attached
464 * or since the channel has been used by an AO streaming write
468 pci224_ao_insn_read(struct comedi_device *dev, struct comedi_subdevice *s,
469 struct comedi_insn *insn, unsigned int *data)
471 struct pci224_private *devpriv = dev->private;
475 chan = CR_CHAN(insn->chanspec);
477 for (i = 0; i < insn->n; i++)
478 data[i] = devpriv->ao_readback[chan];
485 * Just a wrapper for the inline function 'i8253_cascade_ns_to_timer'.
488 pci224_cascade_ns_to_timer(int osc_base, unsigned int *d1, unsigned int *d2,
489 unsigned int *nanosec, int round_mode)
491 i8253_cascade_ns_to_timer(osc_base, d1, d2, nanosec, round_mode);
495 * Kills a command running on the AO subdevice.
497 static void pci224_ao_stop(struct comedi_device *dev,
498 struct comedi_subdevice *s)
500 struct pci224_private *devpriv = dev->private;
503 if (!test_and_clear_bit(AO_CMD_STARTED, &devpriv->state))
507 spin_lock_irqsave(&devpriv->ao_spinlock, flags);
508 /* Kill the interrupts. */
510 outb(0, devpriv->iobase1 + PCI224_INT_SCE);
512 * Interrupt routine may or may not be running. We may or may not
513 * have been called from the interrupt routine (directly or
514 * indirectly via a comedi_events() callback routine). It's highly
515 * unlikely that we've been called from some other interrupt routine
516 * but who knows what strange things coders get up to!
518 * If the interrupt routine is currently running, wait for it to
519 * finish, unless we appear to have been called via the interrupt
522 while (devpriv->intr_running && devpriv->intr_cpuid != THISCPU) {
523 spin_unlock_irqrestore(&devpriv->ao_spinlock, flags);
524 spin_lock_irqsave(&devpriv->ao_spinlock, flags);
526 spin_unlock_irqrestore(&devpriv->ao_spinlock, flags);
527 /* Reconfigure DAC for insn_write usage. */
528 outw(0, dev->iobase + PCI224_DACCEN); /* Disable channels. */
529 devpriv->daccon = COMBINE(devpriv->daccon,
530 PCI224_DACCON_TRIG_SW |
531 PCI224_DACCON_FIFOINTR_EMPTY,
532 PCI224_DACCON_TRIG_MASK |
533 PCI224_DACCON_FIFOINTR_MASK);
534 outw(devpriv->daccon | PCI224_DACCON_FIFORESET,
535 dev->iobase + PCI224_DACCON);
539 * Handles start of acquisition for the AO subdevice.
541 static void pci224_ao_start(struct comedi_device *dev,
542 struct comedi_subdevice *s)
544 struct pci224_private *devpriv = dev->private;
545 struct comedi_cmd *cmd = &s->async->cmd;
548 set_bit(AO_CMD_STARTED, &devpriv->state);
549 if (!devpriv->ao_stop_continuous && devpriv->ao_stop_count == 0) {
550 /* An empty acquisition! */
551 pci224_ao_stop(dev, s);
552 s->async->events |= COMEDI_CB_EOA;
553 comedi_event(dev, s);
555 /* Enable interrupts. */
556 spin_lock_irqsave(&devpriv->ao_spinlock, flags);
557 if (cmd->stop_src == TRIG_EXT)
558 devpriv->intsce = PCI224_INTR_EXT | PCI224_INTR_DAC;
560 devpriv->intsce = PCI224_INTR_DAC;
562 outb(devpriv->intsce, devpriv->iobase1 + PCI224_INT_SCE);
563 spin_unlock_irqrestore(&devpriv->ao_spinlock, flags);
568 * Handles interrupts from the DAC FIFO.
570 static void pci224_ao_handle_fifo(struct comedi_device *dev,
571 struct comedi_subdevice *s)
573 struct pci224_private *devpriv = dev->private;
574 struct comedi_cmd *cmd = &s->async->cmd;
575 unsigned int num_scans;
577 unsigned short dacstat;
579 unsigned int bytes_per_scan;
581 if (cmd->chanlist_len) {
582 bytes_per_scan = cmd->chanlist_len * sizeof(short);
584 /* Shouldn't get here! */
585 bytes_per_scan = sizeof(short);
587 /* Determine number of scans available in buffer. */
588 num_scans = comedi_buf_read_n_available(s->async) / bytes_per_scan;
589 if (!devpriv->ao_stop_continuous) {
590 /* Fixed number of scans. */
591 if (num_scans > devpriv->ao_stop_count)
592 num_scans = devpriv->ao_stop_count;
596 /* Determine how much room is in the FIFO (in samples). */
597 dacstat = inw(dev->iobase + PCI224_DACCON);
598 switch (dacstat & PCI224_DACCON_FIFOFL_MASK) {
599 case PCI224_DACCON_FIFOFL_EMPTY:
600 room = PCI224_FIFO_ROOM_EMPTY;
601 if (!devpriv->ao_stop_continuous && devpriv->ao_stop_count == 0) {
602 /* FIFO empty at end of counted acquisition. */
603 pci224_ao_stop(dev, s);
604 s->async->events |= COMEDI_CB_EOA;
605 comedi_event(dev, s);
609 case PCI224_DACCON_FIFOFL_ONETOHALF:
610 room = PCI224_FIFO_ROOM_ONETOHALF;
612 case PCI224_DACCON_FIFOFL_HALFTOFULL:
613 room = PCI224_FIFO_ROOM_HALFTOFULL;
616 room = PCI224_FIFO_ROOM_FULL;
619 if (room >= PCI224_FIFO_ROOM_ONETOHALF) {
620 /* FIFO is less than half-full. */
621 if (num_scans == 0) {
622 /* Nothing left to put in the FIFO. */
623 pci224_ao_stop(dev, s);
624 s->async->events |= COMEDI_CB_OVERFLOW;
625 dev_err(dev->class_dev, "AO buffer underrun\n");
628 /* Determine how many new scans can be put in the FIFO. */
629 if (cmd->chanlist_len)
630 room /= cmd->chanlist_len;
632 /* Determine how many scans to process. */
633 if (num_scans > room)
637 for (n = 0; n < num_scans; n++) {
638 cfc_read_array_from_buffer(s, &devpriv->ao_scan_vals[0],
640 for (i = 0; i < cmd->chanlist_len; i++) {
641 outw(devpriv->ao_scan_vals[devpriv->ao_scan_order[i]],
642 dev->iobase + PCI224_DACDATA);
645 if (!devpriv->ao_stop_continuous) {
646 devpriv->ao_stop_count -= num_scans;
647 if (devpriv->ao_stop_count == 0) {
649 * Change FIFO interrupt trigger level to wait
650 * until FIFO is empty.
652 devpriv->daccon = COMBINE(devpriv->daccon,
653 PCI224_DACCON_FIFOINTR_EMPTY,
654 PCI224_DACCON_FIFOINTR_MASK);
655 outw(devpriv->daccon, dev->iobase + PCI224_DACCON);
658 if ((devpriv->daccon & PCI224_DACCON_TRIG_MASK) ==
659 PCI224_DACCON_TRIG_NONE) {
663 * This is the initial DAC FIFO interrupt at the
664 * start of the acquisition. The DAC's scan trigger
665 * has been set to 'none' up until now.
667 * Now that data has been written to the FIFO, the
668 * DAC's scan trigger source can be set to the
671 * BUG: The first scan will be triggered immediately
672 * if the scan trigger source is at logic level 1.
674 if (cmd->scan_begin_src == TRIG_TIMER) {
675 trig = PCI224_DACCON_TRIG_Z2CT0;
677 /* cmd->scan_begin_src == TRIG_EXT */
678 if (cmd->scan_begin_arg & CR_INVERT)
679 trig = PCI224_DACCON_TRIG_EXTN;
681 trig = PCI224_DACCON_TRIG_EXTP;
684 devpriv->daccon = COMBINE(devpriv->daccon, trig,
685 PCI224_DACCON_TRIG_MASK);
686 outw(devpriv->daccon, dev->iobase + PCI224_DACCON);
688 if (s->async->events)
689 comedi_event(dev, s);
694 * Internal trigger function to start acquisition on AO subdevice.
697 pci224_ao_inttrig_start(struct comedi_device *dev, struct comedi_subdevice *s,
698 unsigned int trignum)
703 s->async->inttrig = NULL;
704 pci224_ao_start(dev, s);
709 #define MAX_SCAN_PERIOD 0xFFFFFFFFU
710 #define MIN_SCAN_PERIOD 2500
711 #define CONVERT_PERIOD 625
714 * 'do_cmdtest' function for AO subdevice.
717 pci224_ao_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
718 struct comedi_cmd *cmd)
720 struct pci224_private *devpriv = dev->private;
724 /* Step 1: make sure trigger sources are trivially valid. */
726 tmp = cmd->start_src;
727 cmd->start_src &= TRIG_INT | TRIG_EXT;
728 if (!cmd->start_src || tmp != cmd->start_src)
731 tmp = cmd->scan_begin_src;
732 cmd->scan_begin_src &= TRIG_EXT | TRIG_TIMER;
733 if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
736 tmp = cmd->convert_src;
737 cmd->convert_src &= TRIG_NOW;
738 if (!cmd->convert_src || tmp != cmd->convert_src)
741 tmp = cmd->scan_end_src;
742 cmd->scan_end_src &= TRIG_COUNT;
743 if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
747 cmd->stop_src &= TRIG_COUNT | TRIG_EXT | TRIG_NONE;
748 if (!cmd->stop_src || tmp != cmd->stop_src)
754 /* Step 2: make sure trigger sources are unique and mutually
757 /* these tests are true if more than one _src bit is set */
758 if ((cmd->start_src & (cmd->start_src - 1)) != 0)
760 if ((cmd->scan_begin_src & (cmd->scan_begin_src - 1)) != 0)
762 if ((cmd->convert_src & (cmd->convert_src - 1)) != 0)
764 if ((cmd->scan_end_src & (cmd->scan_end_src - 1)) != 0)
766 if ((cmd->stop_src & (cmd->stop_src - 1)) != 0)
769 /* There's only one external trigger signal (which makes these
770 * tests easier). Only one thing can use it. */
772 if (cmd->start_src & TRIG_EXT)
774 if (cmd->scan_begin_src & TRIG_EXT)
776 if (cmd->stop_src & TRIG_EXT)
784 /* Step 3: make sure arguments are trivially compatible. */
786 switch (cmd->start_src) {
788 if (cmd->start_arg != 0) {
794 /* Force to external trigger 0. */
795 if ((cmd->start_arg & ~CR_FLAGS_MASK) != 0) {
796 cmd->start_arg = COMBINE(cmd->start_arg, 0,
800 /* The only flag allowed is CR_EDGE, which is ignored. */
801 if ((cmd->start_arg & CR_FLAGS_MASK & ~CR_EDGE) != 0) {
802 cmd->start_arg = COMBINE(cmd->start_arg, 0,
803 CR_FLAGS_MASK & ~CR_EDGE);
809 switch (cmd->scan_begin_src) {
811 if (cmd->scan_begin_arg > MAX_SCAN_PERIOD) {
812 cmd->scan_begin_arg = MAX_SCAN_PERIOD;
815 tmp = cmd->chanlist_len * CONVERT_PERIOD;
816 if (tmp < MIN_SCAN_PERIOD)
817 tmp = MIN_SCAN_PERIOD;
819 if (cmd->scan_begin_arg < tmp) {
820 cmd->scan_begin_arg = tmp;
825 /* Force to external trigger 0. */
826 if ((cmd->scan_begin_arg & ~CR_FLAGS_MASK) != 0) {
827 cmd->scan_begin_arg = COMBINE(cmd->scan_begin_arg, 0,
831 /* Only allow flags CR_EDGE and CR_INVERT. Ignore CR_EDGE. */
832 if ((cmd->scan_begin_arg & CR_FLAGS_MASK &
833 ~(CR_EDGE | CR_INVERT)) != 0) {
834 cmd->scan_begin_arg = COMBINE(cmd->scan_begin_arg, 0,
835 CR_FLAGS_MASK & ~(CR_EDGE
843 /* cmd->convert_src == TRIG_NOW */
844 if (cmd->convert_arg != 0) {
845 cmd->convert_arg = 0;
849 /* cmd->scan_end_arg == TRIG_COUNT */
850 if (cmd->scan_end_arg != cmd->chanlist_len) {
851 cmd->scan_end_arg = cmd->chanlist_len;
855 switch (cmd->stop_src) {
857 /* Any count allowed. */
860 /* Force to external trigger 0. */
861 if ((cmd->stop_arg & ~CR_FLAGS_MASK) != 0) {
862 cmd->stop_arg = COMBINE(cmd->stop_arg, 0,
866 /* The only flag allowed is CR_EDGE, which is ignored. */
867 if ((cmd->stop_arg & CR_FLAGS_MASK & ~CR_EDGE) != 0) {
868 cmd->stop_arg = COMBINE(cmd->stop_arg, 0,
869 CR_FLAGS_MASK & ~CR_EDGE);
873 if (cmd->stop_arg != 0) {
883 /* Step 4: fix up any arguments. */
885 if (cmd->scan_begin_src == TRIG_TIMER) {
886 unsigned int div1, div2, round;
887 int round_mode = cmd->flags & TRIG_ROUND_MASK;
889 tmp = cmd->scan_begin_arg;
890 /* Check whether to use a single timer. */
891 switch (round_mode) {
892 case TRIG_ROUND_NEAREST:
894 round = TIMEBASE_10MHZ / 2;
896 case TRIG_ROUND_DOWN:
900 round = TIMEBASE_10MHZ - 1;
903 /* Be careful to avoid overflow! */
904 div2 = cmd->scan_begin_arg / TIMEBASE_10MHZ;
905 div2 += (round + cmd->scan_begin_arg % TIMEBASE_10MHZ) /
907 if (div2 <= 0x10000) {
908 /* A single timer will suffice. */
911 cmd->scan_begin_arg = div2 * TIMEBASE_10MHZ;
912 if (cmd->scan_begin_arg < div2 ||
913 cmd->scan_begin_arg < TIMEBASE_10MHZ) {
915 cmd->scan_begin_arg = MAX_SCAN_PERIOD;
918 /* Use two timers. */
919 div1 = devpriv->cached_div1;
920 div2 = devpriv->cached_div2;
921 pci224_cascade_ns_to_timer(TIMEBASE_10MHZ, &div1, &div2,
922 &cmd->scan_begin_arg,
924 devpriv->cached_div1 = div1;
925 devpriv->cached_div2 = div2;
927 if (tmp != cmd->scan_begin_arg)
935 /* Step 5: check channel list. */
937 if (cmd->chanlist && (cmd->chanlist_len > 0)) {
939 enum { range_err = 1, dupchan_err = 2, };
945 * Check all channels have the same range index. Don't care
946 * about analogue reference, as we can't configure it.
948 * Check the list has no duplicate channels.
950 range = CR_RANGE(cmd->chanlist[0]);
953 for (n = 0; n < cmd->chanlist_len; n++) {
954 ch = CR_CHAN(cmd->chanlist[n]);
955 if (tmp & (1U << ch))
956 errors |= dupchan_err;
959 if (CR_RANGE(cmd->chanlist[n]) != range)
964 if (errors & dupchan_err) {
965 DPRINTK("comedi%d: " DRIVER_NAME
967 "entries in chanlist must contain no "
968 "duplicate channels\n", dev->minor);
970 if (errors & range_err) {
971 DPRINTK("comedi%d: " DRIVER_NAME
973 "entries in chanlist must all have "
974 "the same range index\n", dev->minor);
987 * 'do_cmd' function for AO subdevice.
989 static int pci224_ao_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
991 struct pci224_private *devpriv = dev->private;
992 struct comedi_cmd *cmd = &s->async->cmd;
999 /* Cannot handle null/empty chanlist. */
1000 if (cmd->chanlist == NULL || cmd->chanlist_len == 0)
1004 /* Determine which channels are enabled and their load order. */
1005 devpriv->ao_enab = 0;
1007 for (i = 0; i < cmd->chanlist_len; i++) {
1008 ch = CR_CHAN(cmd->chanlist[i]);
1009 devpriv->ao_enab |= 1U << ch;
1011 for (j = 0; j < cmd->chanlist_len; j++) {
1012 if (CR_CHAN(cmd->chanlist[j]) < ch)
1016 devpriv->ao_scan_order[rank] = i;
1019 /* Set enabled channels. */
1020 outw(devpriv->ao_enab, dev->iobase + PCI224_DACCEN);
1022 /* Determine range and polarity. All channels the same. */
1023 range = CR_RANGE(cmd->chanlist[0]);
1026 * Set DAC range and polarity.
1027 * Set DAC scan trigger source to 'none'.
1028 * Set DAC FIFO interrupt trigger level to 'not half full'.
1031 * N.B. DAC FIFO interrupts are currently disabled.
1033 devpriv->daccon = COMBINE(devpriv->daccon,
1035 hwrange[range] | PCI224_DACCON_TRIG_NONE |
1036 PCI224_DACCON_FIFOINTR_NHALF),
1037 (PCI224_DACCON_POLAR_MASK |
1038 PCI224_DACCON_VREF_MASK |
1039 PCI224_DACCON_TRIG_MASK |
1040 PCI224_DACCON_FIFOINTR_MASK));
1041 outw(devpriv->daccon | PCI224_DACCON_FIFORESET,
1042 dev->iobase + PCI224_DACCON);
1044 if (cmd->scan_begin_src == TRIG_TIMER) {
1045 unsigned int div1, div2, round;
1046 unsigned int ns = cmd->scan_begin_arg;
1047 int round_mode = cmd->flags & TRIG_ROUND_MASK;
1049 /* Check whether to use a single timer. */
1050 switch (round_mode) {
1051 case TRIG_ROUND_NEAREST:
1053 round = TIMEBASE_10MHZ / 2;
1055 case TRIG_ROUND_DOWN:
1059 round = TIMEBASE_10MHZ - 1;
1062 /* Be careful to avoid overflow! */
1063 div2 = cmd->scan_begin_arg / TIMEBASE_10MHZ;
1064 div2 += (round + cmd->scan_begin_arg % TIMEBASE_10MHZ) /
1066 if (div2 <= 0x10000) {
1067 /* A single timer will suffice. */
1071 div1 = 1; /* Flag that single timer to be used. */
1073 /* Use two timers. */
1074 div1 = devpriv->cached_div1;
1075 div2 = devpriv->cached_div2;
1076 pci224_cascade_ns_to_timer(TIMEBASE_10MHZ, &div1, &div2,
1081 * The output of timer Z2-0 will be used as the scan trigger
1084 /* Make sure Z2-0 is gated on. */
1085 outb(GAT_CONFIG(0, GAT_VCC),
1086 devpriv->iobase1 + PCI224_ZGAT_SCE);
1088 /* Not cascading. Z2-0 needs 10 MHz clock. */
1089 outb(CLK_CONFIG(0, CLK_10MHZ),
1090 devpriv->iobase1 + PCI224_ZCLK_SCE);
1092 /* Cascading with Z2-2. */
1093 /* Make sure Z2-2 is gated on. */
1094 outb(GAT_CONFIG(2, GAT_VCC),
1095 devpriv->iobase1 + PCI224_ZGAT_SCE);
1096 /* Z2-2 needs 10 MHz clock. */
1097 outb(CLK_CONFIG(2, CLK_10MHZ),
1098 devpriv->iobase1 + PCI224_ZCLK_SCE);
1099 /* Load Z2-2 mode (2) and counter (div1). */
1100 i8254_load(devpriv->iobase1 + PCI224_Z2_CT0, 0,
1102 /* Z2-0 is clocked from Z2-2's output. */
1103 outb(CLK_CONFIG(0, CLK_OUTNM1),
1104 devpriv->iobase1 + PCI224_ZCLK_SCE);
1106 /* Load Z2-0 mode (2) and counter (div2). */
1107 i8254_load(devpriv->iobase1 + PCI224_Z2_CT0, 0, 0, div2, 2);
1111 * Sort out end of acquisition.
1113 switch (cmd->stop_src) {
1115 /* Fixed number of scans. */
1116 devpriv->ao_stop_continuous = 0;
1117 devpriv->ao_stop_count = cmd->stop_arg;
1120 /* Continuous scans. */
1121 devpriv->ao_stop_continuous = 1;
1122 devpriv->ao_stop_count = 0;
1127 * Sort out start of acquisition.
1129 switch (cmd->start_src) {
1131 spin_lock_irqsave(&devpriv->ao_spinlock, flags);
1132 s->async->inttrig = &pci224_ao_inttrig_start;
1133 spin_unlock_irqrestore(&devpriv->ao_spinlock, flags);
1136 /* Enable external interrupt trigger to start acquisition. */
1137 spin_lock_irqsave(&devpriv->ao_spinlock, flags);
1138 devpriv->intsce |= PCI224_INTR_EXT;
1139 outb(devpriv->intsce, devpriv->iobase1 + PCI224_INT_SCE);
1140 spin_unlock_irqrestore(&devpriv->ao_spinlock, flags);
1148 * 'cancel' function for AO subdevice.
1150 static int pci224_ao_cancel(struct comedi_device *dev,
1151 struct comedi_subdevice *s)
1153 pci224_ao_stop(dev, s);
1158 * 'munge' data for AO command.
1161 pci224_ao_munge(struct comedi_device *dev, struct comedi_subdevice *s,
1162 void *data, unsigned int num_bytes, unsigned int chan_index)
1164 const struct pci224_board *thisboard = comedi_board(dev);
1165 struct pci224_private *devpriv = dev->private;
1166 struct comedi_async *async = s->async;
1167 short *array = data;
1168 unsigned int length = num_bytes / sizeof(*array);
1169 unsigned int offset;
1173 /* The hardware expects 16-bit numbers. */
1174 shift = 16 - thisboard->ao_bits;
1175 /* Channels will be all bipolar or all unipolar. */
1176 if ((devpriv->hwrange[CR_RANGE(async->cmd.chanlist[0])] &
1177 PCI224_DACCON_POLAR_MASK) == PCI224_DACCON_POLAR_UNI) {
1184 /* Munge the data. */
1185 for (i = 0; i < length; i++)
1186 array[i] = (array[i] << shift) - offset;
1191 * Interrupt handler.
1193 static irqreturn_t pci224_interrupt(int irq, void *d)
1195 struct comedi_device *dev = d;
1196 struct pci224_private *devpriv = dev->private;
1197 struct comedi_subdevice *s = &dev->subdevices[0];
1198 struct comedi_cmd *cmd;
1199 unsigned char intstat, valid_intstat;
1200 unsigned char curenab;
1202 unsigned long flags;
1204 intstat = inb(devpriv->iobase1 + PCI224_INT_SCE) & 0x3F;
1207 spin_lock_irqsave(&devpriv->ao_spinlock, flags);
1208 valid_intstat = devpriv->intsce & intstat;
1209 /* Temporarily disable interrupt sources. */
1210 curenab = devpriv->intsce & ~intstat;
1211 outb(curenab, devpriv->iobase1 + PCI224_INT_SCE);
1212 devpriv->intr_running = 1;
1213 devpriv->intr_cpuid = THISCPU;
1214 spin_unlock_irqrestore(&devpriv->ao_spinlock, flags);
1215 if (valid_intstat != 0) {
1216 cmd = &s->async->cmd;
1217 if (valid_intstat & PCI224_INTR_EXT) {
1218 devpriv->intsce &= ~PCI224_INTR_EXT;
1219 if (cmd->start_src == TRIG_EXT)
1220 pci224_ao_start(dev, s);
1221 else if (cmd->stop_src == TRIG_EXT)
1222 pci224_ao_stop(dev, s);
1225 if (valid_intstat & PCI224_INTR_DAC)
1226 pci224_ao_handle_fifo(dev, s);
1229 /* Reenable interrupt sources. */
1230 spin_lock_irqsave(&devpriv->ao_spinlock, flags);
1231 if (curenab != devpriv->intsce) {
1232 outb(devpriv->intsce,
1233 devpriv->iobase1 + PCI224_INT_SCE);
1235 devpriv->intr_running = 0;
1236 spin_unlock_irqrestore(&devpriv->ao_spinlock, flags);
1238 return IRQ_RETVAL(retval);
1242 * This function looks for a board matching the supplied PCI device.
1244 static const struct pci224_board
1245 *pci224_find_pci_board(struct pci_dev *pci_dev)
1249 for (i = 0; i < ARRAY_SIZE(pci224_boards); i++)
1250 if (pci_dev->device == pci224_boards[i].devid)
1251 return &pci224_boards[i];
1256 * This function looks for a PCI device matching the requested board name,
1259 static struct pci_dev *
1260 pci224_find_pci(struct comedi_device *dev, int bus, int slot)
1262 const struct pci224_board *thisboard = comedi_board(dev);
1263 struct pci_dev *pci_dev = NULL;
1265 /* Look for matching PCI device. */
1266 for (pci_dev = pci_get_device(PCI_VENDOR_ID_AMPLICON, PCI_ANY_ID, NULL);
1268 pci_dev = pci_get_device(PCI_VENDOR_ID_AMPLICON, PCI_ANY_ID,
1270 /* If bus/slot specified, check them. */
1272 if (bus != pci_dev->bus->number
1273 || slot != PCI_SLOT(pci_dev->devfn))
1276 if (thisboard->model == any_model) {
1277 /* Match any supported model. */
1278 const struct pci224_board *board_ptr;
1279 board_ptr = pci224_find_pci_board(pci_dev);
1280 if (board_ptr == NULL)
1282 /* Change board_ptr to matched board. */
1283 dev->board_ptr = board_ptr;
1284 thisboard = comedi_board(dev);
1286 /* Match specific model name. */
1287 if (thisboard->devid != pci_dev->device)
1291 /* Found a match. */
1294 /* No match found. */
1296 dev_err(dev->class_dev,
1297 "error! no %s found at pci %02x:%02x!\n",
1298 thisboard->name, bus, slot);
1300 dev_err(dev->class_dev, "error! no %s found!\n",
1306 static void pci224_report_attach(struct comedi_device *dev, unsigned int irq)
1308 struct pci224_private *devpriv = dev->private;
1312 snprintf(tmpbuf, sizeof(tmpbuf), "irq %u%s", irq,
1313 (dev->irq ? "" : " UNAVAILABLE"));
1315 snprintf(tmpbuf, sizeof(tmpbuf), "no irq");
1316 dev_info(dev->class_dev, "%s (pci %s) (%s) attached\n",
1317 dev->board_name, pci_name(devpriv->pci_dev), tmpbuf);
1321 * Common part of attach and attach_pci.
1323 static int pci224_attach_common(struct comedi_device *dev,
1324 struct pci_dev *pci_dev, int *options)
1326 const struct pci224_board *thisboard = comedi_board(dev);
1327 struct pci224_private *devpriv = dev->private;
1328 struct comedi_subdevice *s;
1333 devpriv->pci_dev = pci_dev;
1334 ret = comedi_pci_enable(pci_dev, DRIVER_NAME);
1336 dev_err(dev->class_dev,
1337 "error! cannot enable PCI device and request regions!\n"
1341 spin_lock_init(&devpriv->ao_spinlock);
1343 devpriv->iobase1 = pci_resource_start(pci_dev, 2);
1344 dev->iobase = pci_resource_start(pci_dev, 3);
1347 /* Allocate readback buffer for AO channels. */
1348 devpriv->ao_readback = kmalloc(sizeof(devpriv->ao_readback[0]) *
1349 thisboard->ao_chans, GFP_KERNEL);
1350 if (!devpriv->ao_readback)
1354 /* Allocate buffer to hold values for AO channel scan. */
1355 devpriv->ao_scan_vals = kmalloc(sizeof(devpriv->ao_scan_vals[0]) *
1356 thisboard->ao_chans, GFP_KERNEL);
1357 if (!devpriv->ao_scan_vals)
1361 /* Allocate buffer to hold AO channel scan order. */
1362 devpriv->ao_scan_order = kmalloc(sizeof(devpriv->ao_scan_order[0]) *
1363 thisboard->ao_chans, GFP_KERNEL);
1364 if (!devpriv->ao_scan_order)
1368 /* Disable interrupt sources. */
1369 devpriv->intsce = 0;
1370 outb(0, devpriv->iobase1 + PCI224_INT_SCE);
1372 /* Initialize the DAC hardware. */
1373 outw(PCI224_DACCON_GLOBALRESET, dev->iobase + PCI224_DACCON);
1374 outw(0, dev->iobase + PCI224_DACCEN);
1375 outw(0, dev->iobase + PCI224_FIFOSIZ);
1376 devpriv->daccon = (PCI224_DACCON_TRIG_SW | PCI224_DACCON_POLAR_BI |
1377 PCI224_DACCON_FIFOENAB |
1378 PCI224_DACCON_FIFOINTR_EMPTY);
1379 outw(devpriv->daccon | PCI224_DACCON_FIFORESET,
1380 dev->iobase + PCI224_DACCON);
1382 ret = comedi_alloc_subdevices(dev, 1);
1386 s = dev->subdevices + 0;
1387 /* Analog output subdevice. */
1388 s->type = COMEDI_SUBD_AO;
1389 s->subdev_flags = SDF_WRITABLE | SDF_GROUND | SDF_CMD_WRITE;
1390 s->n_chan = thisboard->ao_chans;
1391 s->maxdata = (1 << thisboard->ao_bits) - 1;
1392 s->insn_write = &pci224_ao_insn_write;
1393 s->insn_read = &pci224_ao_insn_read;
1394 s->len_chanlist = s->n_chan;
1396 dev->write_subdev = s;
1397 s->do_cmd = &pci224_ao_cmd;
1398 s->do_cmdtest = &pci224_ao_cmdtest;
1399 s->cancel = &pci224_ao_cancel;
1400 s->munge = &pci224_ao_munge;
1402 /* Sort out channel range options. */
1403 if (thisboard->model == pci234_model) {
1404 /* PCI234 range options. */
1405 const struct comedi_lrange **range_table_list;
1407 s->range_table_list = range_table_list =
1408 kmalloc(sizeof(struct comedi_lrange *) * s->n_chan,
1410 if (!s->range_table_list)
1414 for (n = 2; n < 3 + s->n_chan; n++) {
1415 if (options[n] < 0 || options[n] > 1) {
1416 dev_warn(dev->class_dev, DRIVER_NAME
1417 ": warning! bad options[%u]=%d\n",
1422 for (n = 0; n < s->n_chan; n++) {
1423 if (n < COMEDI_NDEVCONFOPTS - 3 && options &&
1424 options[3 + n] == 1) {
1425 if (options[2] == 1)
1426 range_table_list[n] = &range_pci234_ext;
1428 range_table_list[n] = &range_bipolar5;
1431 if (options && options[2] == 1) {
1432 range_table_list[n] =
1435 range_table_list[n] = &range_bipolar10;
1439 devpriv->hwrange = hwrange_pci234;
1441 /* PCI224 range options. */
1442 if (options && options[2] == 1) {
1443 s->range_table = &range_pci224_external;
1444 devpriv->hwrange = hwrange_pci224_external;
1446 if (options && options[2] != 0) {
1447 dev_warn(dev->class_dev, DRIVER_NAME
1448 ": warning! bad options[2]=%d\n",
1451 s->range_table = &range_pci224_internal;
1452 devpriv->hwrange = hwrange_pci224_internal;
1456 dev->board_name = thisboard->name;
1459 ret = request_irq(irq, pci224_interrupt, IRQF_SHARED,
1462 dev_err(dev->class_dev,
1463 "error! unable to allocate irq %u\n", irq);
1470 pci224_report_attach(dev, irq);
1474 static int pci224_attach(struct comedi_device *dev, struct comedi_devconfig *it)
1476 struct pci_dev *pci_dev;
1480 dev_info(dev->class_dev, DRIVER_NAME ": attach\n");
1482 bus = it->options[0];
1483 slot = it->options[1];
1484 ret = alloc_private(dev, sizeof(struct pci224_private));
1486 dev_err(dev->class_dev, "error! out of memory!\n");
1490 pci_dev = pci224_find_pci(dev, bus, slot);
1491 if (pci_dev == NULL)
1494 return pci224_attach_common(dev, pci_dev, it->options);
1497 static int __devinit
1498 pci224_attach_pci(struct comedi_device *dev, struct pci_dev *pci_dev)
1502 dev_info(dev->class_dev, DRIVER_NAME ": attach_pci %s\n",
1505 ret = alloc_private(dev, sizeof(struct pci224_private));
1507 dev_err(dev->class_dev, "error! out of memory!\n");
1511 dev->board_ptr = pci224_find_pci_board(pci_dev);
1512 if (dev->board_ptr == NULL) {
1513 dev_err(dev->class_dev,
1514 DRIVER_NAME ": BUG! cannot determine board type!\n");
1517 return pci224_attach_common(dev, pci_dev, NULL);
1520 static void pci224_detach(struct comedi_device *dev)
1522 struct pci224_private *devpriv = dev->private;
1525 free_irq(dev->irq, dev);
1526 if (dev->subdevices) {
1527 struct comedi_subdevice *s;
1529 s = dev->subdevices + 0;
1531 kfree(s->range_table_list);
1534 kfree(devpriv->ao_readback);
1535 kfree(devpriv->ao_scan_vals);
1536 kfree(devpriv->ao_scan_order);
1537 if (devpriv->pci_dev) {
1539 comedi_pci_disable(devpriv->pci_dev);
1540 pci_dev_put(devpriv->pci_dev);
1545 static struct comedi_driver amplc_pci224_driver = {
1546 .driver_name = "amplc_pci224",
1547 .module = THIS_MODULE,
1548 .attach = pci224_attach,
1549 .detach = pci224_detach,
1550 .attach_pci = pci224_attach_pci,
1551 .board_name = &pci224_boards[0].name,
1552 .offset = sizeof(struct pci224_board),
1553 .num_names = ARRAY_SIZE(pci224_boards),
1556 static int __devinit amplc_pci224_pci_probe(struct pci_dev *dev,
1557 const struct pci_device_id
1560 return comedi_pci_auto_config(dev, &lc_pci224_driver);
1563 static void __devexit amplc_pci224_pci_remove(struct pci_dev *dev)
1565 comedi_pci_auto_unconfig(dev);
1568 static DEFINE_PCI_DEVICE_TABLE(amplc_pci224_pci_table) = {
1569 { PCI_DEVICE(PCI_VENDOR_ID_AMPLICON, PCI_DEVICE_ID_AMPLICON_PCI224) },
1570 { PCI_DEVICE(PCI_VENDOR_ID_AMPLICON, PCI_DEVICE_ID_AMPLICON_PCI234) },
1573 MODULE_DEVICE_TABLE(pci, amplc_pci224_pci_table);
1575 static struct pci_driver amplc_pci224_pci_driver = {
1576 .name = "amplc_pci224",
1577 .id_table = amplc_pci224_pci_table,
1578 .probe = amplc_pci224_pci_probe,
1579 .remove = __devexit_p(amplc_pci224_pci_remove),
1581 module_comedi_pci_driver(amplc_pci224_driver, amplc_pci224_pci_driver);
1583 MODULE_AUTHOR("Comedi http://www.comedi.org");
1584 MODULE_DESCRIPTION("Comedi low-level driver");
1585 MODULE_LICENSE("GPL");