staging: comedi: propogate error code from comedi_alloc_subdevices
[deliverable/linux.git] / drivers / staging / comedi / drivers / amplc_pci224.c
CommitLineData
ea1aeae4
IA
1/*
2 comedi/drivers/amplc_pci224.c
3 Driver for Amplicon PCI224 and PCI234 AO boards.
4
5 Copyright (C) 2005 MEV Ltd. <http://www.mev.co.uk/>
6
7 COMEDI - Linux Control and Measurement Device Interface
8 Copyright (C) 1998,2000 David A. Schleef <ds@schleef.org>
9
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.
14
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.
19
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.
23
24*/
25/*
26Driver: amplc_pci224
27Description: Amplicon PCI224, PCI234
28Author: Ian Abbott <abbotti@mev.co.uk>
29Devices: [Amplicon] PCI224 (amplc_pci224 or pci224),
30 PCI234 (amplc_pci224 or pci234)
31Updated: Wed, 22 Oct 2008 12:25:08 +0100
32Status: works, but see caveats
33
34Supports:
35
36 - ao_insn read/write
37 - ao_do_cmd mode with the following sources:
38
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
44
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.
48
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.
51
52Configuration 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].
67
68Configuration 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].
85
86Passing a zero for an option is the same as leaving it unspecified.
87
88Caveats:
89
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.
94
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.
104*/
105
70265d24 106#include <linux/interrupt.h>
5a0e3ad6 107#include <linux/slab.h>
70265d24 108
ea1aeae4
IA
109#include "../comedidev.h"
110
ea1aeae4
IA
111#include "comedi_fc.h"
112#include "8253.h"
113
114#define DRIVER_NAME "amplc_pci224"
115
116/*
117 * PCI IDs.
118 */
6608224c 119#define PCI_VENDOR_ID_AMPLICON 0x14dc
ea1aeae4
IA
120#define PCI_DEVICE_ID_AMPLICON_PCI224 0x0007
121#define PCI_DEVICE_ID_AMPLICON_PCI234 0x0008
122#define PCI_DEVICE_ID_INVALID 0xffff
123
124/*
125 * PCI224/234 i/o space 1 (PCIBAR2) registers.
126 */
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 */
136
137/*
138 * PCI224/234 i/o space 2 (PCIBAR3) 16-bit registers.
139 */
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. */
146
147/*
148 * DACCON values.
149 */
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)
193
194/*
195 * DAC FIFO size.
196 */
197#define PCI224_FIFO_SIZE 4096
198
199/*
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
202 * has been written!
203 */
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
208
209/*
210 * Counter/timer clock input configuration sources.
211 */
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
228
229/*
230 * Counter/timer gate input configuration sources.
231 */
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))
238
239/*
240 * Summary of CLK_OUTNM1 and GAT_NOUTNM2 connections for PCI224 and PCI234:
241 *
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
249 */
250
251/*
252 * Interrupt enable/status bits
253 */
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 */
257
258#define PCI224_INTR_EDGE_BITS (PCI224_INTR_EXT | PCI224_INTR_Z2CT1)
259#define PCI224_INTR_LEVEL_BITS PCI224_INTR_DACFIFO
260
261/*
262 * Handy macros.
263 */
264
265/* Combine old and new bits. */
266#define COMBINE(old, new, mask) (((old) & ~(mask)) | ((new) & (mask)))
267
ea1aeae4
IA
268/* Current CPU. XXX should this be hard_smp_processor_id()? */
269#define THISCPU smp_processor_id()
270
271/* State bits for use with atomic bit operations. */
272#define AO_CMD_STARTED 0
273
274/*
275 * Range tables.
276 */
277
278/* The software selectable internal ranges for PCI224 (option[2] == 0). */
9ced1de6 279static const struct comedi_lrange range_pci224_internal = {
ea1aeae4
IA
280 8,
281 {
0a85b6f0
MT
282 BIP_RANGE(10),
283 BIP_RANGE(5),
284 BIP_RANGE(2.5),
285 BIP_RANGE(1.25),
286 UNI_RANGE(10),
287 UNI_RANGE(5),
288 UNI_RANGE(2.5),
289 UNI_RANGE(1.25),
290 }
ea1aeae4
IA
291};
292
293static 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,
302};
303
304/* The software selectable external ranges for PCI224 (option[2] == 1). */
9ced1de6 305static const struct comedi_lrange range_pci224_external = {
ea1aeae4
IA
306 2,
307 {
0a85b6f0
MT
308 RANGE_ext(-1, 1), /* bipolar [-Vref,+Vref] */
309 RANGE_ext(0, 1), /* unipolar [0,+Vref] */
310 }
ea1aeae4
IA
311};
312
313static const unsigned short hwrange_pci224_external[2] = {
314 PCI224_DACCON_POLAR_BI,
315 PCI224_DACCON_POLAR_UNI,
316};
317
318/* The hardware selectable Vref*2 external range for PCI234
319 * (option[2] == 1, option[3+n] == 0). */
9ced1de6 320static const struct comedi_lrange range_pci234_ext2 = {
ea1aeae4
IA
321 1,
322 {
0a85b6f0
MT
323 RANGE_ext(-2, 2),
324 }
ea1aeae4
IA
325};
326
327/* The hardware selectable Vref external range for PCI234
328 * (option[2] == 1, option[3+n] == 1). */
9ced1de6 329static const struct comedi_lrange range_pci234_ext = {
ea1aeae4
IA
330 1,
331 {
0a85b6f0
MT
332 RANGE_ext(-1, 1),
333 }
ea1aeae4
IA
334};
335
336/* This serves for all the PCI234 ranges. */
337static const unsigned short hwrange_pci234[1] = {
338 PCI224_DACCON_POLAR_BI, /* bipolar - hardware ignores it! */
339};
340
341/*
342 * Board descriptions.
343 */
344
345enum pci224_model { any_model, pci224_model, pci234_model };
346
5a676a21 347struct pci224_board {
ea1aeae4
IA
348 const char *name;
349 unsigned short devid;
350 enum pci224_model model;
351 unsigned int ao_chans;
352 unsigned int ao_bits;
5a676a21 353};
ea1aeae4 354
5a676a21 355static const struct pci224_board pci224_boards[] = {
ea1aeae4 356 {
0a85b6f0
MT
357 .name = "pci224",
358 .devid = PCI_DEVICE_ID_AMPLICON_PCI224,
359 .model = pci224_model,
360 .ao_chans = 16,
361 .ao_bits = 12,
362 },
ea1aeae4 363 {
0a85b6f0
MT
364 .name = "pci234",
365 .devid = PCI_DEVICE_ID_AMPLICON_PCI234,
366 .model = pci234_model,
367 .ao_chans = 4,
368 .ao_bits = 16,
369 },
ea1aeae4 370 {
0a85b6f0
MT
371 .name = DRIVER_NAME,
372 .devid = PCI_DEVICE_ID_INVALID,
373 .model = any_model, /* wildcard */
374 },
ea1aeae4
IA
375};
376
ea1aeae4
IA
377/* this structure is for data unique to this hardware driver. If
378 several hardware drivers keep similar information in this structure,
71b5f4f1 379 feel free to suggest moving the variable to the struct comedi_device struct. */
a27872bf 380struct pci224_private {
ea1aeae4
IA
381 struct pci_dev *pci_dev; /* PCI device */
382 const unsigned short *hwrange;
383 unsigned long iobase1;
384 unsigned long state;
385 spinlock_t ao_spinlock;
790c5541
BP
386 unsigned int *ao_readback;
387 short *ao_scan_vals;
ea1aeae4
IA
388 unsigned char *ao_scan_order;
389 int intr_cpuid;
390 short intr_running;
391 unsigned short daccon;
392 unsigned int cached_div1;
393 unsigned int cached_div2;
394 unsigned int ao_stop_count;
395 short ao_stop_continuous;
396 unsigned short ao_enab; /* max 16 channels so 'short' will do */
397 unsigned char intsce;
a27872bf 398};
ea1aeae4 399
ea1aeae4
IA
400/*
401 * Called from the 'insn_write' function to perform a single write.
402 */
403static void
0a85b6f0
MT
404pci224_ao_set_data(struct comedi_device *dev, int chan, int range,
405 unsigned int data)
ea1aeae4 406{
9dc5a822
IA
407 const struct pci224_board *thisboard = comedi_board(dev);
408 struct pci224_private *devpriv = dev->private;
ea1aeae4
IA
409 unsigned short mangled;
410
411 /* Store unmangled data for readback. */
412 devpriv->ao_readback[chan] = data;
413 /* Enable the channel. */
414 outw(1 << chan, dev->iobase + PCI224_DACCEN);
415 /* Set range and reset FIFO. */
416 devpriv->daccon = COMBINE(devpriv->daccon, devpriv->hwrange[range],
0a85b6f0
MT
417 (PCI224_DACCON_POLAR_MASK |
418 PCI224_DACCON_VREF_MASK));
ea1aeae4 419 outw(devpriv->daccon | PCI224_DACCON_FIFORESET,
0a85b6f0 420 dev->iobase + PCI224_DACCON);
ea1aeae4
IA
421 /*
422 * Mangle the data. The hardware expects:
423 * - bipolar: 16-bit 2's complement
424 * - unipolar: 16-bit unsigned
425 */
426 mangled = (unsigned short)data << (16 - thisboard->ao_bits);
427 if ((devpriv->daccon & PCI224_DACCON_POLAR_MASK) ==
0a85b6f0 428 PCI224_DACCON_POLAR_BI) {
ea1aeae4
IA
429 mangled ^= 0x8000;
430 }
431 /* Write mangled data to the FIFO. */
432 outw(mangled, dev->iobase + PCI224_DACDATA);
433 /* Trigger the conversion. */
434 inw(dev->iobase + PCI224_SOFTTRIG);
435}
436
437/*
438 * 'insn_write' function for AO subdevice.
439 */
440static int
da91b269 441pci224_ao_insn_write(struct comedi_device *dev, struct comedi_subdevice *s,
0a85b6f0 442 struct comedi_insn *insn, unsigned int *data)
ea1aeae4
IA
443{
444 int i;
445 int chan, range;
446
447 /* Unpack channel and range. */
448 chan = CR_CHAN(insn->chanspec);
449 range = CR_RANGE(insn->chanspec);
450
451 /* Writing a list of values to an AO channel is probably not
452 * very useful, but that's how the interface is defined. */
767700c4 453 for (i = 0; i < insn->n; i++)
ea1aeae4 454 pci224_ao_set_data(dev, chan, range, data[i]);
767700c4 455
ea1aeae4
IA
456 return i;
457}
458
459/*
460 * 'insn_read' function for AO subdevice.
461 *
462 * N.B. The value read will not be valid if the DAC channel has
463 * never been written successfully since the device was attached
464 * or since the channel has been used by an AO streaming write
465 * command.
466 */
467static int
da91b269 468pci224_ao_insn_read(struct comedi_device *dev, struct comedi_subdevice *s,
0a85b6f0 469 struct comedi_insn *insn, unsigned int *data)
ea1aeae4 470{
9dc5a822 471 struct pci224_private *devpriv = dev->private;
ea1aeae4
IA
472 int i;
473 int chan;
474
475 chan = CR_CHAN(insn->chanspec);
476
767700c4 477 for (i = 0; i < insn->n; i++)
ea1aeae4 478 data[i] = devpriv->ao_readback[chan];
767700c4 479
ea1aeae4
IA
480
481 return i;
482}
483
484/*
485 * Just a wrapper for the inline function 'i8253_cascade_ns_to_timer'.
486 */
487static void
488pci224_cascade_ns_to_timer(int osc_base, unsigned int *d1, unsigned int *d2,
0a85b6f0 489 unsigned int *nanosec, int round_mode)
ea1aeae4
IA
490{
491 i8253_cascade_ns_to_timer(osc_base, d1, d2, nanosec, round_mode);
492}
493
494/*
495 * Kills a command running on the AO subdevice.
496 */
0a85b6f0
MT
497static void pci224_ao_stop(struct comedi_device *dev,
498 struct comedi_subdevice *s)
ea1aeae4 499{
9dc5a822 500 struct pci224_private *devpriv = dev->private;
ea1aeae4
IA
501 unsigned long flags;
502
767700c4 503 if (!test_and_clear_bit(AO_CMD_STARTED, &devpriv->state))
ea1aeae4 504 return;
767700c4 505
ea1aeae4 506
5f74ea14 507 spin_lock_irqsave(&devpriv->ao_spinlock, flags);
ea1aeae4
IA
508 /* Kill the interrupts. */
509 devpriv->intsce = 0;
510 outb(0, devpriv->iobase1 + PCI224_INT_SCE);
511 /*
512 * Interrupt routine may or may not be running. We may or may not
513 * have been called from the interrupt routine (directly or
514 * indirectly via a comedi_events() callback routine). It's highly
515 * unlikely that we've been called from some other interrupt routine
516 * but who knows what strange things coders get up to!
517 *
518 * If the interrupt routine is currently running, wait for it to
519 * finish, unless we appear to have been called via the interrupt
520 * routine.
521 */
522 while (devpriv->intr_running && devpriv->intr_cpuid != THISCPU) {
5f74ea14
GKH
523 spin_unlock_irqrestore(&devpriv->ao_spinlock, flags);
524 spin_lock_irqsave(&devpriv->ao_spinlock, flags);
ea1aeae4 525 }
5f74ea14 526 spin_unlock_irqrestore(&devpriv->ao_spinlock, flags);
ea1aeae4
IA
527 /* Reconfigure DAC for insn_write usage. */
528 outw(0, dev->iobase + PCI224_DACCEN); /* Disable channels. */
529 devpriv->daccon = COMBINE(devpriv->daccon,
0a85b6f0
MT
530 PCI224_DACCON_TRIG_SW |
531 PCI224_DACCON_FIFOINTR_EMPTY,
532 PCI224_DACCON_TRIG_MASK |
533 PCI224_DACCON_FIFOINTR_MASK);
ea1aeae4 534 outw(devpriv->daccon | PCI224_DACCON_FIFORESET,
0a85b6f0 535 dev->iobase + PCI224_DACCON);
ea1aeae4
IA
536}
537
538/*
539 * Handles start of acquisition for the AO subdevice.
540 */
0a85b6f0
MT
541static void pci224_ao_start(struct comedi_device *dev,
542 struct comedi_subdevice *s)
ea1aeae4 543{
9dc5a822 544 struct pci224_private *devpriv = dev->private;
ea6d0d4c 545 struct comedi_cmd *cmd = &s->async->cmd;
ea1aeae4
IA
546 unsigned long flags;
547
548 set_bit(AO_CMD_STARTED, &devpriv->state);
549 if (!devpriv->ao_stop_continuous && devpriv->ao_stop_count == 0) {
550 /* An empty acquisition! */
551 pci224_ao_stop(dev, s);
552 s->async->events |= COMEDI_CB_EOA;
553 comedi_event(dev, s);
554 } else {
555 /* Enable interrupts. */
5f74ea14 556 spin_lock_irqsave(&devpriv->ao_spinlock, flags);
767700c4 557 if (cmd->stop_src == TRIG_EXT)
ea1aeae4 558 devpriv->intsce = PCI224_INTR_EXT | PCI224_INTR_DAC;
767700c4 559 else
ea1aeae4 560 devpriv->intsce = PCI224_INTR_DAC;
767700c4 561
ea1aeae4 562 outb(devpriv->intsce, devpriv->iobase1 + PCI224_INT_SCE);
5f74ea14 563 spin_unlock_irqrestore(&devpriv->ao_spinlock, flags);
ea1aeae4
IA
564 }
565}
566
567/*
568 * Handles interrupts from the DAC FIFO.
569 */
0a85b6f0
MT
570static void pci224_ao_handle_fifo(struct comedi_device *dev,
571 struct comedi_subdevice *s)
ea1aeae4 572{
9dc5a822 573 struct pci224_private *devpriv = dev->private;
ea6d0d4c 574 struct comedi_cmd *cmd = &s->async->cmd;
ea1aeae4
IA
575 unsigned int num_scans;
576 unsigned int room;
577 unsigned short dacstat;
578 unsigned int i, n;
579 unsigned int bytes_per_scan;
580
581 if (cmd->chanlist_len) {
790c5541 582 bytes_per_scan = cmd->chanlist_len * sizeof(short);
ea1aeae4
IA
583 } else {
584 /* Shouldn't get here! */
790c5541 585 bytes_per_scan = sizeof(short);
ea1aeae4
IA
586 }
587 /* Determine number of scans available in buffer. */
588 num_scans = comedi_buf_read_n_available(s->async) / bytes_per_scan;
589 if (!devpriv->ao_stop_continuous) {
590 /* Fixed number of scans. */
767700c4 591 if (num_scans > devpriv->ao_stop_count)
ea1aeae4 592 num_scans = devpriv->ao_stop_count;
767700c4 593
ea1aeae4
IA
594 }
595
596 /* Determine how much room is in the FIFO (in samples). */
597 dacstat = inw(dev->iobase + PCI224_DACCON);
598 switch (dacstat & PCI224_DACCON_FIFOFL_MASK) {
599 case PCI224_DACCON_FIFOFL_EMPTY:
600 room = PCI224_FIFO_ROOM_EMPTY;
0a85b6f0 601 if (!devpriv->ao_stop_continuous && devpriv->ao_stop_count == 0) {
ea1aeae4
IA
602 /* FIFO empty at end of counted acquisition. */
603 pci224_ao_stop(dev, s);
604 s->async->events |= COMEDI_CB_EOA;
605 comedi_event(dev, s);
606 return;
607 }
608 break;
609 case PCI224_DACCON_FIFOFL_ONETOHALF:
610 room = PCI224_FIFO_ROOM_ONETOHALF;
611 break;
612 case PCI224_DACCON_FIFOFL_HALFTOFULL:
613 room = PCI224_FIFO_ROOM_HALFTOFULL;
614 break;
615 default:
616 room = PCI224_FIFO_ROOM_FULL;
617 break;
618 }
619 if (room >= PCI224_FIFO_ROOM_ONETOHALF) {
620 /* FIFO is less than half-full. */
621 if (num_scans == 0) {
622 /* Nothing left to put in the FIFO. */
623 pci224_ao_stop(dev, s);
624 s->async->events |= COMEDI_CB_OVERFLOW;
eedc1b7b 625 dev_err(dev->class_dev, "AO buffer underrun\n");
ea1aeae4
IA
626 }
627 }
628 /* Determine how many new scans can be put in the FIFO. */
767700c4 629 if (cmd->chanlist_len)
ea1aeae4 630 room /= cmd->chanlist_len;
767700c4 631
ea1aeae4 632 /* Determine how many scans to process. */
767700c4 633 if (num_scans > room)
ea1aeae4 634 num_scans = room;
767700c4 635
ea1aeae4
IA
636 /* Process scans. */
637 for (n = 0; n < num_scans; n++) {
638 cfc_read_array_from_buffer(s, &devpriv->ao_scan_vals[0],
0a85b6f0 639 bytes_per_scan);
ea1aeae4 640 for (i = 0; i < cmd->chanlist_len; i++) {
0a85b6f0
MT
641 outw(devpriv->ao_scan_vals[devpriv->ao_scan_order[i]],
642 dev->iobase + PCI224_DACDATA);
ea1aeae4
IA
643 }
644 }
645 if (!devpriv->ao_stop_continuous) {
646 devpriv->ao_stop_count -= num_scans;
647 if (devpriv->ao_stop_count == 0) {
648 /*
649 * Change FIFO interrupt trigger level to wait
650 * until FIFO is empty.
651 */
652 devpriv->daccon = COMBINE(devpriv->daccon,
0a85b6f0
MT
653 PCI224_DACCON_FIFOINTR_EMPTY,
654 PCI224_DACCON_FIFOINTR_MASK);
655 outw(devpriv->daccon, dev->iobase + PCI224_DACCON);
ea1aeae4
IA
656 }
657 }
658 if ((devpriv->daccon & PCI224_DACCON_TRIG_MASK) ==
0a85b6f0 659 PCI224_DACCON_TRIG_NONE) {
ea1aeae4
IA
660 unsigned short trig;
661
662 /*
663 * This is the initial DAC FIFO interrupt at the
664 * start of the acquisition. The DAC's scan trigger
665 * has been set to 'none' up until now.
666 *
667 * Now that data has been written to the FIFO, the
668 * DAC's scan trigger source can be set to the
669 * correct value.
670 *
671 * BUG: The first scan will be triggered immediately
672 * if the scan trigger source is at logic level 1.
673 */
674 if (cmd->scan_begin_src == TRIG_TIMER) {
675 trig = PCI224_DACCON_TRIG_Z2CT0;
676 } else {
677 /* cmd->scan_begin_src == TRIG_EXT */
767700c4 678 if (cmd->scan_begin_arg & CR_INVERT)
ea1aeae4 679 trig = PCI224_DACCON_TRIG_EXTN;
767700c4 680 else
ea1aeae4 681 trig = PCI224_DACCON_TRIG_EXTP;
767700c4 682
ea1aeae4
IA
683 }
684 devpriv->daccon = COMBINE(devpriv->daccon, trig,
0a85b6f0 685 PCI224_DACCON_TRIG_MASK);
ea1aeae4
IA
686 outw(devpriv->daccon, dev->iobase + PCI224_DACCON);
687 }
767700c4 688 if (s->async->events)
ea1aeae4 689 comedi_event(dev, s);
767700c4 690
ea1aeae4
IA
691}
692
693/*
694 * Internal trigger function to start acquisition on AO subdevice.
695 */
696static int
da91b269 697pci224_ao_inttrig_start(struct comedi_device *dev, struct comedi_subdevice *s,
0a85b6f0 698 unsigned int trignum)
ea1aeae4
IA
699{
700 if (trignum != 0)
701 return -EINVAL;
702
cbdfaffc 703 s->async->inttrig = NULL;
ea1aeae4
IA
704 pci224_ao_start(dev, s);
705
706 return 1;
707}
708
709#define MAX_SCAN_PERIOD 0xFFFFFFFFU
710#define MIN_SCAN_PERIOD 2500
711#define CONVERT_PERIOD 625
712
713/*
714 * 'do_cmdtest' function for AO subdevice.
715 */
716static int
0a85b6f0
MT
717pci224_ao_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
718 struct comedi_cmd *cmd)
ea1aeae4 719{
9dc5a822 720 struct pci224_private *devpriv = dev->private;
ea1aeae4
IA
721 int err = 0;
722 unsigned int tmp;
723
724 /* Step 1: make sure trigger sources are trivially valid. */
725
726 tmp = cmd->start_src;
727 cmd->start_src &= TRIG_INT | TRIG_EXT;
728 if (!cmd->start_src || tmp != cmd->start_src)
729 err++;
730
731 tmp = cmd->scan_begin_src;
732 cmd->scan_begin_src &= TRIG_EXT | TRIG_TIMER;
733 if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
734 err++;
735
736 tmp = cmd->convert_src;
737 cmd->convert_src &= TRIG_NOW;
738 if (!cmd->convert_src || tmp != cmd->convert_src)
739 err++;
740
741 tmp = cmd->scan_end_src;
742 cmd->scan_end_src &= TRIG_COUNT;
743 if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
744 err++;
745
746 tmp = cmd->stop_src;
747 cmd->stop_src &= TRIG_COUNT | TRIG_EXT | TRIG_NONE;
748 if (!cmd->stop_src || tmp != cmd->stop_src)
749 err++;
750
751 if (err)
752 return 1;
753
754 /* Step 2: make sure trigger sources are unique and mutually
755 * compatible. */
756
757 /* these tests are true if more than one _src bit is set */
758 if ((cmd->start_src & (cmd->start_src - 1)) != 0)
759 err++;
760 if ((cmd->scan_begin_src & (cmd->scan_begin_src - 1)) != 0)
761 err++;
762 if ((cmd->convert_src & (cmd->convert_src - 1)) != 0)
763 err++;
764 if ((cmd->scan_end_src & (cmd->scan_end_src - 1)) != 0)
765 err++;
766 if ((cmd->stop_src & (cmd->stop_src - 1)) != 0)
767 err++;
768
769 /* There's only one external trigger signal (which makes these
770 * tests easier). Only one thing can use it. */
771 tmp = 0;
772 if (cmd->start_src & TRIG_EXT)
773 tmp++;
774 if (cmd->scan_begin_src & TRIG_EXT)
775 tmp++;
776 if (cmd->stop_src & TRIG_EXT)
777 tmp++;
778 if (tmp > 1)
779 err++;
780
781 if (err)
782 return 2;
783
784 /* Step 3: make sure arguments are trivially compatible. */
785
786 switch (cmd->start_src) {
787 case TRIG_INT:
788 if (cmd->start_arg != 0) {
789 cmd->start_arg = 0;
790 err++;
791 }
792 break;
793 case TRIG_EXT:
794 /* Force to external trigger 0. */
795 if ((cmd->start_arg & ~CR_FLAGS_MASK) != 0) {
796 cmd->start_arg = COMBINE(cmd->start_arg, 0,
0a85b6f0 797 ~CR_FLAGS_MASK);
ea1aeae4
IA
798 err++;
799 }
800 /* The only flag allowed is CR_EDGE, which is ignored. */
801 if ((cmd->start_arg & CR_FLAGS_MASK & ~CR_EDGE) != 0) {
802 cmd->start_arg = COMBINE(cmd->start_arg, 0,
0a85b6f0 803 CR_FLAGS_MASK & ~CR_EDGE);
ea1aeae4
IA
804 err++;
805 }
806 break;
807 }
808
809 switch (cmd->scan_begin_src) {
810 case TRIG_TIMER:
811 if (cmd->scan_begin_arg > MAX_SCAN_PERIOD) {
812 cmd->scan_begin_arg = MAX_SCAN_PERIOD;
813 err++;
814 }
815 tmp = cmd->chanlist_len * CONVERT_PERIOD;
767700c4 816 if (tmp < MIN_SCAN_PERIOD)
ea1aeae4 817 tmp = MIN_SCAN_PERIOD;
767700c4 818
ea1aeae4
IA
819 if (cmd->scan_begin_arg < tmp) {
820 cmd->scan_begin_arg = tmp;
821 err++;
822 }
823 break;
824 case TRIG_EXT:
825 /* Force to external trigger 0. */
826 if ((cmd->scan_begin_arg & ~CR_FLAGS_MASK) != 0) {
827 cmd->scan_begin_arg = COMBINE(cmd->scan_begin_arg, 0,
0a85b6f0 828 ~CR_FLAGS_MASK);
ea1aeae4
IA
829 err++;
830 }
831 /* Only allow flags CR_EDGE and CR_INVERT. Ignore CR_EDGE. */
832 if ((cmd->scan_begin_arg & CR_FLAGS_MASK &
0a85b6f0 833 ~(CR_EDGE | CR_INVERT)) != 0) {
ea1aeae4 834 cmd->scan_begin_arg = COMBINE(cmd->scan_begin_arg, 0,
0a85b6f0
MT
835 CR_FLAGS_MASK & ~(CR_EDGE
836 |
837 CR_INVERT));
ea1aeae4
IA
838 err++;
839 }
840 break;
841 }
842
843 /* cmd->convert_src == TRIG_NOW */
844 if (cmd->convert_arg != 0) {
845 cmd->convert_arg = 0;
846 err++;
847 }
848
849 /* cmd->scan_end_arg == TRIG_COUNT */
850 if (cmd->scan_end_arg != cmd->chanlist_len) {
851 cmd->scan_end_arg = cmd->chanlist_len;
852 err++;
853 }
854
855 switch (cmd->stop_src) {
856 case TRIG_COUNT:
857 /* Any count allowed. */
858 break;
859 case TRIG_EXT:
860 /* Force to external trigger 0. */
861 if ((cmd->stop_arg & ~CR_FLAGS_MASK) != 0) {
862 cmd->stop_arg = COMBINE(cmd->stop_arg, 0,
0a85b6f0 863 ~CR_FLAGS_MASK);
ea1aeae4
IA
864 err++;
865 }
866 /* The only flag allowed is CR_EDGE, which is ignored. */
867 if ((cmd->stop_arg & CR_FLAGS_MASK & ~CR_EDGE) != 0) {
868 cmd->stop_arg = COMBINE(cmd->stop_arg, 0,
0a85b6f0 869 CR_FLAGS_MASK & ~CR_EDGE);
ea1aeae4
IA
870 }
871 break;
872 case TRIG_NONE:
873 if (cmd->stop_arg != 0) {
874 cmd->stop_arg = 0;
875 err++;
876 }
877 break;
878 }
879
880 if (err)
881 return 3;
882
883 /* Step 4: fix up any arguments. */
884
885 if (cmd->scan_begin_src == TRIG_TIMER) {
886 unsigned int div1, div2, round;
887 int round_mode = cmd->flags & TRIG_ROUND_MASK;
888
889 tmp = cmd->scan_begin_arg;
890 /* Check whether to use a single timer. */
891 switch (round_mode) {
892 case TRIG_ROUND_NEAREST:
893 default:
894 round = TIMEBASE_10MHZ / 2;
895 break;
896 case TRIG_ROUND_DOWN:
897 round = 0;
898 break;
899 case TRIG_ROUND_UP:
900 round = TIMEBASE_10MHZ - 1;
901 break;
902 }
903 /* Be careful to avoid overflow! */
904 div2 = cmd->scan_begin_arg / TIMEBASE_10MHZ;
905 div2 += (round + cmd->scan_begin_arg % TIMEBASE_10MHZ) /
0a85b6f0 906 TIMEBASE_10MHZ;
ea1aeae4
IA
907 if (div2 <= 0x10000) {
908 /* A single timer will suffice. */
909 if (div2 < 2)
910 div2 = 2;
911 cmd->scan_begin_arg = div2 * TIMEBASE_10MHZ;
912 if (cmd->scan_begin_arg < div2 ||
0a85b6f0 913 cmd->scan_begin_arg < TIMEBASE_10MHZ) {
ea1aeae4
IA
914 /* Overflow! */
915 cmd->scan_begin_arg = MAX_SCAN_PERIOD;
916 }
917 } else {
918 /* Use two timers. */
919 div1 = devpriv->cached_div1;
920 div2 = devpriv->cached_div2;
921 pci224_cascade_ns_to_timer(TIMEBASE_10MHZ, &div1, &div2,
0a85b6f0
MT
922 &cmd->scan_begin_arg,
923 round_mode);
ea1aeae4
IA
924 devpriv->cached_div1 = div1;
925 devpriv->cached_div2 = div2;
926 }
767700c4 927 if (tmp != cmd->scan_begin_arg)
ea1aeae4 928 err++;
767700c4 929
ea1aeae4
IA
930 }
931
932 if (err)
933 return 4;
934
935 /* Step 5: check channel list. */
936
937 if (cmd->chanlist && (cmd->chanlist_len > 0)) {
938 unsigned int range;
939 enum { range_err = 1, dupchan_err = 2, };
940 unsigned errors;
941 unsigned int n;
942 unsigned int ch;
943
944 /*
945 * Check all channels have the same range index. Don't care
946 * about analogue reference, as we can't configure it.
947 *
948 * Check the list has no duplicate channels.
949 */
950 range = CR_RANGE(cmd->chanlist[0]);
951 errors = 0;
952 tmp = 0;
953 for (n = 0; n < cmd->chanlist_len; n++) {
954 ch = CR_CHAN(cmd->chanlist[n]);
767700c4 955 if (tmp & (1U << ch))
ea1aeae4 956 errors |= dupchan_err;
767700c4 957
ea1aeae4 958 tmp |= (1U << ch);
767700c4 959 if (CR_RANGE(cmd->chanlist[n]) != range)
ea1aeae4 960 errors |= range_err;
767700c4 961
ea1aeae4
IA
962 }
963 if (errors) {
964 if (errors & dupchan_err) {
965 DPRINTK("comedi%d: " DRIVER_NAME
966 ": ao_cmdtest: "
967 "entries in chanlist must contain no "
968 "duplicate channels\n", dev->minor);
969 }
970 if (errors & range_err) {
971 DPRINTK("comedi%d: " DRIVER_NAME
972 ": ao_cmdtest: "
973 "entries in chanlist must all have "
974 "the same range index\n", dev->minor);
975 }
976 err++;
977 }
978 }
979
980 if (err)
981 return 5;
982
983 return 0;
984}
985
986/*
987 * 'do_cmd' function for AO subdevice.
988 */
da91b269 989static int pci224_ao_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
ea1aeae4 990{
9dc5a822 991 struct pci224_private *devpriv = dev->private;
ea6d0d4c 992 struct comedi_cmd *cmd = &s->async->cmd;
ea1aeae4
IA
993 int range;
994 unsigned int i, j;
995 unsigned int ch;
996 unsigned int rank;
997 unsigned long flags;
998
999 /* Cannot handle null/empty chanlist. */
767700c4 1000 if (cmd->chanlist == NULL || cmd->chanlist_len == 0)
ea1aeae4 1001 return -EINVAL;
767700c4 1002
ea1aeae4
IA
1003
1004 /* Determine which channels are enabled and their load order. */
1005 devpriv->ao_enab = 0;
1006
1007 for (i = 0; i < cmd->chanlist_len; i++) {
1008 ch = CR_CHAN(cmd->chanlist[i]);
1009 devpriv->ao_enab |= 1U << ch;
1010 rank = 0;
1011 for (j = 0; j < cmd->chanlist_len; j++) {
767700c4 1012 if (CR_CHAN(cmd->chanlist[j]) < ch)
ea1aeae4 1013 rank++;
767700c4 1014
ea1aeae4
IA
1015 }
1016 devpriv->ao_scan_order[rank] = i;
1017 }
1018
1019 /* Set enabled channels. */
1020 outw(devpriv->ao_enab, dev->iobase + PCI224_DACCEN);
1021
1022 /* Determine range and polarity. All channels the same. */
1023 range = CR_RANGE(cmd->chanlist[0]);
1024
1025 /*
1026 * Set DAC range and polarity.
1027 * Set DAC scan trigger source to 'none'.
1028 * Set DAC FIFO interrupt trigger level to 'not half full'.
1029 * Reset DAC FIFO.
1030 *
1031 * N.B. DAC FIFO interrupts are currently disabled.
1032 */
1033 devpriv->daccon = COMBINE(devpriv->daccon,
0a85b6f0
MT
1034 (devpriv->
1035 hwrange[range] | PCI224_DACCON_TRIG_NONE |
1036 PCI224_DACCON_FIFOINTR_NHALF),
1037 (PCI224_DACCON_POLAR_MASK |
1038 PCI224_DACCON_VREF_MASK |
1039 PCI224_DACCON_TRIG_MASK |
1040 PCI224_DACCON_FIFOINTR_MASK));
ea1aeae4 1041 outw(devpriv->daccon | PCI224_DACCON_FIFORESET,
0a85b6f0 1042 dev->iobase + PCI224_DACCON);
ea1aeae4
IA
1043
1044 if (cmd->scan_begin_src == TRIG_TIMER) {
1045 unsigned int div1, div2, round;
1046 unsigned int ns = cmd->scan_begin_arg;
1047 int round_mode = cmd->flags & TRIG_ROUND_MASK;
1048
1049 /* Check whether to use a single timer. */
1050 switch (round_mode) {
1051 case TRIG_ROUND_NEAREST:
1052 default:
1053 round = TIMEBASE_10MHZ / 2;
1054 break;
1055 case TRIG_ROUND_DOWN:
1056 round = 0;
1057 break;
1058 case TRIG_ROUND_UP:
1059 round = TIMEBASE_10MHZ - 1;
1060 break;
1061 }
1062 /* Be careful to avoid overflow! */
1063 div2 = cmd->scan_begin_arg / TIMEBASE_10MHZ;
1064 div2 += (round + cmd->scan_begin_arg % TIMEBASE_10MHZ) /
0a85b6f0 1065 TIMEBASE_10MHZ;
ea1aeae4
IA
1066 if (div2 <= 0x10000) {
1067 /* A single timer will suffice. */
1068 if (div2 < 2)
1069 div2 = 2;
1070 div2 &= 0xffff;
1071 div1 = 1; /* Flag that single timer to be used. */
1072 } else {
1073 /* Use two timers. */
1074 div1 = devpriv->cached_div1;
1075 div2 = devpriv->cached_div2;
1076 pci224_cascade_ns_to_timer(TIMEBASE_10MHZ, &div1, &div2,
0a85b6f0 1077 &ns, round_mode);
ea1aeae4
IA
1078 }
1079
1080 /*
1081 * The output of timer Z2-0 will be used as the scan trigger
1082 * source.
1083 */
1084 /* Make sure Z2-0 is gated on. */
1085 outb(GAT_CONFIG(0, GAT_VCC),
0a85b6f0 1086 devpriv->iobase1 + PCI224_ZGAT_SCE);
ea1aeae4
IA
1087 if (div1 == 1) {
1088 /* Not cascading. Z2-0 needs 10 MHz clock. */
1089 outb(CLK_CONFIG(0, CLK_10MHZ),
0a85b6f0 1090 devpriv->iobase1 + PCI224_ZCLK_SCE);
ea1aeae4
IA
1091 } else {
1092 /* Cascading with Z2-2. */
1093 /* Make sure Z2-2 is gated on. */
1094 outb(GAT_CONFIG(2, GAT_VCC),
0a85b6f0 1095 devpriv->iobase1 + PCI224_ZGAT_SCE);
ea1aeae4
IA
1096 /* Z2-2 needs 10 MHz clock. */
1097 outb(CLK_CONFIG(2, CLK_10MHZ),
0a85b6f0 1098 devpriv->iobase1 + PCI224_ZCLK_SCE);
ea1aeae4
IA
1099 /* Load Z2-2 mode (2) and counter (div1). */
1100 i8254_load(devpriv->iobase1 + PCI224_Z2_CT0, 0,
0a85b6f0 1101 2, div1, 2);
ea1aeae4
IA
1102 /* Z2-0 is clocked from Z2-2's output. */
1103 outb(CLK_CONFIG(0, CLK_OUTNM1),
0a85b6f0 1104 devpriv->iobase1 + PCI224_ZCLK_SCE);
ea1aeae4
IA
1105 }
1106 /* Load Z2-0 mode (2) and counter (div2). */
1107 i8254_load(devpriv->iobase1 + PCI224_Z2_CT0, 0, 0, div2, 2);
1108 }
1109
1110 /*
1111 * Sort out end of acquisition.
1112 */
1113 switch (cmd->stop_src) {
1114 case TRIG_COUNT:
1115 /* Fixed number of scans. */
1116 devpriv->ao_stop_continuous = 0;
1117 devpriv->ao_stop_count = cmd->stop_arg;
1118 break;
1119 default:
1120 /* Continuous scans. */
1121 devpriv->ao_stop_continuous = 1;
1122 devpriv->ao_stop_count = 0;
1123 break;
1124 }
1125
1126 /*
1127 * Sort out start of acquisition.
1128 */
1129 switch (cmd->start_src) {
1130 case TRIG_INT:
5f74ea14 1131 spin_lock_irqsave(&devpriv->ao_spinlock, flags);
ea1aeae4 1132 s->async->inttrig = &pci224_ao_inttrig_start;
5f74ea14 1133 spin_unlock_irqrestore(&devpriv->ao_spinlock, flags);
ea1aeae4
IA
1134 break;
1135 case TRIG_EXT:
1136 /* Enable external interrupt trigger to start acquisition. */
5f74ea14 1137 spin_lock_irqsave(&devpriv->ao_spinlock, flags);
ea1aeae4
IA
1138 devpriv->intsce |= PCI224_INTR_EXT;
1139 outb(devpriv->intsce, devpriv->iobase1 + PCI224_INT_SCE);
5f74ea14 1140 spin_unlock_irqrestore(&devpriv->ao_spinlock, flags);
ea1aeae4
IA
1141 break;
1142 }
1143
1144 return 0;
1145}
1146
1147/*
1148 * 'cancel' function for AO subdevice.
1149 */
0a85b6f0
MT
1150static int pci224_ao_cancel(struct comedi_device *dev,
1151 struct comedi_subdevice *s)
ea1aeae4
IA
1152{
1153 pci224_ao_stop(dev, s);
1154 return 0;
1155}
1156
1157/*
1158 * 'munge' data for AO command.
1159 */
1160static void
0a85b6f0
MT
1161pci224_ao_munge(struct comedi_device *dev, struct comedi_subdevice *s,
1162 void *data, unsigned int num_bytes, unsigned int chan_index)
ea1aeae4 1163{
9dc5a822
IA
1164 const struct pci224_board *thisboard = comedi_board(dev);
1165 struct pci224_private *devpriv = dev->private;
d163679c 1166 struct comedi_async *async = s->async;
790c5541 1167 short *array = data;
ea1aeae4
IA
1168 unsigned int length = num_bytes / sizeof(*array);
1169 unsigned int offset;
1170 unsigned int shift;
1171 unsigned int i;
1172
1173 /* The hardware expects 16-bit numbers. */
1174 shift = 16 - thisboard->ao_bits;
1175 /* Channels will be all bipolar or all unipolar. */
1176 if ((devpriv->hwrange[CR_RANGE(async->cmd.chanlist[0])] &
0a85b6f0 1177 PCI224_DACCON_POLAR_MASK) == PCI224_DACCON_POLAR_UNI) {
ea1aeae4
IA
1178 /* Unipolar */
1179 offset = 0;
1180 } else {
1181 /* Bipolar */
1182 offset = 32768;
1183 }
1184 /* Munge the data. */
767700c4 1185 for (i = 0; i < length; i++)
ea1aeae4 1186 array[i] = (array[i] << shift) - offset;
767700c4 1187
ea1aeae4
IA
1188}
1189
1190/*
1191 * Interrupt handler.
1192 */
70265d24 1193static irqreturn_t pci224_interrupt(int irq, void *d)
ea1aeae4 1194{
71b5f4f1 1195 struct comedi_device *dev = d;
9dc5a822 1196 struct pci224_private *devpriv = dev->private;
34c43922 1197 struct comedi_subdevice *s = &dev->subdevices[0];
ea6d0d4c 1198 struct comedi_cmd *cmd;
ea1aeae4
IA
1199 unsigned char intstat, valid_intstat;
1200 unsigned char curenab;
1201 int retval = 0;
1202 unsigned long flags;
1203
1204 intstat = inb(devpriv->iobase1 + PCI224_INT_SCE) & 0x3F;
1205 if (intstat) {
1206 retval = 1;
5f74ea14 1207 spin_lock_irqsave(&devpriv->ao_spinlock, flags);
ea1aeae4
IA
1208 valid_intstat = devpriv->intsce & intstat;
1209 /* Temporarily disable interrupt sources. */
1210 curenab = devpriv->intsce & ~intstat;
1211 outb(curenab, devpriv->iobase1 + PCI224_INT_SCE);
1212 devpriv->intr_running = 1;
1213 devpriv->intr_cpuid = THISCPU;
5f74ea14 1214 spin_unlock_irqrestore(&devpriv->ao_spinlock, flags);
ea1aeae4
IA
1215 if (valid_intstat != 0) {
1216 cmd = &s->async->cmd;
1217 if (valid_intstat & PCI224_INTR_EXT) {
1218 devpriv->intsce &= ~PCI224_INTR_EXT;
767700c4 1219 if (cmd->start_src == TRIG_EXT)
ea1aeae4 1220 pci224_ao_start(dev, s);
767700c4 1221 else if (cmd->stop_src == TRIG_EXT)
ea1aeae4 1222 pci224_ao_stop(dev, s);
767700c4 1223
ea1aeae4 1224 }
767700c4 1225 if (valid_intstat & PCI224_INTR_DAC)
ea1aeae4 1226 pci224_ao_handle_fifo(dev, s);
767700c4 1227
ea1aeae4
IA
1228 }
1229 /* Reenable interrupt sources. */
5f74ea14 1230 spin_lock_irqsave(&devpriv->ao_spinlock, flags);
ea1aeae4
IA
1231 if (curenab != devpriv->intsce) {
1232 outb(devpriv->intsce,
0a85b6f0 1233 devpriv->iobase1 + PCI224_INT_SCE);
ea1aeae4
IA
1234 }
1235 devpriv->intr_running = 0;
5f74ea14 1236 spin_unlock_irqrestore(&devpriv->ao_spinlock, flags);
ea1aeae4
IA
1237 }
1238 return IRQ_RETVAL(retval);
1239}
1240
5e9d922f
IA
1241/*
1242 * This function looks for a board matching the supplied PCI device.
1243 */
1244static const struct pci224_board
1245*pci224_find_pci_board(struct pci_dev *pci_dev)
1246{
1247 int i;
1248
1249 for (i = 0; i < ARRAY_SIZE(pci224_boards); i++)
1250 if (pci_dev->device == pci224_boards[i].devid)
1251 return &pci224_boards[i];
1252 return NULL;
1253}
1254
ea1aeae4
IA
1255/*
1256 * This function looks for a PCI device matching the requested board name,
1257 * bus and slot.
1258 */
01ea83bc
IA
1259static struct pci_dev *
1260pci224_find_pci(struct comedi_device *dev, int bus, int slot)
ea1aeae4 1261{
9dc5a822 1262 const struct pci224_board *thisboard = comedi_board(dev);
ea1aeae4
IA
1263 struct pci_dev *pci_dev = NULL;
1264
ea1aeae4
IA
1265 /* Look for matching PCI device. */
1266 for (pci_dev = pci_get_device(PCI_VENDOR_ID_AMPLICON, PCI_ANY_ID, NULL);
0a85b6f0
MT
1267 pci_dev != NULL;
1268 pci_dev = pci_get_device(PCI_VENDOR_ID_AMPLICON, PCI_ANY_ID,
1269 pci_dev)) {
ea1aeae4
IA
1270 /* If bus/slot specified, check them. */
1271 if (bus || slot) {
1272 if (bus != pci_dev->bus->number
0a85b6f0 1273 || slot != PCI_SLOT(pci_dev->devfn))
ea1aeae4
IA
1274 continue;
1275 }
1276 if (thisboard->model == any_model) {
1277 /* Match any supported model. */
5e9d922f
IA
1278 const struct pci224_board *board_ptr;
1279 board_ptr = pci224_find_pci_board(pci_dev);
1280 if (board_ptr == NULL)
ea1aeae4 1281 continue;
5e9d922f
IA
1282 /* Change board_ptr to matched board. */
1283 dev->board_ptr = board_ptr;
9dc5a822 1284 thisboard = comedi_board(dev);
ea1aeae4
IA
1285 } else {
1286 /* Match specific model name. */
1287 if (thisboard->devid != pci_dev->device)
1288 continue;
1289 }
1290
1291 /* Found a match. */
01ea83bc 1292 return pci_dev;
ea1aeae4
IA
1293 }
1294 /* No match found. */
1295 if (bus || slot) {
eedc1b7b
IA
1296 dev_err(dev->class_dev,
1297 "error! no %s found at pci %02x:%02x!\n",
1298 thisboard->name, bus, slot);
ea1aeae4 1299 } else {
eedc1b7b
IA
1300 dev_err(dev->class_dev, "error! no %s found!\n",
1301 thisboard->name);
ea1aeae4 1302 }
01ea83bc 1303 return NULL;
ea1aeae4
IA
1304}
1305
eedc1b7b
IA
1306static void pci224_report_attach(struct comedi_device *dev, unsigned int irq)
1307{
9dc5a822 1308 struct pci224_private *devpriv = dev->private;
eedc1b7b
IA
1309 char tmpbuf[30];
1310
1311 if (irq)
1312 snprintf(tmpbuf, sizeof(tmpbuf), "irq %u%s", irq,
1313 (dev->irq ? "" : " UNAVAILABLE"));
1314 else
1315 snprintf(tmpbuf, sizeof(tmpbuf), "no irq");
1316 dev_info(dev->class_dev, "%s (pci %s) (%s) attached\n",
1317 dev->board_name, pci_name(devpriv->pci_dev), tmpbuf);
1318}
1319
ea1aeae4 1320/*
5e9d922f 1321 * Common part of attach and attach_pci.
ea1aeae4 1322 */
5e9d922f
IA
1323static int pci224_attach_common(struct comedi_device *dev,
1324 struct pci_dev *pci_dev, int *options)
ea1aeae4 1325{
9dc5a822
IA
1326 const struct pci224_board *thisboard = comedi_board(dev);
1327 struct pci224_private *devpriv = dev->private;
34c43922 1328 struct comedi_subdevice *s;
ea1aeae4 1329 unsigned int irq;
ea1aeae4
IA
1330 unsigned n;
1331 int ret;
1332
c3744138
BP
1333 devpriv->pci_dev = pci_dev;
1334 ret = comedi_pci_enable(pci_dev, DRIVER_NAME);
1335 if (ret < 0) {
eedc1b7b
IA
1336 dev_err(dev->class_dev,
1337 "error! cannot enable PCI device and request regions!\n"
1338 );
ea1aeae4
IA
1339 return ret;
1340 }
1341 spin_lock_init(&devpriv->ao_spinlock);
1342
1343 devpriv->iobase1 = pci_resource_start(pci_dev, 2);
1344 dev->iobase = pci_resource_start(pci_dev, 3);
1345 irq = pci_dev->irq;
1346
1347 /* Allocate readback buffer for AO channels. */
1348 devpriv->ao_readback = kmalloc(sizeof(devpriv->ao_readback[0]) *
0a85b6f0 1349 thisboard->ao_chans, GFP_KERNEL);
767700c4 1350 if (!devpriv->ao_readback)
ea1aeae4 1351 return -ENOMEM;
767700c4 1352
ea1aeae4
IA
1353
1354 /* Allocate buffer to hold values for AO channel scan. */
1355 devpriv->ao_scan_vals = kmalloc(sizeof(devpriv->ao_scan_vals[0]) *
0a85b6f0 1356 thisboard->ao_chans, GFP_KERNEL);
767700c4 1357 if (!devpriv->ao_scan_vals)
ea1aeae4 1358 return -ENOMEM;
767700c4 1359
ea1aeae4
IA
1360
1361 /* Allocate buffer to hold AO channel scan order. */
1362 devpriv->ao_scan_order = kmalloc(sizeof(devpriv->ao_scan_order[0]) *
0a85b6f0 1363 thisboard->ao_chans, GFP_KERNEL);
767700c4 1364 if (!devpriv->ao_scan_order)
ea1aeae4 1365 return -ENOMEM;
767700c4 1366
ea1aeae4
IA
1367
1368 /* Disable interrupt sources. */
1369 devpriv->intsce = 0;
1370 outb(0, devpriv->iobase1 + PCI224_INT_SCE);
1371
1372 /* Initialize the DAC hardware. */
1373 outw(PCI224_DACCON_GLOBALRESET, dev->iobase + PCI224_DACCON);
1374 outw(0, dev->iobase + PCI224_DACCEN);
1375 outw(0, dev->iobase + PCI224_FIFOSIZ);
1376 devpriv->daccon = (PCI224_DACCON_TRIG_SW | PCI224_DACCON_POLAR_BI |
0a85b6f0
MT
1377 PCI224_DACCON_FIFOENAB |
1378 PCI224_DACCON_FIFOINTR_EMPTY);
ea1aeae4 1379 outw(devpriv->daccon | PCI224_DACCON_FIFORESET,
0a85b6f0 1380 dev->iobase + PCI224_DACCON);
ea1aeae4 1381
2f0b9d08 1382 ret = comedi_alloc_subdevices(dev, 1);
8b6c5694 1383 if (ret)
ea1aeae4 1384 return ret;
ea1aeae4
IA
1385
1386 s = dev->subdevices + 0;
1387 /* Analog output subdevice. */
1388 s->type = COMEDI_SUBD_AO;
1389 s->subdev_flags = SDF_WRITABLE | SDF_GROUND | SDF_CMD_WRITE;
1390 s->n_chan = thisboard->ao_chans;
1391 s->maxdata = (1 << thisboard->ao_bits) - 1;
1392 s->insn_write = &pci224_ao_insn_write;
1393 s->insn_read = &pci224_ao_insn_read;
1394 s->len_chanlist = s->n_chan;
1395
1396 dev->write_subdev = s;
1397 s->do_cmd = &pci224_ao_cmd;
1398 s->do_cmdtest = &pci224_ao_cmdtest;
1399 s->cancel = &pci224_ao_cancel;
1400 s->munge = &pci224_ao_munge;
1401
1402 /* Sort out channel range options. */
1403 if (thisboard->model == pci234_model) {
1404 /* PCI234 range options. */
9ced1de6 1405 const struct comedi_lrange **range_table_list;
ea1aeae4
IA
1406
1407 s->range_table_list = range_table_list =
0a85b6f0
MT
1408 kmalloc(sizeof(struct comedi_lrange *) * s->n_chan,
1409 GFP_KERNEL);
767700c4 1410 if (!s->range_table_list)
ea1aeae4 1411 return -ENOMEM;
767700c4 1412
5e9d922f
IA
1413 if (options) {
1414 for (n = 2; n < 3 + s->n_chan; n++) {
1415 if (options[n] < 0 || options[n] > 1) {
eedc1b7b
IA
1416 dev_warn(dev->class_dev, DRIVER_NAME
1417 ": warning! bad options[%u]=%d\n",
1418 n, options[n]);
5e9d922f 1419 }
ea1aeae4
IA
1420 }
1421 }
1422 for (n = 0; n < s->n_chan; n++) {
5e9d922f
IA
1423 if (n < COMEDI_NDEVCONFOPTS - 3 && options &&
1424 options[3 + n] == 1) {
1425 if (options[2] == 1)
ea1aeae4 1426 range_table_list[n] = &range_pci234_ext;
767700c4 1427 else
ea1aeae4 1428 range_table_list[n] = &range_bipolar5;
767700c4 1429
ea1aeae4 1430 } else {
5e9d922f 1431 if (options && options[2] == 1) {
ea1aeae4 1432 range_table_list[n] =
0a85b6f0 1433 &range_pci234_ext2;
ea1aeae4
IA
1434 } else {
1435 range_table_list[n] = &range_bipolar10;
1436 }
1437 }
1438 }
1439 devpriv->hwrange = hwrange_pci234;
1440 } else {
1441 /* PCI224 range options. */
5e9d922f 1442 if (options && options[2] == 1) {
ea1aeae4
IA
1443 s->range_table = &range_pci224_external;
1444 devpriv->hwrange = hwrange_pci224_external;
1445 } else {
5e9d922f 1446 if (options && options[2] != 0) {
eedc1b7b
IA
1447 dev_warn(dev->class_dev, DRIVER_NAME
1448 ": warning! bad options[2]=%d\n",
1449 options[2]);
ea1aeae4
IA
1450 }
1451 s->range_table = &range_pci224_internal;
1452 devpriv->hwrange = hwrange_pci224_internal;
1453 }
1454 }
1455
1456 dev->board_name = thisboard->name;
1457
1458 if (irq) {
5f74ea14
GKH
1459 ret = request_irq(irq, pci224_interrupt, IRQF_SHARED,
1460 DRIVER_NAME, dev);
ea1aeae4 1461 if (ret < 0) {
eedc1b7b
IA
1462 dev_err(dev->class_dev,
1463 "error! unable to allocate irq %u\n", irq);
ea1aeae4
IA
1464 return ret;
1465 } else {
1466 dev->irq = irq;
1467 }
1468 }
1469
eedc1b7b 1470 pci224_report_attach(dev, irq);
ea1aeae4
IA
1471 return 1;
1472}
1473
5e9d922f
IA
1474static int pci224_attach(struct comedi_device *dev, struct comedi_devconfig *it)
1475{
1476 struct pci_dev *pci_dev;
1477 int bus, slot;
1478 int ret;
1479
eedc1b7b 1480 dev_info(dev->class_dev, DRIVER_NAME ": attach\n");
5e9d922f
IA
1481
1482 bus = it->options[0];
1483 slot = it->options[1];
1484 ret = alloc_private(dev, sizeof(struct pci224_private));
1485 if (ret < 0) {
eedc1b7b 1486 dev_err(dev->class_dev, "error! out of memory!\n");
5e9d922f
IA
1487 return ret;
1488 }
1489
01ea83bc
IA
1490 pci_dev = pci224_find_pci(dev, bus, slot);
1491 if (pci_dev == NULL)
1492 return -EIO;
5e9d922f
IA
1493
1494 return pci224_attach_common(dev, pci_dev, it->options);
1495}
1496
52954abc 1497static int __devinit
5e9d922f
IA
1498pci224_attach_pci(struct comedi_device *dev, struct pci_dev *pci_dev)
1499{
1500 int ret;
1501
eedc1b7b
IA
1502 dev_info(dev->class_dev, DRIVER_NAME ": attach_pci %s\n",
1503 pci_name(pci_dev));
5e9d922f
IA
1504
1505 ret = alloc_private(dev, sizeof(struct pci224_private));
1506 if (ret < 0) {
eedc1b7b 1507 dev_err(dev->class_dev, "error! out of memory!\n");
5e9d922f
IA
1508 return ret;
1509 }
1510
1511 dev->board_ptr = pci224_find_pci_board(pci_dev);
1512 if (dev->board_ptr == NULL) {
eedc1b7b
IA
1513 dev_err(dev->class_dev,
1514 DRIVER_NAME ": BUG! cannot determine board type!\n");
5e9d922f
IA
1515 return -EINVAL;
1516 }
1517 return pci224_attach_common(dev, pci_dev, NULL);
1518}
1519
484ecc95 1520static void pci224_detach(struct comedi_device *dev)
ea1aeae4 1521{
9dc5a822
IA
1522 struct pci224_private *devpriv = dev->private;
1523
767700c4 1524 if (dev->irq)
5f74ea14 1525 free_irq(dev->irq, dev);
ea1aeae4 1526 if (dev->subdevices) {
34c43922 1527 struct comedi_subdevice *s;
ea1aeae4
IA
1528
1529 s = dev->subdevices + 0;
1530 /* AO subdevice */
48d07f2b 1531 kfree(s->range_table_list);
ea1aeae4
IA
1532 }
1533 if (devpriv) {
48d07f2b 1534 kfree(devpriv->ao_readback);
1535 kfree(devpriv->ao_scan_vals);
1536 kfree(devpriv->ao_scan_order);
ea1aeae4 1537 if (devpriv->pci_dev) {
767700c4 1538 if (dev->iobase)
ea1aeae4 1539 comedi_pci_disable(devpriv->pci_dev);
ea1aeae4
IA
1540 pci_dev_put(devpriv->pci_dev);
1541 }
1542 }
ea1aeae4 1543}
90f703d3 1544
0d09df00
HS
1545static struct comedi_driver amplc_pci224_driver = {
1546 .driver_name = "amplc_pci224",
1547 .module = THIS_MODULE,
1548 .attach = pci224_attach,
1549 .detach = pci224_detach,
1550 .attach_pci = pci224_attach_pci,
1551 .board_name = &pci224_boards[0].name,
1552 .offset = sizeof(struct pci224_board),
1553 .num_names = ARRAY_SIZE(pci224_boards),
1554};
1555
1556static int __devinit amplc_pci224_pci_probe(struct pci_dev *dev,
1557 const struct pci_device_id
1558 *ent)
1559{
1560 return comedi_pci_auto_config(dev, &amplc_pci224_driver);
1561}
1562
1563static void __devexit amplc_pci224_pci_remove(struct pci_dev *dev)
1564{
1565 comedi_pci_auto_unconfig(dev);
1566}
1567
1568static DEFINE_PCI_DEVICE_TABLE(amplc_pci224_pci_table) = {
1569 { PCI_DEVICE(PCI_VENDOR_ID_AMPLICON, PCI_DEVICE_ID_AMPLICON_PCI224) },
1570 { PCI_DEVICE(PCI_VENDOR_ID_AMPLICON, PCI_DEVICE_ID_AMPLICON_PCI234) },
1571 { 0 }
1572};
1573MODULE_DEVICE_TABLE(pci, amplc_pci224_pci_table);
1574
1575static struct pci_driver amplc_pci224_pci_driver = {
1576 .name = "amplc_pci224",
1577 .id_table = amplc_pci224_pci_table,
1578 .probe = amplc_pci224_pci_probe,
1579 .remove = __devexit_p(amplc_pci224_pci_remove),
1580};
1581module_comedi_pci_driver(amplc_pci224_driver, amplc_pci224_pci_driver);
1582
90f703d3
AT
1583MODULE_AUTHOR("Comedi http://www.comedi.org");
1584MODULE_DESCRIPTION("Comedi low-level driver");
1585MODULE_LICENSE("GPL");
This page took 0.380307 seconds and 5 git commands to generate.