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.
22 Description: Amplicon PCI224, PCI234
23 Author: Ian Abbott <abbotti@mev.co.uk>
24 Devices: [Amplicon] PCI224 (amplc_pci224 or pci224),
25 PCI234 (amplc_pci224 or pci234)
26 Updated: Wed, 22 Oct 2008 12:25:08 +0100
27 Status: works, but see caveats
32 - ao_do_cmd mode with the following sources:
34 - start_src TRIG_INT TRIG_EXT
35 - scan_begin_src TRIG_TIMER TRIG_EXT
36 - convert_src TRIG_NOW
37 - scan_end_src TRIG_COUNT
38 - stop_src TRIG_COUNT TRIG_EXT TRIG_NONE
40 The channel list must contain at least one channel with no repeated
41 channels. The scan end count must equal the number of channels in
44 There is only one external trigger source so only one of start_src,
45 scan_begin_src or stop_src may use TRIG_EXT.
47 Configuration options - PCI224:
48 [0] - PCI bus of device (optional).
49 [1] - PCI slot of device (optional).
50 If bus/slot is not specified, the first available PCI device
52 [2] - Select available ranges according to jumper LK1. All channels
53 are set to the same range:
54 0=Jumper position 1-2 (factory default), 4 software-selectable
55 internal voltage references, giving 4 bipolar and 4 unipolar
57 [-10V,+10V], [-5V,+5V], [-2.5V,+2.5V], [-1.25V,+1.25V],
58 [0,+10V], [0,+5V], [0,+2.5V], [0,1.25V].
59 1=Jumper position 2-3, 1 external voltage reference, giving
60 1 bipolar and 1 unipolar range:
61 [-Vext,+Vext], [0,+Vext].
63 Configuration options - PCI234:
64 [0] - PCI bus of device (optional).
65 [1] - PCI slot of device (optional).
66 If bus/slot is not specified, the first available PCI device
68 [2] - Select internal or external voltage reference according to
69 jumper LK1. This affects all channels:
70 0=Jumper position 1-2 (factory default), Vref=5V internal.
71 1=Jumper position 2-3, Vref=Vext external.
72 [3] - Select channel 0 range according to jumper LK2:
73 0=Jumper position 2-3 (factory default), range [-2*Vref,+2*Vref]
74 (10V bipolar when options[2]=0).
75 1=Jumper position 1-2, range [-Vref,+Vref]
76 (5V bipolar when options[2]=0).
77 [4] - Select channel 1 range according to jumper LK3: cf. options[3].
78 [5] - Select channel 2 range according to jumper LK4: cf. options[3].
79 [6] - Select channel 3 range according to jumper LK5: cf. options[3].
81 Passing a zero for an option is the same as leaving it unspecified.
85 1) All channels on the PCI224 share the same range. Any change to the
86 range as a result of insn_write or a streaming command will affect
87 the output voltages of all channels, including those not specified
88 by the instruction or command.
90 2) For the analog output command, the first scan may be triggered
91 falsely at the start of acquisition. This occurs when the DAC scan
92 trigger source is switched from 'none' to 'timer' (scan_begin_src =
93 TRIG_TIMER) or 'external' (scan_begin_src == TRIG_EXT) at the start
94 of acquisition and the trigger source is at logic level 1 at the
95 time of the switch. This is very likely for TRIG_TIMER. For
96 TRIG_EXT, it depends on the state of the external line and whether
97 the CR_INVERT flag has been set. The remaining scans are triggered
101 #include <linux/pci.h>
102 #include <linux/interrupt.h>
103 #include <linux/slab.h>
105 #include "../comedidev.h"
107 #include "comedi_fc.h"
110 #define DRIVER_NAME "amplc_pci224"
115 #define PCI_DEVICE_ID_AMPLICON_PCI224 0x0007
116 #define PCI_DEVICE_ID_AMPLICON_PCI234 0x0008
117 #define PCI_DEVICE_ID_INVALID 0xffff
120 * PCI224/234 i/o space 1 (PCIBAR2) registers.
122 #define PCI224_IO1_SIZE 0x20 /* Size of i/o space 1 (8-bit registers) */
123 #define PCI224_Z2_CT0 0x14 /* 82C54 counter/timer 0 */
124 #define PCI224_Z2_CT1 0x15 /* 82C54 counter/timer 1 */
125 #define PCI224_Z2_CT2 0x16 /* 82C54 counter/timer 2 */
126 #define PCI224_Z2_CTC 0x17 /* 82C54 counter/timer control word */
127 #define PCI224_ZCLK_SCE 0x1A /* Group Z Clock Configuration Register */
128 #define PCI224_ZGAT_SCE 0x1D /* Group Z Gate Configuration Register */
129 #define PCI224_INT_SCE 0x1E /* ISR Interrupt source mask register */
130 /* /Interrupt status */
133 * PCI224/234 i/o space 2 (PCIBAR3) 16-bit registers.
135 #define PCI224_IO2_SIZE 0x10 /* Size of i/o space 2 (16-bit registers). */
136 #define PCI224_DACDATA 0x00 /* (w-o) DAC FIFO data. */
137 #define PCI224_SOFTTRIG 0x00 /* (r-o) DAC software scan trigger. */
138 #define PCI224_DACCON 0x02 /* (r/w) DAC status/configuration. */
139 #define PCI224_FIFOSIZ 0x04 /* (w-o) FIFO size for wraparound mode. */
140 #define PCI224_DACCEN 0x06 /* (w-o) DAC channel enable register. */
145 /* (r/w) Scan trigger. */
146 #define PCI224_DACCON_TRIG_MASK (7 << 0)
147 #define PCI224_DACCON_TRIG_NONE (0 << 0) /* none */
148 #define PCI224_DACCON_TRIG_SW (1 << 0) /* software trig */
149 #define PCI224_DACCON_TRIG_EXTP (2 << 0) /* ext +ve edge */
150 #define PCI224_DACCON_TRIG_EXTN (3 << 0) /* ext -ve edge */
151 #define PCI224_DACCON_TRIG_Z2CT0 (4 << 0) /* Z2 CT0 out */
152 #define PCI224_DACCON_TRIG_Z2CT1 (5 << 0) /* Z2 CT1 out */
153 #define PCI224_DACCON_TRIG_Z2CT2 (6 << 0) /* Z2 CT2 out */
154 /* (r/w) Polarity (PCI224 only, PCI234 always bipolar!). */
155 #define PCI224_DACCON_POLAR_MASK (1 << 3)
156 #define PCI224_DACCON_POLAR_UNI (0 << 3) /* range [0,Vref] */
157 #define PCI224_DACCON_POLAR_BI (1 << 3) /* range [-Vref,Vref] */
158 /* (r/w) Internal Vref (PCI224 only, when LK1 in position 1-2). */
159 #define PCI224_DACCON_VREF_MASK (3 << 4)
160 #define PCI224_DACCON_VREF_1_25 (0 << 4) /* Vref = 1.25V */
161 #define PCI224_DACCON_VREF_2_5 (1 << 4) /* Vref = 2.5V */
162 #define PCI224_DACCON_VREF_5 (2 << 4) /* Vref = 5V */
163 #define PCI224_DACCON_VREF_10 (3 << 4) /* Vref = 10V */
164 /* (r/w) Wraparound mode enable (to play back stored waveform). */
165 #define PCI224_DACCON_FIFOWRAP (1 << 7)
166 /* (r/w) FIFO enable. It MUST be set! */
167 #define PCI224_DACCON_FIFOENAB (1 << 8)
168 /* (r/w) FIFO interrupt trigger level (most values are not very useful). */
169 #define PCI224_DACCON_FIFOINTR_MASK (7 << 9)
170 #define PCI224_DACCON_FIFOINTR_EMPTY (0 << 9) /* when empty */
171 #define PCI224_DACCON_FIFOINTR_NEMPTY (1 << 9) /* when not empty */
172 #define PCI224_DACCON_FIFOINTR_NHALF (2 << 9) /* when not half full */
173 #define PCI224_DACCON_FIFOINTR_HALF (3 << 9) /* when half full */
174 #define PCI224_DACCON_FIFOINTR_NFULL (4 << 9) /* when not full */
175 #define PCI224_DACCON_FIFOINTR_FULL (5 << 9) /* when full */
176 /* (r-o) FIFO fill level. */
177 #define PCI224_DACCON_FIFOFL_MASK (7 << 12)
178 #define PCI224_DACCON_FIFOFL_EMPTY (1 << 12) /* 0 */
179 #define PCI224_DACCON_FIFOFL_ONETOHALF (0 << 12) /* [1,2048] */
180 #define PCI224_DACCON_FIFOFL_HALFTOFULL (4 << 12) /* [2049,4095] */
181 #define PCI224_DACCON_FIFOFL_FULL (6 << 12) /* 4096 */
182 /* (r-o) DAC busy flag. */
183 #define PCI224_DACCON_BUSY (1 << 15)
184 /* (w-o) FIFO reset. */
185 #define PCI224_DACCON_FIFORESET (1 << 12)
186 /* (w-o) Global reset (not sure what it does). */
187 #define PCI224_DACCON_GLOBALRESET (1 << 13)
192 #define PCI224_FIFO_SIZE 4096
195 * DAC FIFO guaranteed minimum room available, depending on reported fill level.
196 * The maximum room available depends on the reported fill level and how much
199 #define PCI224_FIFO_ROOM_EMPTY PCI224_FIFO_SIZE
200 #define PCI224_FIFO_ROOM_ONETOHALF (PCI224_FIFO_SIZE / 2)
201 #define PCI224_FIFO_ROOM_HALFTOFULL 1
202 #define PCI224_FIFO_ROOM_FULL 0
205 * Counter/timer clock input configuration sources.
207 #define CLK_CLK 0 /* reserved (channel-specific clock) */
208 #define CLK_10MHZ 1 /* internal 10 MHz clock */
209 #define CLK_1MHZ 2 /* internal 1 MHz clock */
210 #define CLK_100KHZ 3 /* internal 100 kHz clock */
211 #define CLK_10KHZ 4 /* internal 10 kHz clock */
212 #define CLK_1KHZ 5 /* internal 1 kHz clock */
213 #define CLK_OUTNM1 6 /* output of channel-1 modulo total */
214 #define CLK_EXT 7 /* external clock */
215 /* Macro to construct clock input configuration register value. */
216 #define CLK_CONFIG(chan, src) ((((chan) & 3) << 3) | ((src) & 7))
217 /* Timebases in ns. */
218 #define TIMEBASE_10MHZ 100
219 #define TIMEBASE_1MHZ 1000
220 #define TIMEBASE_100KHZ 10000
221 #define TIMEBASE_10KHZ 100000
222 #define TIMEBASE_1KHZ 1000000
225 * Counter/timer gate input configuration sources.
227 #define GAT_VCC 0 /* VCC (i.e. enabled) */
228 #define GAT_GND 1 /* GND (i.e. disabled) */
229 #define GAT_EXT 2 /* reserved (external gate input) */
230 #define GAT_NOUTNM2 3 /* inverted output of channel-2 modulo total */
231 /* Macro to construct gate input configuration register value. */
232 #define GAT_CONFIG(chan, src) ((((chan) & 3) << 3) | ((src) & 7))
235 * Summary of CLK_OUTNM1 and GAT_NOUTNM2 connections for PCI224 and PCI234:
237 * Channel's Channel's
238 * clock input gate input
239 * Channel CLK_OUTNM1 GAT_NOUTNM2
240 * ------- ---------- -----------
241 * Z2-CT0 Z2-CT2-OUT /Z2-CT1-OUT
242 * Z2-CT1 Z2-CT0-OUT /Z2-CT2-OUT
243 * Z2-CT2 Z2-CT1-OUT /Z2-CT0-OUT
247 * Interrupt enable/status bits
249 #define PCI224_INTR_EXT 0x01 /* rising edge on external input */
250 #define PCI224_INTR_DAC 0x04 /* DAC (FIFO) interrupt */
251 #define PCI224_INTR_Z2CT1 0x20 /* rising edge on Z2-CT1 output */
253 #define PCI224_INTR_EDGE_BITS (PCI224_INTR_EXT | PCI224_INTR_Z2CT1)
254 #define PCI224_INTR_LEVEL_BITS PCI224_INTR_DACFIFO
260 /* Combine old and new bits. */
261 #define COMBINE(old, new, mask) (((old) & ~(mask)) | ((new) & (mask)))
263 /* Current CPU. XXX should this be hard_smp_processor_id()? */
264 #define THISCPU smp_processor_id()
266 /* State bits for use with atomic bit operations. */
267 #define AO_CMD_STARTED 0
273 /* The software selectable internal ranges for PCI224 (option[2] == 0). */
274 static const struct comedi_lrange range_pci224_internal = {
288 static const unsigned short hwrange_pci224_internal[8] = {
289 PCI224_DACCON_POLAR_BI | PCI224_DACCON_VREF_10,
290 PCI224_DACCON_POLAR_BI | PCI224_DACCON_VREF_5,
291 PCI224_DACCON_POLAR_BI | PCI224_DACCON_VREF_2_5,
292 PCI224_DACCON_POLAR_BI | PCI224_DACCON_VREF_1_25,
293 PCI224_DACCON_POLAR_UNI | PCI224_DACCON_VREF_10,
294 PCI224_DACCON_POLAR_UNI | PCI224_DACCON_VREF_5,
295 PCI224_DACCON_POLAR_UNI | PCI224_DACCON_VREF_2_5,
296 PCI224_DACCON_POLAR_UNI | PCI224_DACCON_VREF_1_25,
299 /* The software selectable external ranges for PCI224 (option[2] == 1). */
300 static const struct comedi_lrange range_pci224_external = {
303 RANGE_ext(-1, 1), /* bipolar [-Vref,+Vref] */
304 RANGE_ext(0, 1), /* unipolar [0,+Vref] */
308 static const unsigned short hwrange_pci224_external[2] = {
309 PCI224_DACCON_POLAR_BI,
310 PCI224_DACCON_POLAR_UNI,
313 /* The hardware selectable Vref*2 external range for PCI234
314 * (option[2] == 1, option[3+n] == 0). */
315 static const struct comedi_lrange range_pci234_ext2 = {
322 /* The hardware selectable Vref external range for PCI234
323 * (option[2] == 1, option[3+n] == 1). */
324 static const struct comedi_lrange range_pci234_ext = {
331 /* This serves for all the PCI234 ranges. */
332 static const unsigned short hwrange_pci234[1] = {
333 PCI224_DACCON_POLAR_BI, /* bipolar - hardware ignores it! */
337 * Board descriptions.
340 enum pci224_model { any_model, pci224_model, pci234_model };
342 struct pci224_board {
344 unsigned short devid;
345 enum pci224_model model;
346 unsigned int ao_chans;
347 unsigned int ao_bits;
350 static const struct pci224_board pci224_boards[] = {
353 .devid = PCI_DEVICE_ID_AMPLICON_PCI224,
354 .model = pci224_model,
360 .devid = PCI_DEVICE_ID_AMPLICON_PCI234,
361 .model = pci234_model,
367 .devid = PCI_DEVICE_ID_INVALID,
368 .model = any_model, /* wildcard */
372 /* this structure is for data unique to this hardware driver. If
373 several hardware drivers keep similar information in this structure,
374 feel free to suggest moving the variable to the struct comedi_device struct. */
375 struct pci224_private {
376 const unsigned short *hwrange;
377 unsigned long iobase1;
379 spinlock_t ao_spinlock;
380 unsigned int *ao_readback;
382 unsigned char *ao_scan_order;
385 unsigned short daccon;
386 unsigned int cached_div1;
387 unsigned int cached_div2;
388 unsigned int ao_stop_count;
389 short ao_stop_continuous;
390 unsigned short ao_enab; /* max 16 channels so 'short' will do */
391 unsigned char intsce;
395 * Called from the 'insn_write' function to perform a single write.
398 pci224_ao_set_data(struct comedi_device *dev, int chan, int range,
401 const struct pci224_board *thisboard = comedi_board(dev);
402 struct pci224_private *devpriv = dev->private;
403 unsigned short mangled;
405 /* Store unmangled data for readback. */
406 devpriv->ao_readback[chan] = data;
407 /* Enable the channel. */
408 outw(1 << chan, dev->iobase + PCI224_DACCEN);
409 /* Set range and reset FIFO. */
410 devpriv->daccon = COMBINE(devpriv->daccon, devpriv->hwrange[range],
411 (PCI224_DACCON_POLAR_MASK |
412 PCI224_DACCON_VREF_MASK));
413 outw(devpriv->daccon | PCI224_DACCON_FIFORESET,
414 dev->iobase + PCI224_DACCON);
416 * Mangle the data. The hardware expects:
417 * - bipolar: 16-bit 2's complement
418 * - unipolar: 16-bit unsigned
420 mangled = (unsigned short)data << (16 - thisboard->ao_bits);
421 if ((devpriv->daccon & PCI224_DACCON_POLAR_MASK) ==
422 PCI224_DACCON_POLAR_BI) {
425 /* Write mangled data to the FIFO. */
426 outw(mangled, dev->iobase + PCI224_DACDATA);
427 /* Trigger the conversion. */
428 inw(dev->iobase + PCI224_SOFTTRIG);
432 * 'insn_write' function for AO subdevice.
435 pci224_ao_insn_write(struct comedi_device *dev, struct comedi_subdevice *s,
436 struct comedi_insn *insn, unsigned int *data)
441 /* Unpack channel and range. */
442 chan = CR_CHAN(insn->chanspec);
443 range = CR_RANGE(insn->chanspec);
445 /* Writing a list of values to an AO channel is probably not
446 * very useful, but that's how the interface is defined. */
447 for (i = 0; i < insn->n; i++)
448 pci224_ao_set_data(dev, chan, range, data[i]);
454 * 'insn_read' function for AO subdevice.
456 * N.B. The value read will not be valid if the DAC channel has
457 * never been written successfully since the device was attached
458 * or since the channel has been used by an AO streaming write
462 pci224_ao_insn_read(struct comedi_device *dev, struct comedi_subdevice *s,
463 struct comedi_insn *insn, unsigned int *data)
465 struct pci224_private *devpriv = dev->private;
469 chan = CR_CHAN(insn->chanspec);
471 for (i = 0; i < insn->n; i++)
472 data[i] = devpriv->ao_readback[chan];
479 * Just a wrapper for the inline function 'i8253_cascade_ns_to_timer'.
482 pci224_cascade_ns_to_timer(int osc_base, unsigned int *d1, unsigned int *d2,
483 unsigned int *nanosec, int round_mode)
485 i8253_cascade_ns_to_timer(osc_base, d1, d2, nanosec, round_mode);
489 * Kills a command running on the AO subdevice.
491 static void pci224_ao_stop(struct comedi_device *dev,
492 struct comedi_subdevice *s)
494 struct pci224_private *devpriv = dev->private;
497 if (!test_and_clear_bit(AO_CMD_STARTED, &devpriv->state))
501 spin_lock_irqsave(&devpriv->ao_spinlock, flags);
502 /* Kill the interrupts. */
504 outb(0, devpriv->iobase1 + PCI224_INT_SCE);
506 * Interrupt routine may or may not be running. We may or may not
507 * have been called from the interrupt routine (directly or
508 * indirectly via a comedi_events() callback routine). It's highly
509 * unlikely that we've been called from some other interrupt routine
510 * but who knows what strange things coders get up to!
512 * If the interrupt routine is currently running, wait for it to
513 * finish, unless we appear to have been called via the interrupt
516 while (devpriv->intr_running && devpriv->intr_cpuid != THISCPU) {
517 spin_unlock_irqrestore(&devpriv->ao_spinlock, flags);
518 spin_lock_irqsave(&devpriv->ao_spinlock, flags);
520 spin_unlock_irqrestore(&devpriv->ao_spinlock, flags);
521 /* Reconfigure DAC for insn_write usage. */
522 outw(0, dev->iobase + PCI224_DACCEN); /* Disable channels. */
523 devpriv->daccon = COMBINE(devpriv->daccon,
524 PCI224_DACCON_TRIG_SW |
525 PCI224_DACCON_FIFOINTR_EMPTY,
526 PCI224_DACCON_TRIG_MASK |
527 PCI224_DACCON_FIFOINTR_MASK);
528 outw(devpriv->daccon | PCI224_DACCON_FIFORESET,
529 dev->iobase + PCI224_DACCON);
533 * Handles start of acquisition for the AO subdevice.
535 static void pci224_ao_start(struct comedi_device *dev,
536 struct comedi_subdevice *s)
538 struct pci224_private *devpriv = dev->private;
539 struct comedi_cmd *cmd = &s->async->cmd;
542 set_bit(AO_CMD_STARTED, &devpriv->state);
543 if (!devpriv->ao_stop_continuous && devpriv->ao_stop_count == 0) {
544 /* An empty acquisition! */
545 pci224_ao_stop(dev, s);
546 s->async->events |= COMEDI_CB_EOA;
547 comedi_event(dev, s);
549 /* Enable interrupts. */
550 spin_lock_irqsave(&devpriv->ao_spinlock, flags);
551 if (cmd->stop_src == TRIG_EXT)
552 devpriv->intsce = PCI224_INTR_EXT | PCI224_INTR_DAC;
554 devpriv->intsce = PCI224_INTR_DAC;
556 outb(devpriv->intsce, devpriv->iobase1 + PCI224_INT_SCE);
557 spin_unlock_irqrestore(&devpriv->ao_spinlock, flags);
562 * Handles interrupts from the DAC FIFO.
564 static void pci224_ao_handle_fifo(struct comedi_device *dev,
565 struct comedi_subdevice *s)
567 struct pci224_private *devpriv = dev->private;
568 struct comedi_cmd *cmd = &s->async->cmd;
569 unsigned int num_scans;
571 unsigned short dacstat;
573 unsigned int bytes_per_scan;
575 if (cmd->chanlist_len) {
576 bytes_per_scan = cmd->chanlist_len * sizeof(short);
578 /* Shouldn't get here! */
579 bytes_per_scan = sizeof(short);
581 /* Determine number of scans available in buffer. */
582 num_scans = comedi_buf_read_n_available(s->async) / bytes_per_scan;
583 if (!devpriv->ao_stop_continuous) {
584 /* Fixed number of scans. */
585 if (num_scans > devpriv->ao_stop_count)
586 num_scans = devpriv->ao_stop_count;
590 /* Determine how much room is in the FIFO (in samples). */
591 dacstat = inw(dev->iobase + PCI224_DACCON);
592 switch (dacstat & PCI224_DACCON_FIFOFL_MASK) {
593 case PCI224_DACCON_FIFOFL_EMPTY:
594 room = PCI224_FIFO_ROOM_EMPTY;
595 if (!devpriv->ao_stop_continuous && devpriv->ao_stop_count == 0) {
596 /* FIFO empty at end of counted acquisition. */
597 pci224_ao_stop(dev, s);
598 s->async->events |= COMEDI_CB_EOA;
599 comedi_event(dev, s);
603 case PCI224_DACCON_FIFOFL_ONETOHALF:
604 room = PCI224_FIFO_ROOM_ONETOHALF;
606 case PCI224_DACCON_FIFOFL_HALFTOFULL:
607 room = PCI224_FIFO_ROOM_HALFTOFULL;
610 room = PCI224_FIFO_ROOM_FULL;
613 if (room >= PCI224_FIFO_ROOM_ONETOHALF) {
614 /* FIFO is less than half-full. */
615 if (num_scans == 0) {
616 /* Nothing left to put in the FIFO. */
617 pci224_ao_stop(dev, s);
618 s->async->events |= COMEDI_CB_OVERFLOW;
619 dev_err(dev->class_dev, "AO buffer underrun\n");
622 /* Determine how many new scans can be put in the FIFO. */
623 if (cmd->chanlist_len)
624 room /= cmd->chanlist_len;
626 /* Determine how many scans to process. */
627 if (num_scans > room)
631 for (n = 0; n < num_scans; n++) {
632 cfc_read_array_from_buffer(s, &devpriv->ao_scan_vals[0],
634 for (i = 0; i < cmd->chanlist_len; i++) {
635 outw(devpriv->ao_scan_vals[devpriv->ao_scan_order[i]],
636 dev->iobase + PCI224_DACDATA);
639 if (!devpriv->ao_stop_continuous) {
640 devpriv->ao_stop_count -= num_scans;
641 if (devpriv->ao_stop_count == 0) {
643 * Change FIFO interrupt trigger level to wait
644 * until FIFO is empty.
646 devpriv->daccon = COMBINE(devpriv->daccon,
647 PCI224_DACCON_FIFOINTR_EMPTY,
648 PCI224_DACCON_FIFOINTR_MASK);
649 outw(devpriv->daccon, dev->iobase + PCI224_DACCON);
652 if ((devpriv->daccon & PCI224_DACCON_TRIG_MASK) ==
653 PCI224_DACCON_TRIG_NONE) {
657 * This is the initial DAC FIFO interrupt at the
658 * start of the acquisition. The DAC's scan trigger
659 * has been set to 'none' up until now.
661 * Now that data has been written to the FIFO, the
662 * DAC's scan trigger source can be set to the
665 * BUG: The first scan will be triggered immediately
666 * if the scan trigger source is at logic level 1.
668 if (cmd->scan_begin_src == TRIG_TIMER) {
669 trig = PCI224_DACCON_TRIG_Z2CT0;
671 /* cmd->scan_begin_src == TRIG_EXT */
672 if (cmd->scan_begin_arg & CR_INVERT)
673 trig = PCI224_DACCON_TRIG_EXTN;
675 trig = PCI224_DACCON_TRIG_EXTP;
678 devpriv->daccon = COMBINE(devpriv->daccon, trig,
679 PCI224_DACCON_TRIG_MASK);
680 outw(devpriv->daccon, dev->iobase + PCI224_DACCON);
682 if (s->async->events)
683 comedi_event(dev, s);
688 * Internal trigger function to start acquisition on AO subdevice.
691 pci224_ao_inttrig_start(struct comedi_device *dev, struct comedi_subdevice *s,
692 unsigned int trignum)
697 s->async->inttrig = NULL;
698 pci224_ao_start(dev, s);
703 #define MAX_SCAN_PERIOD 0xFFFFFFFFU
704 #define MIN_SCAN_PERIOD 2500
705 #define CONVERT_PERIOD 625
708 * 'do_cmdtest' function for AO subdevice.
711 pci224_ao_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
712 struct comedi_cmd *cmd)
714 struct pci224_private *devpriv = dev->private;
718 /* Step 1 : check if triggers are trivially valid */
720 err |= cfc_check_trigger_src(&cmd->start_src, TRIG_INT | TRIG_EXT);
721 err |= cfc_check_trigger_src(&cmd->scan_begin_src,
722 TRIG_EXT | TRIG_TIMER);
723 err |= cfc_check_trigger_src(&cmd->convert_src, TRIG_NOW);
724 err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
725 err |= cfc_check_trigger_src(&cmd->stop_src,
726 TRIG_COUNT | TRIG_EXT | TRIG_NONE);
731 /* Step 2a : make sure trigger sources are unique */
733 err |= cfc_check_trigger_is_unique(cmd->start_src);
734 err |= cfc_check_trigger_is_unique(cmd->scan_begin_src);
735 err |= cfc_check_trigger_is_unique(cmd->stop_src);
737 /* Step 2b : and mutually compatible */
740 * There's only one external trigger signal (which makes these
741 * tests easier). Only one thing can use it.
744 if (cmd->start_src & TRIG_EXT)
746 if (cmd->scan_begin_src & TRIG_EXT)
748 if (cmd->stop_src & TRIG_EXT)
756 /* Step 3: check if arguments are trivially valid */
758 switch (cmd->start_src) {
760 err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0);
763 /* Force to external trigger 0. */
764 if ((cmd->start_arg & ~CR_FLAGS_MASK) != 0) {
765 cmd->start_arg = COMBINE(cmd->start_arg, 0,
769 /* The only flag allowed is CR_EDGE, which is ignored. */
770 if ((cmd->start_arg & CR_FLAGS_MASK & ~CR_EDGE) != 0) {
771 cmd->start_arg = COMBINE(cmd->start_arg, 0,
772 CR_FLAGS_MASK & ~CR_EDGE);
778 switch (cmd->scan_begin_src) {
780 err |= cfc_check_trigger_arg_max(&cmd->scan_begin_arg,
783 tmp = cmd->chanlist_len * CONVERT_PERIOD;
784 if (tmp < MIN_SCAN_PERIOD)
785 tmp = MIN_SCAN_PERIOD;
786 err |= cfc_check_trigger_arg_min(&cmd->scan_begin_arg, tmp);
789 /* Force to external trigger 0. */
790 if ((cmd->scan_begin_arg & ~CR_FLAGS_MASK) != 0) {
791 cmd->scan_begin_arg = COMBINE(cmd->scan_begin_arg, 0,
795 /* Only allow flags CR_EDGE and CR_INVERT. Ignore CR_EDGE. */
796 if ((cmd->scan_begin_arg & CR_FLAGS_MASK &
797 ~(CR_EDGE | CR_INVERT)) != 0) {
798 cmd->scan_begin_arg = COMBINE(cmd->scan_begin_arg, 0,
800 ~(CR_EDGE | CR_INVERT));
806 err |= cfc_check_trigger_arg_is(&cmd->convert_arg, 0);
807 err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len);
809 switch (cmd->stop_src) {
811 /* Any count allowed. */
814 /* Force to external trigger 0. */
815 if ((cmd->stop_arg & ~CR_FLAGS_MASK) != 0) {
816 cmd->stop_arg = COMBINE(cmd->stop_arg, 0,
820 /* The only flag allowed is CR_EDGE, which is ignored. */
821 if ((cmd->stop_arg & CR_FLAGS_MASK & ~CR_EDGE) != 0) {
822 cmd->stop_arg = COMBINE(cmd->stop_arg, 0,
823 CR_FLAGS_MASK & ~CR_EDGE);
827 err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0);
834 /* Step 4: fix up any arguments. */
836 if (cmd->scan_begin_src == TRIG_TIMER) {
837 unsigned int div1, div2, round;
838 int round_mode = cmd->flags & TRIG_ROUND_MASK;
840 tmp = cmd->scan_begin_arg;
841 /* Check whether to use a single timer. */
842 switch (round_mode) {
843 case TRIG_ROUND_NEAREST:
845 round = TIMEBASE_10MHZ / 2;
847 case TRIG_ROUND_DOWN:
851 round = TIMEBASE_10MHZ - 1;
854 /* Be careful to avoid overflow! */
855 div2 = cmd->scan_begin_arg / TIMEBASE_10MHZ;
856 div2 += (round + cmd->scan_begin_arg % TIMEBASE_10MHZ) /
858 if (div2 <= 0x10000) {
859 /* A single timer will suffice. */
862 cmd->scan_begin_arg = div2 * TIMEBASE_10MHZ;
863 if (cmd->scan_begin_arg < div2 ||
864 cmd->scan_begin_arg < TIMEBASE_10MHZ) {
866 cmd->scan_begin_arg = MAX_SCAN_PERIOD;
869 /* Use two timers. */
870 div1 = devpriv->cached_div1;
871 div2 = devpriv->cached_div2;
872 pci224_cascade_ns_to_timer(TIMEBASE_10MHZ, &div1, &div2,
873 &cmd->scan_begin_arg,
875 devpriv->cached_div1 = div1;
876 devpriv->cached_div2 = div2;
878 if (tmp != cmd->scan_begin_arg)
886 /* Step 5: check channel list. */
888 if (cmd->chanlist && (cmd->chanlist_len > 0)) {
890 enum { range_err = 1, dupchan_err = 2, };
896 * Check all channels have the same range index. Don't care
897 * about analogue reference, as we can't configure it.
899 * Check the list has no duplicate channels.
901 range = CR_RANGE(cmd->chanlist[0]);
904 for (n = 0; n < cmd->chanlist_len; n++) {
905 ch = CR_CHAN(cmd->chanlist[n]);
906 if (tmp & (1U << ch))
907 errors |= dupchan_err;
910 if (CR_RANGE(cmd->chanlist[n]) != range)
915 if (errors & dupchan_err) {
916 DPRINTK("comedi%d: " DRIVER_NAME
918 "entries in chanlist must contain no "
919 "duplicate channels\n", dev->minor);
921 if (errors & range_err) {
922 DPRINTK("comedi%d: " DRIVER_NAME
924 "entries in chanlist must all have "
925 "the same range index\n", dev->minor);
938 * 'do_cmd' function for AO subdevice.
940 static int pci224_ao_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
942 struct pci224_private *devpriv = dev->private;
943 struct comedi_cmd *cmd = &s->async->cmd;
950 /* Cannot handle null/empty chanlist. */
951 if (cmd->chanlist == NULL || cmd->chanlist_len == 0)
955 /* Determine which channels are enabled and their load order. */
956 devpriv->ao_enab = 0;
958 for (i = 0; i < cmd->chanlist_len; i++) {
959 ch = CR_CHAN(cmd->chanlist[i]);
960 devpriv->ao_enab |= 1U << ch;
962 for (j = 0; j < cmd->chanlist_len; j++) {
963 if (CR_CHAN(cmd->chanlist[j]) < ch)
967 devpriv->ao_scan_order[rank] = i;
970 /* Set enabled channels. */
971 outw(devpriv->ao_enab, dev->iobase + PCI224_DACCEN);
973 /* Determine range and polarity. All channels the same. */
974 range = CR_RANGE(cmd->chanlist[0]);
977 * Set DAC range and polarity.
978 * Set DAC scan trigger source to 'none'.
979 * Set DAC FIFO interrupt trigger level to 'not half full'.
982 * N.B. DAC FIFO interrupts are currently disabled.
984 devpriv->daccon = COMBINE(devpriv->daccon,
986 hwrange[range] | PCI224_DACCON_TRIG_NONE |
987 PCI224_DACCON_FIFOINTR_NHALF),
988 (PCI224_DACCON_POLAR_MASK |
989 PCI224_DACCON_VREF_MASK |
990 PCI224_DACCON_TRIG_MASK |
991 PCI224_DACCON_FIFOINTR_MASK));
992 outw(devpriv->daccon | PCI224_DACCON_FIFORESET,
993 dev->iobase + PCI224_DACCON);
995 if (cmd->scan_begin_src == TRIG_TIMER) {
996 unsigned int div1, div2, round;
997 unsigned int ns = cmd->scan_begin_arg;
998 int round_mode = cmd->flags & TRIG_ROUND_MASK;
1000 /* Check whether to use a single timer. */
1001 switch (round_mode) {
1002 case TRIG_ROUND_NEAREST:
1004 round = TIMEBASE_10MHZ / 2;
1006 case TRIG_ROUND_DOWN:
1010 round = TIMEBASE_10MHZ - 1;
1013 /* Be careful to avoid overflow! */
1014 div2 = cmd->scan_begin_arg / TIMEBASE_10MHZ;
1015 div2 += (round + cmd->scan_begin_arg % TIMEBASE_10MHZ) /
1017 if (div2 <= 0x10000) {
1018 /* A single timer will suffice. */
1022 div1 = 1; /* Flag that single timer to be used. */
1024 /* Use two timers. */
1025 div1 = devpriv->cached_div1;
1026 div2 = devpriv->cached_div2;
1027 pci224_cascade_ns_to_timer(TIMEBASE_10MHZ, &div1, &div2,
1032 * The output of timer Z2-0 will be used as the scan trigger
1035 /* Make sure Z2-0 is gated on. */
1036 outb(GAT_CONFIG(0, GAT_VCC),
1037 devpriv->iobase1 + PCI224_ZGAT_SCE);
1039 /* Not cascading. Z2-0 needs 10 MHz clock. */
1040 outb(CLK_CONFIG(0, CLK_10MHZ),
1041 devpriv->iobase1 + PCI224_ZCLK_SCE);
1043 /* Cascading with Z2-2. */
1044 /* Make sure Z2-2 is gated on. */
1045 outb(GAT_CONFIG(2, GAT_VCC),
1046 devpriv->iobase1 + PCI224_ZGAT_SCE);
1047 /* Z2-2 needs 10 MHz clock. */
1048 outb(CLK_CONFIG(2, CLK_10MHZ),
1049 devpriv->iobase1 + PCI224_ZCLK_SCE);
1050 /* Load Z2-2 mode (2) and counter (div1). */
1051 i8254_load(devpriv->iobase1 + PCI224_Z2_CT0, 0,
1053 /* Z2-0 is clocked from Z2-2's output. */
1054 outb(CLK_CONFIG(0, CLK_OUTNM1),
1055 devpriv->iobase1 + PCI224_ZCLK_SCE);
1057 /* Load Z2-0 mode (2) and counter (div2). */
1058 i8254_load(devpriv->iobase1 + PCI224_Z2_CT0, 0, 0, div2, 2);
1062 * Sort out end of acquisition.
1064 switch (cmd->stop_src) {
1066 /* Fixed number of scans. */
1067 devpriv->ao_stop_continuous = 0;
1068 devpriv->ao_stop_count = cmd->stop_arg;
1071 /* Continuous scans. */
1072 devpriv->ao_stop_continuous = 1;
1073 devpriv->ao_stop_count = 0;
1078 * Sort out start of acquisition.
1080 switch (cmd->start_src) {
1082 spin_lock_irqsave(&devpriv->ao_spinlock, flags);
1083 s->async->inttrig = &pci224_ao_inttrig_start;
1084 spin_unlock_irqrestore(&devpriv->ao_spinlock, flags);
1087 /* Enable external interrupt trigger to start acquisition. */
1088 spin_lock_irqsave(&devpriv->ao_spinlock, flags);
1089 devpriv->intsce |= PCI224_INTR_EXT;
1090 outb(devpriv->intsce, devpriv->iobase1 + PCI224_INT_SCE);
1091 spin_unlock_irqrestore(&devpriv->ao_spinlock, flags);
1099 * 'cancel' function for AO subdevice.
1101 static int pci224_ao_cancel(struct comedi_device *dev,
1102 struct comedi_subdevice *s)
1104 pci224_ao_stop(dev, s);
1109 * 'munge' data for AO command.
1112 pci224_ao_munge(struct comedi_device *dev, struct comedi_subdevice *s,
1113 void *data, unsigned int num_bytes, unsigned int chan_index)
1115 const struct pci224_board *thisboard = comedi_board(dev);
1116 struct pci224_private *devpriv = dev->private;
1117 struct comedi_async *async = s->async;
1118 short *array = data;
1119 unsigned int length = num_bytes / sizeof(*array);
1120 unsigned int offset;
1124 /* The hardware expects 16-bit numbers. */
1125 shift = 16 - thisboard->ao_bits;
1126 /* Channels will be all bipolar or all unipolar. */
1127 if ((devpriv->hwrange[CR_RANGE(async->cmd.chanlist[0])] &
1128 PCI224_DACCON_POLAR_MASK) == PCI224_DACCON_POLAR_UNI) {
1135 /* Munge the data. */
1136 for (i = 0; i < length; i++)
1137 array[i] = (array[i] << shift) - offset;
1142 * Interrupt handler.
1144 static irqreturn_t pci224_interrupt(int irq, void *d)
1146 struct comedi_device *dev = d;
1147 struct pci224_private *devpriv = dev->private;
1148 struct comedi_subdevice *s = &dev->subdevices[0];
1149 struct comedi_cmd *cmd;
1150 unsigned char intstat, valid_intstat;
1151 unsigned char curenab;
1153 unsigned long flags;
1155 intstat = inb(devpriv->iobase1 + PCI224_INT_SCE) & 0x3F;
1158 spin_lock_irqsave(&devpriv->ao_spinlock, flags);
1159 valid_intstat = devpriv->intsce & intstat;
1160 /* Temporarily disable interrupt sources. */
1161 curenab = devpriv->intsce & ~intstat;
1162 outb(curenab, devpriv->iobase1 + PCI224_INT_SCE);
1163 devpriv->intr_running = 1;
1164 devpriv->intr_cpuid = THISCPU;
1165 spin_unlock_irqrestore(&devpriv->ao_spinlock, flags);
1166 if (valid_intstat != 0) {
1167 cmd = &s->async->cmd;
1168 if (valid_intstat & PCI224_INTR_EXT) {
1169 devpriv->intsce &= ~PCI224_INTR_EXT;
1170 if (cmd->start_src == TRIG_EXT)
1171 pci224_ao_start(dev, s);
1172 else if (cmd->stop_src == TRIG_EXT)
1173 pci224_ao_stop(dev, s);
1176 if (valid_intstat & PCI224_INTR_DAC)
1177 pci224_ao_handle_fifo(dev, s);
1180 /* Reenable interrupt sources. */
1181 spin_lock_irqsave(&devpriv->ao_spinlock, flags);
1182 if (curenab != devpriv->intsce) {
1183 outb(devpriv->intsce,
1184 devpriv->iobase1 + PCI224_INT_SCE);
1186 devpriv->intr_running = 0;
1187 spin_unlock_irqrestore(&devpriv->ao_spinlock, flags);
1189 return IRQ_RETVAL(retval);
1193 * This function looks for a board matching the supplied PCI device.
1195 static const struct pci224_board
1196 *pci224_find_pci_board(struct pci_dev *pci_dev)
1200 for (i = 0; i < ARRAY_SIZE(pci224_boards); i++)
1201 if (pci_dev->device == pci224_boards[i].devid)
1202 return &pci224_boards[i];
1207 * This function looks for a PCI device matching the requested board name,
1210 static struct pci_dev *pci224_find_pci_dev(struct comedi_device *dev,
1211 struct comedi_devconfig *it)
1213 const struct pci224_board *thisboard = comedi_board(dev);
1214 struct pci_dev *pci_dev = NULL;
1215 int bus = it->options[0];
1216 int slot = it->options[1];
1218 for_each_pci_dev(pci_dev) {
1220 if (bus != pci_dev->bus->number ||
1221 slot != PCI_SLOT(pci_dev->devfn))
1224 if (pci_dev->vendor != PCI_VENDOR_ID_AMPLICON)
1227 if (thisboard->model == any_model) {
1228 /* Match any supported model. */
1229 const struct pci224_board *board_ptr;
1231 board_ptr = pci224_find_pci_board(pci_dev);
1232 if (board_ptr == NULL)
1234 /* Change board_ptr to matched board. */
1235 dev->board_ptr = board_ptr;
1237 /* Match specific model name. */
1238 if (thisboard->devid != pci_dev->device)
1243 dev_err(dev->class_dev,
1244 "No supported board found! (req. bus %d, slot %d)\n",
1249 static void pci224_report_attach(struct comedi_device *dev, unsigned int irq)
1251 struct pci_dev *pcidev = comedi_to_pci_dev(dev);
1255 snprintf(tmpbuf, sizeof(tmpbuf), "irq %u%s", irq,
1256 (dev->irq ? "" : " UNAVAILABLE"));
1258 snprintf(tmpbuf, sizeof(tmpbuf), "no irq");
1259 dev_info(dev->class_dev, "%s (pci %s) (%s) attached\n",
1260 dev->board_name, pci_name(pcidev), tmpbuf);
1264 * Common part of attach and auto_attach.
1266 static int pci224_attach_common(struct comedi_device *dev,
1267 struct pci_dev *pci_dev, int *options)
1269 const struct pci224_board *thisboard = comedi_board(dev);
1270 struct pci224_private *devpriv = dev->private;
1271 struct comedi_subdevice *s;
1276 comedi_set_hw_dev(dev, &pci_dev->dev);
1278 ret = comedi_pci_enable(dev);
1282 spin_lock_init(&devpriv->ao_spinlock);
1284 devpriv->iobase1 = pci_resource_start(pci_dev, 2);
1285 dev->iobase = pci_resource_start(pci_dev, 3);
1288 /* Allocate readback buffer for AO channels. */
1289 devpriv->ao_readback = kmalloc(sizeof(devpriv->ao_readback[0]) *
1290 thisboard->ao_chans, GFP_KERNEL);
1291 if (!devpriv->ao_readback)
1295 /* Allocate buffer to hold values for AO channel scan. */
1296 devpriv->ao_scan_vals = kmalloc(sizeof(devpriv->ao_scan_vals[0]) *
1297 thisboard->ao_chans, GFP_KERNEL);
1298 if (!devpriv->ao_scan_vals)
1302 /* Allocate buffer to hold AO channel scan order. */
1303 devpriv->ao_scan_order = kmalloc(sizeof(devpriv->ao_scan_order[0]) *
1304 thisboard->ao_chans, GFP_KERNEL);
1305 if (!devpriv->ao_scan_order)
1309 /* Disable interrupt sources. */
1310 devpriv->intsce = 0;
1311 outb(0, devpriv->iobase1 + PCI224_INT_SCE);
1313 /* Initialize the DAC hardware. */
1314 outw(PCI224_DACCON_GLOBALRESET, dev->iobase + PCI224_DACCON);
1315 outw(0, dev->iobase + PCI224_DACCEN);
1316 outw(0, dev->iobase + PCI224_FIFOSIZ);
1317 devpriv->daccon = (PCI224_DACCON_TRIG_SW | PCI224_DACCON_POLAR_BI |
1318 PCI224_DACCON_FIFOENAB |
1319 PCI224_DACCON_FIFOINTR_EMPTY);
1320 outw(devpriv->daccon | PCI224_DACCON_FIFORESET,
1321 dev->iobase + PCI224_DACCON);
1323 ret = comedi_alloc_subdevices(dev, 1);
1327 s = &dev->subdevices[0];
1328 /* Analog output subdevice. */
1329 s->type = COMEDI_SUBD_AO;
1330 s->subdev_flags = SDF_WRITABLE | SDF_GROUND | SDF_CMD_WRITE;
1331 s->n_chan = thisboard->ao_chans;
1332 s->maxdata = (1 << thisboard->ao_bits) - 1;
1333 s->insn_write = &pci224_ao_insn_write;
1334 s->insn_read = &pci224_ao_insn_read;
1335 s->len_chanlist = s->n_chan;
1337 dev->write_subdev = s;
1338 s->do_cmd = &pci224_ao_cmd;
1339 s->do_cmdtest = &pci224_ao_cmdtest;
1340 s->cancel = &pci224_ao_cancel;
1341 s->munge = &pci224_ao_munge;
1343 /* Sort out channel range options. */
1344 if (thisboard->model == pci234_model) {
1345 /* PCI234 range options. */
1346 const struct comedi_lrange **range_table_list;
1348 s->range_table_list = range_table_list =
1349 kmalloc(sizeof(struct comedi_lrange *) * s->n_chan,
1351 if (!s->range_table_list)
1355 for (n = 2; n < 3 + s->n_chan; n++) {
1356 if (options[n] < 0 || options[n] > 1) {
1357 dev_warn(dev->class_dev, DRIVER_NAME
1358 ": warning! bad options[%u]=%d\n",
1363 for (n = 0; n < s->n_chan; n++) {
1364 if (n < COMEDI_NDEVCONFOPTS - 3 && options &&
1365 options[3 + n] == 1) {
1366 if (options[2] == 1)
1367 range_table_list[n] = &range_pci234_ext;
1369 range_table_list[n] = &range_bipolar5;
1372 if (options && options[2] == 1) {
1373 range_table_list[n] =
1376 range_table_list[n] = &range_bipolar10;
1380 devpriv->hwrange = hwrange_pci234;
1382 /* PCI224 range options. */
1383 if (options && options[2] == 1) {
1384 s->range_table = &range_pci224_external;
1385 devpriv->hwrange = hwrange_pci224_external;
1387 if (options && options[2] != 0) {
1388 dev_warn(dev->class_dev, DRIVER_NAME
1389 ": warning! bad options[2]=%d\n",
1392 s->range_table = &range_pci224_internal;
1393 devpriv->hwrange = hwrange_pci224_internal;
1397 dev->board_name = thisboard->name;
1400 ret = request_irq(irq, pci224_interrupt, IRQF_SHARED,
1403 dev_err(dev->class_dev,
1404 "error! unable to allocate irq %u\n", irq);
1411 pci224_report_attach(dev, irq);
1415 static int pci224_attach(struct comedi_device *dev, struct comedi_devconfig *it)
1417 struct pci224_private *devpriv;
1418 struct pci_dev *pci_dev;
1420 dev_info(dev->class_dev, DRIVER_NAME ": attach\n");
1422 devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL);
1425 dev->private = devpriv;
1427 pci_dev = pci224_find_pci_dev(dev, it);
1431 return pci224_attach_common(dev, pci_dev, it->options);
1435 pci224_auto_attach(struct comedi_device *dev, unsigned long context_unused)
1437 struct pci_dev *pci_dev = comedi_to_pci_dev(dev);
1438 struct pci224_private *devpriv;
1440 dev_info(dev->class_dev, DRIVER_NAME ": attach pci %s\n",
1443 devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL);
1446 dev->private = devpriv;
1448 dev->board_ptr = pci224_find_pci_board(pci_dev);
1449 if (dev->board_ptr == NULL) {
1450 dev_err(dev->class_dev,
1451 DRIVER_NAME ": BUG! cannot determine board type!\n");
1455 * Need to 'get' the PCI device to match the 'put' in pci224_detach().
1456 * TODO: Remove the pci_dev_get() and matching pci_dev_put() once
1457 * support for manual attachment of PCI devices via pci224_attach()
1460 pci_dev_get(pci_dev);
1461 return pci224_attach_common(dev, pci_dev, NULL);
1464 static void pci224_detach(struct comedi_device *dev)
1466 struct pci224_private *devpriv = dev->private;
1467 struct pci_dev *pcidev = comedi_to_pci_dev(dev);
1470 free_irq(dev->irq, dev);
1471 if (dev->subdevices) {
1472 struct comedi_subdevice *s;
1474 s = &dev->subdevices[0];
1476 kfree(s->range_table_list);
1479 kfree(devpriv->ao_readback);
1480 kfree(devpriv->ao_scan_vals);
1481 kfree(devpriv->ao_scan_order);
1483 comedi_pci_disable(dev);
1485 pci_dev_put(pcidev);
1488 static struct comedi_driver amplc_pci224_driver = {
1489 .driver_name = "amplc_pci224",
1490 .module = THIS_MODULE,
1491 .attach = pci224_attach,
1492 .detach = pci224_detach,
1493 .auto_attach = pci224_auto_attach,
1494 .board_name = &pci224_boards[0].name,
1495 .offset = sizeof(struct pci224_board),
1496 .num_names = ARRAY_SIZE(pci224_boards),
1499 static int amplc_pci224_pci_probe(struct pci_dev *dev,
1500 const struct pci_device_id *id)
1502 return comedi_pci_auto_config(dev, &lc_pci224_driver,
1506 static DEFINE_PCI_DEVICE_TABLE(amplc_pci224_pci_table) = {
1507 { PCI_DEVICE(PCI_VENDOR_ID_AMPLICON, PCI_DEVICE_ID_AMPLICON_PCI224) },
1508 { PCI_DEVICE(PCI_VENDOR_ID_AMPLICON, PCI_DEVICE_ID_AMPLICON_PCI234) },
1511 MODULE_DEVICE_TABLE(pci, amplc_pci224_pci_table);
1513 static struct pci_driver amplc_pci224_pci_driver = {
1514 .name = "amplc_pci224",
1515 .id_table = amplc_pci224_pci_table,
1516 .probe = amplc_pci224_pci_probe,
1517 .remove = comedi_pci_auto_unconfig,
1519 module_comedi_pci_driver(amplc_pci224_driver, amplc_pci224_pci_driver);
1521 MODULE_AUTHOR("Comedi http://www.comedi.org");
1522 MODULE_DESCRIPTION("Comedi low-level driver");
1523 MODULE_LICENSE("GPL");