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