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