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))
218 /* Timebases in ns. */
219 #define TIMEBASE_10MHZ 100
220 #define TIMEBASE_1MHZ 1000
221 #define TIMEBASE_100KHZ 10000
222 #define TIMEBASE_10KHZ 100000
223 #define TIMEBASE_1KHZ 1000000
226 * Counter/timer gate input configuration sources.
228 #define GAT_VCC 0 /* VCC (i.e. enabled) */
229 #define GAT_GND 1 /* GND (i.e. disabled) */
230 #define GAT_EXT 2 /* reserved (external gate input) */
231 #define GAT_NOUTNM2 3 /* inverted output of channel-2 modulo total */
232 /* Macro to construct gate input configuration register value. */
233 #define GAT_CONFIG(chan, src) ((((chan) & 3) << 3) | ((src) & 7))
236 * Summary of CLK_OUTNM1 and GAT_NOUTNM2 connections for PCI224 and PCI234:
238 * Channel's Channel's
239 * clock input gate input
240 * Channel CLK_OUTNM1 GAT_NOUTNM2
241 * ------- ---------- -----------
242 * Z2-CT0 Z2-CT2-OUT /Z2-CT1-OUT
243 * Z2-CT1 Z2-CT0-OUT /Z2-CT2-OUT
244 * Z2-CT2 Z2-CT1-OUT /Z2-CT0-OUT
248 * Interrupt enable/status bits
250 #define PCI224_INTR_EXT 0x01 /* rising edge on external input */
251 #define PCI224_INTR_DAC 0x04 /* DAC (FIFO) interrupt */
252 #define PCI224_INTR_Z2CT1 0x20 /* rising edge on Z2-CT1 output */
254 #define PCI224_INTR_EDGE_BITS (PCI224_INTR_EXT | PCI224_INTR_Z2CT1)
255 #define PCI224_INTR_LEVEL_BITS PCI224_INTR_DACFIFO
261 /* Combine old and new bits. */
262 #define COMBINE(old, new, mask) (((old) & ~(mask)) | ((new) & (mask)))
264 /* Current CPU. XXX should this be hard_smp_processor_id()? */
265 #define THISCPU smp_processor_id()
267 /* State bits for use with atomic bit operations. */
268 #define AO_CMD_STARTED 0
274 /* The software selectable internal ranges for PCI224 (option[2] == 0). */
275 static const struct comedi_lrange range_pci224_internal = {
289 static const unsigned short hwrange_pci224_internal[8] = {
290 PCI224_DACCON_POLAR_BI | PCI224_DACCON_VREF_10,
291 PCI224_DACCON_POLAR_BI | PCI224_DACCON_VREF_5,
292 PCI224_DACCON_POLAR_BI | PCI224_DACCON_VREF_2_5,
293 PCI224_DACCON_POLAR_BI | PCI224_DACCON_VREF_1_25,
294 PCI224_DACCON_POLAR_UNI | PCI224_DACCON_VREF_10,
295 PCI224_DACCON_POLAR_UNI | PCI224_DACCON_VREF_5,
296 PCI224_DACCON_POLAR_UNI | PCI224_DACCON_VREF_2_5,
297 PCI224_DACCON_POLAR_UNI | PCI224_DACCON_VREF_1_25,
300 /* The software selectable external ranges for PCI224 (option[2] == 1). */
301 static const struct comedi_lrange range_pci224_external = {
304 RANGE_ext(-1, 1), /* bipolar [-Vref,+Vref] */
305 RANGE_ext(0, 1), /* unipolar [0,+Vref] */
309 static const unsigned short hwrange_pci224_external[2] = {
310 PCI224_DACCON_POLAR_BI,
311 PCI224_DACCON_POLAR_UNI,
314 /* The hardware selectable Vref*2 external range for PCI234
315 * (option[2] == 1, option[3+n] == 0). */
316 static const struct comedi_lrange range_pci234_ext2 = {
323 /* The hardware selectable Vref external range for PCI234
324 * (option[2] == 1, option[3+n] == 1). */
325 static const struct comedi_lrange range_pci234_ext = {
332 /* This serves for all the PCI234 ranges. */
333 static const unsigned short hwrange_pci234[1] = {
334 PCI224_DACCON_POLAR_BI, /* bipolar - hardware ignores it! */
338 * Board descriptions.
341 enum pci224_model { any_model, pci224_model, pci234_model };
343 struct pci224_board {
345 unsigned short devid;
346 enum pci224_model model;
347 unsigned int ao_chans;
348 unsigned int ao_bits;
351 static const struct pci224_board pci224_boards[] = {
354 .devid = PCI_DEVICE_ID_AMPLICON_PCI224,
355 .model = pci224_model,
361 .devid = PCI_DEVICE_ID_AMPLICON_PCI234,
362 .model = pci234_model,
368 .devid = PCI_DEVICE_ID_INVALID,
369 .model = any_model, /* wildcard */
373 /* this structure is for data unique to this hardware driver. If
374 several hardware drivers keep similar information in this structure,
375 feel free to suggest moving the variable to the struct comedi_device struct. */
376 struct pci224_private {
377 const unsigned short *hwrange;
378 unsigned long iobase1;
380 spinlock_t ao_spinlock;
381 unsigned int *ao_readback;
383 unsigned char *ao_scan_order;
386 unsigned short daccon;
387 unsigned int cached_div1;
388 unsigned int cached_div2;
389 unsigned int ao_stop_count;
390 short ao_stop_continuous;
391 unsigned short ao_enab; /* max 16 channels so 'short' will do */
392 unsigned char intsce;
396 * Called from the 'insn_write' function to perform a single write.
399 pci224_ao_set_data(struct comedi_device *dev, int chan, int range,
402 const struct pci224_board *thisboard = comedi_board(dev);
403 struct pci224_private *devpriv = dev->private;
404 unsigned short mangled;
406 /* Store unmangled data for readback. */
407 devpriv->ao_readback[chan] = data;
408 /* Enable the channel. */
409 outw(1 << chan, dev->iobase + PCI224_DACCEN);
410 /* Set range and reset FIFO. */
411 devpriv->daccon = COMBINE(devpriv->daccon, devpriv->hwrange[range],
412 (PCI224_DACCON_POLAR_MASK |
413 PCI224_DACCON_VREF_MASK));
414 outw(devpriv->daccon | PCI224_DACCON_FIFORESET,
415 dev->iobase + PCI224_DACCON);
417 * Mangle the data. The hardware expects:
418 * - bipolar: 16-bit 2's complement
419 * - unipolar: 16-bit unsigned
421 mangled = (unsigned short)data << (16 - thisboard->ao_bits);
422 if ((devpriv->daccon & PCI224_DACCON_POLAR_MASK) ==
423 PCI224_DACCON_POLAR_BI) {
426 /* Write mangled data to the FIFO. */
427 outw(mangled, dev->iobase + PCI224_DACDATA);
428 /* Trigger the conversion. */
429 inw(dev->iobase + PCI224_SOFTTRIG);
433 * 'insn_write' function for AO subdevice.
436 pci224_ao_insn_write(struct comedi_device *dev, struct comedi_subdevice *s,
437 struct comedi_insn *insn, unsigned int *data)
442 /* Unpack channel and range. */
443 chan = CR_CHAN(insn->chanspec);
444 range = CR_RANGE(insn->chanspec);
446 /* Writing a list of values to an AO channel is probably not
447 * very useful, but that's how the interface is defined. */
448 for (i = 0; i < insn->n; i++)
449 pci224_ao_set_data(dev, chan, range, data[i]);
455 * 'insn_read' function for AO subdevice.
457 * N.B. The value read will not be valid if the DAC channel has
458 * never been written successfully since the device was attached
459 * or since the channel has been used by an AO streaming write
463 pci224_ao_insn_read(struct comedi_device *dev, struct comedi_subdevice *s,
464 struct comedi_insn *insn, unsigned int *data)
466 struct pci224_private *devpriv = dev->private;
470 chan = CR_CHAN(insn->chanspec);
472 for (i = 0; i < insn->n; i++)
473 data[i] = devpriv->ao_readback[chan];
480 * Just a wrapper for the inline function 'i8253_cascade_ns_to_timer'.
483 pci224_cascade_ns_to_timer(int osc_base, unsigned int *d1, unsigned int *d2,
484 unsigned int *nanosec, int round_mode)
486 i8253_cascade_ns_to_timer(osc_base, d1, d2, nanosec, round_mode);
490 * Kills a command running on the AO subdevice.
492 static void pci224_ao_stop(struct comedi_device *dev,
493 struct comedi_subdevice *s)
495 struct pci224_private *devpriv = dev->private;
498 if (!test_and_clear_bit(AO_CMD_STARTED, &devpriv->state))
502 spin_lock_irqsave(&devpriv->ao_spinlock, flags);
503 /* Kill the interrupts. */
505 outb(0, devpriv->iobase1 + PCI224_INT_SCE);
507 * Interrupt routine may or may not be running. We may or may not
508 * have been called from the interrupt routine (directly or
509 * indirectly via a comedi_events() callback routine). It's highly
510 * unlikely that we've been called from some other interrupt routine
511 * but who knows what strange things coders get up to!
513 * If the interrupt routine is currently running, wait for it to
514 * finish, unless we appear to have been called via the interrupt
517 while (devpriv->intr_running && devpriv->intr_cpuid != THISCPU) {
518 spin_unlock_irqrestore(&devpriv->ao_spinlock, flags);
519 spin_lock_irqsave(&devpriv->ao_spinlock, flags);
521 spin_unlock_irqrestore(&devpriv->ao_spinlock, flags);
522 /* Reconfigure DAC for insn_write usage. */
523 outw(0, dev->iobase + PCI224_DACCEN); /* Disable channels. */
524 devpriv->daccon = COMBINE(devpriv->daccon,
525 PCI224_DACCON_TRIG_SW |
526 PCI224_DACCON_FIFOINTR_EMPTY,
527 PCI224_DACCON_TRIG_MASK |
528 PCI224_DACCON_FIFOINTR_MASK);
529 outw(devpriv->daccon | PCI224_DACCON_FIFORESET,
530 dev->iobase + PCI224_DACCON);
534 * Handles start of acquisition for the AO subdevice.
536 static void pci224_ao_start(struct comedi_device *dev,
537 struct comedi_subdevice *s)
539 struct pci224_private *devpriv = dev->private;
540 struct comedi_cmd *cmd = &s->async->cmd;
543 set_bit(AO_CMD_STARTED, &devpriv->state);
544 if (!devpriv->ao_stop_continuous && devpriv->ao_stop_count == 0) {
545 /* An empty acquisition! */
546 pci224_ao_stop(dev, s);
547 s->async->events |= COMEDI_CB_EOA;
548 comedi_event(dev, s);
550 /* Enable interrupts. */
551 spin_lock_irqsave(&devpriv->ao_spinlock, flags);
552 if (cmd->stop_src == TRIG_EXT)
553 devpriv->intsce = PCI224_INTR_EXT | PCI224_INTR_DAC;
555 devpriv->intsce = PCI224_INTR_DAC;
557 outb(devpriv->intsce, devpriv->iobase1 + PCI224_INT_SCE);
558 spin_unlock_irqrestore(&devpriv->ao_spinlock, flags);
563 * Handles interrupts from the DAC FIFO.
565 static void pci224_ao_handle_fifo(struct comedi_device *dev,
566 struct comedi_subdevice *s)
568 struct pci224_private *devpriv = dev->private;
569 struct comedi_cmd *cmd = &s->async->cmd;
570 unsigned int num_scans;
572 unsigned short dacstat;
574 unsigned int bytes_per_scan;
576 if (cmd->chanlist_len) {
577 bytes_per_scan = cmd->chanlist_len * sizeof(short);
579 /* Shouldn't get here! */
580 bytes_per_scan = sizeof(short);
582 /* Determine number of scans available in buffer. */
583 num_scans = comedi_buf_read_n_available(s->async) / bytes_per_scan;
584 if (!devpriv->ao_stop_continuous) {
585 /* Fixed number of scans. */
586 if (num_scans > devpriv->ao_stop_count)
587 num_scans = devpriv->ao_stop_count;
591 /* Determine how much room is in the FIFO (in samples). */
592 dacstat = inw(dev->iobase + PCI224_DACCON);
593 switch (dacstat & PCI224_DACCON_FIFOFL_MASK) {
594 case PCI224_DACCON_FIFOFL_EMPTY:
595 room = PCI224_FIFO_ROOM_EMPTY;
596 if (!devpriv->ao_stop_continuous && devpriv->ao_stop_count == 0) {
597 /* FIFO empty at end of counted acquisition. */
598 pci224_ao_stop(dev, s);
599 s->async->events |= COMEDI_CB_EOA;
600 comedi_event(dev, s);
604 case PCI224_DACCON_FIFOFL_ONETOHALF:
605 room = PCI224_FIFO_ROOM_ONETOHALF;
607 case PCI224_DACCON_FIFOFL_HALFTOFULL:
608 room = PCI224_FIFO_ROOM_HALFTOFULL;
611 room = PCI224_FIFO_ROOM_FULL;
614 if (room >= PCI224_FIFO_ROOM_ONETOHALF) {
615 /* FIFO is less than half-full. */
616 if (num_scans == 0) {
617 /* Nothing left to put in the FIFO. */
618 pci224_ao_stop(dev, s);
619 s->async->events |= COMEDI_CB_OVERFLOW;
620 dev_err(dev->class_dev, "AO buffer underrun\n");
623 /* Determine how many new scans can be put in the FIFO. */
624 if (cmd->chanlist_len)
625 room /= cmd->chanlist_len;
627 /* Determine how many scans to process. */
628 if (num_scans > room)
632 for (n = 0; n < num_scans; n++) {
633 cfc_read_array_from_buffer(s, &devpriv->ao_scan_vals[0],
635 for (i = 0; i < cmd->chanlist_len; i++) {
636 outw(devpriv->ao_scan_vals[devpriv->ao_scan_order[i]],
637 dev->iobase + PCI224_DACDATA);
640 if (!devpriv->ao_stop_continuous) {
641 devpriv->ao_stop_count -= num_scans;
642 if (devpriv->ao_stop_count == 0) {
644 * Change FIFO interrupt trigger level to wait
645 * until FIFO is empty.
647 devpriv->daccon = COMBINE(devpriv->daccon,
648 PCI224_DACCON_FIFOINTR_EMPTY,
649 PCI224_DACCON_FIFOINTR_MASK);
650 outw(devpriv->daccon, dev->iobase + PCI224_DACCON);
653 if ((devpriv->daccon & PCI224_DACCON_TRIG_MASK) ==
654 PCI224_DACCON_TRIG_NONE) {
658 * This is the initial DAC FIFO interrupt at the
659 * start of the acquisition. The DAC's scan trigger
660 * has been set to 'none' up until now.
662 * Now that data has been written to the FIFO, the
663 * DAC's scan trigger source can be set to the
666 * BUG: The first scan will be triggered immediately
667 * if the scan trigger source is at logic level 1.
669 if (cmd->scan_begin_src == TRIG_TIMER) {
670 trig = PCI224_DACCON_TRIG_Z2CT0;
672 /* cmd->scan_begin_src == TRIG_EXT */
673 if (cmd->scan_begin_arg & CR_INVERT)
674 trig = PCI224_DACCON_TRIG_EXTN;
676 trig = PCI224_DACCON_TRIG_EXTP;
679 devpriv->daccon = COMBINE(devpriv->daccon, trig,
680 PCI224_DACCON_TRIG_MASK);
681 outw(devpriv->daccon, dev->iobase + PCI224_DACCON);
683 if (s->async->events)
684 comedi_event(dev, s);
689 * Internal trigger function to start acquisition on AO subdevice.
692 pci224_ao_inttrig_start(struct comedi_device *dev, struct comedi_subdevice *s,
693 unsigned int trignum)
698 s->async->inttrig = NULL;
699 pci224_ao_start(dev, s);
704 #define MAX_SCAN_PERIOD 0xFFFFFFFFU
705 #define MIN_SCAN_PERIOD 2500
706 #define CONVERT_PERIOD 625
709 * 'do_cmdtest' function for AO subdevice.
712 pci224_ao_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
713 struct comedi_cmd *cmd)
715 struct pci224_private *devpriv = dev->private;
719 /* Step 1 : check if triggers are trivially valid */
721 err |= cfc_check_trigger_src(&cmd->start_src, TRIG_INT | TRIG_EXT);
722 err |= cfc_check_trigger_src(&cmd->scan_begin_src,
723 TRIG_EXT | TRIG_TIMER);
724 err |= cfc_check_trigger_src(&cmd->convert_src, TRIG_NOW);
725 err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
726 err |= cfc_check_trigger_src(&cmd->stop_src,
727 TRIG_COUNT | TRIG_EXT | TRIG_NONE);
732 /* Step 2a : make sure trigger sources are unique */
734 err |= cfc_check_trigger_is_unique(cmd->start_src);
735 err |= cfc_check_trigger_is_unique(cmd->scan_begin_src);
736 err |= cfc_check_trigger_is_unique(cmd->stop_src);
738 /* Step 2b : and mutually compatible */
741 * There's only one external trigger signal (which makes these
742 * tests easier). Only one thing can use it.
745 if (cmd->start_src & TRIG_EXT)
747 if (cmd->scan_begin_src & TRIG_EXT)
749 if (cmd->stop_src & TRIG_EXT)
757 /* Step 3: check if arguments are trivially valid */
759 switch (cmd->start_src) {
761 err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0);
764 /* Force to external trigger 0. */
765 if ((cmd->start_arg & ~CR_FLAGS_MASK) != 0) {
766 cmd->start_arg = COMBINE(cmd->start_arg, 0,
770 /* The only flag allowed is CR_EDGE, which is ignored. */
771 if ((cmd->start_arg & CR_FLAGS_MASK & ~CR_EDGE) != 0) {
772 cmd->start_arg = COMBINE(cmd->start_arg, 0,
773 CR_FLAGS_MASK & ~CR_EDGE);
779 switch (cmd->scan_begin_src) {
781 err |= cfc_check_trigger_arg_max(&cmd->scan_begin_arg,
784 tmp = cmd->chanlist_len * CONVERT_PERIOD;
785 if (tmp < MIN_SCAN_PERIOD)
786 tmp = MIN_SCAN_PERIOD;
787 err |= cfc_check_trigger_arg_min(&cmd->scan_begin_arg, tmp);
790 /* Force to external trigger 0. */
791 if ((cmd->scan_begin_arg & ~CR_FLAGS_MASK) != 0) {
792 cmd->scan_begin_arg = COMBINE(cmd->scan_begin_arg, 0,
796 /* Only allow flags CR_EDGE and CR_INVERT. Ignore CR_EDGE. */
797 if ((cmd->scan_begin_arg & CR_FLAGS_MASK &
798 ~(CR_EDGE | CR_INVERT)) != 0) {
799 cmd->scan_begin_arg = COMBINE(cmd->scan_begin_arg, 0,
801 ~(CR_EDGE | CR_INVERT));
807 err |= cfc_check_trigger_arg_is(&cmd->convert_arg, 0);
808 err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len);
810 switch (cmd->stop_src) {
812 /* Any count allowed. */
815 /* Force to external trigger 0. */
816 if ((cmd->stop_arg & ~CR_FLAGS_MASK) != 0) {
817 cmd->stop_arg = COMBINE(cmd->stop_arg, 0,
821 /* The only flag allowed is CR_EDGE, which is ignored. */
822 if ((cmd->stop_arg & CR_FLAGS_MASK & ~CR_EDGE) != 0) {
823 cmd->stop_arg = COMBINE(cmd->stop_arg, 0,
824 CR_FLAGS_MASK & ~CR_EDGE);
828 err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0);
835 /* Step 4: fix up any arguments. */
837 if (cmd->scan_begin_src == TRIG_TIMER) {
838 unsigned int div1, div2, round;
839 int round_mode = cmd->flags & TRIG_ROUND_MASK;
841 tmp = cmd->scan_begin_arg;
842 /* Check whether to use a single timer. */
843 switch (round_mode) {
844 case TRIG_ROUND_NEAREST:
846 round = TIMEBASE_10MHZ / 2;
848 case TRIG_ROUND_DOWN:
852 round = TIMEBASE_10MHZ - 1;
855 /* Be careful to avoid overflow! */
856 div2 = cmd->scan_begin_arg / TIMEBASE_10MHZ;
857 div2 += (round + cmd->scan_begin_arg % TIMEBASE_10MHZ) /
859 if (div2 <= 0x10000) {
860 /* A single timer will suffice. */
863 cmd->scan_begin_arg = div2 * TIMEBASE_10MHZ;
864 if (cmd->scan_begin_arg < div2 ||
865 cmd->scan_begin_arg < TIMEBASE_10MHZ) {
867 cmd->scan_begin_arg = MAX_SCAN_PERIOD;
870 /* Use two timers. */
871 div1 = devpriv->cached_div1;
872 div2 = devpriv->cached_div2;
873 pci224_cascade_ns_to_timer(TIMEBASE_10MHZ, &div1, &div2,
874 &cmd->scan_begin_arg,
876 devpriv->cached_div1 = div1;
877 devpriv->cached_div2 = div2;
879 if (tmp != cmd->scan_begin_arg)
887 /* Step 5: check channel list. */
889 if (cmd->chanlist && (cmd->chanlist_len > 0)) {
891 enum { range_err = 1, dupchan_err = 2, };
897 * Check all channels have the same range index. Don't care
898 * about analogue reference, as we can't configure it.
900 * Check the list has no duplicate channels.
902 range = CR_RANGE(cmd->chanlist[0]);
905 for (n = 0; n < cmd->chanlist_len; n++) {
906 ch = CR_CHAN(cmd->chanlist[n]);
907 if (tmp & (1U << ch))
908 errors |= dupchan_err;
911 if (CR_RANGE(cmd->chanlist[n]) != range)
916 if (errors & dupchan_err) {
917 DPRINTK("comedi%d: " DRIVER_NAME
919 "entries in chanlist must contain no "
920 "duplicate channels\n", dev->minor);
922 if (errors & range_err) {
923 DPRINTK("comedi%d: " DRIVER_NAME
925 "entries in chanlist must all have "
926 "the same range index\n", dev->minor);
939 * 'do_cmd' function for AO subdevice.
941 static int pci224_ao_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
943 struct pci224_private *devpriv = dev->private;
944 struct comedi_cmd *cmd = &s->async->cmd;
951 /* Cannot handle null/empty chanlist. */
952 if (cmd->chanlist == NULL || cmd->chanlist_len == 0)
956 /* Determine which channels are enabled and their load order. */
957 devpriv->ao_enab = 0;
959 for (i = 0; i < cmd->chanlist_len; i++) {
960 ch = CR_CHAN(cmd->chanlist[i]);
961 devpriv->ao_enab |= 1U << ch;
963 for (j = 0; j < cmd->chanlist_len; j++) {
964 if (CR_CHAN(cmd->chanlist[j]) < ch)
968 devpriv->ao_scan_order[rank] = i;
971 /* Set enabled channels. */
972 outw(devpriv->ao_enab, dev->iobase + PCI224_DACCEN);
974 /* Determine range and polarity. All channels the same. */
975 range = CR_RANGE(cmd->chanlist[0]);
978 * Set DAC range and polarity.
979 * Set DAC scan trigger source to 'none'.
980 * Set DAC FIFO interrupt trigger level to 'not half full'.
983 * N.B. DAC FIFO interrupts are currently disabled.
985 devpriv->daccon = COMBINE(devpriv->daccon,
987 hwrange[range] | PCI224_DACCON_TRIG_NONE |
988 PCI224_DACCON_FIFOINTR_NHALF),
989 (PCI224_DACCON_POLAR_MASK |
990 PCI224_DACCON_VREF_MASK |
991 PCI224_DACCON_TRIG_MASK |
992 PCI224_DACCON_FIFOINTR_MASK));
993 outw(devpriv->daccon | PCI224_DACCON_FIFORESET,
994 dev->iobase + PCI224_DACCON);
996 if (cmd->scan_begin_src == TRIG_TIMER) {
997 unsigned int div1, div2, round;
998 unsigned int ns = cmd->scan_begin_arg;
999 int round_mode = cmd->flags & TRIG_ROUND_MASK;
1001 /* Check whether to use a single timer. */
1002 switch (round_mode) {
1003 case TRIG_ROUND_NEAREST:
1005 round = TIMEBASE_10MHZ / 2;
1007 case TRIG_ROUND_DOWN:
1011 round = TIMEBASE_10MHZ - 1;
1014 /* Be careful to avoid overflow! */
1015 div2 = cmd->scan_begin_arg / TIMEBASE_10MHZ;
1016 div2 += (round + cmd->scan_begin_arg % TIMEBASE_10MHZ) /
1018 if (div2 <= 0x10000) {
1019 /* A single timer will suffice. */
1023 div1 = 1; /* Flag that single timer to be used. */
1025 /* Use two timers. */
1026 div1 = devpriv->cached_div1;
1027 div2 = devpriv->cached_div2;
1028 pci224_cascade_ns_to_timer(TIMEBASE_10MHZ, &div1, &div2,
1033 * The output of timer Z2-0 will be used as the scan trigger
1036 /* Make sure Z2-0 is gated on. */
1037 outb(GAT_CONFIG(0, GAT_VCC),
1038 devpriv->iobase1 + PCI224_ZGAT_SCE);
1040 /* Not cascading. Z2-0 needs 10 MHz clock. */
1041 outb(CLK_CONFIG(0, CLK_10MHZ),
1042 devpriv->iobase1 + PCI224_ZCLK_SCE);
1044 /* Cascading with Z2-2. */
1045 /* Make sure Z2-2 is gated on. */
1046 outb(GAT_CONFIG(2, GAT_VCC),
1047 devpriv->iobase1 + PCI224_ZGAT_SCE);
1048 /* Z2-2 needs 10 MHz clock. */
1049 outb(CLK_CONFIG(2, CLK_10MHZ),
1050 devpriv->iobase1 + PCI224_ZCLK_SCE);
1051 /* Load Z2-2 mode (2) and counter (div1). */
1052 i8254_load(devpriv->iobase1 + PCI224_Z2_CT0, 0,
1054 /* Z2-0 is clocked from Z2-2's output. */
1055 outb(CLK_CONFIG(0, CLK_OUTNM1),
1056 devpriv->iobase1 + PCI224_ZCLK_SCE);
1058 /* Load Z2-0 mode (2) and counter (div2). */
1059 i8254_load(devpriv->iobase1 + PCI224_Z2_CT0, 0, 0, div2, 2);
1063 * Sort out end of acquisition.
1065 switch (cmd->stop_src) {
1067 /* Fixed number of scans. */
1068 devpriv->ao_stop_continuous = 0;
1069 devpriv->ao_stop_count = cmd->stop_arg;
1072 /* Continuous scans. */
1073 devpriv->ao_stop_continuous = 1;
1074 devpriv->ao_stop_count = 0;
1079 * Sort out start of acquisition.
1081 switch (cmd->start_src) {
1083 spin_lock_irqsave(&devpriv->ao_spinlock, flags);
1084 s->async->inttrig = &pci224_ao_inttrig_start;
1085 spin_unlock_irqrestore(&devpriv->ao_spinlock, flags);
1088 /* Enable external interrupt trigger to start acquisition. */
1089 spin_lock_irqsave(&devpriv->ao_spinlock, flags);
1090 devpriv->intsce |= PCI224_INTR_EXT;
1091 outb(devpriv->intsce, devpriv->iobase1 + PCI224_INT_SCE);
1092 spin_unlock_irqrestore(&devpriv->ao_spinlock, flags);
1100 * 'cancel' function for AO subdevice.
1102 static int pci224_ao_cancel(struct comedi_device *dev,
1103 struct comedi_subdevice *s)
1105 pci224_ao_stop(dev, s);
1110 * 'munge' data for AO command.
1113 pci224_ao_munge(struct comedi_device *dev, struct comedi_subdevice *s,
1114 void *data, unsigned int num_bytes, unsigned int chan_index)
1116 const struct pci224_board *thisboard = comedi_board(dev);
1117 struct pci224_private *devpriv = dev->private;
1118 struct comedi_async *async = s->async;
1119 short *array = data;
1120 unsigned int length = num_bytes / sizeof(*array);
1121 unsigned int offset;
1125 /* The hardware expects 16-bit numbers. */
1126 shift = 16 - thisboard->ao_bits;
1127 /* Channels will be all bipolar or all unipolar. */
1128 if ((devpriv->hwrange[CR_RANGE(async->cmd.chanlist[0])] &
1129 PCI224_DACCON_POLAR_MASK) == PCI224_DACCON_POLAR_UNI) {
1136 /* Munge the data. */
1137 for (i = 0; i < length; i++)
1138 array[i] = (array[i] << shift) - offset;
1143 * Interrupt handler.
1145 static irqreturn_t pci224_interrupt(int irq, void *d)
1147 struct comedi_device *dev = d;
1148 struct pci224_private *devpriv = dev->private;
1149 struct comedi_subdevice *s = &dev->subdevices[0];
1150 struct comedi_cmd *cmd;
1151 unsigned char intstat, valid_intstat;
1152 unsigned char curenab;
1154 unsigned long flags;
1156 intstat = inb(devpriv->iobase1 + PCI224_INT_SCE) & 0x3F;
1159 spin_lock_irqsave(&devpriv->ao_spinlock, flags);
1160 valid_intstat = devpriv->intsce & intstat;
1161 /* Temporarily disable interrupt sources. */
1162 curenab = devpriv->intsce & ~intstat;
1163 outb(curenab, devpriv->iobase1 + PCI224_INT_SCE);
1164 devpriv->intr_running = 1;
1165 devpriv->intr_cpuid = THISCPU;
1166 spin_unlock_irqrestore(&devpriv->ao_spinlock, flags);
1167 if (valid_intstat != 0) {
1168 cmd = &s->async->cmd;
1169 if (valid_intstat & PCI224_INTR_EXT) {
1170 devpriv->intsce &= ~PCI224_INTR_EXT;
1171 if (cmd->start_src == TRIG_EXT)
1172 pci224_ao_start(dev, s);
1173 else if (cmd->stop_src == TRIG_EXT)
1174 pci224_ao_stop(dev, s);
1177 if (valid_intstat & PCI224_INTR_DAC)
1178 pci224_ao_handle_fifo(dev, s);
1181 /* Reenable interrupt sources. */
1182 spin_lock_irqsave(&devpriv->ao_spinlock, flags);
1183 if (curenab != devpriv->intsce) {
1184 outb(devpriv->intsce,
1185 devpriv->iobase1 + PCI224_INT_SCE);
1187 devpriv->intr_running = 0;
1188 spin_unlock_irqrestore(&devpriv->ao_spinlock, flags);
1190 return IRQ_RETVAL(retval);
1194 * This function looks for a board matching the supplied PCI device.
1196 static const struct pci224_board
1197 *pci224_find_pci_board(struct pci_dev *pci_dev)
1201 for (i = 0; i < ARRAY_SIZE(pci224_boards); i++)
1202 if (pci_dev->device == pci224_boards[i].devid)
1203 return &pci224_boards[i];
1208 * This function looks for a PCI device matching the requested board name,
1211 static struct pci_dev *pci224_find_pci_dev(struct comedi_device *dev,
1212 struct comedi_devconfig *it)
1214 const struct pci224_board *thisboard = comedi_board(dev);
1215 struct pci_dev *pci_dev = NULL;
1216 int bus = it->options[0];
1217 int slot = it->options[1];
1219 for_each_pci_dev(pci_dev) {
1221 if (bus != pci_dev->bus->number ||
1222 slot != PCI_SLOT(pci_dev->devfn))
1225 if (pci_dev->vendor != PCI_VENDOR_ID_AMPLICON)
1228 if (thisboard->model == any_model) {
1229 /* Match any supported model. */
1230 const struct pci224_board *board_ptr;
1232 board_ptr = pci224_find_pci_board(pci_dev);
1233 if (board_ptr == NULL)
1235 /* Change board_ptr to matched board. */
1236 dev->board_ptr = board_ptr;
1238 /* Match specific model name. */
1239 if (thisboard->devid != pci_dev->device)
1244 dev_err(dev->class_dev,
1245 "No supported board found! (req. bus %d, slot %d)\n",
1250 static void pci224_report_attach(struct comedi_device *dev, unsigned int irq)
1252 struct pci_dev *pcidev = comedi_to_pci_dev(dev);
1256 snprintf(tmpbuf, sizeof(tmpbuf), "irq %u%s", irq,
1257 (dev->irq ? "" : " UNAVAILABLE"));
1259 snprintf(tmpbuf, sizeof(tmpbuf), "no irq");
1260 dev_info(dev->class_dev, "%s (pci %s) (%s) attached\n",
1261 dev->board_name, pci_name(pcidev), tmpbuf);
1265 * Common part of attach and auto_attach.
1267 static int pci224_attach_common(struct comedi_device *dev,
1268 struct pci_dev *pci_dev, int *options)
1270 const struct pci224_board *thisboard = comedi_board(dev);
1271 struct pci224_private *devpriv = dev->private;
1272 struct comedi_subdevice *s;
1277 comedi_set_hw_dev(dev, &pci_dev->dev);
1279 ret = comedi_pci_enable(dev);
1283 spin_lock_init(&devpriv->ao_spinlock);
1285 devpriv->iobase1 = pci_resource_start(pci_dev, 2);
1286 dev->iobase = pci_resource_start(pci_dev, 3);
1289 /* Allocate readback buffer for AO channels. */
1290 devpriv->ao_readback = kmalloc(sizeof(devpriv->ao_readback[0]) *
1291 thisboard->ao_chans, GFP_KERNEL);
1292 if (!devpriv->ao_readback)
1296 /* Allocate buffer to hold values for AO channel scan. */
1297 devpriv->ao_scan_vals = kmalloc(sizeof(devpriv->ao_scan_vals[0]) *
1298 thisboard->ao_chans, GFP_KERNEL);
1299 if (!devpriv->ao_scan_vals)
1303 /* Allocate buffer to hold AO channel scan order. */
1304 devpriv->ao_scan_order = kmalloc(sizeof(devpriv->ao_scan_order[0]) *
1305 thisboard->ao_chans, GFP_KERNEL);
1306 if (!devpriv->ao_scan_order)
1310 /* Disable interrupt sources. */
1311 devpriv->intsce = 0;
1312 outb(0, devpriv->iobase1 + PCI224_INT_SCE);
1314 /* Initialize the DAC hardware. */
1315 outw(PCI224_DACCON_GLOBALRESET, dev->iobase + PCI224_DACCON);
1316 outw(0, dev->iobase + PCI224_DACCEN);
1317 outw(0, dev->iobase + PCI224_FIFOSIZ);
1318 devpriv->daccon = (PCI224_DACCON_TRIG_SW | PCI224_DACCON_POLAR_BI |
1319 PCI224_DACCON_FIFOENAB |
1320 PCI224_DACCON_FIFOINTR_EMPTY);
1321 outw(devpriv->daccon | PCI224_DACCON_FIFORESET,
1322 dev->iobase + PCI224_DACCON);
1324 ret = comedi_alloc_subdevices(dev, 1);
1328 s = &dev->subdevices[0];
1329 /* Analog output subdevice. */
1330 s->type = COMEDI_SUBD_AO;
1331 s->subdev_flags = SDF_WRITABLE | SDF_GROUND | SDF_CMD_WRITE;
1332 s->n_chan = thisboard->ao_chans;
1333 s->maxdata = (1 << thisboard->ao_bits) - 1;
1334 s->insn_write = &pci224_ao_insn_write;
1335 s->insn_read = &pci224_ao_insn_read;
1336 s->len_chanlist = s->n_chan;
1338 dev->write_subdev = s;
1339 s->do_cmd = &pci224_ao_cmd;
1340 s->do_cmdtest = &pci224_ao_cmdtest;
1341 s->cancel = &pci224_ao_cancel;
1342 s->munge = &pci224_ao_munge;
1344 /* Sort out channel range options. */
1345 if (thisboard->model == pci234_model) {
1346 /* PCI234 range options. */
1347 const struct comedi_lrange **range_table_list;
1349 s->range_table_list = range_table_list =
1350 kmalloc(sizeof(struct comedi_lrange *) * s->n_chan,
1352 if (!s->range_table_list)
1356 for (n = 2; n < 3 + s->n_chan; n++) {
1357 if (options[n] < 0 || options[n] > 1) {
1358 dev_warn(dev->class_dev, DRIVER_NAME
1359 ": warning! bad options[%u]=%d\n",
1364 for (n = 0; n < s->n_chan; n++) {
1365 if (n < COMEDI_NDEVCONFOPTS - 3 && options &&
1366 options[3 + n] == 1) {
1367 if (options[2] == 1)
1368 range_table_list[n] = &range_pci234_ext;
1370 range_table_list[n] = &range_bipolar5;
1373 if (options && options[2] == 1) {
1374 range_table_list[n] =
1377 range_table_list[n] = &range_bipolar10;
1381 devpriv->hwrange = hwrange_pci234;
1383 /* PCI224 range options. */
1384 if (options && options[2] == 1) {
1385 s->range_table = &range_pci224_external;
1386 devpriv->hwrange = hwrange_pci224_external;
1388 if (options && options[2] != 0) {
1389 dev_warn(dev->class_dev, DRIVER_NAME
1390 ": warning! bad options[2]=%d\n",
1393 s->range_table = &range_pci224_internal;
1394 devpriv->hwrange = hwrange_pci224_internal;
1398 dev->board_name = thisboard->name;
1401 ret = request_irq(irq, pci224_interrupt, IRQF_SHARED,
1404 dev_err(dev->class_dev,
1405 "error! unable to allocate irq %u\n", irq);
1412 pci224_report_attach(dev, irq);
1416 static int pci224_attach(struct comedi_device *dev, struct comedi_devconfig *it)
1418 struct pci224_private *devpriv;
1419 struct pci_dev *pci_dev;
1421 dev_info(dev->class_dev, DRIVER_NAME ": attach\n");
1423 devpriv = comedi_alloc_devpriv(dev, sizeof(*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 = comedi_alloc_devpriv(dev, sizeof(*devpriv));
1447 dev->board_ptr = pci224_find_pci_board(pci_dev);
1448 if (dev->board_ptr == NULL) {
1449 dev_err(dev->class_dev,
1450 DRIVER_NAME ": BUG! cannot determine board type!\n");
1454 * Need to 'get' the PCI device to match the 'put' in pci224_detach().
1455 * TODO: Remove the pci_dev_get() and matching pci_dev_put() once
1456 * support for manual attachment of PCI devices via pci224_attach()
1459 pci_dev_get(pci_dev);
1460 return pci224_attach_common(dev, pci_dev, NULL);
1463 static void pci224_detach(struct comedi_device *dev)
1465 struct pci224_private *devpriv = dev->private;
1466 struct pci_dev *pcidev = comedi_to_pci_dev(dev);
1469 free_irq(dev->irq, dev);
1470 if (dev->subdevices) {
1471 struct comedi_subdevice *s;
1473 s = &dev->subdevices[0];
1475 kfree(s->range_table_list);
1478 kfree(devpriv->ao_readback);
1479 kfree(devpriv->ao_scan_vals);
1480 kfree(devpriv->ao_scan_order);
1482 comedi_pci_disable(dev);
1484 pci_dev_put(pcidev);
1487 static struct comedi_driver amplc_pci224_driver = {
1488 .driver_name = "amplc_pci224",
1489 .module = THIS_MODULE,
1490 .attach = pci224_attach,
1491 .detach = pci224_detach,
1492 .auto_attach = pci224_auto_attach,
1493 .board_name = &pci224_boards[0].name,
1494 .offset = sizeof(struct pci224_board),
1495 .num_names = ARRAY_SIZE(pci224_boards),
1498 static int amplc_pci224_pci_probe(struct pci_dev *dev,
1499 const struct pci_device_id *id)
1501 return comedi_pci_auto_config(dev, &lc_pci224_driver,
1505 static DEFINE_PCI_DEVICE_TABLE(amplc_pci224_pci_table) = {
1506 { PCI_DEVICE(PCI_VENDOR_ID_AMPLICON, PCI_DEVICE_ID_AMPLICON_PCI224) },
1507 { PCI_DEVICE(PCI_VENDOR_ID_AMPLICON, PCI_DEVICE_ID_AMPLICON_PCI234) },
1510 MODULE_DEVICE_TABLE(pci, amplc_pci224_pci_table);
1512 static struct pci_driver amplc_pci224_pci_driver = {
1513 .name = "amplc_pci224",
1514 .id_table = amplc_pci224_pci_table,
1515 .probe = amplc_pci224_pci_probe,
1516 .remove = comedi_pci_auto_unconfig,
1518 module_comedi_pci_driver(amplc_pci224_driver, amplc_pci224_pci_driver);
1520 MODULE_AUTHOR("Comedi http://www.comedi.org");
1521 MODULE_DESCRIPTION("Comedi low-level driver");
1522 MODULE_LICENSE("GPL");