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/module.h>
102 #include <linux/pci.h>
103 #include <linux/interrupt.h>
104 #include <linux/slab.h>
106 #include "../comedidev.h"
108 #include "comedi_fc.h"
111 #define DRIVER_NAME "amplc_pci224"
116 #define PCI_DEVICE_ID_AMPLICON_PCI224 0x0007
117 #define PCI_DEVICE_ID_AMPLICON_PCI234 0x0008
118 #define PCI_DEVICE_ID_INVALID 0xffff
121 * PCI224/234 i/o space 1 (PCIBAR2) registers.
123 #define PCI224_IO1_SIZE 0x20 /* Size of i/o space 1 (8-bit registers) */
124 #define PCI224_Z2_CT0 0x14 /* 82C54 counter/timer 0 */
125 #define PCI224_Z2_CT1 0x15 /* 82C54 counter/timer 1 */
126 #define PCI224_Z2_CT2 0x16 /* 82C54 counter/timer 2 */
127 #define PCI224_Z2_CTC 0x17 /* 82C54 counter/timer control word */
128 #define PCI224_ZCLK_SCE 0x1A /* Group Z Clock Configuration Register */
129 #define PCI224_ZGAT_SCE 0x1D /* Group Z Gate Configuration Register */
130 #define PCI224_INT_SCE 0x1E /* ISR Interrupt source mask register */
131 /* /Interrupt status */
134 * PCI224/234 i/o space 2 (PCIBAR3) 16-bit registers.
136 #define PCI224_IO2_SIZE 0x10 /* Size of i/o space 2 (16-bit registers). */
137 #define PCI224_DACDATA 0x00 /* (w-o) DAC FIFO data. */
138 #define PCI224_SOFTTRIG 0x00 /* (r-o) DAC software scan trigger. */
139 #define PCI224_DACCON 0x02 /* (r/w) DAC status/configuration. */
140 #define PCI224_FIFOSIZ 0x04 /* (w-o) FIFO size for wraparound mode. */
141 #define PCI224_DACCEN 0x06 /* (w-o) DAC channel enable register. */
146 /* (r/w) Scan trigger. */
147 #define PCI224_DACCON_TRIG_MASK (7 << 0)
148 #define PCI224_DACCON_TRIG_NONE (0 << 0) /* none */
149 #define PCI224_DACCON_TRIG_SW (1 << 0) /* software trig */
150 #define PCI224_DACCON_TRIG_EXTP (2 << 0) /* ext +ve edge */
151 #define PCI224_DACCON_TRIG_EXTN (3 << 0) /* ext -ve edge */
152 #define PCI224_DACCON_TRIG_Z2CT0 (4 << 0) /* Z2 CT0 out */
153 #define PCI224_DACCON_TRIG_Z2CT1 (5 << 0) /* Z2 CT1 out */
154 #define PCI224_DACCON_TRIG_Z2CT2 (6 << 0) /* Z2 CT2 out */
155 /* (r/w) Polarity (PCI224 only, PCI234 always bipolar!). */
156 #define PCI224_DACCON_POLAR_MASK (1 << 3)
157 #define PCI224_DACCON_POLAR_UNI (0 << 3) /* range [0,Vref] */
158 #define PCI224_DACCON_POLAR_BI (1 << 3) /* range [-Vref,Vref] */
159 /* (r/w) Internal Vref (PCI224 only, when LK1 in position 1-2). */
160 #define PCI224_DACCON_VREF_MASK (3 << 4)
161 #define PCI224_DACCON_VREF_1_25 (0 << 4) /* Vref = 1.25V */
162 #define PCI224_DACCON_VREF_2_5 (1 << 4) /* Vref = 2.5V */
163 #define PCI224_DACCON_VREF_5 (2 << 4) /* Vref = 5V */
164 #define PCI224_DACCON_VREF_10 (3 << 4) /* Vref = 10V */
165 /* (r/w) Wraparound mode enable (to play back stored waveform). */
166 #define PCI224_DACCON_FIFOWRAP (1 << 7)
167 /* (r/w) FIFO enable. It MUST be set! */
168 #define PCI224_DACCON_FIFOENAB (1 << 8)
169 /* (r/w) FIFO interrupt trigger level (most values are not very useful). */
170 #define PCI224_DACCON_FIFOINTR_MASK (7 << 9)
171 #define PCI224_DACCON_FIFOINTR_EMPTY (0 << 9) /* when empty */
172 #define PCI224_DACCON_FIFOINTR_NEMPTY (1 << 9) /* when not empty */
173 #define PCI224_DACCON_FIFOINTR_NHALF (2 << 9) /* when not half full */
174 #define PCI224_DACCON_FIFOINTR_HALF (3 << 9) /* when half full */
175 #define PCI224_DACCON_FIFOINTR_NFULL (4 << 9) /* when not full */
176 #define PCI224_DACCON_FIFOINTR_FULL (5 << 9) /* when full */
177 /* (r-o) FIFO fill level. */
178 #define PCI224_DACCON_FIFOFL_MASK (7 << 12)
179 #define PCI224_DACCON_FIFOFL_EMPTY (1 << 12) /* 0 */
180 #define PCI224_DACCON_FIFOFL_ONETOHALF (0 << 12) /* [1,2048] */
181 #define PCI224_DACCON_FIFOFL_HALFTOFULL (4 << 12) /* [2049,4095] */
182 #define PCI224_DACCON_FIFOFL_FULL (6 << 12) /* 4096 */
183 /* (r-o) DAC busy flag. */
184 #define PCI224_DACCON_BUSY (1 << 15)
185 /* (w-o) FIFO reset. */
186 #define PCI224_DACCON_FIFORESET (1 << 12)
187 /* (w-o) Global reset (not sure what it does). */
188 #define PCI224_DACCON_GLOBALRESET (1 << 13)
193 #define PCI224_FIFO_SIZE 4096
196 * DAC FIFO guaranteed minimum room available, depending on reported fill level.
197 * The maximum room available depends on the reported fill level and how much
200 #define PCI224_FIFO_ROOM_EMPTY PCI224_FIFO_SIZE
201 #define PCI224_FIFO_ROOM_ONETOHALF (PCI224_FIFO_SIZE / 2)
202 #define PCI224_FIFO_ROOM_HALFTOFULL 1
203 #define PCI224_FIFO_ROOM_FULL 0
206 * Counter/timer clock input configuration sources.
208 #define CLK_CLK 0 /* reserved (channel-specific clock) */
209 #define CLK_10MHZ 1 /* internal 10 MHz clock */
210 #define CLK_1MHZ 2 /* internal 1 MHz clock */
211 #define CLK_100KHZ 3 /* internal 100 kHz clock */
212 #define CLK_10KHZ 4 /* internal 10 kHz clock */
213 #define CLK_1KHZ 5 /* internal 1 kHz clock */
214 #define CLK_OUTNM1 6 /* output of channel-1 modulo total */
215 #define CLK_EXT 7 /* external clock */
216 /* Macro to construct clock input configuration register value. */
217 #define CLK_CONFIG(chan, src) ((((chan) & 3) << 3) | ((src) & 7))
220 * Counter/timer gate input configuration sources.
222 #define GAT_VCC 0 /* VCC (i.e. enabled) */
223 #define GAT_GND 1 /* GND (i.e. disabled) */
224 #define GAT_EXT 2 /* reserved (external gate input) */
225 #define GAT_NOUTNM2 3 /* inverted output of channel-2 modulo total */
226 /* Macro to construct gate input configuration register value. */
227 #define GAT_CONFIG(chan, src) ((((chan) & 3) << 3) | ((src) & 7))
230 * Summary of CLK_OUTNM1 and GAT_NOUTNM2 connections for PCI224 and PCI234:
232 * Channel's Channel's
233 * clock input gate input
234 * Channel CLK_OUTNM1 GAT_NOUTNM2
235 * ------- ---------- -----------
236 * Z2-CT0 Z2-CT2-OUT /Z2-CT1-OUT
237 * Z2-CT1 Z2-CT0-OUT /Z2-CT2-OUT
238 * Z2-CT2 Z2-CT1-OUT /Z2-CT0-OUT
242 * Interrupt enable/status bits
244 #define PCI224_INTR_EXT 0x01 /* rising edge on external input */
245 #define PCI224_INTR_DAC 0x04 /* DAC (FIFO) interrupt */
246 #define PCI224_INTR_Z2CT1 0x20 /* rising edge on Z2-CT1 output */
248 #define PCI224_INTR_EDGE_BITS (PCI224_INTR_EXT | PCI224_INTR_Z2CT1)
249 #define PCI224_INTR_LEVEL_BITS PCI224_INTR_DACFIFO
255 /* Combine old and new bits. */
256 #define COMBINE(old, new, mask) (((old) & ~(mask)) | ((new) & (mask)))
258 /* Current CPU. XXX should this be hard_smp_processor_id()? */
259 #define THISCPU smp_processor_id()
261 /* State bits for use with atomic bit operations. */
262 #define AO_CMD_STARTED 0
268 /* The software selectable internal ranges for PCI224 (option[2] == 0). */
269 static const struct comedi_lrange range_pci224_internal = {
283 static const unsigned short hwrange_pci224_internal[8] = {
284 PCI224_DACCON_POLAR_BI | PCI224_DACCON_VREF_10,
285 PCI224_DACCON_POLAR_BI | PCI224_DACCON_VREF_5,
286 PCI224_DACCON_POLAR_BI | PCI224_DACCON_VREF_2_5,
287 PCI224_DACCON_POLAR_BI | PCI224_DACCON_VREF_1_25,
288 PCI224_DACCON_POLAR_UNI | PCI224_DACCON_VREF_10,
289 PCI224_DACCON_POLAR_UNI | PCI224_DACCON_VREF_5,
290 PCI224_DACCON_POLAR_UNI | PCI224_DACCON_VREF_2_5,
291 PCI224_DACCON_POLAR_UNI | PCI224_DACCON_VREF_1_25,
294 /* The software selectable external ranges for PCI224 (option[2] == 1). */
295 static const struct comedi_lrange range_pci224_external = {
298 RANGE_ext(-1, 1), /* bipolar [-Vref,+Vref] */
299 RANGE_ext(0, 1), /* unipolar [0,+Vref] */
303 static const unsigned short hwrange_pci224_external[2] = {
304 PCI224_DACCON_POLAR_BI,
305 PCI224_DACCON_POLAR_UNI,
308 /* The hardware selectable Vref*2 external range for PCI234
309 * (option[2] == 1, option[3+n] == 0). */
310 static const struct comedi_lrange range_pci234_ext2 = {
317 /* The hardware selectable Vref external range for PCI234
318 * (option[2] == 1, option[3+n] == 1). */
319 static const struct comedi_lrange range_pci234_ext = {
326 /* This serves for all the PCI234 ranges. */
327 static const unsigned short hwrange_pci234[1] = {
328 PCI224_DACCON_POLAR_BI, /* bipolar - hardware ignores it! */
332 * Board descriptions.
335 enum pci224_model { any_model, pci224_model, pci234_model };
337 struct pci224_board {
339 unsigned short devid;
340 enum pci224_model model;
341 unsigned int ao_chans;
342 unsigned int ao_bits;
345 static const struct pci224_board pci224_boards[] = {
348 .devid = PCI_DEVICE_ID_AMPLICON_PCI224,
349 .model = pci224_model,
355 .devid = PCI_DEVICE_ID_AMPLICON_PCI234,
356 .model = pci234_model,
362 .devid = PCI_DEVICE_ID_INVALID,
363 .model = any_model, /* wildcard */
367 /* this structure is for data unique to this hardware driver. If
368 several hardware drivers keep similar information in this structure,
369 feel free to suggest moving the variable to the struct comedi_device struct. */
370 struct pci224_private {
371 const unsigned short *hwrange;
372 unsigned long iobase1;
374 spinlock_t ao_spinlock;
375 unsigned int *ao_readback;
376 unsigned short *ao_scan_vals;
377 unsigned char *ao_scan_order;
380 unsigned short daccon;
381 unsigned int cached_div1;
382 unsigned int cached_div2;
383 unsigned int ao_stop_count;
384 short ao_stop_continuous;
385 unsigned short ao_enab; /* max 16 channels so 'short' will do */
386 unsigned char intsce;
390 * Called from the 'insn_write' function to perform a single write.
393 pci224_ao_set_data(struct comedi_device *dev, int chan, int range,
396 const struct pci224_board *thisboard = comedi_board(dev);
397 struct pci224_private *devpriv = dev->private;
398 unsigned short mangled;
400 /* Store unmangled data for readback. */
401 devpriv->ao_readback[chan] = data;
402 /* Enable the channel. */
403 outw(1 << chan, dev->iobase + PCI224_DACCEN);
404 /* Set range and reset FIFO. */
405 devpriv->daccon = COMBINE(devpriv->daccon, devpriv->hwrange[range],
406 (PCI224_DACCON_POLAR_MASK |
407 PCI224_DACCON_VREF_MASK));
408 outw(devpriv->daccon | PCI224_DACCON_FIFORESET,
409 dev->iobase + PCI224_DACCON);
411 * Mangle the data. The hardware expects:
412 * - bipolar: 16-bit 2's complement
413 * - unipolar: 16-bit unsigned
415 mangled = (unsigned short)data << (16 - thisboard->ao_bits);
416 if ((devpriv->daccon & PCI224_DACCON_POLAR_MASK) ==
417 PCI224_DACCON_POLAR_BI) {
420 /* Write mangled data to the FIFO. */
421 outw(mangled, dev->iobase + PCI224_DACDATA);
422 /* Trigger the conversion. */
423 inw(dev->iobase + PCI224_SOFTTRIG);
427 * 'insn_write' function for AO subdevice.
430 pci224_ao_insn_write(struct comedi_device *dev, struct comedi_subdevice *s,
431 struct comedi_insn *insn, unsigned int *data)
436 /* Unpack channel and range. */
437 chan = CR_CHAN(insn->chanspec);
438 range = CR_RANGE(insn->chanspec);
440 /* Writing a list of values to an AO channel is probably not
441 * very useful, but that's how the interface is defined. */
442 for (i = 0; i < insn->n; i++)
443 pci224_ao_set_data(dev, chan, range, data[i]);
449 * 'insn_read' function for AO subdevice.
451 * N.B. The value read will not be valid if the DAC channel has
452 * never been written successfully since the device was attached
453 * or since the channel has been used by an AO streaming write
457 pci224_ao_insn_read(struct comedi_device *dev, struct comedi_subdevice *s,
458 struct comedi_insn *insn, unsigned int *data)
460 struct pci224_private *devpriv = dev->private;
464 chan = CR_CHAN(insn->chanspec);
466 for (i = 0; i < insn->n; i++)
467 data[i] = devpriv->ao_readback[chan];
474 * Just a wrapper for the inline function 'i8253_cascade_ns_to_timer'.
477 pci224_cascade_ns_to_timer(int osc_base, unsigned int *d1, unsigned int *d2,
478 unsigned int *nanosec, int round_mode)
480 i8253_cascade_ns_to_timer(osc_base, d1, d2, nanosec, round_mode);
484 * Kills a command running on the AO subdevice.
486 static void pci224_ao_stop(struct comedi_device *dev,
487 struct comedi_subdevice *s)
489 struct pci224_private *devpriv = dev->private;
492 if (!test_and_clear_bit(AO_CMD_STARTED, &devpriv->state))
496 spin_lock_irqsave(&devpriv->ao_spinlock, flags);
497 /* Kill the interrupts. */
499 outb(0, devpriv->iobase1 + PCI224_INT_SCE);
501 * Interrupt routine may or may not be running. We may or may not
502 * have been called from the interrupt routine (directly or
503 * indirectly via a comedi_events() callback routine). It's highly
504 * unlikely that we've been called from some other interrupt routine
505 * but who knows what strange things coders get up to!
507 * If the interrupt routine is currently running, wait for it to
508 * finish, unless we appear to have been called via the interrupt
511 while (devpriv->intr_running && devpriv->intr_cpuid != THISCPU) {
512 spin_unlock_irqrestore(&devpriv->ao_spinlock, flags);
513 spin_lock_irqsave(&devpriv->ao_spinlock, flags);
515 spin_unlock_irqrestore(&devpriv->ao_spinlock, flags);
516 /* Reconfigure DAC for insn_write usage. */
517 outw(0, dev->iobase + PCI224_DACCEN); /* Disable channels. */
518 devpriv->daccon = COMBINE(devpriv->daccon,
519 PCI224_DACCON_TRIG_SW |
520 PCI224_DACCON_FIFOINTR_EMPTY,
521 PCI224_DACCON_TRIG_MASK |
522 PCI224_DACCON_FIFOINTR_MASK);
523 outw(devpriv->daccon | PCI224_DACCON_FIFORESET,
524 dev->iobase + PCI224_DACCON);
528 * Handles start of acquisition for the AO subdevice.
530 static void pci224_ao_start(struct comedi_device *dev,
531 struct comedi_subdevice *s)
533 struct pci224_private *devpriv = dev->private;
534 struct comedi_cmd *cmd = &s->async->cmd;
537 set_bit(AO_CMD_STARTED, &devpriv->state);
538 if (!devpriv->ao_stop_continuous && devpriv->ao_stop_count == 0) {
539 /* An empty acquisition! */
540 pci224_ao_stop(dev, s);
541 s->async->events |= COMEDI_CB_EOA;
542 comedi_event(dev, s);
544 /* Enable interrupts. */
545 spin_lock_irqsave(&devpriv->ao_spinlock, flags);
546 if (cmd->stop_src == TRIG_EXT)
547 devpriv->intsce = PCI224_INTR_EXT | PCI224_INTR_DAC;
549 devpriv->intsce = PCI224_INTR_DAC;
551 outb(devpriv->intsce, devpriv->iobase1 + PCI224_INT_SCE);
552 spin_unlock_irqrestore(&devpriv->ao_spinlock, flags);
557 * Handles interrupts from the DAC FIFO.
559 static void pci224_ao_handle_fifo(struct comedi_device *dev,
560 struct comedi_subdevice *s)
562 struct pci224_private *devpriv = dev->private;
563 struct comedi_cmd *cmd = &s->async->cmd;
564 unsigned int num_scans;
566 unsigned short dacstat;
568 unsigned int bytes_per_scan;
570 if (cmd->chanlist_len) {
571 bytes_per_scan = cmd->chanlist_len * sizeof(short);
573 /* Shouldn't get here! */
574 bytes_per_scan = sizeof(short);
576 /* Determine number of scans available in buffer. */
577 num_scans = comedi_buf_read_n_available(s->async) / bytes_per_scan;
578 if (!devpriv->ao_stop_continuous) {
579 /* Fixed number of scans. */
580 if (num_scans > devpriv->ao_stop_count)
581 num_scans = devpriv->ao_stop_count;
585 /* Determine how much room is in the FIFO (in samples). */
586 dacstat = inw(dev->iobase + PCI224_DACCON);
587 switch (dacstat & PCI224_DACCON_FIFOFL_MASK) {
588 case PCI224_DACCON_FIFOFL_EMPTY:
589 room = PCI224_FIFO_ROOM_EMPTY;
590 if (!devpriv->ao_stop_continuous && devpriv->ao_stop_count == 0) {
591 /* FIFO empty at end of counted acquisition. */
592 pci224_ao_stop(dev, s);
593 s->async->events |= COMEDI_CB_EOA;
594 comedi_event(dev, s);
598 case PCI224_DACCON_FIFOFL_ONETOHALF:
599 room = PCI224_FIFO_ROOM_ONETOHALF;
601 case PCI224_DACCON_FIFOFL_HALFTOFULL:
602 room = PCI224_FIFO_ROOM_HALFTOFULL;
605 room = PCI224_FIFO_ROOM_FULL;
608 if (room >= PCI224_FIFO_ROOM_ONETOHALF) {
609 /* FIFO is less than half-full. */
610 if (num_scans == 0) {
611 /* Nothing left to put in the FIFO. */
612 pci224_ao_stop(dev, s);
613 s->async->events |= COMEDI_CB_OVERFLOW;
614 dev_err(dev->class_dev, "AO buffer underrun\n");
617 /* Determine how many new scans can be put in the FIFO. */
618 if (cmd->chanlist_len)
619 room /= cmd->chanlist_len;
621 /* Determine how many scans to process. */
622 if (num_scans > room)
626 for (n = 0; n < num_scans; n++) {
627 cfc_read_array_from_buffer(s, &devpriv->ao_scan_vals[0],
629 for (i = 0; i < cmd->chanlist_len; i++) {
630 outw(devpriv->ao_scan_vals[devpriv->ao_scan_order[i]],
631 dev->iobase + PCI224_DACDATA);
634 if (!devpriv->ao_stop_continuous) {
635 devpriv->ao_stop_count -= num_scans;
636 if (devpriv->ao_stop_count == 0) {
638 * Change FIFO interrupt trigger level to wait
639 * until FIFO is empty.
641 devpriv->daccon = COMBINE(devpriv->daccon,
642 PCI224_DACCON_FIFOINTR_EMPTY,
643 PCI224_DACCON_FIFOINTR_MASK);
644 outw(devpriv->daccon, dev->iobase + PCI224_DACCON);
647 if ((devpriv->daccon & PCI224_DACCON_TRIG_MASK) ==
648 PCI224_DACCON_TRIG_NONE) {
652 * This is the initial DAC FIFO interrupt at the
653 * start of the acquisition. The DAC's scan trigger
654 * has been set to 'none' up until now.
656 * Now that data has been written to the FIFO, the
657 * DAC's scan trigger source can be set to the
660 * BUG: The first scan will be triggered immediately
661 * if the scan trigger source is at logic level 1.
663 if (cmd->scan_begin_src == TRIG_TIMER) {
664 trig = PCI224_DACCON_TRIG_Z2CT0;
666 /* cmd->scan_begin_src == TRIG_EXT */
667 if (cmd->scan_begin_arg & CR_INVERT)
668 trig = PCI224_DACCON_TRIG_EXTN;
670 trig = PCI224_DACCON_TRIG_EXTP;
673 devpriv->daccon = COMBINE(devpriv->daccon, trig,
674 PCI224_DACCON_TRIG_MASK);
675 outw(devpriv->daccon, dev->iobase + PCI224_DACCON);
677 if (s->async->events)
678 comedi_event(dev, s);
683 * Internal trigger function to start acquisition on AO subdevice.
686 pci224_ao_inttrig_start(struct comedi_device *dev, struct comedi_subdevice *s,
687 unsigned int trignum)
692 s->async->inttrig = NULL;
693 pci224_ao_start(dev, s);
698 #define MAX_SCAN_PERIOD 0xFFFFFFFFU
699 #define MIN_SCAN_PERIOD 2500
700 #define CONVERT_PERIOD 625
703 * 'do_cmdtest' function for AO subdevice.
706 pci224_ao_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
707 struct comedi_cmd *cmd)
709 struct pci224_private *devpriv = dev->private;
713 /* Step 1 : check if triggers are trivially valid */
715 err |= cfc_check_trigger_src(&cmd->start_src, TRIG_INT | TRIG_EXT);
716 err |= cfc_check_trigger_src(&cmd->scan_begin_src,
717 TRIG_EXT | TRIG_TIMER);
718 err |= cfc_check_trigger_src(&cmd->convert_src, TRIG_NOW);
719 err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
720 err |= cfc_check_trigger_src(&cmd->stop_src,
721 TRIG_COUNT | TRIG_EXT | TRIG_NONE);
726 /* Step 2a : make sure trigger sources are unique */
728 err |= cfc_check_trigger_is_unique(cmd->start_src);
729 err |= cfc_check_trigger_is_unique(cmd->scan_begin_src);
730 err |= cfc_check_trigger_is_unique(cmd->stop_src);
732 /* Step 2b : and mutually compatible */
735 * There's only one external trigger signal (which makes these
736 * tests easier). Only one thing can use it.
739 if (cmd->start_src & TRIG_EXT)
741 if (cmd->scan_begin_src & TRIG_EXT)
743 if (cmd->stop_src & TRIG_EXT)
751 /* Step 3: check if arguments are trivially valid */
753 switch (cmd->start_src) {
755 err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0);
758 /* Force to external trigger 0. */
759 if ((cmd->start_arg & ~CR_FLAGS_MASK) != 0) {
760 cmd->start_arg = COMBINE(cmd->start_arg, 0,
764 /* The only flag allowed is CR_EDGE, which is ignored. */
765 if ((cmd->start_arg & CR_FLAGS_MASK & ~CR_EDGE) != 0) {
766 cmd->start_arg = COMBINE(cmd->start_arg, 0,
767 CR_FLAGS_MASK & ~CR_EDGE);
773 switch (cmd->scan_begin_src) {
775 err |= cfc_check_trigger_arg_max(&cmd->scan_begin_arg,
778 tmp = cmd->chanlist_len * CONVERT_PERIOD;
779 if (tmp < MIN_SCAN_PERIOD)
780 tmp = MIN_SCAN_PERIOD;
781 err |= cfc_check_trigger_arg_min(&cmd->scan_begin_arg, tmp);
784 /* Force to external trigger 0. */
785 if ((cmd->scan_begin_arg & ~CR_FLAGS_MASK) != 0) {
786 cmd->scan_begin_arg = COMBINE(cmd->scan_begin_arg, 0,
790 /* Only allow flags CR_EDGE and CR_INVERT. Ignore CR_EDGE. */
791 if ((cmd->scan_begin_arg & CR_FLAGS_MASK &
792 ~(CR_EDGE | CR_INVERT)) != 0) {
793 cmd->scan_begin_arg = COMBINE(cmd->scan_begin_arg, 0,
795 ~(CR_EDGE | CR_INVERT));
801 err |= cfc_check_trigger_arg_is(&cmd->convert_arg, 0);
802 err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len);
804 switch (cmd->stop_src) {
806 /* Any count allowed. */
809 /* Force to external trigger 0. */
810 if ((cmd->stop_arg & ~CR_FLAGS_MASK) != 0) {
811 cmd->stop_arg = COMBINE(cmd->stop_arg, 0,
815 /* The only flag allowed is CR_EDGE, which is ignored. */
816 if ((cmd->stop_arg & CR_FLAGS_MASK & ~CR_EDGE) != 0) {
817 cmd->stop_arg = COMBINE(cmd->stop_arg, 0,
818 CR_FLAGS_MASK & ~CR_EDGE);
822 err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0);
829 /* Step 4: fix up any arguments. */
831 if (cmd->scan_begin_src == TRIG_TIMER) {
832 unsigned int div1, div2, round;
833 int round_mode = cmd->flags & TRIG_ROUND_MASK;
835 tmp = cmd->scan_begin_arg;
836 /* Check whether to use a single timer. */
837 switch (round_mode) {
838 case TRIG_ROUND_NEAREST:
840 round = I8254_OSC_BASE_10MHZ / 2;
842 case TRIG_ROUND_DOWN:
846 round = I8254_OSC_BASE_10MHZ - 1;
849 /* Be careful to avoid overflow! */
850 div2 = cmd->scan_begin_arg / I8254_OSC_BASE_10MHZ;
851 div2 += (round + cmd->scan_begin_arg % I8254_OSC_BASE_10MHZ) /
852 I8254_OSC_BASE_10MHZ;
853 if (div2 <= 0x10000) {
854 /* A single timer will suffice. */
857 cmd->scan_begin_arg = div2 * I8254_OSC_BASE_10MHZ;
858 if (cmd->scan_begin_arg < div2 ||
859 cmd->scan_begin_arg < I8254_OSC_BASE_10MHZ) {
861 cmd->scan_begin_arg = MAX_SCAN_PERIOD;
864 /* Use two timers. */
865 div1 = devpriv->cached_div1;
866 div2 = devpriv->cached_div2;
867 pci224_cascade_ns_to_timer(I8254_OSC_BASE_10MHZ,
869 &cmd->scan_begin_arg,
871 devpriv->cached_div1 = div1;
872 devpriv->cached_div2 = div2;
874 if (tmp != cmd->scan_begin_arg)
882 /* Step 5: check channel list. */
884 if (cmd->chanlist && (cmd->chanlist_len > 0)) {
886 enum { range_err = 1, dupchan_err = 2, };
892 * Check all channels have the same range index. Don't care
893 * about analogue reference, as we can't configure it.
895 * Check the list has no duplicate channels.
897 range = CR_RANGE(cmd->chanlist[0]);
900 for (n = 0; n < cmd->chanlist_len; n++) {
901 ch = CR_CHAN(cmd->chanlist[n]);
902 if (tmp & (1U << ch))
903 errors |= dupchan_err;
906 if (CR_RANGE(cmd->chanlist[n]) != range)
911 if (errors & dupchan_err) {
912 DPRINTK("comedi%d: " DRIVER_NAME
914 "entries in chanlist must contain no "
915 "duplicate channels\n", dev->minor);
917 if (errors & range_err) {
918 DPRINTK("comedi%d: " DRIVER_NAME
920 "entries in chanlist must all have "
921 "the same range index\n", dev->minor);
934 * 'do_cmd' function for AO subdevice.
936 static int pci224_ao_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
938 struct pci224_private *devpriv = dev->private;
939 struct comedi_cmd *cmd = &s->async->cmd;
946 /* Cannot handle null/empty chanlist. */
947 if (cmd->chanlist == NULL || cmd->chanlist_len == 0)
951 /* Determine which channels are enabled and their load order. */
952 devpriv->ao_enab = 0;
954 for (i = 0; i < cmd->chanlist_len; i++) {
955 ch = CR_CHAN(cmd->chanlist[i]);
956 devpriv->ao_enab |= 1U << ch;
958 for (j = 0; j < cmd->chanlist_len; j++) {
959 if (CR_CHAN(cmd->chanlist[j]) < ch)
963 devpriv->ao_scan_order[rank] = i;
966 /* Set enabled channels. */
967 outw(devpriv->ao_enab, dev->iobase + PCI224_DACCEN);
969 /* Determine range and polarity. All channels the same. */
970 range = CR_RANGE(cmd->chanlist[0]);
973 * Set DAC range and polarity.
974 * Set DAC scan trigger source to 'none'.
975 * Set DAC FIFO interrupt trigger level to 'not half full'.
978 * N.B. DAC FIFO interrupts are currently disabled.
980 devpriv->daccon = COMBINE(devpriv->daccon,
982 hwrange[range] | PCI224_DACCON_TRIG_NONE |
983 PCI224_DACCON_FIFOINTR_NHALF),
984 (PCI224_DACCON_POLAR_MASK |
985 PCI224_DACCON_VREF_MASK |
986 PCI224_DACCON_TRIG_MASK |
987 PCI224_DACCON_FIFOINTR_MASK));
988 outw(devpriv->daccon | PCI224_DACCON_FIFORESET,
989 dev->iobase + PCI224_DACCON);
991 if (cmd->scan_begin_src == TRIG_TIMER) {
992 unsigned int div1, div2, round;
993 unsigned int ns = cmd->scan_begin_arg;
994 int round_mode = cmd->flags & TRIG_ROUND_MASK;
996 /* Check whether to use a single timer. */
997 switch (round_mode) {
998 case TRIG_ROUND_NEAREST:
1000 round = I8254_OSC_BASE_10MHZ / 2;
1002 case TRIG_ROUND_DOWN:
1006 round = I8254_OSC_BASE_10MHZ - 1;
1009 /* Be careful to avoid overflow! */
1010 div2 = cmd->scan_begin_arg / I8254_OSC_BASE_10MHZ;
1011 div2 += (round + cmd->scan_begin_arg % I8254_OSC_BASE_10MHZ) /
1012 I8254_OSC_BASE_10MHZ;
1013 if (div2 <= 0x10000) {
1014 /* A single timer will suffice. */
1018 div1 = 1; /* Flag that single timer to be used. */
1020 /* Use two timers. */
1021 div1 = devpriv->cached_div1;
1022 div2 = devpriv->cached_div2;
1023 pci224_cascade_ns_to_timer(I8254_OSC_BASE_10MHZ,
1029 * The output of timer Z2-0 will be used as the scan trigger
1032 /* Make sure Z2-0 is gated on. */
1033 outb(GAT_CONFIG(0, GAT_VCC),
1034 devpriv->iobase1 + PCI224_ZGAT_SCE);
1036 /* Not cascading. Z2-0 needs 10 MHz clock. */
1037 outb(CLK_CONFIG(0, CLK_10MHZ),
1038 devpriv->iobase1 + PCI224_ZCLK_SCE);
1040 /* Cascading with Z2-2. */
1041 /* Make sure Z2-2 is gated on. */
1042 outb(GAT_CONFIG(2, GAT_VCC),
1043 devpriv->iobase1 + PCI224_ZGAT_SCE);
1044 /* Z2-2 needs 10 MHz clock. */
1045 outb(CLK_CONFIG(2, CLK_10MHZ),
1046 devpriv->iobase1 + PCI224_ZCLK_SCE);
1047 /* Load Z2-2 mode (2) and counter (div1). */
1048 i8254_load(devpriv->iobase1 + PCI224_Z2_CT0, 0,
1050 /* Z2-0 is clocked from Z2-2's output. */
1051 outb(CLK_CONFIG(0, CLK_OUTNM1),
1052 devpriv->iobase1 + PCI224_ZCLK_SCE);
1054 /* Load Z2-0 mode (2) and counter (div2). */
1055 i8254_load(devpriv->iobase1 + PCI224_Z2_CT0, 0, 0, div2, 2);
1059 * Sort out end of acquisition.
1061 switch (cmd->stop_src) {
1063 /* Fixed number of scans. */
1064 devpriv->ao_stop_continuous = 0;
1065 devpriv->ao_stop_count = cmd->stop_arg;
1068 /* Continuous scans. */
1069 devpriv->ao_stop_continuous = 1;
1070 devpriv->ao_stop_count = 0;
1075 * Sort out start of acquisition.
1077 switch (cmd->start_src) {
1079 spin_lock_irqsave(&devpriv->ao_spinlock, flags);
1080 s->async->inttrig = &pci224_ao_inttrig_start;
1081 spin_unlock_irqrestore(&devpriv->ao_spinlock, flags);
1084 /* Enable external interrupt trigger to start acquisition. */
1085 spin_lock_irqsave(&devpriv->ao_spinlock, flags);
1086 devpriv->intsce |= PCI224_INTR_EXT;
1087 outb(devpriv->intsce, devpriv->iobase1 + PCI224_INT_SCE);
1088 spin_unlock_irqrestore(&devpriv->ao_spinlock, flags);
1096 * 'cancel' function for AO subdevice.
1098 static int pci224_ao_cancel(struct comedi_device *dev,
1099 struct comedi_subdevice *s)
1101 pci224_ao_stop(dev, s);
1106 * 'munge' data for AO command.
1109 pci224_ao_munge(struct comedi_device *dev, struct comedi_subdevice *s,
1110 void *data, unsigned int num_bytes, unsigned int chan_index)
1112 const struct pci224_board *thisboard = comedi_board(dev);
1113 struct pci224_private *devpriv = dev->private;
1114 struct comedi_async *async = s->async;
1115 unsigned short *array = data;
1116 unsigned int length = num_bytes / sizeof(*array);
1117 unsigned int offset;
1121 /* The hardware expects 16-bit numbers. */
1122 shift = 16 - thisboard->ao_bits;
1123 /* Channels will be all bipolar or all unipolar. */
1124 if ((devpriv->hwrange[CR_RANGE(async->cmd.chanlist[0])] &
1125 PCI224_DACCON_POLAR_MASK) == PCI224_DACCON_POLAR_UNI) {
1132 /* Munge the data. */
1133 for (i = 0; i < length; i++)
1134 array[i] = (array[i] << shift) - offset;
1139 * Interrupt handler.
1141 static irqreturn_t pci224_interrupt(int irq, void *d)
1143 struct comedi_device *dev = d;
1144 struct pci224_private *devpriv = dev->private;
1145 struct comedi_subdevice *s = &dev->subdevices[0];
1146 struct comedi_cmd *cmd;
1147 unsigned char intstat, valid_intstat;
1148 unsigned char curenab;
1150 unsigned long flags;
1152 intstat = inb(devpriv->iobase1 + PCI224_INT_SCE) & 0x3F;
1155 spin_lock_irqsave(&devpriv->ao_spinlock, flags);
1156 valid_intstat = devpriv->intsce & intstat;
1157 /* Temporarily disable interrupt sources. */
1158 curenab = devpriv->intsce & ~intstat;
1159 outb(curenab, devpriv->iobase1 + PCI224_INT_SCE);
1160 devpriv->intr_running = 1;
1161 devpriv->intr_cpuid = THISCPU;
1162 spin_unlock_irqrestore(&devpriv->ao_spinlock, flags);
1163 if (valid_intstat != 0) {
1164 cmd = &s->async->cmd;
1165 if (valid_intstat & PCI224_INTR_EXT) {
1166 devpriv->intsce &= ~PCI224_INTR_EXT;
1167 if (cmd->start_src == TRIG_EXT)
1168 pci224_ao_start(dev, s);
1169 else if (cmd->stop_src == TRIG_EXT)
1170 pci224_ao_stop(dev, s);
1173 if (valid_intstat & PCI224_INTR_DAC)
1174 pci224_ao_handle_fifo(dev, s);
1177 /* Reenable interrupt sources. */
1178 spin_lock_irqsave(&devpriv->ao_spinlock, flags);
1179 if (curenab != devpriv->intsce) {
1180 outb(devpriv->intsce,
1181 devpriv->iobase1 + PCI224_INT_SCE);
1183 devpriv->intr_running = 0;
1184 spin_unlock_irqrestore(&devpriv->ao_spinlock, flags);
1186 return IRQ_RETVAL(retval);
1190 * This function looks for a board matching the supplied PCI device.
1192 static const struct pci224_board
1193 *pci224_find_pci_board(struct pci_dev *pci_dev)
1197 for (i = 0; i < ARRAY_SIZE(pci224_boards); i++)
1198 if (pci_dev->device == pci224_boards[i].devid)
1199 return &pci224_boards[i];
1204 * This function looks for a PCI device matching the requested board name,
1207 static struct pci_dev *pci224_find_pci_dev(struct comedi_device *dev,
1208 struct comedi_devconfig *it)
1210 const struct pci224_board *thisboard = comedi_board(dev);
1211 struct pci_dev *pci_dev = NULL;
1212 int bus = it->options[0];
1213 int slot = it->options[1];
1215 for_each_pci_dev(pci_dev) {
1217 if (bus != pci_dev->bus->number ||
1218 slot != PCI_SLOT(pci_dev->devfn))
1221 if (pci_dev->vendor != PCI_VENDOR_ID_AMPLICON)
1224 if (thisboard->model == any_model) {
1225 /* Match any supported model. */
1226 const struct pci224_board *board_ptr;
1228 board_ptr = pci224_find_pci_board(pci_dev);
1229 if (board_ptr == NULL)
1231 /* Change board_ptr to matched board. */
1232 dev->board_ptr = board_ptr;
1234 /* Match specific model name. */
1235 if (thisboard->devid != pci_dev->device)
1240 dev_err(dev->class_dev,
1241 "No supported board found! (req. bus %d, slot %d)\n",
1246 static void pci224_report_attach(struct comedi_device *dev, unsigned int irq)
1248 struct pci_dev *pcidev = comedi_to_pci_dev(dev);
1252 snprintf(tmpbuf, sizeof(tmpbuf), "irq %u%s", irq,
1253 (dev->irq ? "" : " UNAVAILABLE"));
1255 snprintf(tmpbuf, sizeof(tmpbuf), "no irq");
1256 dev_info(dev->class_dev, "%s (pci %s) (%s) attached\n",
1257 dev->board_name, pci_name(pcidev), tmpbuf);
1261 * Common part of attach and auto_attach.
1263 static int pci224_attach_common(struct comedi_device *dev,
1264 struct pci_dev *pci_dev, int *options)
1266 const struct pci224_board *thisboard = comedi_board(dev);
1267 struct pci224_private *devpriv = dev->private;
1268 struct comedi_subdevice *s;
1273 comedi_set_hw_dev(dev, &pci_dev->dev);
1275 ret = comedi_pci_enable(dev);
1279 spin_lock_init(&devpriv->ao_spinlock);
1281 devpriv->iobase1 = pci_resource_start(pci_dev, 2);
1282 dev->iobase = pci_resource_start(pci_dev, 3);
1285 /* Allocate readback buffer for AO channels. */
1286 devpriv->ao_readback = kmalloc(sizeof(devpriv->ao_readback[0]) *
1287 thisboard->ao_chans, GFP_KERNEL);
1288 if (!devpriv->ao_readback)
1292 /* Allocate buffer to hold values for AO channel scan. */
1293 devpriv->ao_scan_vals = kmalloc(sizeof(devpriv->ao_scan_vals[0]) *
1294 thisboard->ao_chans, GFP_KERNEL);
1295 if (!devpriv->ao_scan_vals)
1299 /* Allocate buffer to hold AO channel scan order. */
1300 devpriv->ao_scan_order = kmalloc(sizeof(devpriv->ao_scan_order[0]) *
1301 thisboard->ao_chans, GFP_KERNEL);
1302 if (!devpriv->ao_scan_order)
1306 /* Disable interrupt sources. */
1307 devpriv->intsce = 0;
1308 outb(0, devpriv->iobase1 + PCI224_INT_SCE);
1310 /* Initialize the DAC hardware. */
1311 outw(PCI224_DACCON_GLOBALRESET, dev->iobase + PCI224_DACCON);
1312 outw(0, dev->iobase + PCI224_DACCEN);
1313 outw(0, dev->iobase + PCI224_FIFOSIZ);
1314 devpriv->daccon = (PCI224_DACCON_TRIG_SW | PCI224_DACCON_POLAR_BI |
1315 PCI224_DACCON_FIFOENAB |
1316 PCI224_DACCON_FIFOINTR_EMPTY);
1317 outw(devpriv->daccon | PCI224_DACCON_FIFORESET,
1318 dev->iobase + PCI224_DACCON);
1320 ret = comedi_alloc_subdevices(dev, 1);
1324 s = &dev->subdevices[0];
1325 /* Analog output subdevice. */
1326 s->type = COMEDI_SUBD_AO;
1327 s->subdev_flags = SDF_WRITABLE | SDF_GROUND | SDF_CMD_WRITE;
1328 s->n_chan = thisboard->ao_chans;
1329 s->maxdata = (1 << thisboard->ao_bits) - 1;
1330 s->insn_write = &pci224_ao_insn_write;
1331 s->insn_read = &pci224_ao_insn_read;
1332 s->len_chanlist = s->n_chan;
1334 dev->write_subdev = s;
1335 s->do_cmd = &pci224_ao_cmd;
1336 s->do_cmdtest = &pci224_ao_cmdtest;
1337 s->cancel = &pci224_ao_cancel;
1338 s->munge = &pci224_ao_munge;
1340 /* Sort out channel range options. */
1341 if (thisboard->model == pci234_model) {
1342 /* PCI234 range options. */
1343 const struct comedi_lrange **range_table_list;
1345 s->range_table_list = range_table_list =
1346 kmalloc(sizeof(struct comedi_lrange *) * s->n_chan,
1348 if (!s->range_table_list)
1352 for (n = 2; n < 3 + s->n_chan; n++) {
1353 if (options[n] < 0 || options[n] > 1) {
1354 dev_warn(dev->class_dev, DRIVER_NAME
1355 ": warning! bad options[%u]=%d\n",
1360 for (n = 0; n < s->n_chan; n++) {
1361 if (n < COMEDI_NDEVCONFOPTS - 3 && options &&
1362 options[3 + n] == 1) {
1363 if (options[2] == 1)
1364 range_table_list[n] = &range_pci234_ext;
1366 range_table_list[n] = &range_bipolar5;
1369 if (options && options[2] == 1) {
1370 range_table_list[n] =
1373 range_table_list[n] = &range_bipolar10;
1377 devpriv->hwrange = hwrange_pci234;
1379 /* PCI224 range options. */
1380 if (options && options[2] == 1) {
1381 s->range_table = &range_pci224_external;
1382 devpriv->hwrange = hwrange_pci224_external;
1384 if (options && options[2] != 0) {
1385 dev_warn(dev->class_dev, DRIVER_NAME
1386 ": warning! bad options[2]=%d\n",
1389 s->range_table = &range_pci224_internal;
1390 devpriv->hwrange = hwrange_pci224_internal;
1394 dev->board_name = thisboard->name;
1397 ret = request_irq(irq, pci224_interrupt, IRQF_SHARED,
1400 dev_err(dev->class_dev,
1401 "error! unable to allocate irq %u\n", irq);
1408 pci224_report_attach(dev, irq);
1412 static int pci224_attach(struct comedi_device *dev, struct comedi_devconfig *it)
1414 struct pci224_private *devpriv;
1415 struct pci_dev *pci_dev;
1417 dev_info(dev->class_dev, DRIVER_NAME ": attach\n");
1419 devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
1423 pci_dev = pci224_find_pci_dev(dev, it);
1427 return pci224_attach_common(dev, pci_dev, it->options);
1431 pci224_auto_attach(struct comedi_device *dev, unsigned long context_unused)
1433 struct pci_dev *pci_dev = comedi_to_pci_dev(dev);
1434 struct pci224_private *devpriv;
1436 dev_info(dev->class_dev, DRIVER_NAME ": attach pci %s\n",
1439 devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
1443 dev->board_ptr = pci224_find_pci_board(pci_dev);
1444 if (dev->board_ptr == NULL) {
1445 dev_err(dev->class_dev,
1446 DRIVER_NAME ": BUG! cannot determine board type!\n");
1450 * Need to 'get' the PCI device to match the 'put' in pci224_detach().
1451 * TODO: Remove the pci_dev_get() and matching pci_dev_put() once
1452 * support for manual attachment of PCI devices via pci224_attach()
1455 pci_dev_get(pci_dev);
1456 return pci224_attach_common(dev, pci_dev, NULL);
1459 static void pci224_detach(struct comedi_device *dev)
1461 struct pci224_private *devpriv = dev->private;
1462 struct pci_dev *pcidev = comedi_to_pci_dev(dev);
1465 free_irq(dev->irq, dev);
1466 if (dev->subdevices) {
1467 struct comedi_subdevice *s;
1469 s = &dev->subdevices[0];
1471 kfree(s->range_table_list);
1474 kfree(devpriv->ao_readback);
1475 kfree(devpriv->ao_scan_vals);
1476 kfree(devpriv->ao_scan_order);
1478 comedi_pci_disable(dev);
1480 pci_dev_put(pcidev);
1483 static struct comedi_driver amplc_pci224_driver = {
1484 .driver_name = "amplc_pci224",
1485 .module = THIS_MODULE,
1486 .attach = pci224_attach,
1487 .detach = pci224_detach,
1488 .auto_attach = pci224_auto_attach,
1489 .board_name = &pci224_boards[0].name,
1490 .offset = sizeof(struct pci224_board),
1491 .num_names = ARRAY_SIZE(pci224_boards),
1494 static int amplc_pci224_pci_probe(struct pci_dev *dev,
1495 const struct pci_device_id *id)
1497 return comedi_pci_auto_config(dev, &lc_pci224_driver,
1501 static DEFINE_PCI_DEVICE_TABLE(amplc_pci224_pci_table) = {
1502 { PCI_DEVICE(PCI_VENDOR_ID_AMPLICON, PCI_DEVICE_ID_AMPLICON_PCI224) },
1503 { PCI_DEVICE(PCI_VENDOR_ID_AMPLICON, PCI_DEVICE_ID_AMPLICON_PCI234) },
1506 MODULE_DEVICE_TABLE(pci, amplc_pci224_pci_table);
1508 static struct pci_driver amplc_pci224_pci_driver = {
1509 .name = "amplc_pci224",
1510 .id_table = amplc_pci224_pci_table,
1511 .probe = amplc_pci224_pci_probe,
1512 .remove = comedi_pci_auto_unconfig,
1514 module_comedi_pci_driver(amplc_pci224_driver, amplc_pci224_pci_driver);
1516 MODULE_AUTHOR("Comedi http://www.comedi.org");
1517 MODULE_DESCRIPTION("Comedi low-level driver");
1518 MODULE_LICENSE("GPL");