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_DEVICE_ID_AMPLICON_PCI224 0x0007
120 #define PCI_DEVICE_ID_AMPLICON_PCI234 0x0008
121 #define PCI_DEVICE_ID_INVALID 0xffff
124 * PCI224/234 i/o space 1 (PCIBAR2) registers.
126 #define PCI224_IO1_SIZE 0x20 /* Size of i/o space 1 (8-bit registers) */
127 #define PCI224_Z2_CT0 0x14 /* 82C54 counter/timer 0 */
128 #define PCI224_Z2_CT1 0x15 /* 82C54 counter/timer 1 */
129 #define PCI224_Z2_CT2 0x16 /* 82C54 counter/timer 2 */
130 #define PCI224_Z2_CTC 0x17 /* 82C54 counter/timer control word */
131 #define PCI224_ZCLK_SCE 0x1A /* Group Z Clock Configuration Register */
132 #define PCI224_ZGAT_SCE 0x1D /* Group Z Gate Configuration Register */
133 #define PCI224_INT_SCE 0x1E /* ISR Interrupt source mask register */
134 /* /Interrupt status */
137 * PCI224/234 i/o space 2 (PCIBAR3) 16-bit registers.
139 #define PCI224_IO2_SIZE 0x10 /* Size of i/o space 2 (16-bit registers). */
140 #define PCI224_DACDATA 0x00 /* (w-o) DAC FIFO data. */
141 #define PCI224_SOFTTRIG 0x00 /* (r-o) DAC software scan trigger. */
142 #define PCI224_DACCON 0x02 /* (r/w) DAC status/configuration. */
143 #define PCI224_FIFOSIZ 0x04 /* (w-o) FIFO size for wraparound mode. */
144 #define PCI224_DACCEN 0x06 /* (w-o) DAC channel enable register. */
149 /* (r/w) Scan trigger. */
150 #define PCI224_DACCON_TRIG_MASK (7 << 0)
151 #define PCI224_DACCON_TRIG_NONE (0 << 0) /* none */
152 #define PCI224_DACCON_TRIG_SW (1 << 0) /* software trig */
153 #define PCI224_DACCON_TRIG_EXTP (2 << 0) /* ext +ve edge */
154 #define PCI224_DACCON_TRIG_EXTN (3 << 0) /* ext -ve edge */
155 #define PCI224_DACCON_TRIG_Z2CT0 (4 << 0) /* Z2 CT0 out */
156 #define PCI224_DACCON_TRIG_Z2CT1 (5 << 0) /* Z2 CT1 out */
157 #define PCI224_DACCON_TRIG_Z2CT2 (6 << 0) /* Z2 CT2 out */
158 /* (r/w) Polarity (PCI224 only, PCI234 always bipolar!). */
159 #define PCI224_DACCON_POLAR_MASK (1 << 3)
160 #define PCI224_DACCON_POLAR_UNI (0 << 3) /* range [0,Vref] */
161 #define PCI224_DACCON_POLAR_BI (1 << 3) /* range [-Vref,Vref] */
162 /* (r/w) Internal Vref (PCI224 only, when LK1 in position 1-2). */
163 #define PCI224_DACCON_VREF_MASK (3 << 4)
164 #define PCI224_DACCON_VREF_1_25 (0 << 4) /* Vref = 1.25V */
165 #define PCI224_DACCON_VREF_2_5 (1 << 4) /* Vref = 2.5V */
166 #define PCI224_DACCON_VREF_5 (2 << 4) /* Vref = 5V */
167 #define PCI224_DACCON_VREF_10 (3 << 4) /* Vref = 10V */
168 /* (r/w) Wraparound mode enable (to play back stored waveform). */
169 #define PCI224_DACCON_FIFOWRAP (1 << 7)
170 /* (r/w) FIFO enable. It MUST be set! */
171 #define PCI224_DACCON_FIFOENAB (1 << 8)
172 /* (r/w) FIFO interrupt trigger level (most values are not very useful). */
173 #define PCI224_DACCON_FIFOINTR_MASK (7 << 9)
174 #define PCI224_DACCON_FIFOINTR_EMPTY (0 << 9) /* when empty */
175 #define PCI224_DACCON_FIFOINTR_NEMPTY (1 << 9) /* when not empty */
176 #define PCI224_DACCON_FIFOINTR_NHALF (2 << 9) /* when not half full */
177 #define PCI224_DACCON_FIFOINTR_HALF (3 << 9) /* when half full */
178 #define PCI224_DACCON_FIFOINTR_NFULL (4 << 9) /* when not full */
179 #define PCI224_DACCON_FIFOINTR_FULL (5 << 9) /* when full */
180 /* (r-o) FIFO fill level. */
181 #define PCI224_DACCON_FIFOFL_MASK (7 << 12)
182 #define PCI224_DACCON_FIFOFL_EMPTY (1 << 12) /* 0 */
183 #define PCI224_DACCON_FIFOFL_ONETOHALF (0 << 12) /* [1,2048] */
184 #define PCI224_DACCON_FIFOFL_HALFTOFULL (4 << 12) /* [2049,4095] */
185 #define PCI224_DACCON_FIFOFL_FULL (6 << 12) /* 4096 */
186 /* (r-o) DAC busy flag. */
187 #define PCI224_DACCON_BUSY (1 << 15)
188 /* (w-o) FIFO reset. */
189 #define PCI224_DACCON_FIFORESET (1 << 12)
190 /* (w-o) Global reset (not sure what it does). */
191 #define PCI224_DACCON_GLOBALRESET (1 << 13)
196 #define PCI224_FIFO_SIZE 4096
199 * DAC FIFO guaranteed minimum room available, depending on reported fill level.
200 * The maximum room available depends on the reported fill level and how much
203 #define PCI224_FIFO_ROOM_EMPTY PCI224_FIFO_SIZE
204 #define PCI224_FIFO_ROOM_ONETOHALF (PCI224_FIFO_SIZE / 2)
205 #define PCI224_FIFO_ROOM_HALFTOFULL 1
206 #define PCI224_FIFO_ROOM_FULL 0
209 * Counter/timer clock input configuration sources.
211 #define CLK_CLK 0 /* reserved (channel-specific clock) */
212 #define CLK_10MHZ 1 /* internal 10 MHz clock */
213 #define CLK_1MHZ 2 /* internal 1 MHz clock */
214 #define CLK_100KHZ 3 /* internal 100 kHz clock */
215 #define CLK_10KHZ 4 /* internal 10 kHz clock */
216 #define CLK_1KHZ 5 /* internal 1 kHz clock */
217 #define CLK_OUTNM1 6 /* output of channel-1 modulo total */
218 #define CLK_EXT 7 /* external clock */
219 /* Macro to construct clock input configuration register value. */
220 #define CLK_CONFIG(chan, src) ((((chan) & 3) << 3) | ((src) & 7))
221 /* Timebases in ns. */
222 #define TIMEBASE_10MHZ 100
223 #define TIMEBASE_1MHZ 1000
224 #define TIMEBASE_100KHZ 10000
225 #define TIMEBASE_10KHZ 100000
226 #define TIMEBASE_1KHZ 1000000
229 * Counter/timer gate input configuration sources.
231 #define GAT_VCC 0 /* VCC (i.e. enabled) */
232 #define GAT_GND 1 /* GND (i.e. disabled) */
233 #define GAT_EXT 2 /* reserved (external gate input) */
234 #define GAT_NOUTNM2 3 /* inverted output of channel-2 modulo total */
235 /* Macro to construct gate input configuration register value. */
236 #define GAT_CONFIG(chan, src) ((((chan) & 3) << 3) | ((src) & 7))
239 * Summary of CLK_OUTNM1 and GAT_NOUTNM2 connections for PCI224 and PCI234:
241 * Channel's Channel's
242 * clock input gate input
243 * Channel CLK_OUTNM1 GAT_NOUTNM2
244 * ------- ---------- -----------
245 * Z2-CT0 Z2-CT2-OUT /Z2-CT1-OUT
246 * Z2-CT1 Z2-CT0-OUT /Z2-CT2-OUT
247 * Z2-CT2 Z2-CT1-OUT /Z2-CT0-OUT
251 * Interrupt enable/status bits
253 #define PCI224_INTR_EXT 0x01 /* rising edge on external input */
254 #define PCI224_INTR_DAC 0x04 /* DAC (FIFO) interrupt */
255 #define PCI224_INTR_Z2CT1 0x20 /* rising edge on Z2-CT1 output */
257 #define PCI224_INTR_EDGE_BITS (PCI224_INTR_EXT | PCI224_INTR_Z2CT1)
258 #define PCI224_INTR_LEVEL_BITS PCI224_INTR_DACFIFO
264 /* Combine old and new bits. */
265 #define COMBINE(old, new, mask) (((old) & ~(mask)) | ((new) & (mask)))
267 /* Current CPU. XXX should this be hard_smp_processor_id()? */
268 #define THISCPU smp_processor_id()
270 /* State bits for use with atomic bit operations. */
271 #define AO_CMD_STARTED 0
277 /* The software selectable internal ranges for PCI224 (option[2] == 0). */
278 static const struct comedi_lrange range_pci224_internal = {
292 static const unsigned short hwrange_pci224_internal[8] = {
293 PCI224_DACCON_POLAR_BI | PCI224_DACCON_VREF_10,
294 PCI224_DACCON_POLAR_BI | PCI224_DACCON_VREF_5,
295 PCI224_DACCON_POLAR_BI | PCI224_DACCON_VREF_2_5,
296 PCI224_DACCON_POLAR_BI | PCI224_DACCON_VREF_1_25,
297 PCI224_DACCON_POLAR_UNI | PCI224_DACCON_VREF_10,
298 PCI224_DACCON_POLAR_UNI | PCI224_DACCON_VREF_5,
299 PCI224_DACCON_POLAR_UNI | PCI224_DACCON_VREF_2_5,
300 PCI224_DACCON_POLAR_UNI | PCI224_DACCON_VREF_1_25,
303 /* The software selectable external ranges for PCI224 (option[2] == 1). */
304 static const struct comedi_lrange range_pci224_external = {
307 RANGE_ext(-1, 1), /* bipolar [-Vref,+Vref] */
308 RANGE_ext(0, 1), /* unipolar [0,+Vref] */
312 static const unsigned short hwrange_pci224_external[2] = {
313 PCI224_DACCON_POLAR_BI,
314 PCI224_DACCON_POLAR_UNI,
317 /* The hardware selectable Vref*2 external range for PCI234
318 * (option[2] == 1, option[3+n] == 0). */
319 static const struct comedi_lrange range_pci234_ext2 = {
326 /* The hardware selectable Vref external range for PCI234
327 * (option[2] == 1, option[3+n] == 1). */
328 static const struct comedi_lrange range_pci234_ext = {
335 /* This serves for all the PCI234 ranges. */
336 static const unsigned short hwrange_pci234[1] = {
337 PCI224_DACCON_POLAR_BI, /* bipolar - hardware ignores it! */
341 * Board descriptions.
344 enum pci224_model { any_model, pci224_model, pci234_model };
346 struct pci224_board {
348 unsigned short devid;
349 enum pci224_model model;
350 unsigned int ao_chans;
351 unsigned int ao_bits;
354 static const struct pci224_board pci224_boards[] = {
357 .devid = PCI_DEVICE_ID_AMPLICON_PCI224,
358 .model = pci224_model,
364 .devid = PCI_DEVICE_ID_AMPLICON_PCI234,
365 .model = pci234_model,
371 .devid = PCI_DEVICE_ID_INVALID,
372 .model = any_model, /* wildcard */
376 /* this structure is for data unique to this hardware driver. If
377 several hardware drivers keep similar information in this structure,
378 feel free to suggest moving the variable to the struct comedi_device struct. */
379 struct pci224_private {
380 const unsigned short *hwrange;
381 unsigned long iobase1;
383 spinlock_t ao_spinlock;
384 unsigned int *ao_readback;
386 unsigned char *ao_scan_order;
389 unsigned short daccon;
390 unsigned int cached_div1;
391 unsigned int cached_div2;
392 unsigned int ao_stop_count;
393 short ao_stop_continuous;
394 unsigned short ao_enab; /* max 16 channels so 'short' will do */
395 unsigned char intsce;
399 * Called from the 'insn_write' function to perform a single write.
402 pci224_ao_set_data(struct comedi_device *dev, int chan, int range,
405 const struct pci224_board *thisboard = comedi_board(dev);
406 struct pci224_private *devpriv = dev->private;
407 unsigned short mangled;
409 /* Store unmangled data for readback. */
410 devpriv->ao_readback[chan] = data;
411 /* Enable the channel. */
412 outw(1 << chan, dev->iobase + PCI224_DACCEN);
413 /* Set range and reset FIFO. */
414 devpriv->daccon = COMBINE(devpriv->daccon, devpriv->hwrange[range],
415 (PCI224_DACCON_POLAR_MASK |
416 PCI224_DACCON_VREF_MASK));
417 outw(devpriv->daccon | PCI224_DACCON_FIFORESET,
418 dev->iobase + PCI224_DACCON);
420 * Mangle the data. The hardware expects:
421 * - bipolar: 16-bit 2's complement
422 * - unipolar: 16-bit unsigned
424 mangled = (unsigned short)data << (16 - thisboard->ao_bits);
425 if ((devpriv->daccon & PCI224_DACCON_POLAR_MASK) ==
426 PCI224_DACCON_POLAR_BI) {
429 /* Write mangled data to the FIFO. */
430 outw(mangled, dev->iobase + PCI224_DACDATA);
431 /* Trigger the conversion. */
432 inw(dev->iobase + PCI224_SOFTTRIG);
436 * 'insn_write' function for AO subdevice.
439 pci224_ao_insn_write(struct comedi_device *dev, struct comedi_subdevice *s,
440 struct comedi_insn *insn, unsigned int *data)
445 /* Unpack channel and range. */
446 chan = CR_CHAN(insn->chanspec);
447 range = CR_RANGE(insn->chanspec);
449 /* Writing a list of values to an AO channel is probably not
450 * very useful, but that's how the interface is defined. */
451 for (i = 0; i < insn->n; i++)
452 pci224_ao_set_data(dev, chan, range, data[i]);
458 * 'insn_read' function for AO subdevice.
460 * N.B. The value read will not be valid if the DAC channel has
461 * never been written successfully since the device was attached
462 * or since the channel has been used by an AO streaming write
466 pci224_ao_insn_read(struct comedi_device *dev, struct comedi_subdevice *s,
467 struct comedi_insn *insn, unsigned int *data)
469 struct pci224_private *devpriv = dev->private;
473 chan = CR_CHAN(insn->chanspec);
475 for (i = 0; i < insn->n; i++)
476 data[i] = devpriv->ao_readback[chan];
483 * Just a wrapper for the inline function 'i8253_cascade_ns_to_timer'.
486 pci224_cascade_ns_to_timer(int osc_base, unsigned int *d1, unsigned int *d2,
487 unsigned int *nanosec, int round_mode)
489 i8253_cascade_ns_to_timer(osc_base, d1, d2, nanosec, round_mode);
493 * Kills a command running on the AO subdevice.
495 static void pci224_ao_stop(struct comedi_device *dev,
496 struct comedi_subdevice *s)
498 struct pci224_private *devpriv = dev->private;
501 if (!test_and_clear_bit(AO_CMD_STARTED, &devpriv->state))
505 spin_lock_irqsave(&devpriv->ao_spinlock, flags);
506 /* Kill the interrupts. */
508 outb(0, devpriv->iobase1 + PCI224_INT_SCE);
510 * Interrupt routine may or may not be running. We may or may not
511 * have been called from the interrupt routine (directly or
512 * indirectly via a comedi_events() callback routine). It's highly
513 * unlikely that we've been called from some other interrupt routine
514 * but who knows what strange things coders get up to!
516 * If the interrupt routine is currently running, wait for it to
517 * finish, unless we appear to have been called via the interrupt
520 while (devpriv->intr_running && devpriv->intr_cpuid != THISCPU) {
521 spin_unlock_irqrestore(&devpriv->ao_spinlock, flags);
522 spin_lock_irqsave(&devpriv->ao_spinlock, flags);
524 spin_unlock_irqrestore(&devpriv->ao_spinlock, flags);
525 /* Reconfigure DAC for insn_write usage. */
526 outw(0, dev->iobase + PCI224_DACCEN); /* Disable channels. */
527 devpriv->daccon = COMBINE(devpriv->daccon,
528 PCI224_DACCON_TRIG_SW |
529 PCI224_DACCON_FIFOINTR_EMPTY,
530 PCI224_DACCON_TRIG_MASK |
531 PCI224_DACCON_FIFOINTR_MASK);
532 outw(devpriv->daccon | PCI224_DACCON_FIFORESET,
533 dev->iobase + PCI224_DACCON);
537 * Handles start of acquisition for the AO subdevice.
539 static void pci224_ao_start(struct comedi_device *dev,
540 struct comedi_subdevice *s)
542 struct pci224_private *devpriv = dev->private;
543 struct comedi_cmd *cmd = &s->async->cmd;
546 set_bit(AO_CMD_STARTED, &devpriv->state);
547 if (!devpriv->ao_stop_continuous && devpriv->ao_stop_count == 0) {
548 /* An empty acquisition! */
549 pci224_ao_stop(dev, s);
550 s->async->events |= COMEDI_CB_EOA;
551 comedi_event(dev, s);
553 /* Enable interrupts. */
554 spin_lock_irqsave(&devpriv->ao_spinlock, flags);
555 if (cmd->stop_src == TRIG_EXT)
556 devpriv->intsce = PCI224_INTR_EXT | PCI224_INTR_DAC;
558 devpriv->intsce = PCI224_INTR_DAC;
560 outb(devpriv->intsce, devpriv->iobase1 + PCI224_INT_SCE);
561 spin_unlock_irqrestore(&devpriv->ao_spinlock, flags);
566 * Handles interrupts from the DAC FIFO.
568 static void pci224_ao_handle_fifo(struct comedi_device *dev,
569 struct comedi_subdevice *s)
571 struct pci224_private *devpriv = dev->private;
572 struct comedi_cmd *cmd = &s->async->cmd;
573 unsigned int num_scans;
575 unsigned short dacstat;
577 unsigned int bytes_per_scan;
579 if (cmd->chanlist_len) {
580 bytes_per_scan = cmd->chanlist_len * sizeof(short);
582 /* Shouldn't get here! */
583 bytes_per_scan = sizeof(short);
585 /* Determine number of scans available in buffer. */
586 num_scans = comedi_buf_read_n_available(s->async) / bytes_per_scan;
587 if (!devpriv->ao_stop_continuous) {
588 /* Fixed number of scans. */
589 if (num_scans > devpriv->ao_stop_count)
590 num_scans = devpriv->ao_stop_count;
594 /* Determine how much room is in the FIFO (in samples). */
595 dacstat = inw(dev->iobase + PCI224_DACCON);
596 switch (dacstat & PCI224_DACCON_FIFOFL_MASK) {
597 case PCI224_DACCON_FIFOFL_EMPTY:
598 room = PCI224_FIFO_ROOM_EMPTY;
599 if (!devpriv->ao_stop_continuous && devpriv->ao_stop_count == 0) {
600 /* FIFO empty at end of counted acquisition. */
601 pci224_ao_stop(dev, s);
602 s->async->events |= COMEDI_CB_EOA;
603 comedi_event(dev, s);
607 case PCI224_DACCON_FIFOFL_ONETOHALF:
608 room = PCI224_FIFO_ROOM_ONETOHALF;
610 case PCI224_DACCON_FIFOFL_HALFTOFULL:
611 room = PCI224_FIFO_ROOM_HALFTOFULL;
614 room = PCI224_FIFO_ROOM_FULL;
617 if (room >= PCI224_FIFO_ROOM_ONETOHALF) {
618 /* FIFO is less than half-full. */
619 if (num_scans == 0) {
620 /* Nothing left to put in the FIFO. */
621 pci224_ao_stop(dev, s);
622 s->async->events |= COMEDI_CB_OVERFLOW;
623 dev_err(dev->class_dev, "AO buffer underrun\n");
626 /* Determine how many new scans can be put in the FIFO. */
627 if (cmd->chanlist_len)
628 room /= cmd->chanlist_len;
630 /* Determine how many scans to process. */
631 if (num_scans > room)
635 for (n = 0; n < num_scans; n++) {
636 cfc_read_array_from_buffer(s, &devpriv->ao_scan_vals[0],
638 for (i = 0; i < cmd->chanlist_len; i++) {
639 outw(devpriv->ao_scan_vals[devpriv->ao_scan_order[i]],
640 dev->iobase + PCI224_DACDATA);
643 if (!devpriv->ao_stop_continuous) {
644 devpriv->ao_stop_count -= num_scans;
645 if (devpriv->ao_stop_count == 0) {
647 * Change FIFO interrupt trigger level to wait
648 * until FIFO is empty.
650 devpriv->daccon = COMBINE(devpriv->daccon,
651 PCI224_DACCON_FIFOINTR_EMPTY,
652 PCI224_DACCON_FIFOINTR_MASK);
653 outw(devpriv->daccon, dev->iobase + PCI224_DACCON);
656 if ((devpriv->daccon & PCI224_DACCON_TRIG_MASK) ==
657 PCI224_DACCON_TRIG_NONE) {
661 * This is the initial DAC FIFO interrupt at the
662 * start of the acquisition. The DAC's scan trigger
663 * has been set to 'none' up until now.
665 * Now that data has been written to the FIFO, the
666 * DAC's scan trigger source can be set to the
669 * BUG: The first scan will be triggered immediately
670 * if the scan trigger source is at logic level 1.
672 if (cmd->scan_begin_src == TRIG_TIMER) {
673 trig = PCI224_DACCON_TRIG_Z2CT0;
675 /* cmd->scan_begin_src == TRIG_EXT */
676 if (cmd->scan_begin_arg & CR_INVERT)
677 trig = PCI224_DACCON_TRIG_EXTN;
679 trig = PCI224_DACCON_TRIG_EXTP;
682 devpriv->daccon = COMBINE(devpriv->daccon, trig,
683 PCI224_DACCON_TRIG_MASK);
684 outw(devpriv->daccon, dev->iobase + PCI224_DACCON);
686 if (s->async->events)
687 comedi_event(dev, s);
692 * Internal trigger function to start acquisition on AO subdevice.
695 pci224_ao_inttrig_start(struct comedi_device *dev, struct comedi_subdevice *s,
696 unsigned int trignum)
701 s->async->inttrig = NULL;
702 pci224_ao_start(dev, s);
707 #define MAX_SCAN_PERIOD 0xFFFFFFFFU
708 #define MIN_SCAN_PERIOD 2500
709 #define CONVERT_PERIOD 625
712 * 'do_cmdtest' function for AO subdevice.
715 pci224_ao_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
716 struct comedi_cmd *cmd)
718 struct pci224_private *devpriv = dev->private;
722 /* Step 1 : check if triggers are trivially valid */
724 err |= cfc_check_trigger_src(&cmd->start_src, TRIG_INT | TRIG_EXT);
725 err |= cfc_check_trigger_src(&cmd->scan_begin_src,
726 TRIG_EXT | TRIG_TIMER);
727 err |= cfc_check_trigger_src(&cmd->convert_src, TRIG_NOW);
728 err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
729 err |= cfc_check_trigger_src(&cmd->stop_src,
730 TRIG_COUNT | TRIG_EXT | TRIG_NONE);
735 /* Step 2a : make sure trigger sources are unique */
737 err |= cfc_check_trigger_is_unique(cmd->start_src);
738 err |= cfc_check_trigger_is_unique(cmd->scan_begin_src);
739 err |= cfc_check_trigger_is_unique(cmd->stop_src);
741 /* Step 2b : and mutually compatible */
744 * There's only one external trigger signal (which makes these
745 * tests easier). Only one thing can use it.
748 if (cmd->start_src & TRIG_EXT)
750 if (cmd->scan_begin_src & TRIG_EXT)
752 if (cmd->stop_src & TRIG_EXT)
760 /* Step 3: make sure arguments are trivially compatible. */
762 switch (cmd->start_src) {
764 if (cmd->start_arg != 0) {
770 /* Force to external trigger 0. */
771 if ((cmd->start_arg & ~CR_FLAGS_MASK) != 0) {
772 cmd->start_arg = COMBINE(cmd->start_arg, 0,
776 /* The only flag allowed is CR_EDGE, which is ignored. */
777 if ((cmd->start_arg & CR_FLAGS_MASK & ~CR_EDGE) != 0) {
778 cmd->start_arg = COMBINE(cmd->start_arg, 0,
779 CR_FLAGS_MASK & ~CR_EDGE);
785 switch (cmd->scan_begin_src) {
787 if (cmd->scan_begin_arg > MAX_SCAN_PERIOD) {
788 cmd->scan_begin_arg = MAX_SCAN_PERIOD;
791 tmp = cmd->chanlist_len * CONVERT_PERIOD;
792 if (tmp < MIN_SCAN_PERIOD)
793 tmp = MIN_SCAN_PERIOD;
795 if (cmd->scan_begin_arg < tmp) {
796 cmd->scan_begin_arg = tmp;
801 /* Force to external trigger 0. */
802 if ((cmd->scan_begin_arg & ~CR_FLAGS_MASK) != 0) {
803 cmd->scan_begin_arg = COMBINE(cmd->scan_begin_arg, 0,
807 /* Only allow flags CR_EDGE and CR_INVERT. Ignore CR_EDGE. */
808 if ((cmd->scan_begin_arg & CR_FLAGS_MASK &
809 ~(CR_EDGE | CR_INVERT)) != 0) {
810 cmd->scan_begin_arg = COMBINE(cmd->scan_begin_arg, 0,
811 CR_FLAGS_MASK & ~(CR_EDGE
819 /* cmd->convert_src == TRIG_NOW */
820 if (cmd->convert_arg != 0) {
821 cmd->convert_arg = 0;
825 /* cmd->scan_end_arg == TRIG_COUNT */
826 if (cmd->scan_end_arg != cmd->chanlist_len) {
827 cmd->scan_end_arg = cmd->chanlist_len;
831 switch (cmd->stop_src) {
833 /* Any count allowed. */
836 /* Force to external trigger 0. */
837 if ((cmd->stop_arg & ~CR_FLAGS_MASK) != 0) {
838 cmd->stop_arg = COMBINE(cmd->stop_arg, 0,
842 /* The only flag allowed is CR_EDGE, which is ignored. */
843 if ((cmd->stop_arg & CR_FLAGS_MASK & ~CR_EDGE) != 0) {
844 cmd->stop_arg = COMBINE(cmd->stop_arg, 0,
845 CR_FLAGS_MASK & ~CR_EDGE);
849 if (cmd->stop_arg != 0) {
859 /* Step 4: fix up any arguments. */
861 if (cmd->scan_begin_src == TRIG_TIMER) {
862 unsigned int div1, div2, round;
863 int round_mode = cmd->flags & TRIG_ROUND_MASK;
865 tmp = cmd->scan_begin_arg;
866 /* Check whether to use a single timer. */
867 switch (round_mode) {
868 case TRIG_ROUND_NEAREST:
870 round = TIMEBASE_10MHZ / 2;
872 case TRIG_ROUND_DOWN:
876 round = TIMEBASE_10MHZ - 1;
879 /* Be careful to avoid overflow! */
880 div2 = cmd->scan_begin_arg / TIMEBASE_10MHZ;
881 div2 += (round + cmd->scan_begin_arg % TIMEBASE_10MHZ) /
883 if (div2 <= 0x10000) {
884 /* A single timer will suffice. */
887 cmd->scan_begin_arg = div2 * TIMEBASE_10MHZ;
888 if (cmd->scan_begin_arg < div2 ||
889 cmd->scan_begin_arg < TIMEBASE_10MHZ) {
891 cmd->scan_begin_arg = MAX_SCAN_PERIOD;
894 /* Use two timers. */
895 div1 = devpriv->cached_div1;
896 div2 = devpriv->cached_div2;
897 pci224_cascade_ns_to_timer(TIMEBASE_10MHZ, &div1, &div2,
898 &cmd->scan_begin_arg,
900 devpriv->cached_div1 = div1;
901 devpriv->cached_div2 = div2;
903 if (tmp != cmd->scan_begin_arg)
911 /* Step 5: check channel list. */
913 if (cmd->chanlist && (cmd->chanlist_len > 0)) {
915 enum { range_err = 1, dupchan_err = 2, };
921 * Check all channels have the same range index. Don't care
922 * about analogue reference, as we can't configure it.
924 * Check the list has no duplicate channels.
926 range = CR_RANGE(cmd->chanlist[0]);
929 for (n = 0; n < cmd->chanlist_len; n++) {
930 ch = CR_CHAN(cmd->chanlist[n]);
931 if (tmp & (1U << ch))
932 errors |= dupchan_err;
935 if (CR_RANGE(cmd->chanlist[n]) != range)
940 if (errors & dupchan_err) {
941 DPRINTK("comedi%d: " DRIVER_NAME
943 "entries in chanlist must contain no "
944 "duplicate channels\n", dev->minor);
946 if (errors & range_err) {
947 DPRINTK("comedi%d: " DRIVER_NAME
949 "entries in chanlist must all have "
950 "the same range index\n", dev->minor);
963 * 'do_cmd' function for AO subdevice.
965 static int pci224_ao_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
967 struct pci224_private *devpriv = dev->private;
968 struct comedi_cmd *cmd = &s->async->cmd;
975 /* Cannot handle null/empty chanlist. */
976 if (cmd->chanlist == NULL || cmd->chanlist_len == 0)
980 /* Determine which channels are enabled and their load order. */
981 devpriv->ao_enab = 0;
983 for (i = 0; i < cmd->chanlist_len; i++) {
984 ch = CR_CHAN(cmd->chanlist[i]);
985 devpriv->ao_enab |= 1U << ch;
987 for (j = 0; j < cmd->chanlist_len; j++) {
988 if (CR_CHAN(cmd->chanlist[j]) < ch)
992 devpriv->ao_scan_order[rank] = i;
995 /* Set enabled channels. */
996 outw(devpriv->ao_enab, dev->iobase + PCI224_DACCEN);
998 /* Determine range and polarity. All channels the same. */
999 range = CR_RANGE(cmd->chanlist[0]);
1002 * Set DAC range and polarity.
1003 * Set DAC scan trigger source to 'none'.
1004 * Set DAC FIFO interrupt trigger level to 'not half full'.
1007 * N.B. DAC FIFO interrupts are currently disabled.
1009 devpriv->daccon = COMBINE(devpriv->daccon,
1011 hwrange[range] | PCI224_DACCON_TRIG_NONE |
1012 PCI224_DACCON_FIFOINTR_NHALF),
1013 (PCI224_DACCON_POLAR_MASK |
1014 PCI224_DACCON_VREF_MASK |
1015 PCI224_DACCON_TRIG_MASK |
1016 PCI224_DACCON_FIFOINTR_MASK));
1017 outw(devpriv->daccon | PCI224_DACCON_FIFORESET,
1018 dev->iobase + PCI224_DACCON);
1020 if (cmd->scan_begin_src == TRIG_TIMER) {
1021 unsigned int div1, div2, round;
1022 unsigned int ns = cmd->scan_begin_arg;
1023 int round_mode = cmd->flags & TRIG_ROUND_MASK;
1025 /* Check whether to use a single timer. */
1026 switch (round_mode) {
1027 case TRIG_ROUND_NEAREST:
1029 round = TIMEBASE_10MHZ / 2;
1031 case TRIG_ROUND_DOWN:
1035 round = TIMEBASE_10MHZ - 1;
1038 /* Be careful to avoid overflow! */
1039 div2 = cmd->scan_begin_arg / TIMEBASE_10MHZ;
1040 div2 += (round + cmd->scan_begin_arg % TIMEBASE_10MHZ) /
1042 if (div2 <= 0x10000) {
1043 /* A single timer will suffice. */
1047 div1 = 1; /* Flag that single timer to be used. */
1049 /* Use two timers. */
1050 div1 = devpriv->cached_div1;
1051 div2 = devpriv->cached_div2;
1052 pci224_cascade_ns_to_timer(TIMEBASE_10MHZ, &div1, &div2,
1057 * The output of timer Z2-0 will be used as the scan trigger
1060 /* Make sure Z2-0 is gated on. */
1061 outb(GAT_CONFIG(0, GAT_VCC),
1062 devpriv->iobase1 + PCI224_ZGAT_SCE);
1064 /* Not cascading. Z2-0 needs 10 MHz clock. */
1065 outb(CLK_CONFIG(0, CLK_10MHZ),
1066 devpriv->iobase1 + PCI224_ZCLK_SCE);
1068 /* Cascading with Z2-2. */
1069 /* Make sure Z2-2 is gated on. */
1070 outb(GAT_CONFIG(2, GAT_VCC),
1071 devpriv->iobase1 + PCI224_ZGAT_SCE);
1072 /* Z2-2 needs 10 MHz clock. */
1073 outb(CLK_CONFIG(2, CLK_10MHZ),
1074 devpriv->iobase1 + PCI224_ZCLK_SCE);
1075 /* Load Z2-2 mode (2) and counter (div1). */
1076 i8254_load(devpriv->iobase1 + PCI224_Z2_CT0, 0,
1078 /* Z2-0 is clocked from Z2-2's output. */
1079 outb(CLK_CONFIG(0, CLK_OUTNM1),
1080 devpriv->iobase1 + PCI224_ZCLK_SCE);
1082 /* Load Z2-0 mode (2) and counter (div2). */
1083 i8254_load(devpriv->iobase1 + PCI224_Z2_CT0, 0, 0, div2, 2);
1087 * Sort out end of acquisition.
1089 switch (cmd->stop_src) {
1091 /* Fixed number of scans. */
1092 devpriv->ao_stop_continuous = 0;
1093 devpriv->ao_stop_count = cmd->stop_arg;
1096 /* Continuous scans. */
1097 devpriv->ao_stop_continuous = 1;
1098 devpriv->ao_stop_count = 0;
1103 * Sort out start of acquisition.
1105 switch (cmd->start_src) {
1107 spin_lock_irqsave(&devpriv->ao_spinlock, flags);
1108 s->async->inttrig = &pci224_ao_inttrig_start;
1109 spin_unlock_irqrestore(&devpriv->ao_spinlock, flags);
1112 /* Enable external interrupt trigger to start acquisition. */
1113 spin_lock_irqsave(&devpriv->ao_spinlock, flags);
1114 devpriv->intsce |= PCI224_INTR_EXT;
1115 outb(devpriv->intsce, devpriv->iobase1 + PCI224_INT_SCE);
1116 spin_unlock_irqrestore(&devpriv->ao_spinlock, flags);
1124 * 'cancel' function for AO subdevice.
1126 static int pci224_ao_cancel(struct comedi_device *dev,
1127 struct comedi_subdevice *s)
1129 pci224_ao_stop(dev, s);
1134 * 'munge' data for AO command.
1137 pci224_ao_munge(struct comedi_device *dev, struct comedi_subdevice *s,
1138 void *data, unsigned int num_bytes, unsigned int chan_index)
1140 const struct pci224_board *thisboard = comedi_board(dev);
1141 struct pci224_private *devpriv = dev->private;
1142 struct comedi_async *async = s->async;
1143 short *array = data;
1144 unsigned int length = num_bytes / sizeof(*array);
1145 unsigned int offset;
1149 /* The hardware expects 16-bit numbers. */
1150 shift = 16 - thisboard->ao_bits;
1151 /* Channels will be all bipolar or all unipolar. */
1152 if ((devpriv->hwrange[CR_RANGE(async->cmd.chanlist[0])] &
1153 PCI224_DACCON_POLAR_MASK) == PCI224_DACCON_POLAR_UNI) {
1160 /* Munge the data. */
1161 for (i = 0; i < length; i++)
1162 array[i] = (array[i] << shift) - offset;
1167 * Interrupt handler.
1169 static irqreturn_t pci224_interrupt(int irq, void *d)
1171 struct comedi_device *dev = d;
1172 struct pci224_private *devpriv = dev->private;
1173 struct comedi_subdevice *s = &dev->subdevices[0];
1174 struct comedi_cmd *cmd;
1175 unsigned char intstat, valid_intstat;
1176 unsigned char curenab;
1178 unsigned long flags;
1180 intstat = inb(devpriv->iobase1 + PCI224_INT_SCE) & 0x3F;
1183 spin_lock_irqsave(&devpriv->ao_spinlock, flags);
1184 valid_intstat = devpriv->intsce & intstat;
1185 /* Temporarily disable interrupt sources. */
1186 curenab = devpriv->intsce & ~intstat;
1187 outb(curenab, devpriv->iobase1 + PCI224_INT_SCE);
1188 devpriv->intr_running = 1;
1189 devpriv->intr_cpuid = THISCPU;
1190 spin_unlock_irqrestore(&devpriv->ao_spinlock, flags);
1191 if (valid_intstat != 0) {
1192 cmd = &s->async->cmd;
1193 if (valid_intstat & PCI224_INTR_EXT) {
1194 devpriv->intsce &= ~PCI224_INTR_EXT;
1195 if (cmd->start_src == TRIG_EXT)
1196 pci224_ao_start(dev, s);
1197 else if (cmd->stop_src == TRIG_EXT)
1198 pci224_ao_stop(dev, s);
1201 if (valid_intstat & PCI224_INTR_DAC)
1202 pci224_ao_handle_fifo(dev, s);
1205 /* Reenable interrupt sources. */
1206 spin_lock_irqsave(&devpriv->ao_spinlock, flags);
1207 if (curenab != devpriv->intsce) {
1208 outb(devpriv->intsce,
1209 devpriv->iobase1 + PCI224_INT_SCE);
1211 devpriv->intr_running = 0;
1212 spin_unlock_irqrestore(&devpriv->ao_spinlock, flags);
1214 return IRQ_RETVAL(retval);
1218 * This function looks for a board matching the supplied PCI device.
1220 static const struct pci224_board
1221 *pci224_find_pci_board(struct pci_dev *pci_dev)
1225 for (i = 0; i < ARRAY_SIZE(pci224_boards); i++)
1226 if (pci_dev->device == pci224_boards[i].devid)
1227 return &pci224_boards[i];
1232 * This function looks for a PCI device matching the requested board name,
1235 static struct pci_dev *pci224_find_pci_dev(struct comedi_device *dev,
1236 struct comedi_devconfig *it)
1238 const struct pci224_board *thisboard = comedi_board(dev);
1239 struct pci_dev *pci_dev = NULL;
1240 int bus = it->options[0];
1241 int slot = it->options[1];
1243 for_each_pci_dev(pci_dev) {
1245 if (bus != pci_dev->bus->number ||
1246 slot != PCI_SLOT(pci_dev->devfn))
1249 if (pci_dev->vendor != PCI_VENDOR_ID_AMPLICON)
1252 if (thisboard->model == any_model) {
1253 /* Match any supported model. */
1254 const struct pci224_board *board_ptr;
1256 board_ptr = pci224_find_pci_board(pci_dev);
1257 if (board_ptr == NULL)
1259 /* Change board_ptr to matched board. */
1260 dev->board_ptr = board_ptr;
1262 /* Match specific model name. */
1263 if (thisboard->devid != pci_dev->device)
1268 dev_err(dev->class_dev,
1269 "No supported board found! (req. bus %d, slot %d)\n",
1274 static void pci224_report_attach(struct comedi_device *dev, unsigned int irq)
1276 struct pci_dev *pcidev = comedi_to_pci_dev(dev);
1280 snprintf(tmpbuf, sizeof(tmpbuf), "irq %u%s", irq,
1281 (dev->irq ? "" : " UNAVAILABLE"));
1283 snprintf(tmpbuf, sizeof(tmpbuf), "no irq");
1284 dev_info(dev->class_dev, "%s (pci %s) (%s) attached\n",
1285 dev->board_name, pci_name(pcidev), tmpbuf);
1289 * Common part of attach and attach_pci.
1291 static int pci224_attach_common(struct comedi_device *dev,
1292 struct pci_dev *pci_dev, int *options)
1294 const struct pci224_board *thisboard = comedi_board(dev);
1295 struct pci224_private *devpriv = dev->private;
1296 struct comedi_subdevice *s;
1301 comedi_set_hw_dev(dev, &pci_dev->dev);
1303 ret = comedi_pci_enable(pci_dev, DRIVER_NAME);
1305 dev_err(dev->class_dev,
1306 "error! cannot enable PCI device and request regions!\n"
1310 spin_lock_init(&devpriv->ao_spinlock);
1312 devpriv->iobase1 = pci_resource_start(pci_dev, 2);
1313 dev->iobase = pci_resource_start(pci_dev, 3);
1316 /* Allocate readback buffer for AO channels. */
1317 devpriv->ao_readback = kmalloc(sizeof(devpriv->ao_readback[0]) *
1318 thisboard->ao_chans, GFP_KERNEL);
1319 if (!devpriv->ao_readback)
1323 /* Allocate buffer to hold values for AO channel scan. */
1324 devpriv->ao_scan_vals = kmalloc(sizeof(devpriv->ao_scan_vals[0]) *
1325 thisboard->ao_chans, GFP_KERNEL);
1326 if (!devpriv->ao_scan_vals)
1330 /* Allocate buffer to hold AO channel scan order. */
1331 devpriv->ao_scan_order = kmalloc(sizeof(devpriv->ao_scan_order[0]) *
1332 thisboard->ao_chans, GFP_KERNEL);
1333 if (!devpriv->ao_scan_order)
1337 /* Disable interrupt sources. */
1338 devpriv->intsce = 0;
1339 outb(0, devpriv->iobase1 + PCI224_INT_SCE);
1341 /* Initialize the DAC hardware. */
1342 outw(PCI224_DACCON_GLOBALRESET, dev->iobase + PCI224_DACCON);
1343 outw(0, dev->iobase + PCI224_DACCEN);
1344 outw(0, dev->iobase + PCI224_FIFOSIZ);
1345 devpriv->daccon = (PCI224_DACCON_TRIG_SW | PCI224_DACCON_POLAR_BI |
1346 PCI224_DACCON_FIFOENAB |
1347 PCI224_DACCON_FIFOINTR_EMPTY);
1348 outw(devpriv->daccon | PCI224_DACCON_FIFORESET,
1349 dev->iobase + PCI224_DACCON);
1351 ret = comedi_alloc_subdevices(dev, 1);
1355 s = &dev->subdevices[0];
1356 /* Analog output subdevice. */
1357 s->type = COMEDI_SUBD_AO;
1358 s->subdev_flags = SDF_WRITABLE | SDF_GROUND | SDF_CMD_WRITE;
1359 s->n_chan = thisboard->ao_chans;
1360 s->maxdata = (1 << thisboard->ao_bits) - 1;
1361 s->insn_write = &pci224_ao_insn_write;
1362 s->insn_read = &pci224_ao_insn_read;
1363 s->len_chanlist = s->n_chan;
1365 dev->write_subdev = s;
1366 s->do_cmd = &pci224_ao_cmd;
1367 s->do_cmdtest = &pci224_ao_cmdtest;
1368 s->cancel = &pci224_ao_cancel;
1369 s->munge = &pci224_ao_munge;
1371 /* Sort out channel range options. */
1372 if (thisboard->model == pci234_model) {
1373 /* PCI234 range options. */
1374 const struct comedi_lrange **range_table_list;
1376 s->range_table_list = range_table_list =
1377 kmalloc(sizeof(struct comedi_lrange *) * s->n_chan,
1379 if (!s->range_table_list)
1383 for (n = 2; n < 3 + s->n_chan; n++) {
1384 if (options[n] < 0 || options[n] > 1) {
1385 dev_warn(dev->class_dev, DRIVER_NAME
1386 ": warning! bad options[%u]=%d\n",
1391 for (n = 0; n < s->n_chan; n++) {
1392 if (n < COMEDI_NDEVCONFOPTS - 3 && options &&
1393 options[3 + n] == 1) {
1394 if (options[2] == 1)
1395 range_table_list[n] = &range_pci234_ext;
1397 range_table_list[n] = &range_bipolar5;
1400 if (options && options[2] == 1) {
1401 range_table_list[n] =
1404 range_table_list[n] = &range_bipolar10;
1408 devpriv->hwrange = hwrange_pci234;
1410 /* PCI224 range options. */
1411 if (options && options[2] == 1) {
1412 s->range_table = &range_pci224_external;
1413 devpriv->hwrange = hwrange_pci224_external;
1415 if (options && options[2] != 0) {
1416 dev_warn(dev->class_dev, DRIVER_NAME
1417 ": warning! bad options[2]=%d\n",
1420 s->range_table = &range_pci224_internal;
1421 devpriv->hwrange = hwrange_pci224_internal;
1425 dev->board_name = thisboard->name;
1428 ret = request_irq(irq, pci224_interrupt, IRQF_SHARED,
1431 dev_err(dev->class_dev,
1432 "error! unable to allocate irq %u\n", irq);
1439 pci224_report_attach(dev, irq);
1443 static int pci224_attach(struct comedi_device *dev, struct comedi_devconfig *it)
1445 struct pci224_private *devpriv;
1446 struct pci_dev *pci_dev;
1448 dev_info(dev->class_dev, DRIVER_NAME ": attach\n");
1450 devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL);
1453 dev->private = devpriv;
1455 pci_dev = pci224_find_pci_dev(dev, it);
1459 return pci224_attach_common(dev, pci_dev, it->options);
1462 static int __devinit
1463 pci224_attach_pci(struct comedi_device *dev, struct pci_dev *pci_dev)
1465 struct pci224_private *devpriv;
1467 dev_info(dev->class_dev, DRIVER_NAME ": attach_pci %s\n",
1470 devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL);
1473 dev->private = devpriv;
1475 dev->board_ptr = pci224_find_pci_board(pci_dev);
1476 if (dev->board_ptr == NULL) {
1477 dev_err(dev->class_dev,
1478 DRIVER_NAME ": BUG! cannot determine board type!\n");
1482 * Need to 'get' the PCI device to match the 'put' in pci224_detach().
1483 * TODO: Remove the pci_dev_get() and matching pci_dev_put() once
1484 * support for manual attachment of PCI devices via pci224_attach()
1487 pci_dev_get(pci_dev);
1488 return pci224_attach_common(dev, pci_dev, NULL);
1491 static void pci224_detach(struct comedi_device *dev)
1493 struct pci224_private *devpriv = dev->private;
1494 struct pci_dev *pcidev = comedi_to_pci_dev(dev);
1497 free_irq(dev->irq, dev);
1498 if (dev->subdevices) {
1499 struct comedi_subdevice *s;
1501 s = &dev->subdevices[0];
1503 kfree(s->range_table_list);
1506 kfree(devpriv->ao_readback);
1507 kfree(devpriv->ao_scan_vals);
1508 kfree(devpriv->ao_scan_order);
1512 comedi_pci_disable(pcidev);
1513 pci_dev_put(pcidev);
1517 static struct comedi_driver amplc_pci224_driver = {
1518 .driver_name = "amplc_pci224",
1519 .module = THIS_MODULE,
1520 .attach = pci224_attach,
1521 .detach = pci224_detach,
1522 .attach_pci = pci224_attach_pci,
1523 .board_name = &pci224_boards[0].name,
1524 .offset = sizeof(struct pci224_board),
1525 .num_names = ARRAY_SIZE(pci224_boards),
1528 static int __devinit amplc_pci224_pci_probe(struct pci_dev *dev,
1529 const struct pci_device_id
1532 return comedi_pci_auto_config(dev, &lc_pci224_driver);
1535 static void __devexit amplc_pci224_pci_remove(struct pci_dev *dev)
1537 comedi_pci_auto_unconfig(dev);
1540 static DEFINE_PCI_DEVICE_TABLE(amplc_pci224_pci_table) = {
1541 { PCI_DEVICE(PCI_VENDOR_ID_AMPLICON, PCI_DEVICE_ID_AMPLICON_PCI224) },
1542 { PCI_DEVICE(PCI_VENDOR_ID_AMPLICON, PCI_DEVICE_ID_AMPLICON_PCI234) },
1545 MODULE_DEVICE_TABLE(pci, amplc_pci224_pci_table);
1547 static struct pci_driver amplc_pci224_pci_driver = {
1548 .name = "amplc_pci224",
1549 .id_table = amplc_pci224_pci_table,
1550 .probe = amplc_pci224_pci_probe,
1551 .remove = __devexit_p(amplc_pci224_pci_remove),
1553 module_comedi_pci_driver(amplc_pci224_driver, amplc_pci224_pci_driver);
1555 MODULE_AUTHOR("Comedi http://www.comedi.org");
1556 MODULE_DESCRIPTION("Comedi low-level driver");
1557 MODULE_LICENSE("GPL");