Staging: comedi: remove comedi-specific wrappers
[linux-2.6/linux-acpi-2.6/ibm-acpi-2.6.git] / drivers / staging / comedi / drivers / amplc_pci224.c
blobd1a64e80cddb77ec16fc76ab8b490015cd9e4679
1 /*
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.
26 Driver: amplc_pci224
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
34 Supports:
36 - ao_insn read/write
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
47 the channel list.
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
56 will be used.
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
61 ranges:
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
72 will be used.
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.
88 Caveats:
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
103 correctly.
106 #include <linux/interrupt.h>
108 #include "../comedidev.h"
110 #include "comedi_pci.h"
112 #include "comedi_fc.h"
113 #include "8253.h"
115 #define DRIVER_NAME "amplc_pci224"
118 * PCI IDs.
120 /* #define PCI_VENDOR_ID_AMPLICON 0x14dc */
121 #define PCI_DEVICE_ID_AMPLICON_PCI224 0x0007
122 #define PCI_DEVICE_ID_AMPLICON_PCI234 0x0008
123 #define PCI_DEVICE_ID_INVALID 0xffff
126 * PCI224/234 i/o space 1 (PCIBAR2) registers.
128 #define PCI224_IO1_SIZE 0x20 /* Size of i/o space 1 (8-bit registers) */
129 #define PCI224_Z2_CT0 0x14 /* 82C54 counter/timer 0 */
130 #define PCI224_Z2_CT1 0x15 /* 82C54 counter/timer 1 */
131 #define PCI224_Z2_CT2 0x16 /* 82C54 counter/timer 2 */
132 #define PCI224_Z2_CTC 0x17 /* 82C54 counter/timer control word */
133 #define PCI224_ZCLK_SCE 0x1A /* Group Z Clock Configuration Register */
134 #define PCI224_ZGAT_SCE 0x1D /* Group Z Gate Configuration Register */
135 #define PCI224_INT_SCE 0x1E /* ISR Interrupt source mask register */
136 /* /Interrupt status */
139 * PCI224/234 i/o space 2 (PCIBAR3) 16-bit registers.
141 #define PCI224_IO2_SIZE 0x10 /* Size of i/o space 2 (16-bit registers). */
142 #define PCI224_DACDATA 0x00 /* (w-o) DAC FIFO data. */
143 #define PCI224_SOFTTRIG 0x00 /* (r-o) DAC software scan trigger. */
144 #define PCI224_DACCON 0x02 /* (r/w) DAC status/configuration. */
145 #define PCI224_FIFOSIZ 0x04 /* (w-o) FIFO size for wraparound mode. */
146 #define PCI224_DACCEN 0x06 /* (w-o) DAC channel enable register. */
149 * DACCON values.
151 /* (r/w) Scan trigger. */
152 #define PCI224_DACCON_TRIG_MASK (7 << 0)
153 #define PCI224_DACCON_TRIG_NONE (0 << 0) /* none */
154 #define PCI224_DACCON_TRIG_SW (1 << 0) /* software trig */
155 #define PCI224_DACCON_TRIG_EXTP (2 << 0) /* ext +ve edge */
156 #define PCI224_DACCON_TRIG_EXTN (3 << 0) /* ext -ve edge */
157 #define PCI224_DACCON_TRIG_Z2CT0 (4 << 0) /* Z2 CT0 out */
158 #define PCI224_DACCON_TRIG_Z2CT1 (5 << 0) /* Z2 CT1 out */
159 #define PCI224_DACCON_TRIG_Z2CT2 (6 << 0) /* Z2 CT2 out */
160 /* (r/w) Polarity (PCI224 only, PCI234 always bipolar!). */
161 #define PCI224_DACCON_POLAR_MASK (1 << 3)
162 #define PCI224_DACCON_POLAR_UNI (0 << 3) /* range [0,Vref] */
163 #define PCI224_DACCON_POLAR_BI (1 << 3) /* range [-Vref,Vref] */
164 /* (r/w) Internal Vref (PCI224 only, when LK1 in position 1-2). */
165 #define PCI224_DACCON_VREF_MASK (3 << 4)
166 #define PCI224_DACCON_VREF_1_25 (0 << 4) /* Vref = 1.25V */
167 #define PCI224_DACCON_VREF_2_5 (1 << 4) /* Vref = 2.5V */
168 #define PCI224_DACCON_VREF_5 (2 << 4) /* Vref = 5V */
169 #define PCI224_DACCON_VREF_10 (3 << 4) /* Vref = 10V */
170 /* (r/w) Wraparound mode enable (to play back stored waveform). */
171 #define PCI224_DACCON_FIFOWRAP (1 << 7)
172 /* (r/w) FIFO enable. It MUST be set! */
173 #define PCI224_DACCON_FIFOENAB (1 << 8)
174 /* (r/w) FIFO interrupt trigger level (most values are not very useful). */
175 #define PCI224_DACCON_FIFOINTR_MASK (7 << 9)
176 #define PCI224_DACCON_FIFOINTR_EMPTY (0 << 9) /* when empty */
177 #define PCI224_DACCON_FIFOINTR_NEMPTY (1 << 9) /* when not empty */
178 #define PCI224_DACCON_FIFOINTR_NHALF (2 << 9) /* when not half full */
179 #define PCI224_DACCON_FIFOINTR_HALF (3 << 9) /* when half full */
180 #define PCI224_DACCON_FIFOINTR_NFULL (4 << 9) /* when not full */
181 #define PCI224_DACCON_FIFOINTR_FULL (5 << 9) /* when full */
182 /* (r-o) FIFO fill level. */
183 #define PCI224_DACCON_FIFOFL_MASK (7 << 12)
184 #define PCI224_DACCON_FIFOFL_EMPTY (1 << 12) /* 0 */
185 #define PCI224_DACCON_FIFOFL_ONETOHALF (0 << 12) /* [1,2048] */
186 #define PCI224_DACCON_FIFOFL_HALFTOFULL (4 << 12) /* [2049,4095] */
187 #define PCI224_DACCON_FIFOFL_FULL (6 << 12) /* 4096 */
188 /* (r-o) DAC busy flag. */
189 #define PCI224_DACCON_BUSY (1 << 15)
190 /* (w-o) FIFO reset. */
191 #define PCI224_DACCON_FIFORESET (1 << 12)
192 /* (w-o) Global reset (not sure what it does). */
193 #define PCI224_DACCON_GLOBALRESET (1 << 13)
196 * DAC FIFO size.
198 #define PCI224_FIFO_SIZE 4096
201 * DAC FIFO guaranteed minimum room available, depending on reported fill level.
202 * The maximum room available depends on the reported fill level and how much
203 * has been written!
205 #define PCI224_FIFO_ROOM_EMPTY PCI224_FIFO_SIZE
206 #define PCI224_FIFO_ROOM_ONETOHALF (PCI224_FIFO_SIZE / 2)
207 #define PCI224_FIFO_ROOM_HALFTOFULL 1
208 #define PCI224_FIFO_ROOM_FULL 0
211 * Counter/timer clock input configuration sources.
213 #define CLK_CLK 0 /* reserved (channel-specific clock) */
214 #define CLK_10MHZ 1 /* internal 10 MHz clock */
215 #define CLK_1MHZ 2 /* internal 1 MHz clock */
216 #define CLK_100KHZ 3 /* internal 100 kHz clock */
217 #define CLK_10KHZ 4 /* internal 10 kHz clock */
218 #define CLK_1KHZ 5 /* internal 1 kHz clock */
219 #define CLK_OUTNM1 6 /* output of channel-1 modulo total */
220 #define CLK_EXT 7 /* external clock */
221 /* Macro to construct clock input configuration register value. */
222 #define CLK_CONFIG(chan, src) ((((chan) & 3) << 3) | ((src) & 7))
223 /* Timebases in ns. */
224 #define TIMEBASE_10MHZ 100
225 #define TIMEBASE_1MHZ 1000
226 #define TIMEBASE_100KHZ 10000
227 #define TIMEBASE_10KHZ 100000
228 #define TIMEBASE_1KHZ 1000000
231 * Counter/timer gate input configuration sources.
233 #define GAT_VCC 0 /* VCC (i.e. enabled) */
234 #define GAT_GND 1 /* GND (i.e. disabled) */
235 #define GAT_EXT 2 /* reserved (external gate input) */
236 #define GAT_NOUTNM2 3 /* inverted output of channel-2 modulo total */
237 /* Macro to construct gate input configuration register value. */
238 #define GAT_CONFIG(chan, src) ((((chan) & 3) << 3) | ((src) & 7))
241 * Summary of CLK_OUTNM1 and GAT_NOUTNM2 connections for PCI224 and PCI234:
243 * Channel's Channel's
244 * clock input gate input
245 * Channel CLK_OUTNM1 GAT_NOUTNM2
246 * ------- ---------- -----------
247 * Z2-CT0 Z2-CT2-OUT /Z2-CT1-OUT
248 * Z2-CT1 Z2-CT0-OUT /Z2-CT2-OUT
249 * Z2-CT2 Z2-CT1-OUT /Z2-CT0-OUT
253 * Interrupt enable/status bits
255 #define PCI224_INTR_EXT 0x01 /* rising edge on external input */
256 #define PCI224_INTR_DAC 0x04 /* DAC (FIFO) interrupt */
257 #define PCI224_INTR_Z2CT1 0x20 /* rising edge on Z2-CT1 output */
259 #define PCI224_INTR_EDGE_BITS (PCI224_INTR_EXT | PCI224_INTR_Z2CT1)
260 #define PCI224_INTR_LEVEL_BITS PCI224_INTR_DACFIFO
263 * Handy macros.
266 /* Combine old and new bits. */
267 #define COMBINE(old, new, mask) (((old) & ~(mask)) | ((new) & (mask)))
269 /* A generic null function pointer value. */
270 #define NULLFUNC 0
272 /* Current CPU. XXX should this be hard_smp_processor_id()? */
273 #define THISCPU smp_processor_id()
275 /* State bits for use with atomic bit operations. */
276 #define AO_CMD_STARTED 0
279 * Range tables.
282 /* The software selectable internal ranges for PCI224 (option[2] == 0). */
283 static const struct comedi_lrange range_pci224_internal = {
286 BIP_RANGE(10),
287 BIP_RANGE(5),
288 BIP_RANGE(2.5),
289 BIP_RANGE(1.25),
290 UNI_RANGE(10),
291 UNI_RANGE(5),
292 UNI_RANGE(2.5),
293 UNI_RANGE(1.25),
297 static const unsigned short hwrange_pci224_internal[8] = {
298 PCI224_DACCON_POLAR_BI | PCI224_DACCON_VREF_10,
299 PCI224_DACCON_POLAR_BI | PCI224_DACCON_VREF_5,
300 PCI224_DACCON_POLAR_BI | PCI224_DACCON_VREF_2_5,
301 PCI224_DACCON_POLAR_BI | PCI224_DACCON_VREF_1_25,
302 PCI224_DACCON_POLAR_UNI | PCI224_DACCON_VREF_10,
303 PCI224_DACCON_POLAR_UNI | PCI224_DACCON_VREF_5,
304 PCI224_DACCON_POLAR_UNI | PCI224_DACCON_VREF_2_5,
305 PCI224_DACCON_POLAR_UNI | PCI224_DACCON_VREF_1_25,
308 /* The software selectable external ranges for PCI224 (option[2] == 1). */
309 static const struct comedi_lrange range_pci224_external = {
312 RANGE_ext(-1, 1), /* bipolar [-Vref,+Vref] */
313 RANGE_ext(0, 1), /* unipolar [0,+Vref] */
317 static const unsigned short hwrange_pci224_external[2] = {
318 PCI224_DACCON_POLAR_BI,
319 PCI224_DACCON_POLAR_UNI,
322 /* The hardware selectable Vref*2 external range for PCI234
323 * (option[2] == 1, option[3+n] == 0). */
324 static const struct comedi_lrange range_pci234_ext2 = {
327 RANGE_ext(-2, 2),
331 /* The hardware selectable Vref external range for PCI234
332 * (option[2] == 1, option[3+n] == 1). */
333 static const struct comedi_lrange range_pci234_ext = {
336 RANGE_ext(-1, 1),
340 /* This serves for all the PCI234 ranges. */
341 static const unsigned short hwrange_pci234[1] = {
342 PCI224_DACCON_POLAR_BI, /* bipolar - hardware ignores it! */
346 * Board descriptions.
349 enum pci224_model { any_model, pci224_model, pci234_model };
351 struct pci224_board {
352 const char *name;
353 unsigned short devid;
354 enum pci224_model model;
355 unsigned int ao_chans;
356 unsigned int ao_bits;
359 static const struct pci224_board pci224_boards[] = {
361 .name = "pci224",
362 .devid = PCI_DEVICE_ID_AMPLICON_PCI224,
363 .model = pci224_model,
364 .ao_chans = 16,
365 .ao_bits = 12,
368 .name = "pci234",
369 .devid = PCI_DEVICE_ID_AMPLICON_PCI234,
370 .model = pci234_model,
371 .ao_chans = 4,
372 .ao_bits = 16,
375 .name = DRIVER_NAME,
376 .devid = PCI_DEVICE_ID_INVALID,
377 .model = any_model, /* wildcard */
382 * PCI driver table.
385 static DEFINE_PCI_DEVICE_TABLE(pci224_pci_table) = {
386 {PCI_VENDOR_ID_AMPLICON, PCI_DEVICE_ID_AMPLICON_PCI224,
387 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
388 {PCI_VENDOR_ID_AMPLICON, PCI_DEVICE_ID_AMPLICON_PCI234,
389 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
393 MODULE_DEVICE_TABLE(pci, pci224_pci_table);
396 * Useful for shorthand access to the particular board structure
398 #define thisboard ((struct pci224_board *)dev->board_ptr)
400 /* this structure is for data unique to this hardware driver. If
401 several hardware drivers keep similar information in this structure,
402 feel free to suggest moving the variable to the struct comedi_device struct. */
403 struct pci224_private {
404 struct pci_dev *pci_dev; /* PCI device */
405 const unsigned short *hwrange;
406 unsigned long iobase1;
407 unsigned long state;
408 spinlock_t ao_spinlock;
409 unsigned int *ao_readback;
410 short *ao_scan_vals;
411 unsigned char *ao_scan_order;
412 int intr_cpuid;
413 short intr_running;
414 unsigned short daccon;
415 unsigned int cached_div1;
416 unsigned int cached_div2;
417 unsigned int ao_stop_count;
418 short ao_stop_continuous;
419 unsigned short ao_enab; /* max 16 channels so 'short' will do */
420 unsigned char intsce;
423 #define devpriv ((struct pci224_private *)dev->private)
426 * The struct comedi_driver structure tells the Comedi core module
427 * which functions to call to configure/deconfigure (attach/detach)
428 * the board, and also about the kernel module that contains
429 * the device code.
431 static int pci224_attach(struct comedi_device *dev, struct comedi_devconfig *it);
432 static int pci224_detach(struct comedi_device *dev);
433 static struct comedi_driver driver_amplc_pci224 = {
434 .driver_name = DRIVER_NAME,
435 .module = THIS_MODULE,
436 .attach = pci224_attach,
437 .detach = pci224_detach,
438 .board_name = &pci224_boards[0].name,
439 .offset = sizeof(struct pci224_board),
440 .num_names = ARRAY_SIZE(pci224_boards),
443 COMEDI_PCI_INITCLEANUP(driver_amplc_pci224, pci224_pci_table);
446 * Called from the 'insn_write' function to perform a single write.
448 static void
449 pci224_ao_set_data(struct comedi_device *dev, int chan, int range, unsigned int data)
451 unsigned short mangled;
453 /* Store unmangled data for readback. */
454 devpriv->ao_readback[chan] = data;
455 /* Enable the channel. */
456 outw(1 << chan, dev->iobase + PCI224_DACCEN);
457 /* Set range and reset FIFO. */
458 devpriv->daccon = COMBINE(devpriv->daccon, devpriv->hwrange[range],
459 (PCI224_DACCON_POLAR_MASK | PCI224_DACCON_VREF_MASK));
460 outw(devpriv->daccon | PCI224_DACCON_FIFORESET,
461 dev->iobase + PCI224_DACCON);
463 * Mangle the data. The hardware expects:
464 * - bipolar: 16-bit 2's complement
465 * - unipolar: 16-bit unsigned
467 mangled = (unsigned short)data << (16 - thisboard->ao_bits);
468 if ((devpriv->daccon & PCI224_DACCON_POLAR_MASK) ==
469 PCI224_DACCON_POLAR_BI) {
470 mangled ^= 0x8000;
472 /* Write mangled data to the FIFO. */
473 outw(mangled, dev->iobase + PCI224_DACDATA);
474 /* Trigger the conversion. */
475 inw(dev->iobase + PCI224_SOFTTRIG);
479 * 'insn_write' function for AO subdevice.
481 static int
482 pci224_ao_insn_write(struct comedi_device *dev, struct comedi_subdevice *s,
483 struct comedi_insn *insn, unsigned int *data)
485 int i;
486 int chan, range;
488 /* Unpack channel and range. */
489 chan = CR_CHAN(insn->chanspec);
490 range = CR_RANGE(insn->chanspec);
492 /* Writing a list of values to an AO channel is probably not
493 * very useful, but that's how the interface is defined. */
494 for (i = 0; i < insn->n; i++) {
495 pci224_ao_set_data(dev, chan, range, data[i]);
497 return i;
501 * 'insn_read' function for AO subdevice.
503 * N.B. The value read will not be valid if the DAC channel has
504 * never been written successfully since the device was attached
505 * or since the channel has been used by an AO streaming write
506 * command.
508 static int
509 pci224_ao_insn_read(struct comedi_device *dev, struct comedi_subdevice *s,
510 struct comedi_insn *insn, unsigned int *data)
512 int i;
513 int chan;
515 chan = CR_CHAN(insn->chanspec);
517 for (i = 0; i < insn->n; i++) {
518 data[i] = devpriv->ao_readback[chan];
521 return i;
525 * Just a wrapper for the inline function 'i8253_cascade_ns_to_timer'.
527 static void
528 pci224_cascade_ns_to_timer(int osc_base, unsigned int *d1, unsigned int *d2,
529 unsigned int *nanosec, int round_mode)
531 i8253_cascade_ns_to_timer(osc_base, d1, d2, nanosec, round_mode);
535 * Kills a command running on the AO subdevice.
537 static void pci224_ao_stop(struct comedi_device *dev, struct comedi_subdevice *s)
539 unsigned long flags;
541 if (!test_and_clear_bit(AO_CMD_STARTED, &devpriv->state)) {
542 return;
545 spin_lock_irqsave(&devpriv->ao_spinlock, flags);
546 /* Kill the interrupts. */
547 devpriv->intsce = 0;
548 outb(0, devpriv->iobase1 + PCI224_INT_SCE);
550 * Interrupt routine may or may not be running. We may or may not
551 * have been called from the interrupt routine (directly or
552 * indirectly via a comedi_events() callback routine). It's highly
553 * unlikely that we've been called from some other interrupt routine
554 * but who knows what strange things coders get up to!
556 * If the interrupt routine is currently running, wait for it to
557 * finish, unless we appear to have been called via the interrupt
558 * routine.
560 while (devpriv->intr_running && devpriv->intr_cpuid != THISCPU) {
561 spin_unlock_irqrestore(&devpriv->ao_spinlock, flags);
562 spin_lock_irqsave(&devpriv->ao_spinlock, flags);
564 spin_unlock_irqrestore(&devpriv->ao_spinlock, flags);
565 /* Reconfigure DAC for insn_write usage. */
566 outw(0, dev->iobase + PCI224_DACCEN); /* Disable channels. */
567 devpriv->daccon = COMBINE(devpriv->daccon,
568 PCI224_DACCON_TRIG_SW | PCI224_DACCON_FIFOINTR_EMPTY,
569 PCI224_DACCON_TRIG_MASK | PCI224_DACCON_FIFOINTR_MASK);
570 outw(devpriv->daccon | PCI224_DACCON_FIFORESET,
571 dev->iobase + PCI224_DACCON);
575 * Handles start of acquisition for the AO subdevice.
577 static void pci224_ao_start(struct comedi_device *dev, struct comedi_subdevice *s)
579 struct comedi_cmd *cmd = &s->async->cmd;
580 unsigned long flags;
582 set_bit(AO_CMD_STARTED, &devpriv->state);
583 if (!devpriv->ao_stop_continuous && devpriv->ao_stop_count == 0) {
584 /* An empty acquisition! */
585 pci224_ao_stop(dev, s);
586 s->async->events |= COMEDI_CB_EOA;
587 comedi_event(dev, s);
588 } else {
589 /* Enable interrupts. */
590 spin_lock_irqsave(&devpriv->ao_spinlock, flags);
591 if (cmd->stop_src == TRIG_EXT) {
592 devpriv->intsce = PCI224_INTR_EXT | PCI224_INTR_DAC;
593 } else {
594 devpriv->intsce = PCI224_INTR_DAC;
596 outb(devpriv->intsce, devpriv->iobase1 + PCI224_INT_SCE);
597 spin_unlock_irqrestore(&devpriv->ao_spinlock, flags);
602 * Handles interrupts from the DAC FIFO.
604 static void pci224_ao_handle_fifo(struct comedi_device *dev, struct comedi_subdevice *s)
606 struct comedi_cmd *cmd = &s->async->cmd;
607 unsigned int num_scans;
608 unsigned int room;
609 unsigned short dacstat;
610 unsigned int i, n;
611 unsigned int bytes_per_scan;
613 if (cmd->chanlist_len) {
614 bytes_per_scan = cmd->chanlist_len * sizeof(short);
615 } else {
616 /* Shouldn't get here! */
617 bytes_per_scan = sizeof(short);
619 /* Determine number of scans available in buffer. */
620 num_scans = comedi_buf_read_n_available(s->async) / bytes_per_scan;
621 if (!devpriv->ao_stop_continuous) {
622 /* Fixed number of scans. */
623 if (num_scans > devpriv->ao_stop_count) {
624 num_scans = devpriv->ao_stop_count;
628 /* Determine how much room is in the FIFO (in samples). */
629 dacstat = inw(dev->iobase + PCI224_DACCON);
630 switch (dacstat & PCI224_DACCON_FIFOFL_MASK) {
631 case PCI224_DACCON_FIFOFL_EMPTY:
632 room = PCI224_FIFO_ROOM_EMPTY;
633 if (!devpriv->ao_stop_continuous
634 && devpriv->ao_stop_count == 0) {
635 /* FIFO empty at end of counted acquisition. */
636 pci224_ao_stop(dev, s);
637 s->async->events |= COMEDI_CB_EOA;
638 comedi_event(dev, s);
639 return;
641 break;
642 case PCI224_DACCON_FIFOFL_ONETOHALF:
643 room = PCI224_FIFO_ROOM_ONETOHALF;
644 break;
645 case PCI224_DACCON_FIFOFL_HALFTOFULL:
646 room = PCI224_FIFO_ROOM_HALFTOFULL;
647 break;
648 default:
649 room = PCI224_FIFO_ROOM_FULL;
650 break;
652 if (room >= PCI224_FIFO_ROOM_ONETOHALF) {
653 /* FIFO is less than half-full. */
654 if (num_scans == 0) {
655 /* Nothing left to put in the FIFO. */
656 pci224_ao_stop(dev, s);
657 s->async->events |= COMEDI_CB_OVERFLOW;
658 printk(KERN_ERR "comedi%d: "
659 "AO buffer underrun\n", dev->minor);
662 /* Determine how many new scans can be put in the FIFO. */
663 if (cmd->chanlist_len) {
664 room /= cmd->chanlist_len;
666 /* Determine how many scans to process. */
667 if (num_scans > room) {
668 num_scans = room;
670 /* Process scans. */
671 for (n = 0; n < num_scans; n++) {
672 cfc_read_array_from_buffer(s, &devpriv->ao_scan_vals[0],
673 bytes_per_scan);
674 for (i = 0; i < cmd->chanlist_len; i++) {
675 outw(devpriv->ao_scan_vals[devpriv->
676 ao_scan_order[i]],
677 dev->iobase + PCI224_DACDATA);
680 if (!devpriv->ao_stop_continuous) {
681 devpriv->ao_stop_count -= num_scans;
682 if (devpriv->ao_stop_count == 0) {
684 * Change FIFO interrupt trigger level to wait
685 * until FIFO is empty.
687 devpriv->daccon = COMBINE(devpriv->daccon,
688 PCI224_DACCON_FIFOINTR_EMPTY,
689 PCI224_DACCON_FIFOINTR_MASK);
690 outw(devpriv->daccon,
691 dev->iobase + PCI224_DACCON);
694 if ((devpriv->daccon & PCI224_DACCON_TRIG_MASK) ==
695 PCI224_DACCON_TRIG_NONE) {
696 unsigned short trig;
699 * This is the initial DAC FIFO interrupt at the
700 * start of the acquisition. The DAC's scan trigger
701 * has been set to 'none' up until now.
703 * Now that data has been written to the FIFO, the
704 * DAC's scan trigger source can be set to the
705 * correct value.
707 * BUG: The first scan will be triggered immediately
708 * if the scan trigger source is at logic level 1.
710 if (cmd->scan_begin_src == TRIG_TIMER) {
711 trig = PCI224_DACCON_TRIG_Z2CT0;
712 } else {
713 /* cmd->scan_begin_src == TRIG_EXT */
714 if (cmd->scan_begin_arg & CR_INVERT) {
715 trig = PCI224_DACCON_TRIG_EXTN;
716 } else {
717 trig = PCI224_DACCON_TRIG_EXTP;
720 devpriv->daccon = COMBINE(devpriv->daccon, trig,
721 PCI224_DACCON_TRIG_MASK);
722 outw(devpriv->daccon, dev->iobase + PCI224_DACCON);
724 if (s->async->events) {
725 comedi_event(dev, s);
730 * Internal trigger function to start acquisition on AO subdevice.
732 static int
733 pci224_ao_inttrig_start(struct comedi_device *dev, struct comedi_subdevice *s,
734 unsigned int trignum)
736 if (trignum != 0)
737 return -EINVAL;
739 s->async->inttrig = NULLFUNC;
740 pci224_ao_start(dev, s);
742 return 1;
745 #define MAX_SCAN_PERIOD 0xFFFFFFFFU
746 #define MIN_SCAN_PERIOD 2500
747 #define CONVERT_PERIOD 625
750 * 'do_cmdtest' function for AO subdevice.
752 static int
753 pci224_ao_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_cmd *cmd)
755 int err = 0;
756 unsigned int tmp;
758 /* Step 1: make sure trigger sources are trivially valid. */
760 tmp = cmd->start_src;
761 cmd->start_src &= TRIG_INT | TRIG_EXT;
762 if (!cmd->start_src || tmp != cmd->start_src)
763 err++;
765 tmp = cmd->scan_begin_src;
766 cmd->scan_begin_src &= TRIG_EXT | TRIG_TIMER;
767 if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
768 err++;
770 tmp = cmd->convert_src;
771 cmd->convert_src &= TRIG_NOW;
772 if (!cmd->convert_src || tmp != cmd->convert_src)
773 err++;
775 tmp = cmd->scan_end_src;
776 cmd->scan_end_src &= TRIG_COUNT;
777 if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
778 err++;
780 tmp = cmd->stop_src;
781 cmd->stop_src &= TRIG_COUNT | TRIG_EXT | TRIG_NONE;
782 if (!cmd->stop_src || tmp != cmd->stop_src)
783 err++;
785 if (err)
786 return 1;
788 /* Step 2: make sure trigger sources are unique and mutually
789 * compatible. */
791 /* these tests are true if more than one _src bit is set */
792 if ((cmd->start_src & (cmd->start_src - 1)) != 0)
793 err++;
794 if ((cmd->scan_begin_src & (cmd->scan_begin_src - 1)) != 0)
795 err++;
796 if ((cmd->convert_src & (cmd->convert_src - 1)) != 0)
797 err++;
798 if ((cmd->scan_end_src & (cmd->scan_end_src - 1)) != 0)
799 err++;
800 if ((cmd->stop_src & (cmd->stop_src - 1)) != 0)
801 err++;
803 /* There's only one external trigger signal (which makes these
804 * tests easier). Only one thing can use it. */
805 tmp = 0;
806 if (cmd->start_src & TRIG_EXT)
807 tmp++;
808 if (cmd->scan_begin_src & TRIG_EXT)
809 tmp++;
810 if (cmd->stop_src & TRIG_EXT)
811 tmp++;
812 if (tmp > 1)
813 err++;
815 if (err)
816 return 2;
818 /* Step 3: make sure arguments are trivially compatible. */
820 switch (cmd->start_src) {
821 case TRIG_INT:
822 if (cmd->start_arg != 0) {
823 cmd->start_arg = 0;
824 err++;
826 break;
827 case TRIG_EXT:
828 /* Force to external trigger 0. */
829 if ((cmd->start_arg & ~CR_FLAGS_MASK) != 0) {
830 cmd->start_arg = COMBINE(cmd->start_arg, 0,
831 ~CR_FLAGS_MASK);
832 err++;
834 /* The only flag allowed is CR_EDGE, which is ignored. */
835 if ((cmd->start_arg & CR_FLAGS_MASK & ~CR_EDGE) != 0) {
836 cmd->start_arg = COMBINE(cmd->start_arg, 0,
837 CR_FLAGS_MASK & ~CR_EDGE);
838 err++;
840 break;
843 switch (cmd->scan_begin_src) {
844 case TRIG_TIMER:
845 if (cmd->scan_begin_arg > MAX_SCAN_PERIOD) {
846 cmd->scan_begin_arg = MAX_SCAN_PERIOD;
847 err++;
849 tmp = cmd->chanlist_len * CONVERT_PERIOD;
850 if (tmp < MIN_SCAN_PERIOD) {
851 tmp = MIN_SCAN_PERIOD;
853 if (cmd->scan_begin_arg < tmp) {
854 cmd->scan_begin_arg = tmp;
855 err++;
857 break;
858 case TRIG_EXT:
859 /* Force to external trigger 0. */
860 if ((cmd->scan_begin_arg & ~CR_FLAGS_MASK) != 0) {
861 cmd->scan_begin_arg = COMBINE(cmd->scan_begin_arg, 0,
862 ~CR_FLAGS_MASK);
863 err++;
865 /* Only allow flags CR_EDGE and CR_INVERT. Ignore CR_EDGE. */
866 if ((cmd->scan_begin_arg & CR_FLAGS_MASK &
867 ~(CR_EDGE | CR_INVERT)) != 0) {
868 cmd->scan_begin_arg = COMBINE(cmd->scan_begin_arg, 0,
869 CR_FLAGS_MASK & ~(CR_EDGE | CR_INVERT));
870 err++;
872 break;
875 /* cmd->convert_src == TRIG_NOW */
876 if (cmd->convert_arg != 0) {
877 cmd->convert_arg = 0;
878 err++;
881 /* cmd->scan_end_arg == TRIG_COUNT */
882 if (cmd->scan_end_arg != cmd->chanlist_len) {
883 cmd->scan_end_arg = cmd->chanlist_len;
884 err++;
887 switch (cmd->stop_src) {
888 case TRIG_COUNT:
889 /* Any count allowed. */
890 break;
891 case TRIG_EXT:
892 /* Force to external trigger 0. */
893 if ((cmd->stop_arg & ~CR_FLAGS_MASK) != 0) {
894 cmd->stop_arg = COMBINE(cmd->stop_arg, 0,
895 ~CR_FLAGS_MASK);
896 err++;
898 /* The only flag allowed is CR_EDGE, which is ignored. */
899 if ((cmd->stop_arg & CR_FLAGS_MASK & ~CR_EDGE) != 0) {
900 cmd->stop_arg = COMBINE(cmd->stop_arg, 0,
901 CR_FLAGS_MASK & ~CR_EDGE);
903 break;
904 case TRIG_NONE:
905 if (cmd->stop_arg != 0) {
906 cmd->stop_arg = 0;
907 err++;
909 break;
912 if (err)
913 return 3;
915 /* Step 4: fix up any arguments. */
917 if (cmd->scan_begin_src == TRIG_TIMER) {
918 unsigned int div1, div2, round;
919 int round_mode = cmd->flags & TRIG_ROUND_MASK;
921 tmp = cmd->scan_begin_arg;
922 /* Check whether to use a single timer. */
923 switch (round_mode) {
924 case TRIG_ROUND_NEAREST:
925 default:
926 round = TIMEBASE_10MHZ / 2;
927 break;
928 case TRIG_ROUND_DOWN:
929 round = 0;
930 break;
931 case TRIG_ROUND_UP:
932 round = TIMEBASE_10MHZ - 1;
933 break;
935 /* Be careful to avoid overflow! */
936 div2 = cmd->scan_begin_arg / TIMEBASE_10MHZ;
937 div2 += (round + cmd->scan_begin_arg % TIMEBASE_10MHZ) /
938 TIMEBASE_10MHZ;
939 if (div2 <= 0x10000) {
940 /* A single timer will suffice. */
941 if (div2 < 2)
942 div2 = 2;
943 cmd->scan_begin_arg = div2 * TIMEBASE_10MHZ;
944 if (cmd->scan_begin_arg < div2 ||
945 cmd->scan_begin_arg < TIMEBASE_10MHZ) {
946 /* Overflow! */
947 cmd->scan_begin_arg = MAX_SCAN_PERIOD;
949 } else {
950 /* Use two timers. */
951 div1 = devpriv->cached_div1;
952 div2 = devpriv->cached_div2;
953 pci224_cascade_ns_to_timer(TIMEBASE_10MHZ, &div1, &div2,
954 &cmd->scan_begin_arg, round_mode);
955 devpriv->cached_div1 = div1;
956 devpriv->cached_div2 = div2;
958 if (tmp != cmd->scan_begin_arg) {
959 err++;
963 if (err)
964 return 4;
966 /* Step 5: check channel list. */
968 if (cmd->chanlist && (cmd->chanlist_len > 0)) {
969 unsigned int range;
970 enum { range_err = 1, dupchan_err = 2, };
971 unsigned errors;
972 unsigned int n;
973 unsigned int ch;
976 * Check all channels have the same range index. Don't care
977 * about analogue reference, as we can't configure it.
979 * Check the list has no duplicate channels.
981 range = CR_RANGE(cmd->chanlist[0]);
982 errors = 0;
983 tmp = 0;
984 for (n = 0; n < cmd->chanlist_len; n++) {
985 ch = CR_CHAN(cmd->chanlist[n]);
986 if (tmp & (1U << ch)) {
987 errors |= dupchan_err;
989 tmp |= (1U << ch);
990 if (CR_RANGE(cmd->chanlist[n]) != range) {
991 errors |= range_err;
994 if (errors) {
995 if (errors & dupchan_err) {
996 DPRINTK("comedi%d: " DRIVER_NAME
997 ": ao_cmdtest: "
998 "entries in chanlist must contain no "
999 "duplicate channels\n", dev->minor);
1001 if (errors & range_err) {
1002 DPRINTK("comedi%d: " DRIVER_NAME
1003 ": ao_cmdtest: "
1004 "entries in chanlist must all have "
1005 "the same range index\n", dev->minor);
1007 err++;
1011 if (err)
1012 return 5;
1014 return 0;
1018 * 'do_cmd' function for AO subdevice.
1020 static int pci224_ao_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
1022 struct comedi_cmd *cmd = &s->async->cmd;
1023 int range;
1024 unsigned int i, j;
1025 unsigned int ch;
1026 unsigned int rank;
1027 unsigned long flags;
1029 /* Cannot handle null/empty chanlist. */
1030 if (cmd->chanlist == NULL || cmd->chanlist_len == 0) {
1031 return -EINVAL;
1034 /* Determine which channels are enabled and their load order. */
1035 devpriv->ao_enab = 0;
1037 for (i = 0; i < cmd->chanlist_len; i++) {
1038 ch = CR_CHAN(cmd->chanlist[i]);
1039 devpriv->ao_enab |= 1U << ch;
1040 rank = 0;
1041 for (j = 0; j < cmd->chanlist_len; j++) {
1042 if (CR_CHAN(cmd->chanlist[j]) < ch) {
1043 rank++;
1046 devpriv->ao_scan_order[rank] = i;
1049 /* Set enabled channels. */
1050 outw(devpriv->ao_enab, dev->iobase + PCI224_DACCEN);
1052 /* Determine range and polarity. All channels the same. */
1053 range = CR_RANGE(cmd->chanlist[0]);
1056 * Set DAC range and polarity.
1057 * Set DAC scan trigger source to 'none'.
1058 * Set DAC FIFO interrupt trigger level to 'not half full'.
1059 * Reset DAC FIFO.
1061 * N.B. DAC FIFO interrupts are currently disabled.
1063 devpriv->daccon = COMBINE(devpriv->daccon,
1064 (devpriv->hwrange[range] | PCI224_DACCON_TRIG_NONE |
1065 PCI224_DACCON_FIFOINTR_NHALF),
1066 (PCI224_DACCON_POLAR_MASK | PCI224_DACCON_VREF_MASK |
1067 PCI224_DACCON_TRIG_MASK | PCI224_DACCON_FIFOINTR_MASK));
1068 outw(devpriv->daccon | PCI224_DACCON_FIFORESET,
1069 dev->iobase + PCI224_DACCON);
1071 if (cmd->scan_begin_src == TRIG_TIMER) {
1072 unsigned int div1, div2, round;
1073 unsigned int ns = cmd->scan_begin_arg;
1074 int round_mode = cmd->flags & TRIG_ROUND_MASK;
1076 /* Check whether to use a single timer. */
1077 switch (round_mode) {
1078 case TRIG_ROUND_NEAREST:
1079 default:
1080 round = TIMEBASE_10MHZ / 2;
1081 break;
1082 case TRIG_ROUND_DOWN:
1083 round = 0;
1084 break;
1085 case TRIG_ROUND_UP:
1086 round = TIMEBASE_10MHZ - 1;
1087 break;
1089 /* Be careful to avoid overflow! */
1090 div2 = cmd->scan_begin_arg / TIMEBASE_10MHZ;
1091 div2 += (round + cmd->scan_begin_arg % TIMEBASE_10MHZ) /
1092 TIMEBASE_10MHZ;
1093 if (div2 <= 0x10000) {
1094 /* A single timer will suffice. */
1095 if (div2 < 2)
1096 div2 = 2;
1097 div2 &= 0xffff;
1098 div1 = 1; /* Flag that single timer to be used. */
1099 } else {
1100 /* Use two timers. */
1101 div1 = devpriv->cached_div1;
1102 div2 = devpriv->cached_div2;
1103 pci224_cascade_ns_to_timer(TIMEBASE_10MHZ, &div1, &div2,
1104 &ns, round_mode);
1108 * The output of timer Z2-0 will be used as the scan trigger
1109 * source.
1111 /* Make sure Z2-0 is gated on. */
1112 outb(GAT_CONFIG(0, GAT_VCC),
1113 devpriv->iobase1 + PCI224_ZGAT_SCE);
1114 if (div1 == 1) {
1115 /* Not cascading. Z2-0 needs 10 MHz clock. */
1116 outb(CLK_CONFIG(0, CLK_10MHZ),
1117 devpriv->iobase1 + PCI224_ZCLK_SCE);
1118 } else {
1119 /* Cascading with Z2-2. */
1120 /* Make sure Z2-2 is gated on. */
1121 outb(GAT_CONFIG(2, GAT_VCC),
1122 devpriv->iobase1 + PCI224_ZGAT_SCE);
1123 /* Z2-2 needs 10 MHz clock. */
1124 outb(CLK_CONFIG(2, CLK_10MHZ),
1125 devpriv->iobase1 + PCI224_ZCLK_SCE);
1126 /* Load Z2-2 mode (2) and counter (div1). */
1127 i8254_load(devpriv->iobase1 + PCI224_Z2_CT0, 0,
1128 2, div1, 2);
1129 /* Z2-0 is clocked from Z2-2's output. */
1130 outb(CLK_CONFIG(0, CLK_OUTNM1),
1131 devpriv->iobase1 + PCI224_ZCLK_SCE);
1133 /* Load Z2-0 mode (2) and counter (div2). */
1134 i8254_load(devpriv->iobase1 + PCI224_Z2_CT0, 0, 0, div2, 2);
1138 * Sort out end of acquisition.
1140 switch (cmd->stop_src) {
1141 case TRIG_COUNT:
1142 /* Fixed number of scans. */
1143 devpriv->ao_stop_continuous = 0;
1144 devpriv->ao_stop_count = cmd->stop_arg;
1145 break;
1146 default:
1147 /* Continuous scans. */
1148 devpriv->ao_stop_continuous = 1;
1149 devpriv->ao_stop_count = 0;
1150 break;
1154 * Sort out start of acquisition.
1156 switch (cmd->start_src) {
1157 case TRIG_INT:
1158 spin_lock_irqsave(&devpriv->ao_spinlock, flags);
1159 s->async->inttrig = &pci224_ao_inttrig_start;
1160 spin_unlock_irqrestore(&devpriv->ao_spinlock, flags);
1161 break;
1162 case TRIG_EXT:
1163 /* Enable external interrupt trigger to start acquisition. */
1164 spin_lock_irqsave(&devpriv->ao_spinlock, flags);
1165 devpriv->intsce |= PCI224_INTR_EXT;
1166 outb(devpriv->intsce, devpriv->iobase1 + PCI224_INT_SCE);
1167 spin_unlock_irqrestore(&devpriv->ao_spinlock, flags);
1168 break;
1171 return 0;
1175 * 'cancel' function for AO subdevice.
1177 static int pci224_ao_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
1179 pci224_ao_stop(dev, s);
1180 return 0;
1184 * 'munge' data for AO command.
1186 static void
1187 pci224_ao_munge(struct comedi_device *dev, struct comedi_subdevice *s, void *data,
1188 unsigned int num_bytes, unsigned int chan_index)
1190 struct comedi_async *async = s->async;
1191 short *array = data;
1192 unsigned int length = num_bytes / sizeof(*array);
1193 unsigned int offset;
1194 unsigned int shift;
1195 unsigned int i;
1197 /* The hardware expects 16-bit numbers. */
1198 shift = 16 - thisboard->ao_bits;
1199 /* Channels will be all bipolar or all unipolar. */
1200 if ((devpriv->hwrange[CR_RANGE(async->cmd.chanlist[0])] &
1201 PCI224_DACCON_POLAR_MASK) == PCI224_DACCON_POLAR_UNI) {
1202 /* Unipolar */
1203 offset = 0;
1204 } else {
1205 /* Bipolar */
1206 offset = 32768;
1208 /* Munge the data. */
1209 for (i = 0; i < length; i++) {
1210 array[i] = (array[i] << shift) - offset;
1215 * Interrupt handler.
1217 static irqreturn_t pci224_interrupt(int irq, void *d)
1219 struct comedi_device *dev = d;
1220 struct comedi_subdevice *s = &dev->subdevices[0];
1221 struct comedi_cmd *cmd;
1222 unsigned char intstat, valid_intstat;
1223 unsigned char curenab;
1224 int retval = 0;
1225 unsigned long flags;
1227 intstat = inb(devpriv->iobase1 + PCI224_INT_SCE) & 0x3F;
1228 if (intstat) {
1229 retval = 1;
1230 spin_lock_irqsave(&devpriv->ao_spinlock, flags);
1231 valid_intstat = devpriv->intsce & intstat;
1232 /* Temporarily disable interrupt sources. */
1233 curenab = devpriv->intsce & ~intstat;
1234 outb(curenab, devpriv->iobase1 + PCI224_INT_SCE);
1235 devpriv->intr_running = 1;
1236 devpriv->intr_cpuid = THISCPU;
1237 spin_unlock_irqrestore(&devpriv->ao_spinlock, flags);
1238 if (valid_intstat != 0) {
1239 cmd = &s->async->cmd;
1240 if (valid_intstat & PCI224_INTR_EXT) {
1241 devpriv->intsce &= ~PCI224_INTR_EXT;
1242 if (cmd->start_src == TRIG_EXT) {
1243 pci224_ao_start(dev, s);
1244 } else if (cmd->stop_src == TRIG_EXT) {
1245 pci224_ao_stop(dev, s);
1248 if (valid_intstat & PCI224_INTR_DAC) {
1249 pci224_ao_handle_fifo(dev, s);
1252 /* Reenable interrupt sources. */
1253 spin_lock_irqsave(&devpriv->ao_spinlock, flags);
1254 if (curenab != devpriv->intsce) {
1255 outb(devpriv->intsce,
1256 devpriv->iobase1 + PCI224_INT_SCE);
1258 devpriv->intr_running = 0;
1259 spin_unlock_irqrestore(&devpriv->ao_spinlock, flags);
1261 return IRQ_RETVAL(retval);
1265 * This function looks for a PCI device matching the requested board name,
1266 * bus and slot.
1268 static int
1269 pci224_find_pci(struct comedi_device *dev, int bus, int slot,
1270 struct pci_dev **pci_dev_p)
1272 struct pci_dev *pci_dev = NULL;
1274 *pci_dev_p = NULL;
1276 /* Look for matching PCI device. */
1277 for (pci_dev = pci_get_device(PCI_VENDOR_ID_AMPLICON, PCI_ANY_ID, NULL);
1278 pci_dev != NULL;
1279 pci_dev = pci_get_device(PCI_VENDOR_ID_AMPLICON, PCI_ANY_ID,
1280 pci_dev)) {
1281 /* If bus/slot specified, check them. */
1282 if (bus || slot) {
1283 if (bus != pci_dev->bus->number
1284 || slot != PCI_SLOT(pci_dev->devfn))
1285 continue;
1287 if (thisboard->model == any_model) {
1288 /* Match any supported model. */
1289 int i;
1291 for (i = 0; i < ARRAY_SIZE(pci224_boards); i++) {
1292 if (pci_dev->device == pci224_boards[i].devid) {
1293 /* Change board_ptr to matched board. */
1294 dev->board_ptr = &pci224_boards[i];
1295 break;
1298 if (i == ARRAY_SIZE(pci224_boards))
1299 continue;
1300 } else {
1301 /* Match specific model name. */
1302 if (thisboard->devid != pci_dev->device)
1303 continue;
1306 /* Found a match. */
1307 *pci_dev_p = pci_dev;
1308 return 0;
1310 /* No match found. */
1311 if (bus || slot) {
1312 printk(KERN_ERR "comedi%d: error! "
1313 "no %s found at pci %02x:%02x!\n",
1314 dev->minor, thisboard->name, bus, slot);
1315 } else {
1316 printk(KERN_ERR "comedi%d: error! no %s found!\n",
1317 dev->minor, thisboard->name);
1319 return -EIO;
1323 * Attach is called by the Comedi core to configure the driver
1324 * for a particular board. If you specified a board_name array
1325 * in the driver structure, dev->board_ptr contains that
1326 * address.
1328 static int pci224_attach(struct comedi_device *dev, struct comedi_devconfig *it)
1330 struct comedi_subdevice *s;
1331 struct pci_dev *pci_dev;
1332 unsigned int irq;
1333 int bus = 0, slot = 0;
1334 unsigned n;
1335 int ret;
1337 printk(KERN_DEBUG "comedi%d: %s: attach\n", dev->minor, DRIVER_NAME);
1339 bus = it->options[0];
1340 slot = it->options[1];
1341 ret = alloc_private(dev, sizeof(struct pci224_private));
1342 if (ret < 0) {
1343 printk(KERN_ERR "comedi%d: error! out of memory!\n",
1344 dev->minor);
1345 return ret;
1348 ret = pci224_find_pci(dev, bus, slot, &pci_dev);
1349 if (ret < 0)
1350 return ret;
1352 devpriv->pci_dev = pci_dev;
1353 ret = comedi_pci_enable(pci_dev, DRIVER_NAME);
1354 if (ret < 0) {
1355 printk(KERN_ERR
1356 "comedi%d: error! cannot enable PCI device "
1357 "and request regions!\n", dev->minor);
1358 return ret;
1360 spin_lock_init(&devpriv->ao_spinlock);
1362 devpriv->iobase1 = pci_resource_start(pci_dev, 2);
1363 dev->iobase = pci_resource_start(pci_dev, 3);
1364 irq = pci_dev->irq;
1366 /* Allocate readback buffer for AO channels. */
1367 devpriv->ao_readback = kmalloc(sizeof(devpriv->ao_readback[0]) *
1368 thisboard->ao_chans, GFP_KERNEL);
1369 if (!devpriv->ao_readback) {
1370 return -ENOMEM;
1373 /* Allocate buffer to hold values for AO channel scan. */
1374 devpriv->ao_scan_vals = kmalloc(sizeof(devpriv->ao_scan_vals[0]) *
1375 thisboard->ao_chans, GFP_KERNEL);
1376 if (!devpriv->ao_scan_vals) {
1377 return -ENOMEM;
1380 /* Allocate buffer to hold AO channel scan order. */
1381 devpriv->ao_scan_order = kmalloc(sizeof(devpriv->ao_scan_order[0]) *
1382 thisboard->ao_chans, GFP_KERNEL);
1383 if (!devpriv->ao_scan_order) {
1384 return -ENOMEM;
1387 /* Disable interrupt sources. */
1388 devpriv->intsce = 0;
1389 outb(0, devpriv->iobase1 + PCI224_INT_SCE);
1391 /* Initialize the DAC hardware. */
1392 outw(PCI224_DACCON_GLOBALRESET, dev->iobase + PCI224_DACCON);
1393 outw(0, dev->iobase + PCI224_DACCEN);
1394 outw(0, dev->iobase + PCI224_FIFOSIZ);
1395 devpriv->daccon = (PCI224_DACCON_TRIG_SW | PCI224_DACCON_POLAR_BI |
1396 PCI224_DACCON_FIFOENAB | PCI224_DACCON_FIFOINTR_EMPTY);
1397 outw(devpriv->daccon | PCI224_DACCON_FIFORESET,
1398 dev->iobase + PCI224_DACCON);
1400 /* Allocate subdevices. There is only one! */
1401 ret = alloc_subdevices(dev, 1);
1402 if (ret < 0) {
1403 printk(KERN_ERR "comedi%d: error! out of memory!\n",
1404 dev->minor);
1405 return ret;
1408 s = dev->subdevices + 0;
1409 /* Analog output subdevice. */
1410 s->type = COMEDI_SUBD_AO;
1411 s->subdev_flags = SDF_WRITABLE | SDF_GROUND | SDF_CMD_WRITE;
1412 s->n_chan = thisboard->ao_chans;
1413 s->maxdata = (1 << thisboard->ao_bits) - 1;
1414 s->insn_write = &pci224_ao_insn_write;
1415 s->insn_read = &pci224_ao_insn_read;
1416 s->len_chanlist = s->n_chan;
1418 dev->write_subdev = s;
1419 s->do_cmd = &pci224_ao_cmd;
1420 s->do_cmdtest = &pci224_ao_cmdtest;
1421 s->cancel = &pci224_ao_cancel;
1422 s->munge = &pci224_ao_munge;
1424 /* Sort out channel range options. */
1425 if (thisboard->model == pci234_model) {
1426 /* PCI234 range options. */
1427 const struct comedi_lrange **range_table_list;
1429 s->range_table_list = range_table_list =
1430 kmalloc(sizeof(struct comedi_lrange *) * s->n_chan,
1431 GFP_KERNEL);
1432 if (!s->range_table_list) {
1433 return -ENOMEM;
1435 for (n = 2; n < 3 + s->n_chan; n++) {
1436 if (it->options[n] < 0 || it->options[n] > 1) {
1437 printk(KERN_WARNING "comedi%d: %s: warning! "
1438 "bad options[%u]=%d\n",
1439 dev->minor, DRIVER_NAME, n,
1440 it->options[n]);
1443 for (n = 0; n < s->n_chan; n++) {
1444 if (n < COMEDI_NDEVCONFOPTS - 3 &&
1445 it->options[3 + n] == 1) {
1446 if (it->options[2] == 1) {
1447 range_table_list[n] = &range_pci234_ext;
1448 } else {
1449 range_table_list[n] = &range_bipolar5;
1451 } else {
1452 if (it->options[2] == 1) {
1453 range_table_list[n] =
1454 &range_pci234_ext2;
1455 } else {
1456 range_table_list[n] = &range_bipolar10;
1460 devpriv->hwrange = hwrange_pci234;
1461 } else {
1462 /* PCI224 range options. */
1463 if (it->options[2] == 1) {
1464 s->range_table = &range_pci224_external;
1465 devpriv->hwrange = hwrange_pci224_external;
1466 } else {
1467 if (it->options[2] != 0) {
1468 printk(KERN_WARNING "comedi%d: %s: warning! "
1469 "bad options[2]=%d\n",
1470 dev->minor, DRIVER_NAME,
1471 it->options[2]);
1473 s->range_table = &range_pci224_internal;
1474 devpriv->hwrange = hwrange_pci224_internal;
1478 dev->board_name = thisboard->name;
1480 if (irq) {
1481 ret = request_irq(irq, pci224_interrupt, IRQF_SHARED,
1482 DRIVER_NAME, dev);
1483 if (ret < 0) {
1484 printk(KERN_ERR "comedi%d: error! "
1485 "unable to allocate irq %u\n", dev->minor, irq);
1486 return ret;
1487 } else {
1488 dev->irq = irq;
1492 printk(KERN_INFO "comedi%d: %s ", dev->minor, dev->board_name);
1493 printk("(pci %s) ", pci_name(pci_dev));
1494 if (irq) {
1495 printk("(irq %u%s) ", irq, (dev->irq ? "" : " UNAVAILABLE"));
1496 } else {
1497 printk("(no irq) ");
1500 printk("attached\n");
1502 return 1;
1506 * _detach is called to deconfigure a device. It should deallocate
1507 * resources.
1508 * This function is also called when _attach() fails, so it should be
1509 * careful not to release resources that were not necessarily
1510 * allocated by _attach(). dev->private and dev->subdevices are
1511 * deallocated automatically by the core.
1513 static int pci224_detach(struct comedi_device *dev)
1515 printk(KERN_DEBUG "comedi%d: %s: detach\n", dev->minor, DRIVER_NAME);
1517 if (dev->irq) {
1518 free_irq(dev->irq, dev);
1520 if (dev->subdevices) {
1521 struct comedi_subdevice *s;
1523 s = dev->subdevices + 0;
1524 /* AO subdevice */
1525 if (s->range_table_list) {
1526 kfree(s->range_table_list);
1529 if (devpriv) {
1530 if (devpriv->ao_readback) {
1531 kfree(devpriv->ao_readback);
1533 if (devpriv->ao_scan_vals) {
1534 kfree(devpriv->ao_scan_vals);
1536 if (devpriv->ao_scan_order) {
1537 kfree(devpriv->ao_scan_order);
1539 if (devpriv->pci_dev) {
1540 if (dev->iobase) {
1541 comedi_pci_disable(devpriv->pci_dev);
1543 pci_dev_put(devpriv->pci_dev);
1546 if (dev->board_name) {
1547 printk(KERN_INFO "comedi%d: %s removed\n",
1548 dev->minor, dev->board_name);
1551 return 0;