2 comedi/drivers/amplc_pci224.c
3 Driver for Amplicon PCI224 and PCI234 AO boards.
5 Copyright (C) 2005 MEV Ltd. <http://www.mev.co.uk/>
7 COMEDI - Linux Control and Measurement Device Interface
8 Copyright (C) 1998,2000 David A. Schleef <ds@schleef.org>
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 2 of the License, or
13 (at your option) any later version.
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
27 Description: Amplicon PCI224, PCI234
28 Author: Ian Abbott <abbotti@mev.co.uk>
29 Devices: [Amplicon] PCI224 (amplc_pci224 or pci224),
30 PCI234 (amplc_pci224 or pci234)
31 Updated: Wed, 22 Oct 2008 12:25:08 +0100
32 Status: works, but see caveats
37 - ao_do_cmd mode with the following sources:
39 - start_src TRIG_INT TRIG_EXT
40 - scan_begin_src TRIG_TIMER TRIG_EXT
41 - convert_src TRIG_NOW
42 - scan_end_src TRIG_COUNT
43 - stop_src TRIG_COUNT TRIG_EXT TRIG_NONE
45 The channel list must contain at least one channel with no repeated
46 channels. The scan end count must equal the number of channels in
49 There is only one external trigger source so only one of start_src,
50 scan_begin_src or stop_src may use TRIG_EXT.
52 Configuration options - PCI224:
53 [0] - PCI bus of device (optional).
54 [1] - PCI slot of device (optional).
55 If bus/slot is not specified, the first available PCI device
57 [2] - Select available ranges according to jumper LK1. All channels
58 are set to the same range:
59 0=Jumper position 1-2 (factory default), 4 software-selectable
60 internal voltage references, giving 4 bipolar and 4 unipolar
62 [-10V,+10V], [-5V,+5V], [-2.5V,+2.5V], [-1.25V,+1.25V],
63 [0,+10V], [0,+5V], [0,+2.5V], [0,1.25V].
64 1=Jumper position 2-3, 1 external voltage reference, giving
65 1 bipolar and 1 unipolar range:
66 [-Vext,+Vext], [0,+Vext].
68 Configuration options - PCI234:
69 [0] - PCI bus of device (optional).
70 [1] - PCI slot of device (optional).
71 If bus/slot is not specified, the first available PCI device
73 [2] - Select internal or external voltage reference according to
74 jumper LK1. This affects all channels:
75 0=Jumper position 1-2 (factory default), Vref=5V internal.
76 1=Jumper position 2-3, Vref=Vext external.
77 [3] - Select channel 0 range according to jumper LK2:
78 0=Jumper position 2-3 (factory default), range [-2*Vref,+2*Vref]
79 (10V bipolar when options[2]=0).
80 1=Jumper position 1-2, range [-Vref,+Vref]
81 (5V bipolar when options[2]=0).
82 [4] - Select channel 1 range according to jumper LK3: cf. options[3].
83 [5] - Select channel 2 range according to jumper LK4: cf. options[3].
84 [6] - Select channel 3 range according to jumper LK5: cf. options[3].
86 Passing a zero for an option is the same as leaving it unspecified.
90 1) All channels on the PCI224 share the same range. Any change to the
91 range as a result of insn_write or a streaming command will affect
92 the output voltages of all channels, including those not specified
93 by the instruction or command.
95 2) For the analog output command, the first scan may be triggered
96 falsely at the start of acquisition. This occurs when the DAC scan
97 trigger source is switched from 'none' to 'timer' (scan_begin_src =
98 TRIG_TIMER) or 'external' (scan_begin_src == TRIG_EXT) at the start
99 of acquisition and the trigger source is at logic level 1 at the
100 time of the switch. This is very likely for TRIG_TIMER. For
101 TRIG_EXT, it depends on the state of the external line and whether
102 the CR_INVERT flag has been set. The remaining scans are triggered
106 #include <linux/interrupt.h>
107 #include <linux/slab.h>
109 #include "../comedidev.h"
111 #include "comedi_fc.h"
114 #define DRIVER_NAME "amplc_pci224"
119 #define PCI_VENDOR_ID_AMPLICON 0x14dc
120 #define PCI_DEVICE_ID_AMPLICON_PCI224 0x0007
121 #define PCI_DEVICE_ID_AMPLICON_PCI234 0x0008
122 #define PCI_DEVICE_ID_INVALID 0xffff
125 * PCI224/234 i/o space 1 (PCIBAR2) registers.
127 #define PCI224_IO1_SIZE 0x20 /* Size of i/o space 1 (8-bit registers) */
128 #define PCI224_Z2_CT0 0x14 /* 82C54 counter/timer 0 */
129 #define PCI224_Z2_CT1 0x15 /* 82C54 counter/timer 1 */
130 #define PCI224_Z2_CT2 0x16 /* 82C54 counter/timer 2 */
131 #define PCI224_Z2_CTC 0x17 /* 82C54 counter/timer control word */
132 #define PCI224_ZCLK_SCE 0x1A /* Group Z Clock Configuration Register */
133 #define PCI224_ZGAT_SCE 0x1D /* Group Z Gate Configuration Register */
134 #define PCI224_INT_SCE 0x1E /* ISR Interrupt source mask register */
135 /* /Interrupt status */
138 * PCI224/234 i/o space 2 (PCIBAR3) 16-bit registers.
140 #define PCI224_IO2_SIZE 0x10 /* Size of i/o space 2 (16-bit registers). */
141 #define PCI224_DACDATA 0x00 /* (w-o) DAC FIFO data. */
142 #define PCI224_SOFTTRIG 0x00 /* (r-o) DAC software scan trigger. */
143 #define PCI224_DACCON 0x02 /* (r/w) DAC status/configuration. */
144 #define PCI224_FIFOSIZ 0x04 /* (w-o) FIFO size for wraparound mode. */
145 #define PCI224_DACCEN 0x06 /* (w-o) DAC channel enable register. */
150 /* (r/w) Scan trigger. */
151 #define PCI224_DACCON_TRIG_MASK (7 << 0)
152 #define PCI224_DACCON_TRIG_NONE (0 << 0) /* none */
153 #define PCI224_DACCON_TRIG_SW (1 << 0) /* software trig */
154 #define PCI224_DACCON_TRIG_EXTP (2 << 0) /* ext +ve edge */
155 #define PCI224_DACCON_TRIG_EXTN (3 << 0) /* ext -ve edge */
156 #define PCI224_DACCON_TRIG_Z2CT0 (4 << 0) /* Z2 CT0 out */
157 #define PCI224_DACCON_TRIG_Z2CT1 (5 << 0) /* Z2 CT1 out */
158 #define PCI224_DACCON_TRIG_Z2CT2 (6 << 0) /* Z2 CT2 out */
159 /* (r/w) Polarity (PCI224 only, PCI234 always bipolar!). */
160 #define PCI224_DACCON_POLAR_MASK (1 << 3)
161 #define PCI224_DACCON_POLAR_UNI (0 << 3) /* range [0,Vref] */
162 #define PCI224_DACCON_POLAR_BI (1 << 3) /* range [-Vref,Vref] */
163 /* (r/w) Internal Vref (PCI224 only, when LK1 in position 1-2). */
164 #define PCI224_DACCON_VREF_MASK (3 << 4)
165 #define PCI224_DACCON_VREF_1_25 (0 << 4) /* Vref = 1.25V */
166 #define PCI224_DACCON_VREF_2_5 (1 << 4) /* Vref = 2.5V */
167 #define PCI224_DACCON_VREF_5 (2 << 4) /* Vref = 5V */
168 #define PCI224_DACCON_VREF_10 (3 << 4) /* Vref = 10V */
169 /* (r/w) Wraparound mode enable (to play back stored waveform). */
170 #define PCI224_DACCON_FIFOWRAP (1 << 7)
171 /* (r/w) FIFO enable. It MUST be set! */
172 #define PCI224_DACCON_FIFOENAB (1 << 8)
173 /* (r/w) FIFO interrupt trigger level (most values are not very useful). */
174 #define PCI224_DACCON_FIFOINTR_MASK (7 << 9)
175 #define PCI224_DACCON_FIFOINTR_EMPTY (0 << 9) /* when empty */
176 #define PCI224_DACCON_FIFOINTR_NEMPTY (1 << 9) /* when not empty */
177 #define PCI224_DACCON_FIFOINTR_NHALF (2 << 9) /* when not half full */
178 #define PCI224_DACCON_FIFOINTR_HALF (3 << 9) /* when half full */
179 #define PCI224_DACCON_FIFOINTR_NFULL (4 << 9) /* when not full */
180 #define PCI224_DACCON_FIFOINTR_FULL (5 << 9) /* when full */
181 /* (r-o) FIFO fill level. */
182 #define PCI224_DACCON_FIFOFL_MASK (7 << 12)
183 #define PCI224_DACCON_FIFOFL_EMPTY (1 << 12) /* 0 */
184 #define PCI224_DACCON_FIFOFL_ONETOHALF (0 << 12) /* [1,2048] */
185 #define PCI224_DACCON_FIFOFL_HALFTOFULL (4 << 12) /* [2049,4095] */
186 #define PCI224_DACCON_FIFOFL_FULL (6 << 12) /* 4096 */
187 /* (r-o) DAC busy flag. */
188 #define PCI224_DACCON_BUSY (1 << 15)
189 /* (w-o) FIFO reset. */
190 #define PCI224_DACCON_FIFORESET (1 << 12)
191 /* (w-o) Global reset (not sure what it does). */
192 #define PCI224_DACCON_GLOBALRESET (1 << 13)
197 #define PCI224_FIFO_SIZE 4096
200 * DAC FIFO guaranteed minimum room available, depending on reported fill level.
201 * The maximum room available depends on the reported fill level and how much
204 #define PCI224_FIFO_ROOM_EMPTY PCI224_FIFO_SIZE
205 #define PCI224_FIFO_ROOM_ONETOHALF (PCI224_FIFO_SIZE / 2)
206 #define PCI224_FIFO_ROOM_HALFTOFULL 1
207 #define PCI224_FIFO_ROOM_FULL 0
210 * Counter/timer clock input configuration sources.
212 #define CLK_CLK 0 /* reserved (channel-specific clock) */
213 #define CLK_10MHZ 1 /* internal 10 MHz clock */
214 #define CLK_1MHZ 2 /* internal 1 MHz clock */
215 #define CLK_100KHZ 3 /* internal 100 kHz clock */
216 #define CLK_10KHZ 4 /* internal 10 kHz clock */
217 #define CLK_1KHZ 5 /* internal 1 kHz clock */
218 #define CLK_OUTNM1 6 /* output of channel-1 modulo total */
219 #define CLK_EXT 7 /* external clock */
220 /* Macro to construct clock input configuration register value. */
221 #define CLK_CONFIG(chan, src) ((((chan) & 3) << 3) | ((src) & 7))
222 /* Timebases in ns. */
223 #define TIMEBASE_10MHZ 100
224 #define TIMEBASE_1MHZ 1000
225 #define TIMEBASE_100KHZ 10000
226 #define TIMEBASE_10KHZ 100000
227 #define TIMEBASE_1KHZ 1000000
230 * Counter/timer gate input configuration sources.
232 #define GAT_VCC 0 /* VCC (i.e. enabled) */
233 #define GAT_GND 1 /* GND (i.e. disabled) */
234 #define GAT_EXT 2 /* reserved (external gate input) */
235 #define GAT_NOUTNM2 3 /* inverted output of channel-2 modulo total */
236 /* Macro to construct gate input configuration register value. */
237 #define GAT_CONFIG(chan, src) ((((chan) & 3) << 3) | ((src) & 7))
240 * Summary of CLK_OUTNM1 and GAT_NOUTNM2 connections for PCI224 and PCI234:
242 * Channel's Channel's
243 * clock input gate input
244 * Channel CLK_OUTNM1 GAT_NOUTNM2
245 * ------- ---------- -----------
246 * Z2-CT0 Z2-CT2-OUT /Z2-CT1-OUT
247 * Z2-CT1 Z2-CT0-OUT /Z2-CT2-OUT
248 * Z2-CT2 Z2-CT1-OUT /Z2-CT0-OUT
252 * Interrupt enable/status bits
254 #define PCI224_INTR_EXT 0x01 /* rising edge on external input */
255 #define PCI224_INTR_DAC 0x04 /* DAC (FIFO) interrupt */
256 #define PCI224_INTR_Z2CT1 0x20 /* rising edge on Z2-CT1 output */
258 #define PCI224_INTR_EDGE_BITS (PCI224_INTR_EXT | PCI224_INTR_Z2CT1)
259 #define PCI224_INTR_LEVEL_BITS PCI224_INTR_DACFIFO
265 /* Combine old and new bits. */
266 #define COMBINE(old, new, mask) (((old) & ~(mask)) | ((new) & (mask)))
268 /* Current CPU. XXX should this be hard_smp_processor_id()? */
269 #define THISCPU smp_processor_id()
271 /* State bits for use with atomic bit operations. */
272 #define AO_CMD_STARTED 0
278 /* The software selectable internal ranges for PCI224 (option[2] == 0). */
279 static const struct comedi_lrange range_pci224_internal
= {
293 static const unsigned short hwrange_pci224_internal
[8] = {
294 PCI224_DACCON_POLAR_BI
| PCI224_DACCON_VREF_10
,
295 PCI224_DACCON_POLAR_BI
| PCI224_DACCON_VREF_5
,
296 PCI224_DACCON_POLAR_BI
| PCI224_DACCON_VREF_2_5
,
297 PCI224_DACCON_POLAR_BI
| PCI224_DACCON_VREF_1_25
,
298 PCI224_DACCON_POLAR_UNI
| PCI224_DACCON_VREF_10
,
299 PCI224_DACCON_POLAR_UNI
| PCI224_DACCON_VREF_5
,
300 PCI224_DACCON_POLAR_UNI
| PCI224_DACCON_VREF_2_5
,
301 PCI224_DACCON_POLAR_UNI
| PCI224_DACCON_VREF_1_25
,
304 /* The software selectable external ranges for PCI224 (option[2] == 1). */
305 static const struct comedi_lrange range_pci224_external
= {
308 RANGE_ext(-1, 1), /* bipolar [-Vref,+Vref] */
309 RANGE_ext(0, 1), /* unipolar [0,+Vref] */
313 static const unsigned short hwrange_pci224_external
[2] = {
314 PCI224_DACCON_POLAR_BI
,
315 PCI224_DACCON_POLAR_UNI
,
318 /* The hardware selectable Vref*2 external range for PCI234
319 * (option[2] == 1, option[3+n] == 0). */
320 static const struct comedi_lrange range_pci234_ext2
= {
327 /* The hardware selectable Vref external range for PCI234
328 * (option[2] == 1, option[3+n] == 1). */
329 static const struct comedi_lrange range_pci234_ext
= {
336 /* This serves for all the PCI234 ranges. */
337 static const unsigned short hwrange_pci234
[1] = {
338 PCI224_DACCON_POLAR_BI
, /* bipolar - hardware ignores it! */
342 * Board descriptions.
345 enum pci224_model
{ any_model
, pci224_model
, pci234_model
};
347 struct pci224_board
{
349 unsigned short devid
;
350 enum pci224_model model
;
351 unsigned int ao_chans
;
352 unsigned int ao_bits
;
355 static const struct pci224_board pci224_boards
[] = {
358 .devid
= PCI_DEVICE_ID_AMPLICON_PCI224
,
359 .model
= pci224_model
,
365 .devid
= PCI_DEVICE_ID_AMPLICON_PCI234
,
366 .model
= pci234_model
,
372 .devid
= PCI_DEVICE_ID_INVALID
,
373 .model
= any_model
, /* wildcard */
377 /* this structure is for data unique to this hardware driver. If
378 several hardware drivers keep similar information in this structure,
379 feel free to suggest moving the variable to the struct comedi_device struct. */
380 struct pci224_private
{
381 const unsigned short *hwrange
;
382 unsigned long iobase1
;
384 spinlock_t ao_spinlock
;
385 unsigned int *ao_readback
;
387 unsigned char *ao_scan_order
;
390 unsigned short daccon
;
391 unsigned int cached_div1
;
392 unsigned int cached_div2
;
393 unsigned int ao_stop_count
;
394 short ao_stop_continuous
;
395 unsigned short ao_enab
; /* max 16 channels so 'short' will do */
396 unsigned char intsce
;
400 * Called from the 'insn_write' function to perform a single write.
403 pci224_ao_set_data(struct comedi_device
*dev
, int chan
, int range
,
406 const struct pci224_board
*thisboard
= comedi_board(dev
);
407 struct pci224_private
*devpriv
= dev
->private;
408 unsigned short mangled
;
410 /* Store unmangled data for readback. */
411 devpriv
->ao_readback
[chan
] = data
;
412 /* Enable the channel. */
413 outw(1 << chan
, dev
->iobase
+ PCI224_DACCEN
);
414 /* Set range and reset FIFO. */
415 devpriv
->daccon
= COMBINE(devpriv
->daccon
, devpriv
->hwrange
[range
],
416 (PCI224_DACCON_POLAR_MASK
|
417 PCI224_DACCON_VREF_MASK
));
418 outw(devpriv
->daccon
| PCI224_DACCON_FIFORESET
,
419 dev
->iobase
+ PCI224_DACCON
);
421 * Mangle the data. The hardware expects:
422 * - bipolar: 16-bit 2's complement
423 * - unipolar: 16-bit unsigned
425 mangled
= (unsigned short)data
<< (16 - thisboard
->ao_bits
);
426 if ((devpriv
->daccon
& PCI224_DACCON_POLAR_MASK
) ==
427 PCI224_DACCON_POLAR_BI
) {
430 /* Write mangled data to the FIFO. */
431 outw(mangled
, dev
->iobase
+ PCI224_DACDATA
);
432 /* Trigger the conversion. */
433 inw(dev
->iobase
+ PCI224_SOFTTRIG
);
437 * 'insn_write' function for AO subdevice.
440 pci224_ao_insn_write(struct comedi_device
*dev
, struct comedi_subdevice
*s
,
441 struct comedi_insn
*insn
, unsigned int *data
)
446 /* Unpack channel and range. */
447 chan
= CR_CHAN(insn
->chanspec
);
448 range
= CR_RANGE(insn
->chanspec
);
450 /* Writing a list of values to an AO channel is probably not
451 * very useful, but that's how the interface is defined. */
452 for (i
= 0; i
< insn
->n
; i
++)
453 pci224_ao_set_data(dev
, chan
, range
, data
[i
]);
459 * 'insn_read' function for AO subdevice.
461 * N.B. The value read will not be valid if the DAC channel has
462 * never been written successfully since the device was attached
463 * or since the channel has been used by an AO streaming write
467 pci224_ao_insn_read(struct comedi_device
*dev
, struct comedi_subdevice
*s
,
468 struct comedi_insn
*insn
, unsigned int *data
)
470 struct pci224_private
*devpriv
= dev
->private;
474 chan
= CR_CHAN(insn
->chanspec
);
476 for (i
= 0; i
< insn
->n
; i
++)
477 data
[i
] = devpriv
->ao_readback
[chan
];
484 * Just a wrapper for the inline function 'i8253_cascade_ns_to_timer'.
487 pci224_cascade_ns_to_timer(int osc_base
, unsigned int *d1
, unsigned int *d2
,
488 unsigned int *nanosec
, int round_mode
)
490 i8253_cascade_ns_to_timer(osc_base
, d1
, d2
, nanosec
, round_mode
);
494 * Kills a command running on the AO subdevice.
496 static void pci224_ao_stop(struct comedi_device
*dev
,
497 struct comedi_subdevice
*s
)
499 struct pci224_private
*devpriv
= dev
->private;
502 if (!test_and_clear_bit(AO_CMD_STARTED
, &devpriv
->state
))
506 spin_lock_irqsave(&devpriv
->ao_spinlock
, flags
);
507 /* Kill the interrupts. */
509 outb(0, devpriv
->iobase1
+ PCI224_INT_SCE
);
511 * Interrupt routine may or may not be running. We may or may not
512 * have been called from the interrupt routine (directly or
513 * indirectly via a comedi_events() callback routine). It's highly
514 * unlikely that we've been called from some other interrupt routine
515 * but who knows what strange things coders get up to!
517 * If the interrupt routine is currently running, wait for it to
518 * finish, unless we appear to have been called via the interrupt
521 while (devpriv
->intr_running
&& devpriv
->intr_cpuid
!= THISCPU
) {
522 spin_unlock_irqrestore(&devpriv
->ao_spinlock
, flags
);
523 spin_lock_irqsave(&devpriv
->ao_spinlock
, flags
);
525 spin_unlock_irqrestore(&devpriv
->ao_spinlock
, flags
);
526 /* Reconfigure DAC for insn_write usage. */
527 outw(0, dev
->iobase
+ PCI224_DACCEN
); /* Disable channels. */
528 devpriv
->daccon
= COMBINE(devpriv
->daccon
,
529 PCI224_DACCON_TRIG_SW
|
530 PCI224_DACCON_FIFOINTR_EMPTY
,
531 PCI224_DACCON_TRIG_MASK
|
532 PCI224_DACCON_FIFOINTR_MASK
);
533 outw(devpriv
->daccon
| PCI224_DACCON_FIFORESET
,
534 dev
->iobase
+ PCI224_DACCON
);
538 * Handles start of acquisition for the AO subdevice.
540 static void pci224_ao_start(struct comedi_device
*dev
,
541 struct comedi_subdevice
*s
)
543 struct pci224_private
*devpriv
= dev
->private;
544 struct comedi_cmd
*cmd
= &s
->async
->cmd
;
547 set_bit(AO_CMD_STARTED
, &devpriv
->state
);
548 if (!devpriv
->ao_stop_continuous
&& devpriv
->ao_stop_count
== 0) {
549 /* An empty acquisition! */
550 pci224_ao_stop(dev
, s
);
551 s
->async
->events
|= COMEDI_CB_EOA
;
552 comedi_event(dev
, s
);
554 /* Enable interrupts. */
555 spin_lock_irqsave(&devpriv
->ao_spinlock
, flags
);
556 if (cmd
->stop_src
== TRIG_EXT
)
557 devpriv
->intsce
= PCI224_INTR_EXT
| PCI224_INTR_DAC
;
559 devpriv
->intsce
= PCI224_INTR_DAC
;
561 outb(devpriv
->intsce
, devpriv
->iobase1
+ PCI224_INT_SCE
);
562 spin_unlock_irqrestore(&devpriv
->ao_spinlock
, flags
);
567 * Handles interrupts from the DAC FIFO.
569 static void pci224_ao_handle_fifo(struct comedi_device
*dev
,
570 struct comedi_subdevice
*s
)
572 struct pci224_private
*devpriv
= dev
->private;
573 struct comedi_cmd
*cmd
= &s
->async
->cmd
;
574 unsigned int num_scans
;
576 unsigned short dacstat
;
578 unsigned int bytes_per_scan
;
580 if (cmd
->chanlist_len
) {
581 bytes_per_scan
= cmd
->chanlist_len
* sizeof(short);
583 /* Shouldn't get here! */
584 bytes_per_scan
= sizeof(short);
586 /* Determine number of scans available in buffer. */
587 num_scans
= comedi_buf_read_n_available(s
->async
) / bytes_per_scan
;
588 if (!devpriv
->ao_stop_continuous
) {
589 /* Fixed number of scans. */
590 if (num_scans
> devpriv
->ao_stop_count
)
591 num_scans
= devpriv
->ao_stop_count
;
595 /* Determine how much room is in the FIFO (in samples). */
596 dacstat
= inw(dev
->iobase
+ PCI224_DACCON
);
597 switch (dacstat
& PCI224_DACCON_FIFOFL_MASK
) {
598 case PCI224_DACCON_FIFOFL_EMPTY
:
599 room
= PCI224_FIFO_ROOM_EMPTY
;
600 if (!devpriv
->ao_stop_continuous
&& devpriv
->ao_stop_count
== 0) {
601 /* FIFO empty at end of counted acquisition. */
602 pci224_ao_stop(dev
, s
);
603 s
->async
->events
|= COMEDI_CB_EOA
;
604 comedi_event(dev
, s
);
608 case PCI224_DACCON_FIFOFL_ONETOHALF
:
609 room
= PCI224_FIFO_ROOM_ONETOHALF
;
611 case PCI224_DACCON_FIFOFL_HALFTOFULL
:
612 room
= PCI224_FIFO_ROOM_HALFTOFULL
;
615 room
= PCI224_FIFO_ROOM_FULL
;
618 if (room
>= PCI224_FIFO_ROOM_ONETOHALF
) {
619 /* FIFO is less than half-full. */
620 if (num_scans
== 0) {
621 /* Nothing left to put in the FIFO. */
622 pci224_ao_stop(dev
, s
);
623 s
->async
->events
|= COMEDI_CB_OVERFLOW
;
624 dev_err(dev
->class_dev
, "AO buffer underrun\n");
627 /* Determine how many new scans can be put in the FIFO. */
628 if (cmd
->chanlist_len
)
629 room
/= cmd
->chanlist_len
;
631 /* Determine how many scans to process. */
632 if (num_scans
> room
)
636 for (n
= 0; n
< num_scans
; n
++) {
637 cfc_read_array_from_buffer(s
, &devpriv
->ao_scan_vals
[0],
639 for (i
= 0; i
< cmd
->chanlist_len
; i
++) {
640 outw(devpriv
->ao_scan_vals
[devpriv
->ao_scan_order
[i
]],
641 dev
->iobase
+ PCI224_DACDATA
);
644 if (!devpriv
->ao_stop_continuous
) {
645 devpriv
->ao_stop_count
-= num_scans
;
646 if (devpriv
->ao_stop_count
== 0) {
648 * Change FIFO interrupt trigger level to wait
649 * until FIFO is empty.
651 devpriv
->daccon
= COMBINE(devpriv
->daccon
,
652 PCI224_DACCON_FIFOINTR_EMPTY
,
653 PCI224_DACCON_FIFOINTR_MASK
);
654 outw(devpriv
->daccon
, dev
->iobase
+ PCI224_DACCON
);
657 if ((devpriv
->daccon
& PCI224_DACCON_TRIG_MASK
) ==
658 PCI224_DACCON_TRIG_NONE
) {
662 * This is the initial DAC FIFO interrupt at the
663 * start of the acquisition. The DAC's scan trigger
664 * has been set to 'none' up until now.
666 * Now that data has been written to the FIFO, the
667 * DAC's scan trigger source can be set to the
670 * BUG: The first scan will be triggered immediately
671 * if the scan trigger source is at logic level 1.
673 if (cmd
->scan_begin_src
== TRIG_TIMER
) {
674 trig
= PCI224_DACCON_TRIG_Z2CT0
;
676 /* cmd->scan_begin_src == TRIG_EXT */
677 if (cmd
->scan_begin_arg
& CR_INVERT
)
678 trig
= PCI224_DACCON_TRIG_EXTN
;
680 trig
= PCI224_DACCON_TRIG_EXTP
;
683 devpriv
->daccon
= COMBINE(devpriv
->daccon
, trig
,
684 PCI224_DACCON_TRIG_MASK
);
685 outw(devpriv
->daccon
, dev
->iobase
+ PCI224_DACCON
);
687 if (s
->async
->events
)
688 comedi_event(dev
, s
);
693 * Internal trigger function to start acquisition on AO subdevice.
696 pci224_ao_inttrig_start(struct comedi_device
*dev
, struct comedi_subdevice
*s
,
697 unsigned int trignum
)
702 s
->async
->inttrig
= NULL
;
703 pci224_ao_start(dev
, s
);
708 #define MAX_SCAN_PERIOD 0xFFFFFFFFU
709 #define MIN_SCAN_PERIOD 2500
710 #define CONVERT_PERIOD 625
713 * 'do_cmdtest' function for AO subdevice.
716 pci224_ao_cmdtest(struct comedi_device
*dev
, struct comedi_subdevice
*s
,
717 struct comedi_cmd
*cmd
)
719 struct pci224_private
*devpriv
= dev
->private;
723 /* Step 1 : check if triggers are trivially valid */
725 err
|= cfc_check_trigger_src(&cmd
->start_src
, TRIG_INT
| TRIG_EXT
);
726 err
|= cfc_check_trigger_src(&cmd
->scan_begin_src
,
727 TRIG_EXT
| TRIG_TIMER
);
728 err
|= cfc_check_trigger_src(&cmd
->convert_src
, TRIG_NOW
);
729 err
|= cfc_check_trigger_src(&cmd
->scan_end_src
, TRIG_COUNT
);
730 err
|= cfc_check_trigger_src(&cmd
->stop_src
,
731 TRIG_COUNT
| TRIG_EXT
| TRIG_NONE
);
736 /* Step 2a : make sure trigger sources are unique */
738 err
|= cfc_check_trigger_is_unique(cmd
->start_src
);
739 err
|= cfc_check_trigger_is_unique(cmd
->scan_begin_src
);
740 err
|= cfc_check_trigger_is_unique(cmd
->stop_src
);
742 /* Step 2b : and mutually compatible */
745 * There's only one external trigger signal (which makes these
746 * tests easier). Only one thing can use it.
749 if (cmd
->start_src
& TRIG_EXT
)
751 if (cmd
->scan_begin_src
& TRIG_EXT
)
753 if (cmd
->stop_src
& TRIG_EXT
)
761 /* Step 3: make sure arguments are trivially compatible. */
763 switch (cmd
->start_src
) {
765 if (cmd
->start_arg
!= 0) {
771 /* Force to external trigger 0. */
772 if ((cmd
->start_arg
& ~CR_FLAGS_MASK
) != 0) {
773 cmd
->start_arg
= COMBINE(cmd
->start_arg
, 0,
777 /* The only flag allowed is CR_EDGE, which is ignored. */
778 if ((cmd
->start_arg
& CR_FLAGS_MASK
& ~CR_EDGE
) != 0) {
779 cmd
->start_arg
= COMBINE(cmd
->start_arg
, 0,
780 CR_FLAGS_MASK
& ~CR_EDGE
);
786 switch (cmd
->scan_begin_src
) {
788 if (cmd
->scan_begin_arg
> MAX_SCAN_PERIOD
) {
789 cmd
->scan_begin_arg
= MAX_SCAN_PERIOD
;
792 tmp
= cmd
->chanlist_len
* CONVERT_PERIOD
;
793 if (tmp
< MIN_SCAN_PERIOD
)
794 tmp
= MIN_SCAN_PERIOD
;
796 if (cmd
->scan_begin_arg
< tmp
) {
797 cmd
->scan_begin_arg
= tmp
;
802 /* Force to external trigger 0. */
803 if ((cmd
->scan_begin_arg
& ~CR_FLAGS_MASK
) != 0) {
804 cmd
->scan_begin_arg
= COMBINE(cmd
->scan_begin_arg
, 0,
808 /* Only allow flags CR_EDGE and CR_INVERT. Ignore CR_EDGE. */
809 if ((cmd
->scan_begin_arg
& CR_FLAGS_MASK
&
810 ~(CR_EDGE
| CR_INVERT
)) != 0) {
811 cmd
->scan_begin_arg
= COMBINE(cmd
->scan_begin_arg
, 0,
812 CR_FLAGS_MASK
& ~(CR_EDGE
820 /* cmd->convert_src == TRIG_NOW */
821 if (cmd
->convert_arg
!= 0) {
822 cmd
->convert_arg
= 0;
826 /* cmd->scan_end_arg == TRIG_COUNT */
827 if (cmd
->scan_end_arg
!= cmd
->chanlist_len
) {
828 cmd
->scan_end_arg
= cmd
->chanlist_len
;
832 switch (cmd
->stop_src
) {
834 /* Any count allowed. */
837 /* Force to external trigger 0. */
838 if ((cmd
->stop_arg
& ~CR_FLAGS_MASK
) != 0) {
839 cmd
->stop_arg
= COMBINE(cmd
->stop_arg
, 0,
843 /* The only flag allowed is CR_EDGE, which is ignored. */
844 if ((cmd
->stop_arg
& CR_FLAGS_MASK
& ~CR_EDGE
) != 0) {
845 cmd
->stop_arg
= COMBINE(cmd
->stop_arg
, 0,
846 CR_FLAGS_MASK
& ~CR_EDGE
);
850 if (cmd
->stop_arg
!= 0) {
860 /* Step 4: fix up any arguments. */
862 if (cmd
->scan_begin_src
== TRIG_TIMER
) {
863 unsigned int div1
, div2
, round
;
864 int round_mode
= cmd
->flags
& TRIG_ROUND_MASK
;
866 tmp
= cmd
->scan_begin_arg
;
867 /* Check whether to use a single timer. */
868 switch (round_mode
) {
869 case TRIG_ROUND_NEAREST
:
871 round
= TIMEBASE_10MHZ
/ 2;
873 case TRIG_ROUND_DOWN
:
877 round
= TIMEBASE_10MHZ
- 1;
880 /* Be careful to avoid overflow! */
881 div2
= cmd
->scan_begin_arg
/ TIMEBASE_10MHZ
;
882 div2
+= (round
+ cmd
->scan_begin_arg
% TIMEBASE_10MHZ
) /
884 if (div2
<= 0x10000) {
885 /* A single timer will suffice. */
888 cmd
->scan_begin_arg
= div2
* TIMEBASE_10MHZ
;
889 if (cmd
->scan_begin_arg
< div2
||
890 cmd
->scan_begin_arg
< TIMEBASE_10MHZ
) {
892 cmd
->scan_begin_arg
= MAX_SCAN_PERIOD
;
895 /* Use two timers. */
896 div1
= devpriv
->cached_div1
;
897 div2
= devpriv
->cached_div2
;
898 pci224_cascade_ns_to_timer(TIMEBASE_10MHZ
, &div1
, &div2
,
899 &cmd
->scan_begin_arg
,
901 devpriv
->cached_div1
= div1
;
902 devpriv
->cached_div2
= div2
;
904 if (tmp
!= cmd
->scan_begin_arg
)
912 /* Step 5: check channel list. */
914 if (cmd
->chanlist
&& (cmd
->chanlist_len
> 0)) {
916 enum { range_err
= 1, dupchan_err
= 2, };
922 * Check all channels have the same range index. Don't care
923 * about analogue reference, as we can't configure it.
925 * Check the list has no duplicate channels.
927 range
= CR_RANGE(cmd
->chanlist
[0]);
930 for (n
= 0; n
< cmd
->chanlist_len
; n
++) {
931 ch
= CR_CHAN(cmd
->chanlist
[n
]);
932 if (tmp
& (1U << ch
))
933 errors
|= dupchan_err
;
936 if (CR_RANGE(cmd
->chanlist
[n
]) != range
)
941 if (errors
& dupchan_err
) {
942 DPRINTK("comedi%d: " DRIVER_NAME
944 "entries in chanlist must contain no "
945 "duplicate channels\n", dev
->minor
);
947 if (errors
& range_err
) {
948 DPRINTK("comedi%d: " DRIVER_NAME
950 "entries in chanlist must all have "
951 "the same range index\n", dev
->minor
);
964 * 'do_cmd' function for AO subdevice.
966 static int pci224_ao_cmd(struct comedi_device
*dev
, struct comedi_subdevice
*s
)
968 struct pci224_private
*devpriv
= dev
->private;
969 struct comedi_cmd
*cmd
= &s
->async
->cmd
;
976 /* Cannot handle null/empty chanlist. */
977 if (cmd
->chanlist
== NULL
|| cmd
->chanlist_len
== 0)
981 /* Determine which channels are enabled and their load order. */
982 devpriv
->ao_enab
= 0;
984 for (i
= 0; i
< cmd
->chanlist_len
; i
++) {
985 ch
= CR_CHAN(cmd
->chanlist
[i
]);
986 devpriv
->ao_enab
|= 1U << ch
;
988 for (j
= 0; j
< cmd
->chanlist_len
; j
++) {
989 if (CR_CHAN(cmd
->chanlist
[j
]) < ch
)
993 devpriv
->ao_scan_order
[rank
] = i
;
996 /* Set enabled channels. */
997 outw(devpriv
->ao_enab
, dev
->iobase
+ PCI224_DACCEN
);
999 /* Determine range and polarity. All channels the same. */
1000 range
= CR_RANGE(cmd
->chanlist
[0]);
1003 * Set DAC range and polarity.
1004 * Set DAC scan trigger source to 'none'.
1005 * Set DAC FIFO interrupt trigger level to 'not half full'.
1008 * N.B. DAC FIFO interrupts are currently disabled.
1010 devpriv
->daccon
= COMBINE(devpriv
->daccon
,
1012 hwrange
[range
] | PCI224_DACCON_TRIG_NONE
|
1013 PCI224_DACCON_FIFOINTR_NHALF
),
1014 (PCI224_DACCON_POLAR_MASK
|
1015 PCI224_DACCON_VREF_MASK
|
1016 PCI224_DACCON_TRIG_MASK
|
1017 PCI224_DACCON_FIFOINTR_MASK
));
1018 outw(devpriv
->daccon
| PCI224_DACCON_FIFORESET
,
1019 dev
->iobase
+ PCI224_DACCON
);
1021 if (cmd
->scan_begin_src
== TRIG_TIMER
) {
1022 unsigned int div1
, div2
, round
;
1023 unsigned int ns
= cmd
->scan_begin_arg
;
1024 int round_mode
= cmd
->flags
& TRIG_ROUND_MASK
;
1026 /* Check whether to use a single timer. */
1027 switch (round_mode
) {
1028 case TRIG_ROUND_NEAREST
:
1030 round
= TIMEBASE_10MHZ
/ 2;
1032 case TRIG_ROUND_DOWN
:
1036 round
= TIMEBASE_10MHZ
- 1;
1039 /* Be careful to avoid overflow! */
1040 div2
= cmd
->scan_begin_arg
/ TIMEBASE_10MHZ
;
1041 div2
+= (round
+ cmd
->scan_begin_arg
% TIMEBASE_10MHZ
) /
1043 if (div2
<= 0x10000) {
1044 /* A single timer will suffice. */
1048 div1
= 1; /* Flag that single timer to be used. */
1050 /* Use two timers. */
1051 div1
= devpriv
->cached_div1
;
1052 div2
= devpriv
->cached_div2
;
1053 pci224_cascade_ns_to_timer(TIMEBASE_10MHZ
, &div1
, &div2
,
1058 * The output of timer Z2-0 will be used as the scan trigger
1061 /* Make sure Z2-0 is gated on. */
1062 outb(GAT_CONFIG(0, GAT_VCC
),
1063 devpriv
->iobase1
+ PCI224_ZGAT_SCE
);
1065 /* Not cascading. Z2-0 needs 10 MHz clock. */
1066 outb(CLK_CONFIG(0, CLK_10MHZ
),
1067 devpriv
->iobase1
+ PCI224_ZCLK_SCE
);
1069 /* Cascading with Z2-2. */
1070 /* Make sure Z2-2 is gated on. */
1071 outb(GAT_CONFIG(2, GAT_VCC
),
1072 devpriv
->iobase1
+ PCI224_ZGAT_SCE
);
1073 /* Z2-2 needs 10 MHz clock. */
1074 outb(CLK_CONFIG(2, CLK_10MHZ
),
1075 devpriv
->iobase1
+ PCI224_ZCLK_SCE
);
1076 /* Load Z2-2 mode (2) and counter (div1). */
1077 i8254_load(devpriv
->iobase1
+ PCI224_Z2_CT0
, 0,
1079 /* Z2-0 is clocked from Z2-2's output. */
1080 outb(CLK_CONFIG(0, CLK_OUTNM1
),
1081 devpriv
->iobase1
+ PCI224_ZCLK_SCE
);
1083 /* Load Z2-0 mode (2) and counter (div2). */
1084 i8254_load(devpriv
->iobase1
+ PCI224_Z2_CT0
, 0, 0, div2
, 2);
1088 * Sort out end of acquisition.
1090 switch (cmd
->stop_src
) {
1092 /* Fixed number of scans. */
1093 devpriv
->ao_stop_continuous
= 0;
1094 devpriv
->ao_stop_count
= cmd
->stop_arg
;
1097 /* Continuous scans. */
1098 devpriv
->ao_stop_continuous
= 1;
1099 devpriv
->ao_stop_count
= 0;
1104 * Sort out start of acquisition.
1106 switch (cmd
->start_src
) {
1108 spin_lock_irqsave(&devpriv
->ao_spinlock
, flags
);
1109 s
->async
->inttrig
= &pci224_ao_inttrig_start
;
1110 spin_unlock_irqrestore(&devpriv
->ao_spinlock
, flags
);
1113 /* Enable external interrupt trigger to start acquisition. */
1114 spin_lock_irqsave(&devpriv
->ao_spinlock
, flags
);
1115 devpriv
->intsce
|= PCI224_INTR_EXT
;
1116 outb(devpriv
->intsce
, devpriv
->iobase1
+ PCI224_INT_SCE
);
1117 spin_unlock_irqrestore(&devpriv
->ao_spinlock
, flags
);
1125 * 'cancel' function for AO subdevice.
1127 static int pci224_ao_cancel(struct comedi_device
*dev
,
1128 struct comedi_subdevice
*s
)
1130 pci224_ao_stop(dev
, s
);
1135 * 'munge' data for AO command.
1138 pci224_ao_munge(struct comedi_device
*dev
, struct comedi_subdevice
*s
,
1139 void *data
, unsigned int num_bytes
, unsigned int chan_index
)
1141 const struct pci224_board
*thisboard
= comedi_board(dev
);
1142 struct pci224_private
*devpriv
= dev
->private;
1143 struct comedi_async
*async
= s
->async
;
1144 short *array
= data
;
1145 unsigned int length
= num_bytes
/ sizeof(*array
);
1146 unsigned int offset
;
1150 /* The hardware expects 16-bit numbers. */
1151 shift
= 16 - thisboard
->ao_bits
;
1152 /* Channels will be all bipolar or all unipolar. */
1153 if ((devpriv
->hwrange
[CR_RANGE(async
->cmd
.chanlist
[0])] &
1154 PCI224_DACCON_POLAR_MASK
) == PCI224_DACCON_POLAR_UNI
) {
1161 /* Munge the data. */
1162 for (i
= 0; i
< length
; i
++)
1163 array
[i
] = (array
[i
] << shift
) - offset
;
1168 * Interrupt handler.
1170 static irqreturn_t
pci224_interrupt(int irq
, void *d
)
1172 struct comedi_device
*dev
= d
;
1173 struct pci224_private
*devpriv
= dev
->private;
1174 struct comedi_subdevice
*s
= &dev
->subdevices
[0];
1175 struct comedi_cmd
*cmd
;
1176 unsigned char intstat
, valid_intstat
;
1177 unsigned char curenab
;
1179 unsigned long flags
;
1181 intstat
= inb(devpriv
->iobase1
+ PCI224_INT_SCE
) & 0x3F;
1184 spin_lock_irqsave(&devpriv
->ao_spinlock
, flags
);
1185 valid_intstat
= devpriv
->intsce
& intstat
;
1186 /* Temporarily disable interrupt sources. */
1187 curenab
= devpriv
->intsce
& ~intstat
;
1188 outb(curenab
, devpriv
->iobase1
+ PCI224_INT_SCE
);
1189 devpriv
->intr_running
= 1;
1190 devpriv
->intr_cpuid
= THISCPU
;
1191 spin_unlock_irqrestore(&devpriv
->ao_spinlock
, flags
);
1192 if (valid_intstat
!= 0) {
1193 cmd
= &s
->async
->cmd
;
1194 if (valid_intstat
& PCI224_INTR_EXT
) {
1195 devpriv
->intsce
&= ~PCI224_INTR_EXT
;
1196 if (cmd
->start_src
== TRIG_EXT
)
1197 pci224_ao_start(dev
, s
);
1198 else if (cmd
->stop_src
== TRIG_EXT
)
1199 pci224_ao_stop(dev
, s
);
1202 if (valid_intstat
& PCI224_INTR_DAC
)
1203 pci224_ao_handle_fifo(dev
, s
);
1206 /* Reenable interrupt sources. */
1207 spin_lock_irqsave(&devpriv
->ao_spinlock
, flags
);
1208 if (curenab
!= devpriv
->intsce
) {
1209 outb(devpriv
->intsce
,
1210 devpriv
->iobase1
+ PCI224_INT_SCE
);
1212 devpriv
->intr_running
= 0;
1213 spin_unlock_irqrestore(&devpriv
->ao_spinlock
, flags
);
1215 return IRQ_RETVAL(retval
);
1219 * This function looks for a board matching the supplied PCI device.
1221 static const struct pci224_board
1222 *pci224_find_pci_board(struct pci_dev
*pci_dev
)
1226 for (i
= 0; i
< ARRAY_SIZE(pci224_boards
); i
++)
1227 if (pci_dev
->device
== pci224_boards
[i
].devid
)
1228 return &pci224_boards
[i
];
1233 * This function looks for a PCI device matching the requested board name,
1236 static struct pci_dev
*pci224_find_pci_dev(struct comedi_device
*dev
,
1237 struct comedi_devconfig
*it
)
1239 const struct pci224_board
*thisboard
= comedi_board(dev
);
1240 struct pci_dev
*pci_dev
= NULL
;
1241 int bus
= it
->options
[0];
1242 int slot
= it
->options
[1];
1244 for_each_pci_dev(pci_dev
) {
1246 if (bus
!= pci_dev
->bus
->number
||
1247 slot
!= PCI_SLOT(pci_dev
->devfn
))
1250 if (pci_dev
->vendor
!= PCI_VENDOR_ID_AMPLICON
)
1253 if (thisboard
->model
== any_model
) {
1254 /* Match any supported model. */
1255 const struct pci224_board
*board_ptr
;
1257 board_ptr
= pci224_find_pci_board(pci_dev
);
1258 if (board_ptr
== NULL
)
1260 /* Change board_ptr to matched board. */
1261 dev
->board_ptr
= board_ptr
;
1263 /* Match specific model name. */
1264 if (thisboard
->devid
!= pci_dev
->device
)
1269 dev_err(dev
->class_dev
,
1270 "No supported board found! (req. bus %d, slot %d)\n",
1275 static void pci224_report_attach(struct comedi_device
*dev
, unsigned int irq
)
1277 struct pci_dev
*pcidev
= comedi_to_pci_dev(dev
);
1281 snprintf(tmpbuf
, sizeof(tmpbuf
), "irq %u%s", irq
,
1282 (dev
->irq
? "" : " UNAVAILABLE"));
1284 snprintf(tmpbuf
, sizeof(tmpbuf
), "no irq");
1285 dev_info(dev
->class_dev
, "%s (pci %s) (%s) attached\n",
1286 dev
->board_name
, pci_name(pcidev
), tmpbuf
);
1290 * Common part of attach and attach_pci.
1292 static int pci224_attach_common(struct comedi_device
*dev
,
1293 struct pci_dev
*pci_dev
, int *options
)
1295 const struct pci224_board
*thisboard
= comedi_board(dev
);
1296 struct pci224_private
*devpriv
= dev
->private;
1297 struct comedi_subdevice
*s
;
1302 comedi_set_hw_dev(dev
, &pci_dev
->dev
);
1304 ret
= comedi_pci_enable(pci_dev
, DRIVER_NAME
);
1306 dev_err(dev
->class_dev
,
1307 "error! cannot enable PCI device and request regions!\n"
1311 spin_lock_init(&devpriv
->ao_spinlock
);
1313 devpriv
->iobase1
= pci_resource_start(pci_dev
, 2);
1314 dev
->iobase
= pci_resource_start(pci_dev
, 3);
1317 /* Allocate readback buffer for AO channels. */
1318 devpriv
->ao_readback
= kmalloc(sizeof(devpriv
->ao_readback
[0]) *
1319 thisboard
->ao_chans
, GFP_KERNEL
);
1320 if (!devpriv
->ao_readback
)
1324 /* Allocate buffer to hold values for AO channel scan. */
1325 devpriv
->ao_scan_vals
= kmalloc(sizeof(devpriv
->ao_scan_vals
[0]) *
1326 thisboard
->ao_chans
, GFP_KERNEL
);
1327 if (!devpriv
->ao_scan_vals
)
1331 /* Allocate buffer to hold AO channel scan order. */
1332 devpriv
->ao_scan_order
= kmalloc(sizeof(devpriv
->ao_scan_order
[0]) *
1333 thisboard
->ao_chans
, GFP_KERNEL
);
1334 if (!devpriv
->ao_scan_order
)
1338 /* Disable interrupt sources. */
1339 devpriv
->intsce
= 0;
1340 outb(0, devpriv
->iobase1
+ PCI224_INT_SCE
);
1342 /* Initialize the DAC hardware. */
1343 outw(PCI224_DACCON_GLOBALRESET
, dev
->iobase
+ PCI224_DACCON
);
1344 outw(0, dev
->iobase
+ PCI224_DACCEN
);
1345 outw(0, dev
->iobase
+ PCI224_FIFOSIZ
);
1346 devpriv
->daccon
= (PCI224_DACCON_TRIG_SW
| PCI224_DACCON_POLAR_BI
|
1347 PCI224_DACCON_FIFOENAB
|
1348 PCI224_DACCON_FIFOINTR_EMPTY
);
1349 outw(devpriv
->daccon
| PCI224_DACCON_FIFORESET
,
1350 dev
->iobase
+ PCI224_DACCON
);
1352 ret
= comedi_alloc_subdevices(dev
, 1);
1356 s
= &dev
->subdevices
[0];
1357 /* Analog output subdevice. */
1358 s
->type
= COMEDI_SUBD_AO
;
1359 s
->subdev_flags
= SDF_WRITABLE
| SDF_GROUND
| SDF_CMD_WRITE
;
1360 s
->n_chan
= thisboard
->ao_chans
;
1361 s
->maxdata
= (1 << thisboard
->ao_bits
) - 1;
1362 s
->insn_write
= &pci224_ao_insn_write
;
1363 s
->insn_read
= &pci224_ao_insn_read
;
1364 s
->len_chanlist
= s
->n_chan
;
1366 dev
->write_subdev
= s
;
1367 s
->do_cmd
= &pci224_ao_cmd
;
1368 s
->do_cmdtest
= &pci224_ao_cmdtest
;
1369 s
->cancel
= &pci224_ao_cancel
;
1370 s
->munge
= &pci224_ao_munge
;
1372 /* Sort out channel range options. */
1373 if (thisboard
->model
== pci234_model
) {
1374 /* PCI234 range options. */
1375 const struct comedi_lrange
**range_table_list
;
1377 s
->range_table_list
= range_table_list
=
1378 kmalloc(sizeof(struct comedi_lrange
*) * s
->n_chan
,
1380 if (!s
->range_table_list
)
1384 for (n
= 2; n
< 3 + s
->n_chan
; n
++) {
1385 if (options
[n
] < 0 || options
[n
] > 1) {
1386 dev_warn(dev
->class_dev
, DRIVER_NAME
1387 ": warning! bad options[%u]=%d\n",
1392 for (n
= 0; n
< s
->n_chan
; n
++) {
1393 if (n
< COMEDI_NDEVCONFOPTS
- 3 && options
&&
1394 options
[3 + n
] == 1) {
1395 if (options
[2] == 1)
1396 range_table_list
[n
] = &range_pci234_ext
;
1398 range_table_list
[n
] = &range_bipolar5
;
1401 if (options
&& options
[2] == 1) {
1402 range_table_list
[n
] =
1405 range_table_list
[n
] = &range_bipolar10
;
1409 devpriv
->hwrange
= hwrange_pci234
;
1411 /* PCI224 range options. */
1412 if (options
&& options
[2] == 1) {
1413 s
->range_table
= &range_pci224_external
;
1414 devpriv
->hwrange
= hwrange_pci224_external
;
1416 if (options
&& options
[2] != 0) {
1417 dev_warn(dev
->class_dev
, DRIVER_NAME
1418 ": warning! bad options[2]=%d\n",
1421 s
->range_table
= &range_pci224_internal
;
1422 devpriv
->hwrange
= hwrange_pci224_internal
;
1426 dev
->board_name
= thisboard
->name
;
1429 ret
= request_irq(irq
, pci224_interrupt
, IRQF_SHARED
,
1432 dev_err(dev
->class_dev
,
1433 "error! unable to allocate irq %u\n", irq
);
1440 pci224_report_attach(dev
, irq
);
1444 static int pci224_attach(struct comedi_device
*dev
, struct comedi_devconfig
*it
)
1446 struct pci224_private
*devpriv
;
1447 struct pci_dev
*pci_dev
;
1449 dev_info(dev
->class_dev
, DRIVER_NAME
": attach\n");
1451 devpriv
= kzalloc(sizeof(*devpriv
), GFP_KERNEL
);
1454 dev
->private = devpriv
;
1456 pci_dev
= pci224_find_pci_dev(dev
, it
);
1460 return pci224_attach_common(dev
, pci_dev
, it
->options
);
1463 static int __devinit
1464 pci224_attach_pci(struct comedi_device
*dev
, struct pci_dev
*pci_dev
)
1466 struct pci224_private
*devpriv
;
1468 dev_info(dev
->class_dev
, DRIVER_NAME
": attach_pci %s\n",
1471 devpriv
= kzalloc(sizeof(*devpriv
), GFP_KERNEL
);
1474 dev
->private = devpriv
;
1476 dev
->board_ptr
= pci224_find_pci_board(pci_dev
);
1477 if (dev
->board_ptr
== NULL
) {
1478 dev_err(dev
->class_dev
,
1479 DRIVER_NAME
": BUG! cannot determine board type!\n");
1483 * Need to 'get' the PCI device to match the 'put' in pci224_detach().
1484 * TODO: Remove the pci_dev_get() and matching pci_dev_put() once
1485 * support for manual attachment of PCI devices via pci224_attach()
1488 pci_dev_get(pci_dev
);
1489 return pci224_attach_common(dev
, pci_dev
, NULL
);
1492 static void pci224_detach(struct comedi_device
*dev
)
1494 struct pci224_private
*devpriv
= dev
->private;
1495 struct pci_dev
*pcidev
= comedi_to_pci_dev(dev
);
1498 free_irq(dev
->irq
, dev
);
1499 if (dev
->subdevices
) {
1500 struct comedi_subdevice
*s
;
1502 s
= &dev
->subdevices
[0];
1504 kfree(s
->range_table_list
);
1507 kfree(devpriv
->ao_readback
);
1508 kfree(devpriv
->ao_scan_vals
);
1509 kfree(devpriv
->ao_scan_order
);
1513 comedi_pci_disable(pcidev
);
1514 pci_dev_put(pcidev
);
1518 static struct comedi_driver amplc_pci224_driver
= {
1519 .driver_name
= "amplc_pci224",
1520 .module
= THIS_MODULE
,
1521 .attach
= pci224_attach
,
1522 .detach
= pci224_detach
,
1523 .attach_pci
= pci224_attach_pci
,
1524 .board_name
= &pci224_boards
[0].name
,
1525 .offset
= sizeof(struct pci224_board
),
1526 .num_names
= ARRAY_SIZE(pci224_boards
),
1529 static int __devinit
amplc_pci224_pci_probe(struct pci_dev
*dev
,
1530 const struct pci_device_id
1533 return comedi_pci_auto_config(dev
, &lc_pci224_driver
);
1536 static void __devexit
amplc_pci224_pci_remove(struct pci_dev
*dev
)
1538 comedi_pci_auto_unconfig(dev
);
1541 static DEFINE_PCI_DEVICE_TABLE(amplc_pci224_pci_table
) = {
1542 { PCI_DEVICE(PCI_VENDOR_ID_AMPLICON
, PCI_DEVICE_ID_AMPLICON_PCI224
) },
1543 { PCI_DEVICE(PCI_VENDOR_ID_AMPLICON
, PCI_DEVICE_ID_AMPLICON_PCI234
) },
1546 MODULE_DEVICE_TABLE(pci
, amplc_pci224_pci_table
);
1548 static struct pci_driver amplc_pci224_pci_driver
= {
1549 .name
= "amplc_pci224",
1550 .id_table
= amplc_pci224_pci_table
,
1551 .probe
= amplc_pci224_pci_probe
,
1552 .remove
= __devexit_p(amplc_pci224_pci_remove
),
1554 module_comedi_pci_driver(amplc_pci224_driver
, amplc_pci224_pci_driver
);
1556 MODULE_AUTHOR("Comedi http://www.comedi.org");
1557 MODULE_DESCRIPTION("Comedi low-level driver");
1558 MODULE_LICENSE("GPL");