amplc_pci230.c revision b6ac161364eccce1bea4a23a9de395883e90d7ab
1 /*
2    comedi/drivers/amplc_pci230.c
3    Driver for Amplicon PCI230 and PCI260 Multifunction I/O boards.
4
5    Copyright (C) 2001 Allan Willcox <allanwillcox@ozemail.com.au>
6
7    COMEDI - Linux Control and Measurement Device Interface
8    Copyright (C) 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/*
25Driver: amplc_pci230
26Description: Amplicon PCI230, PCI260 Multifunction I/O boards
27Author: Allan Willcox <allanwillcox@ozemail.com.au>,
28  Steve D Sharples <steve.sharples@nottingham.ac.uk>,
29  Ian Abbott <abbotti@mev.co.uk>
30Updated: Wed, 22 Oct 2008 12:34:49 +0100
31Devices: [Amplicon] PCI230 (pci230 or amplc_pci230),
32  PCI230+ (pci230+ or amplc_pci230),
33  PCI260 (pci260 or amplc_pci230), PCI260+ (pci260+ or amplc_pci230)
34Status: works
35
36Configuration options:
37  [0] - PCI bus of device (optional).
38  [1] - PCI slot of device (optional).
39          If bus/slot is not specified, the first available PCI device
40          will be used.
41
42Configuring a "amplc_pci230" will match any supported card and it will
43choose the best match, picking the "+" models if possible.  Configuring
44a "pci230" will match a PCI230 or PCI230+ card and it will be treated as
45a PCI230.  Configuring a "pci260" will match a PCI260 or PCI260+ card
46and it will be treated as a PCI260.  Configuring a "pci230+" will match
47a PCI230+ card.  Configuring a "pci260+" will match a PCI260+ card.
48
49Subdevices:
50
51                PCI230(+)    PCI260(+)
52                ---------    ---------
53  Subdevices       3            1
54        0          AI           AI
55	1          AO
56	2          DIO
57
58AI Subdevice:
59
60  The AI subdevice has 16 single-ended channels or 8 differential
61  channels.
62
63  The PCI230 and PCI260 cards have 12-bit resolution.  The PCI230+ and
64  PCI260+ cards have 16-bit resolution.
65
66  For differential mode, use inputs 2N and 2N+1 for channel N (e.g. use
67  inputs 14 and 15 for channel 7).  If the card is physically a PCI230
68  or PCI260 then it actually uses a "pseudo-differential" mode where the
69  inputs are sampled a few microseconds apart.  The PCI230+ and PCI260+
70  use true differential sampling.  Another difference is that if the
71  card is physically a PCI230 or PCI260, the inverting input is 2N,
72  whereas for a PCI230+ or PCI260+ the inverting input is 2N+1.  So if a
73  PCI230 is physically replaced by a PCI230+ (or a PCI260 with a
74  PCI260+) and differential mode is used, the differential inputs need
75  to be physically swapped on the connector.
76
77  The following input ranges are supported:
78
79    0 => [-10, +10] V
80    1 => [-5, +5] V
81    2 => [-2.5, +2.5] V
82    3 => [-1.25, +1.25] V
83    4 => [0, 10] V
84    5 => [0, 5] V
85    6 => [0, 2.5] V
86
87AI Commands:
88
89  +=========+==============+===========+============+==========+
90  |start_src|scan_begin_src|convert_src|scan_end_src| stop_src |
91  +=========+==============+===========+============+==========+
92  |TRIG_NOW | TRIG_FOLLOW  |TRIG_TIMER | TRIG_COUNT |TRIG_NONE |
93  |TRIG_INT |              |TRIG_EXT(3)|            |TRIG_COUNT|
94  |         |              |TRIG_INT   |            |          |
95  |         |--------------|-----------|            |          |
96  |         | TRIG_TIMER(1)|TRIG_TIMER |            |          |
97  |         | TRIG_EXT(2)  |           |            |          |
98  |         | TRIG_INT     |           |            |          |
99  +---------+--------------+-----------+------------+----------+
100
101  Note 1: If AI command and AO command are used simultaneously, only
102          one may have scan_begin_src == TRIG_TIMER.
103
104  Note 2: For PCI230 and PCI230+, scan_begin_src == TRIG_EXT uses
105          DIO channel 16 (pin 49) which will need to be configured as
106          a digital input.  For PCI260+, the EXTTRIG/EXTCONVCLK input
107          (pin 17) is used instead.  For PCI230, scan_begin_src ==
108          TRIG_EXT is not supported.  The trigger is a rising edge
109          on the input.
110
111  Note 3: For convert_src == TRIG_EXT, the EXTTRIG/EXTCONVCLK input
112          (pin 25 on PCI230(+), pin 17 on PCI260(+)) is used.  The
113          convert_arg value is interpreted as follows:
114
115            convert_arg == (CR_EDGE | 0) => rising edge
116            convert_arg == (CR_EDGE | CR_INVERT | 0) => falling edge
117            convert_arg == 0 => falling edge (backwards compatibility)
118            convert_arg == 1 => rising edge (backwards compatibility)
119
120  All entries in the channel list must use the same analogue reference.
121  If the analogue reference is not AREF_DIFF (not differential) each
122  pair of channel numbers (0 and 1, 2 and 3, etc.) must use the same
123  input range.  The input ranges used in the sequence must be all
124  bipolar (ranges 0 to 3) or all unipolar (ranges 4 to 6).  The channel
125  sequence must consist of 1 or more identical subsequences.  Within the
126  subsequence, channels must be in ascending order with no repeated
127  channels.  For example, the following sequences are valid: 0 1 2 3
128  (single valid subsequence), 0 2 3 5 0 2 3 5 (repeated valid
129  subsequence), 1 1 1 1 (repeated valid subsequence).  The following
130  sequences are invalid: 0 3 2 1 (invalid subsequence), 0 2 3 5 0 2 3
131  (incompletely repeated subsequence).  Some versions of the PCI230+ and
132  PCI260+ have a bug that requires a subsequence longer than one entry
133  long to include channel 0.
134
135AO Subdevice:
136
137  The AO subdevice has 2 channels with 12-bit resolution.
138
139  The following output ranges are supported:
140
141    0 => [0, 10] V
142    1 => [-10, +10] V
143
144AO Commands:
145
146  +=========+==============+===========+============+==========+
147  |start_src|scan_begin_src|convert_src|scan_end_src| stop_src |
148  +=========+==============+===========+============+==========+
149  |TRIG_INT | TRIG_TIMER(1)| TRIG_NOW  | TRIG_COUNT |TRIG_NONE |
150  |         | TRIG_EXT(2)  |           |            |TRIG_COUNT|
151  |         | TRIG_INT     |           |            |          |
152  +---------+--------------+-----------+------------+----------+
153
154  Note 1: If AI command and AO command are used simultaneously, only
155          one may have scan_begin_src == TRIG_TIMER.
156
157  Note 2: scan_begin_src == TRIG_EXT is only supported if the card is
158          configured as a PCI230+ and is only supported on later
159          versions of the card.  As a card configured as a PCI230+ is
160          not guaranteed to support external triggering, please consider
161          this support to be a bonus.  It uses the EXTTRIG/ EXTCONVCLK
162          input (PCI230+ pin 25).  Triggering will be on the rising edge
163          unless the CR_INVERT flag is set in scan_begin_arg.
164
165  The channels in the channel sequence must be in ascending order with
166  no repeats.  All entries in the channel sequence must use the same
167  output range.
168
169DIO Subdevice:
170
171  The DIO subdevice is a 8255 chip providing 24 DIO channels.  The DIO
172  channels are configurable as inputs or outputs in four groups:
173
174    Port A  - channels  0 to  7
175    Port B  - channels  8 to 15
176    Port CL - channels 16 to 19
177    Port CH - channels 20 to 23
178
179  Only mode 0 of the 8255 chip is supported.
180
181  Bit 0 of port C (DIO channel 16) is also used as an external scan
182  trigger input for AI commands on PCI230 and PCI230+, so would need to
183  be configured as an input to use it for that purpose.
184*/
185/*
186Extra triggered scan functionality, interrupt bug-fix added by Steve Sharples.
187Support for PCI230+/260+, more triggered scan functionality, and workarounds
188for (or detection of) various hardware problems added by Ian Abbott.
189*/
190
191#include "../comedidev.h"
192
193#include <linux/delay.h>
194#include <linux/interrupt.h>
195
196#include "comedi_pci.h"
197#include "8253.h"
198#include "8255.h"
199
200/* PCI230 PCI configuration register information */
201#define PCI_VENDOR_ID_AMPLICON 0x14dc
202#define PCI_DEVICE_ID_PCI230 0x0000
203#define PCI_DEVICE_ID_PCI260 0x0006
204#define PCI_DEVICE_ID_INVALID 0xffff
205
206#define PCI230_IO1_SIZE 32	/* Size of I/O space 1 */
207#define PCI230_IO2_SIZE 16	/* Size of I/O space 2 */
208
209/* PCI230 i/o space 1 registers. */
210#define PCI230_PPI_X_BASE	0x00	/* User PPI (82C55) base */
211#define PCI230_PPI_X_A		0x00	/* User PPI (82C55) port A */
212#define PCI230_PPI_X_B		0x01	/* User PPI (82C55) port B */
213#define PCI230_PPI_X_C		0x02	/* User PPI (82C55) port C */
214#define PCI230_PPI_X_CMD	0x03	/* User PPI (82C55) control word */
215#define PCI230_Z2_CT_BASE	0x14	/* 82C54 counter/timer base */
216#define PCI230_Z2_CT0		0x14	/* 82C54 counter/timer 0 */
217#define PCI230_Z2_CT1		0x15	/* 82C54 counter/timer 1 */
218#define PCI230_Z2_CT2		0x16	/* 82C54 counter/timer 2 */
219#define PCI230_Z2_CTC		0x17	/* 82C54 counter/timer control word */
220#define PCI230_ZCLK_SCE		0x1A	/* Group Z Clock Configuration */
221#define PCI230_ZGAT_SCE		0x1D	/* Group Z Gate Configuration */
222#define PCI230_INT_SCE		0x1E	/* Interrupt source mask (w) */
223#define PCI230_INT_STAT		0x1E	/* Interrupt status (r) */
224
225/* PCI230 i/o space 2 registers. */
226#define PCI230_DACCON		0x00	/* DAC control */
227#define PCI230_DACOUT1		0x02	/* DAC channel 0 (w) */
228#define PCI230_DACOUT2		0x04	/* DAC channel 1 (w) (not FIFO mode) */
229#define PCI230_ADCDATA		0x08	/* ADC data (r) */
230#define PCI230_ADCSWTRIG	0x08	/* ADC software trigger (w) */
231#define PCI230_ADCCON		0x0A	/* ADC control */
232#define PCI230_ADCEN		0x0C	/* ADC channel enable bits */
233#define PCI230_ADCG		0x0E	/* ADC gain control bits */
234/* PCI230+ i/o space 2 additional registers. */
235#define PCI230P_ADCTRIG		0x10	/* ADC start acquisition trigger */
236#define PCI230P_ADCTH		0x12	/* ADC analog trigger threshold */
237#define PCI230P_ADCFFTH		0x14	/* ADC FIFO interrupt threshold */
238#define PCI230P_ADCFFLEV	0x16	/* ADC FIFO level (r) */
239#define PCI230P_ADCPTSC		0x18	/* ADC pre-trigger sample count (r) */
240#define PCI230P_ADCHYST		0x1A	/* ADC analog trigger hysteresys */
241#define PCI230P_EXTFUNC		0x1C	/* Extended functions */
242#define PCI230P_HWVER		0x1E	/* Hardware version (r) */
243/* PCI230+ hardware version 2 onwards. */
244#define PCI230P2_DACDATA	0x02	/* DAC data (FIFO mode) (w) */
245#define PCI230P2_DACSWTRIG	0x02	/* DAC soft trigger (FIFO mode) (r) */
246#define PCI230P2_DACEN		0x06	/* DAC channel enable (FIFO mode) */
247
248/* Convertor related constants. */
249#define PCI230_DAC_SETTLE 5	/* Analogue output settling time in µs */
250				/* (DAC itself is 1µs nominally). */
251#define PCI230_ADC_SETTLE 1	/* Analogue input settling time in µs */
252				/* (ADC itself is 1.6µs nominally but we poll
253				 * anyway). */
254#define PCI230_MUX_SETTLE 10	/* ADC MUX settling time in µS */
255				/* - 10µs for se, 20µs de. */
256
257/* DACCON read-write values. */
258#define PCI230_DAC_OR_UNI		(0<<0)	/* Output range unipolar */
259#define PCI230_DAC_OR_BIP		(1<<0)	/* Output range bipolar */
260#define PCI230_DAC_OR_MASK		(1<<0)
261/* The following applies only if DAC FIFO support is enabled in the EXTFUNC
262 * register (and only for PCI230+ hardware version 2 onwards). */
263#define PCI230P2_DAC_FIFO_EN		(1<<8)	/* FIFO enable */
264/* The following apply only if the DAC FIFO is enabled (and only for PCI230+
265 * hardware version 2 onwards). */
266#define PCI230P2_DAC_TRIG_NONE		(0<<2)	/* No trigger */
267#define PCI230P2_DAC_TRIG_SW		(1<<2)	/* Software trigger trigger */
268#define PCI230P2_DAC_TRIG_EXTP		(2<<2)	/* EXTTRIG +ve edge trigger */
269#define PCI230P2_DAC_TRIG_EXTN		(3<<2)	/* EXTTRIG -ve edge trigger */
270#define PCI230P2_DAC_TRIG_Z2CT0		(4<<2)	/* CT0-OUT +ve edge trigger */
271#define PCI230P2_DAC_TRIG_Z2CT1		(5<<2)	/* CT1-OUT +ve edge trigger */
272#define PCI230P2_DAC_TRIG_Z2CT2		(6<<2)	/* CT2-OUT +ve edge trigger */
273#define PCI230P2_DAC_TRIG_MASK		(7<<2)
274#define PCI230P2_DAC_FIFO_WRAP		(1<<7)	/* FIFO wraparound mode */
275#define PCI230P2_DAC_INT_FIFO_EMPTY	(0<<9)	/* FIFO interrupt empty */
276#define PCI230P2_DAC_INT_FIFO_NEMPTY	(1<<9)
277#define PCI230P2_DAC_INT_FIFO_NHALF	(2<<9)	/* FIFO intr not half full */
278#define PCI230P2_DAC_INT_FIFO_HALF	(3<<9)
279#define PCI230P2_DAC_INT_FIFO_NFULL	(4<<9)	/* FIFO interrupt not full */
280#define PCI230P2_DAC_INT_FIFO_FULL	(5<<9)
281#define PCI230P2_DAC_INT_FIFO_MASK	(7<<9)
282
283/* DACCON read-only values. */
284#define PCI230_DAC_BUSY			(1<<1)	/* DAC busy. */
285/* The following apply only if the DAC FIFO is enabled (and only for PCI230+
286 * hardware version 2 onwards). */
287#define PCI230P2_DAC_FIFO_UNDERRUN_LATCHED	(1<<5)	/* Underrun error */
288#define PCI230P2_DAC_FIFO_EMPTY		(1<<13)	/* FIFO empty */
289#define PCI230P2_DAC_FIFO_FULL		(1<<14)	/* FIFO full */
290#define PCI230P2_DAC_FIFO_HALF		(1<<15)	/* FIFO half full */
291
292/* DACCON write-only, transient values. */
293/* The following apply only if the DAC FIFO is enabled (and only for PCI230+
294 * hardware version 2 onwards). */
295#define PCI230P2_DAC_FIFO_UNDERRUN_CLEAR	(1<<5)	/* Clear underrun */
296#define PCI230P2_DAC_FIFO_RESET		(1<<12)	/* FIFO reset */
297
298/* PCI230+ hardware version 2 DAC FIFO levels. */
299#define PCI230P2_DAC_FIFOLEVEL_HALF	512
300#define PCI230P2_DAC_FIFOLEVEL_FULL	1024
301/* Free space in DAC FIFO. */
302#define PCI230P2_DAC_FIFOROOM_EMPTY		PCI230P2_DAC_FIFOLEVEL_FULL
303#define PCI230P2_DAC_FIFOROOM_ONETOHALF		\
304	(PCI230P2_DAC_FIFOLEVEL_FULL - PCI230P2_DAC_FIFOLEVEL_HALF)
305#define PCI230P2_DAC_FIFOROOM_HALFTOFULL	1
306#define PCI230P2_DAC_FIFOROOM_FULL		0
307
308/* ADCCON read/write values. */
309#define PCI230_ADC_TRIG_NONE		(0<<0)	/* No trigger */
310#define PCI230_ADC_TRIG_SW		(1<<0)	/* Software trigger trigger */
311#define PCI230_ADC_TRIG_EXTP		(2<<0)	/* EXTTRIG +ve edge trigger */
312#define PCI230_ADC_TRIG_EXTN		(3<<0)	/* EXTTRIG -ve edge trigger */
313#define PCI230_ADC_TRIG_Z2CT0		(4<<0)	/* CT0-OUT +ve edge trigger */
314#define PCI230_ADC_TRIG_Z2CT1		(5<<0)	/* CT1-OUT +ve edge trigger */
315#define PCI230_ADC_TRIG_Z2CT2		(6<<0)	/* CT2-OUT +ve edge trigger */
316#define PCI230_ADC_TRIG_MASK		(7<<0)
317#define PCI230_ADC_IR_UNI		(0<<3)	/* Input range unipolar */
318#define PCI230_ADC_IR_BIP		(1<<3)	/* Input range bipolar */
319#define PCI230_ADC_IR_MASK		(1<<3)
320#define PCI230_ADC_IM_SE		(0<<4)	/* Input mode single ended */
321#define PCI230_ADC_IM_DIF		(1<<4)	/* Input mode differential */
322#define PCI230_ADC_IM_MASK		(1<<4)
323#define PCI230_ADC_FIFO_EN		(1<<8)	/* FIFO enable */
324#define PCI230_ADC_INT_FIFO_EMPTY	(0<<9)
325#define PCI230_ADC_INT_FIFO_NEMPTY	(1<<9)	/* FIFO interrupt not empty */
326#define PCI230_ADC_INT_FIFO_NHALF	(2<<9)
327#define PCI230_ADC_INT_FIFO_HALF	(3<<9)	/* FIFO interrupt half full */
328#define PCI230_ADC_INT_FIFO_NFULL	(4<<9)
329#define PCI230_ADC_INT_FIFO_FULL	(5<<9)	/* FIFO interrupt full */
330#define PCI230P_ADC_INT_FIFO_THRESH	(7<<9)	/* FIFO interrupt threshold */
331#define PCI230_ADC_INT_FIFO_MASK	(7<<9)
332
333/* ADCCON write-only, transient values. */
334#define PCI230_ADC_FIFO_RESET		(1<<12)	/* FIFO reset */
335#define PCI230_ADC_GLOB_RESET		(1<<13)	/* Global reset */
336
337/* ADCCON read-only values. */
338#define PCI230_ADC_BUSY			(1<<15)	/* ADC busy */
339#define PCI230_ADC_FIFO_EMPTY		(1<<12)	/* FIFO empty */
340#define PCI230_ADC_FIFO_FULL		(1<<13)	/* FIFO full */
341#define PCI230_ADC_FIFO_HALF		(1<<14)	/* FIFO half full */
342#define PCI230_ADC_FIFO_FULL_LATCHED	(1<<5)	/* Indicates overrun occurred */
343
344/* PCI230 ADC FIFO levels. */
345#define PCI230_ADC_FIFOLEVEL_HALFFULL	2049	/* Value for FIFO half full */
346#define PCI230_ADC_FIFOLEVEL_FULL	4096	/* FIFO size */
347
348/* Value to write to ADCSWTRIG to trigger ADC conversion in software trigger
349 * mode.  Can be anything.  */
350#define PCI230_ADC_CONV			0xffff
351
352/* PCI230+ EXTFUNC values. */
353#define PCI230P_EXTFUNC_GAT_EXTTRIG	(1<<0)
354			/* Route EXTTRIG pin to external gate inputs. */
355/* PCI230+ hardware version 2 values. */
356#define PCI230P2_EXTFUNC_DACFIFO	(1<<1)
357			/* Allow DAC FIFO to be enabled. */
358
359/*
360 * Counter/timer clock input configuration sources.
361 */
362#define CLK_CLK		0	/* reserved (channel-specific clock) */
363#define CLK_10MHZ	1	/* internal 10 MHz clock */
364#define CLK_1MHZ	2	/* internal 1 MHz clock */
365#define CLK_100KHZ	3	/* internal 100 kHz clock */
366#define CLK_10KHZ	4	/* internal 10 kHz clock */
367#define CLK_1KHZ	5	/* internal 1 kHz clock */
368#define CLK_OUTNM1	6	/* output of channel-1 modulo total */
369#define CLK_EXT		7	/* external clock */
370/* Macro to construct clock input configuration register value. */
371#define CLK_CONFIG(chan, src)	((((chan) & 3) << 3) | ((src) & 7))
372/* Timebases in ns. */
373#define TIMEBASE_10MHZ		100
374#define TIMEBASE_1MHZ		1000
375#define TIMEBASE_100KHZ		10000
376#define TIMEBASE_10KHZ		100000
377#define TIMEBASE_1KHZ		1000000
378
379/*
380 * Counter/timer gate input configuration sources.
381 */
382#define GAT_VCC		0	/* VCC (i.e. enabled) */
383#define GAT_GND		1	/* GND (i.e. disabled) */
384#define GAT_EXT		2	/* external gate input (PPCn on PCI230) */
385#define GAT_NOUTNM2	3	/* inverted output of channel-2 modulo total */
386/* Macro to construct gate input configuration register value. */
387#define GAT_CONFIG(chan, src)	((((chan) & 3) << 3) | ((src) & 7))
388
389/*
390 * Summary of CLK_OUTNM1 and GAT_NOUTNM2 connections for PCI230 and PCI260:
391 *
392 *              Channel's       Channel's
393 *              clock input     gate input
394 * Channel      CLK_OUTNM1      GAT_NOUTNM2
395 * -------      ----------      -----------
396 * Z2-CT0       Z2-CT2-OUT      /Z2-CT1-OUT
397 * Z2-CT1       Z2-CT0-OUT      /Z2-CT2-OUT
398 * Z2-CT2       Z2-CT1-OUT      /Z2-CT0-OUT
399 */
400
401/* Interrupt enables/status register values. */
402#define PCI230_INT_DISABLE		0
403#define PCI230_INT_PPI_C0		(1<<0)
404#define PCI230_INT_PPI_C3		(1<<1)
405#define PCI230_INT_ADC			(1<<2)
406#define PCI230_INT_ZCLK_CT1		(1<<5)
407/* For PCI230+ hardware version 2 when DAC FIFO enabled. */
408#define PCI230P2_INT_DAC		(1<<4)
409
410#define PCI230_TEST_BIT(val, n)	((val>>n)&1)
411			/* Assumes bits numbered with zero offset, ie. 0-15 */
412
413/* (Potentially) shared resources and their owners */
414enum {
415	RES_Z2CT0,		/* Z2-CT0 */
416	RES_Z2CT1,		/* Z2-CT1 */
417	RES_Z2CT2,		/* Z2-CT2 */
418	NUM_RESOURCES		/* Number of (potentially) shared resources. */
419};
420
421enum {
422	OWNER_NONE,		/* Not owned */
423	OWNER_AICMD,		/* Owned by AI command */
424	OWNER_AOCMD		/* Owned by AO command */
425};
426
427/*
428 * Handy macros.
429 */
430
431/* Combine old and new bits. */
432#define COMBINE(old, new, mask)	(((old) & ~(mask)) | ((new) & (mask)))
433
434/* A generic null function pointer value.  */
435#define NULLFUNC	0
436
437/* Current CPU.  XXX should this be hard_smp_processor_id()? */
438#define THISCPU		smp_processor_id()
439
440/* State flags for atomic bit operations */
441#define AI_CMD_STARTED	0
442#define AO_CMD_STARTED	1
443
444/*
445 * Board descriptions for the two boards supported.
446 */
447
448struct pci230_board {
449	const char *name;
450	unsigned short id;
451	int ai_chans;
452	int ai_bits;
453	int ao_chans;
454	int ao_bits;
455	int have_dio;
456	unsigned int min_hwver;	/* Minimum hardware version supported. */
457};
458static const struct pci230_board pci230_boards[] = {
459	{
460	 .name = "pci230+",
461	 .id = PCI_DEVICE_ID_PCI230,
462	 .ai_chans = 16,
463	 .ai_bits = 16,
464	 .ao_chans = 2,
465	 .ao_bits = 12,
466	 .have_dio = 1,
467	 .min_hwver = 1,
468	 },
469	{
470	 .name = "pci260+",
471	 .id = PCI_DEVICE_ID_PCI260,
472	 .ai_chans = 16,
473	 .ai_bits = 16,
474	 .ao_chans = 0,
475	 .ao_bits = 0,
476	 .have_dio = 0,
477	 .min_hwver = 1,
478	 },
479	{
480	 .name = "pci230",
481	 .id = PCI_DEVICE_ID_PCI230,
482	 .ai_chans = 16,
483	 .ai_bits = 12,
484	 .ao_chans = 2,
485	 .ao_bits = 12,
486	 .have_dio = 1,
487	 },
488	{
489	 .name = "pci260",
490	 .id = PCI_DEVICE_ID_PCI260,
491	 .ai_chans = 16,
492	 .ai_bits = 12,
493	 .ao_chans = 0,
494	 .ao_bits = 0,
495	 .have_dio = 0,
496	 },
497	{
498	 .name = "amplc_pci230",	/* Wildcard matches any above */
499	 .id = PCI_DEVICE_ID_INVALID,
500	 },
501};
502
503static DEFINE_PCI_DEVICE_TABLE(pci230_pci_table) = {
504	{
505	PCI_VENDOR_ID_AMPLICON, PCI_DEVICE_ID_PCI230, PCI_ANY_ID,
506		    PCI_ANY_ID, 0, 0, 0}, {
507	PCI_VENDOR_ID_AMPLICON, PCI_DEVICE_ID_PCI260, PCI_ANY_ID,
508		    PCI_ANY_ID, 0, 0, 0}, {
509	0}
510};
511
512MODULE_DEVICE_TABLE(pci, pci230_pci_table);
513/*
514 * Useful for shorthand access to the particular board structure
515 */
516#define n_pci230_boards ARRAY_SIZE(pci230_boards)
517#define thisboard ((const struct pci230_board *)dev->board_ptr)
518
519/* this structure is for data unique to this hardware driver.  If
520   several hardware drivers keep similar information in this structure,
521   feel free to suggest moving the variable to the struct comedi_device struct.  */
522struct pci230_private {
523	struct pci_dev *pci_dev;
524	spinlock_t isr_spinlock;	/* Interrupt spin lock */
525	spinlock_t res_spinlock;	/* Shared resources spin lock */
526	spinlock_t ai_stop_spinlock;	/* Spin lock for stopping AI command */
527	spinlock_t ao_stop_spinlock;	/* Spin lock for stopping AO command */
528	unsigned long state;	/* State flags */
529	unsigned long iobase1;	/* PCI230's I/O space 1 */
530	unsigned int ao_readback[2];	/* Used for AO readback */
531	unsigned int ai_scan_count;	/* Number of analogue input scans
532					 * remaining.  */
533	unsigned int ai_scan_pos;	/* Current position within analogue
534					 * input scan */
535	unsigned int ao_scan_count;	/* Number of analogue output scans
536					 * remaining.  */
537	int intr_cpuid;		/* ID of CPU running interrupt routine. */
538	unsigned short hwver;	/* Hardware version (for '+' models). */
539	unsigned short adccon;	/* ADCCON register value. */
540	unsigned short daccon;	/* DACCON register value. */
541	unsigned short adcfifothresh;	/* ADC FIFO programmable interrupt
542					 * level threshold (PCI230+/260+). */
543	unsigned short adcg;	/* ADCG register value. */
544	unsigned char int_en;	/* Interrupt enables bits. */
545	unsigned char ai_continuous;	/* Flag set when cmd->stop_src ==
546					 * TRIG_NONE - user chooses to stop
547					 * continuous conversion by
548					 * cancelation. */
549	unsigned char ao_continuous;	/* Flag set when cmd->stop_src ==
550					 * TRIG_NONE - user chooses to stop
551					 * continuous conversion by
552					 * cancelation. */
553	unsigned char ai_bipolar;	/* Set if bipolar input range so we
554					 * know to mangle it. */
555	unsigned char ao_bipolar;	/* Set if bipolar output range so we
556					 * know to mangle it. */
557	unsigned char ier;	/* Copy of interrupt enables/status register. */
558	unsigned char intr_running;	/* Flag set in interrupt routine. */
559	unsigned char res_owner[NUM_RESOURCES];	/* Shared resource owners. */
560};
561
562#define devpriv ((struct pci230_private *)dev->private)
563
564/* PCI230 clock source periods in ns */
565static const unsigned int pci230_timebase[8] = {
566	[CLK_10MHZ] = TIMEBASE_10MHZ,
567	[CLK_1MHZ] = TIMEBASE_1MHZ,
568	[CLK_100KHZ] = TIMEBASE_100KHZ,
569	[CLK_10KHZ] = TIMEBASE_10KHZ,
570	[CLK_1KHZ] = TIMEBASE_1KHZ,
571};
572
573/* PCI230 analogue input range table */
574static const struct comedi_lrange pci230_ai_range = { 7, {
575							  BIP_RANGE(10),
576							  BIP_RANGE(5),
577							  BIP_RANGE(2.5),
578							  BIP_RANGE(1.25),
579							  UNI_RANGE(10),
580							  UNI_RANGE(5),
581							  UNI_RANGE(2.5)
582							  }
583};
584
585/* PCI230 analogue gain bits for each input range. */
586static const unsigned char pci230_ai_gain[7] = { 0, 1, 2, 3, 1, 2, 3 };
587
588/* PCI230 adccon bipolar flag for each analogue input range. */
589static const unsigned char pci230_ai_bipolar[7] = { 1, 1, 1, 1, 0, 0, 0 };
590
591/* PCI230 analogue output range table */
592static const struct comedi_lrange pci230_ao_range = { 2, {
593							  UNI_RANGE(10),
594							  BIP_RANGE(10)
595							  }
596};
597
598/* PCI230 daccon bipolar flag for each analogue output range. */
599static const unsigned char pci230_ao_bipolar[2] = { 0, 1 };
600
601/*
602 * The struct comedi_driver structure tells the Comedi core module
603 * which functions to call to configure/deconfigure (attach/detach)
604 * the board, and also about the kernel module that contains
605 * the device code.
606 */
607static int pci230_attach(struct comedi_device *dev,
608			 struct comedi_devconfig *it);
609static int pci230_detach(struct comedi_device *dev);
610static struct comedi_driver driver_amplc_pci230 = {
611	.driver_name = "amplc_pci230",
612	.module = THIS_MODULE,
613	.attach = pci230_attach,
614	.detach = pci230_detach,
615	.board_name = &pci230_boards[0].name,
616	.offset = sizeof(pci230_boards[0]),
617	.num_names = ARRAY_SIZE(pci230_boards),
618};
619
620COMEDI_PCI_INITCLEANUP(driver_amplc_pci230, pci230_pci_table);
621
622static int pci230_ai_rinsn(struct comedi_device *dev,
623			   struct comedi_subdevice *s, struct comedi_insn *insn,
624			   unsigned int *data);
625static int pci230_ao_winsn(struct comedi_device *dev,
626			   struct comedi_subdevice *s, struct comedi_insn *insn,
627			   unsigned int *data);
628static int pci230_ao_rinsn(struct comedi_device *dev,
629			   struct comedi_subdevice *s, struct comedi_insn *insn,
630			   unsigned int *data);
631static void pci230_ct_setup_ns_mode(struct comedi_device *dev, unsigned int ct,
632				    unsigned int mode, uint64_t ns,
633				    unsigned int round);
634static void pci230_ns_to_single_timer(unsigned int *ns, unsigned int round);
635static void pci230_cancel_ct(struct comedi_device *dev, unsigned int ct);
636static irqreturn_t pci230_interrupt(int irq, void *d);
637static int pci230_ao_cmdtest(struct comedi_device *dev,
638			     struct comedi_subdevice *s,
639			     struct comedi_cmd *cmd);
640static int pci230_ao_cmd(struct comedi_device *dev, struct comedi_subdevice *s);
641static int pci230_ao_cancel(struct comedi_device *dev,
642			    struct comedi_subdevice *s);
643static void pci230_ao_stop(struct comedi_device *dev,
644			   struct comedi_subdevice *s);
645static void pci230_handle_ao_nofifo(struct comedi_device *dev,
646				    struct comedi_subdevice *s);
647static int pci230_handle_ao_fifo(struct comedi_device *dev,
648				 struct comedi_subdevice *s);
649static int pci230_ai_cmdtest(struct comedi_device *dev,
650			     struct comedi_subdevice *s,
651			     struct comedi_cmd *cmd);
652static int pci230_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s);
653static int pci230_ai_cancel(struct comedi_device *dev,
654			    struct comedi_subdevice *s);
655static void pci230_ai_stop(struct comedi_device *dev,
656			   struct comedi_subdevice *s);
657static void pci230_handle_ai(struct comedi_device *dev,
658			     struct comedi_subdevice *s);
659
660static short pci230_ai_read(struct comedi_device *dev)
661{
662	/* Read sample. */
663	short data = (short)inw(dev->iobase + PCI230_ADCDATA);
664
665	/* PCI230 is 12 bit - stored in upper bits of 16 bit register (lower
666	 * four bits reserved for expansion). */
667	/* PCI230+ is 16 bit AI. */
668	data = data >> (16 - thisboard->ai_bits);
669
670	/* If a bipolar range was specified, mangle it (twos
671	 * complement->straight binary). */
672	if (devpriv->ai_bipolar) {
673		data ^= 1 << (thisboard->ai_bits - 1);
674	}
675	return data;
676}
677
678static inline unsigned short pci230_ao_mangle_datum(struct comedi_device *dev,
679						    short datum)
680{
681	/* If a bipolar range was specified, mangle it (straight binary->twos
682	 * complement). */
683	if (devpriv->ao_bipolar) {
684		datum ^= 1 << (thisboard->ao_bits - 1);
685	}
686
687	/* PCI230 is 12 bit - stored in upper bits of 16 bit register (lower
688	 * four bits reserved for expansion). */
689	/* PCI230+ is also 12 bit AO. */
690	datum <<= (16 - thisboard->ao_bits);
691	return (unsigned short)datum;
692}
693
694static inline void pci230_ao_write_nofifo(struct comedi_device *dev,
695					  short datum, unsigned int chan)
696{
697	/* Store unmangled datum to be read back later. */
698	devpriv->ao_readback[chan] = datum;
699
700	/* Write mangled datum to appropriate DACOUT register. */
701	outw(pci230_ao_mangle_datum(dev, datum), dev->iobase + (((chan) == 0)
702								? PCI230_DACOUT1
703								:
704								PCI230_DACOUT2));
705}
706
707static inline void pci230_ao_write_fifo(struct comedi_device *dev, short datum,
708					unsigned int chan)
709{
710	/* Store unmangled datum to be read back later. */
711	devpriv->ao_readback[chan] = datum;
712
713	/* Write mangled datum to appropriate DACDATA register. */
714	outw(pci230_ao_mangle_datum(dev, datum),
715	     dev->iobase + PCI230P2_DACDATA);
716}
717
718/*
719 * Attach is called by the Comedi core to configure the driver
720 * for a particular board.  If you specified a board_name array
721 * in the driver structure, dev->board_ptr contains that
722 * address.
723 */
724static int pci230_attach(struct comedi_device *dev, struct comedi_devconfig *it)
725{
726	struct comedi_subdevice *s;
727	unsigned long iobase1, iobase2;
728	/* PCI230's I/O spaces 1 and 2 respectively. */
729	struct pci_dev *pci_dev;
730	int i = 0, irq_hdl, rc;
731
732	printk("comedi%d: amplc_pci230: attach %s %d,%d\n", dev->minor,
733	       thisboard->name, it->options[0], it->options[1]);
734
735	/* Allocate the private structure area using alloc_private().
736	 * Macro defined in comedidev.h - memsets struct fields to 0. */
737	if ((alloc_private(dev, sizeof(struct pci230_private))) < 0) {
738		return -ENOMEM;
739	}
740	spin_lock_init(&devpriv->isr_spinlock);
741	spin_lock_init(&devpriv->res_spinlock);
742	spin_lock_init(&devpriv->ai_stop_spinlock);
743	spin_lock_init(&devpriv->ao_stop_spinlock);
744	/* Find card */
745	for (pci_dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, NULL);
746	     pci_dev != NULL;
747	     pci_dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pci_dev)) {
748		if (it->options[0] || it->options[1]) {
749			/* Match against bus/slot options. */
750			if (it->options[0] != pci_dev->bus->number ||
751			    it->options[1] != PCI_SLOT(pci_dev->devfn))
752				continue;
753		}
754		if (pci_dev->vendor != PCI_VENDOR_ID_AMPLICON)
755			continue;
756		if (thisboard->id == PCI_DEVICE_ID_INVALID) {
757			/* The name was specified as "amplc_pci230" which is
758			 * used to match any supported device.  Replace the
759			 * current dev->board_ptr with one that matches the
760			 * PCI device ID. */
761			for (i = 0; i < n_pci230_boards; i++) {
762				if (pci_dev->device == pci230_boards[i].id) {
763					if (pci230_boards[i].min_hwver > 0) {
764						/* Check for a '+' model.
765						 * First check length of
766						 * registers. */
767						if (pci_resource_len(pci_dev, 3)
768						    < 32) {
769							/* Not a '+' model. */
770							continue;
771						}
772						/* TODO: temporarily enable the
773						 * PCI device and read the
774						 * hardware version register.
775						 * For now assume it's okay. */
776					}
777					/* Change board_ptr to matched board */
778					dev->board_ptr = &pci230_boards[i];
779					break;
780				}
781			}
782			if (i < n_pci230_boards)
783				break;
784		} else {
785			/* The name was specified as a specific device name.
786			 * The current dev->board_ptr is correct.  Check
787			 * whether it matches the PCI device ID. */
788			if (thisboard->id == pci_dev->device) {
789				/* Check minimum hardware version. */
790				if (thisboard->min_hwver > 0) {
791					/* Looking for a '+' model.  First
792					 * check length of registers. */
793					if (pci_resource_len(pci_dev, 3) < 32) {
794						/* Not a '+' model. */
795						continue;
796					}
797					/* TODO: temporarily enable the PCI
798					 * device and read the hardware version
799					 * register.  For now, assume it's
800					 * okay. */
801					break;
802				} else {
803					break;
804				}
805			}
806		}
807	}
808	if (!pci_dev) {
809		printk("comedi%d: No %s card found\n", dev->minor,
810		       thisboard->name);
811		return -EIO;
812	}
813	devpriv->pci_dev = pci_dev;
814
815	/*
816	 * Initialize dev->board_name.
817	 */
818	dev->board_name = thisboard->name;
819
820	/* Enable PCI device and reserve I/O spaces. */
821	if (comedi_pci_enable(pci_dev, "amplc_pci230") < 0) {
822		printk("comedi%d: failed to enable PCI device "
823		       "and request regions\n", dev->minor);
824		return -EIO;
825	}
826
827	/* Read base addresses of the PCI230's two I/O regions from PCI
828	 * configuration register. */
829	iobase1 = pci_resource_start(pci_dev, 2);
830	iobase2 = pci_resource_start(pci_dev, 3);
831
832	printk("comedi%d: %s I/O region 1 0x%04lx I/O region 2 0x%04lx\n",
833	       dev->minor, dev->board_name, iobase1, iobase2);
834
835	devpriv->iobase1 = iobase1;
836	dev->iobase = iobase2;
837
838	/* Read bits of DACCON register - only the output range. */
839	devpriv->daccon = inw(dev->iobase + PCI230_DACCON) & PCI230_DAC_OR_MASK;
840
841	/* Read hardware version register and set extended function register
842	 * if they exist. */
843	if (pci_resource_len(pci_dev, 3) >= 32) {
844		unsigned short extfunc = 0;
845
846		devpriv->hwver = inw(dev->iobase + PCI230P_HWVER);
847		if (devpriv->hwver < thisboard->min_hwver) {
848			printk("comedi%d: %s - bad hardware version "
849			       "- got %u, need %u\n", dev->minor,
850			       dev->board_name, devpriv->hwver,
851			       thisboard->min_hwver);
852			return -EIO;
853		}
854		if (devpriv->hwver > 0) {
855			if (!thisboard->have_dio) {
856				/* No DIO ports.  Route counters' external gates
857				 * to the EXTTRIG signal (PCI260+ pin 17).
858				 * (Otherwise, they would be routed to DIO
859				 * inputs PC0, PC1 and PC2 which don't exist
860				 * on PCI260[+].) */
861				extfunc |= PCI230P_EXTFUNC_GAT_EXTTRIG;
862			}
863			if ((thisboard->ao_chans > 0)
864			    && (devpriv->hwver >= 2)) {
865				/* Enable DAC FIFO functionality. */
866				extfunc |= PCI230P2_EXTFUNC_DACFIFO;
867			}
868		}
869		outw(extfunc, dev->iobase + PCI230P_EXTFUNC);
870		if ((extfunc & PCI230P2_EXTFUNC_DACFIFO) != 0) {
871			/* Temporarily enable DAC FIFO, reset it and disable
872			 * FIFO wraparound. */
873			outw(devpriv->daccon | PCI230P2_DAC_FIFO_EN
874			     | PCI230P2_DAC_FIFO_RESET,
875			     dev->iobase + PCI230_DACCON);
876			/* Clear DAC FIFO channel enable register. */
877			outw(0, dev->iobase + PCI230P2_DACEN);
878			/* Disable DAC FIFO. */
879			outw(devpriv->daccon, dev->iobase + PCI230_DACCON);
880		}
881	}
882
883	/* Disable board's interrupts. */
884	outb(0, devpriv->iobase1 + PCI230_INT_SCE);
885
886	/* Set ADC to a reasonable state. */
887	devpriv->adcg = 0;
888	devpriv->adccon = PCI230_ADC_TRIG_NONE | PCI230_ADC_IM_SE
889	    | PCI230_ADC_IR_BIP;
890	outw(1 << 0, dev->iobase + PCI230_ADCEN);
891	outw(devpriv->adcg, dev->iobase + PCI230_ADCG);
892	outw(devpriv->adccon | PCI230_ADC_FIFO_RESET,
893	     dev->iobase + PCI230_ADCCON);
894
895	/* Register the interrupt handler. */
896	irq_hdl = request_irq(devpriv->pci_dev->irq, pci230_interrupt,
897			      IRQF_SHARED, "amplc_pci230", dev);
898	if (irq_hdl < 0) {
899		printk("comedi%d: unable to register irq, "
900		       "commands will not be available %d\n", dev->minor,
901		       devpriv->pci_dev->irq);
902	} else {
903		dev->irq = devpriv->pci_dev->irq;
904		printk("comedi%d: registered irq %u\n", dev->minor,
905		       devpriv->pci_dev->irq);
906	}
907
908	/*
909	 * Allocate the subdevice structures.  alloc_subdevice() is a
910	 * convenient macro defined in comedidev.h.
911	 */
912	if (alloc_subdevices(dev, 3) < 0)
913		return -ENOMEM;
914
915	s = dev->subdevices + 0;
916	/* analog input subdevice */
917	s->type = COMEDI_SUBD_AI;
918	s->subdev_flags = SDF_READABLE | SDF_DIFF | SDF_GROUND;
919	s->n_chan = thisboard->ai_chans;
920	s->maxdata = (1 << thisboard->ai_bits) - 1;
921	s->range_table = &pci230_ai_range;
922	s->insn_read = &pci230_ai_rinsn;
923	s->len_chanlist = 256;	/* but there are restrictions. */
924	/* Only register commands if the interrupt handler is installed. */
925	if (irq_hdl == 0) {
926		dev->read_subdev = s;
927		s->subdev_flags |= SDF_CMD_READ;
928		s->do_cmd = &pci230_ai_cmd;
929		s->do_cmdtest = &pci230_ai_cmdtest;
930		s->cancel = pci230_ai_cancel;
931	}
932
933	s = dev->subdevices + 1;
934	/* analog output subdevice */
935	if (thisboard->ao_chans > 0) {
936		s->type = COMEDI_SUBD_AO;
937		s->subdev_flags = SDF_WRITABLE | SDF_GROUND;
938		s->n_chan = thisboard->ao_chans;;
939		s->maxdata = (1 << thisboard->ao_bits) - 1;
940		s->range_table = &pci230_ao_range;
941		s->insn_write = &pci230_ao_winsn;
942		s->insn_read = &pci230_ao_rinsn;
943		s->len_chanlist = thisboard->ao_chans;
944		/* Only register commands if the interrupt handler is
945		 * installed. */
946		if (irq_hdl == 0) {
947			dev->write_subdev = s;
948			s->subdev_flags |= SDF_CMD_WRITE;
949			s->do_cmd = &pci230_ao_cmd;
950			s->do_cmdtest = &pci230_ao_cmdtest;
951			s->cancel = pci230_ao_cancel;
952		}
953	} else {
954		s->type = COMEDI_SUBD_UNUSED;
955	}
956
957	s = dev->subdevices + 2;
958	/* digital i/o subdevice */
959	if (thisboard->have_dio) {
960		rc = subdev_8255_init(dev, s, NULL,
961				      (devpriv->iobase1 + PCI230_PPI_X_BASE));
962		if (rc < 0)
963			return rc;
964	} else {
965		s->type = COMEDI_SUBD_UNUSED;
966	}
967
968	printk("comedi%d: attached\n", dev->minor);
969
970	return 1;
971}
972
973/*
974 * _detach is called to deconfigure a device.  It should deallocate
975 * resources.
976 * This function is also called when _attach() fails, so it should be
977 * careful not to release resources that were not necessarily
978 * allocated by _attach().  dev->private and dev->subdevices are
979 * deallocated automatically by the core.
980 */
981static int pci230_detach(struct comedi_device *dev)
982{
983	printk("comedi%d: amplc_pci230: remove\n", dev->minor);
984
985	if (dev->subdevices && thisboard->have_dio)
986		/* Clean up dio subdevice. */
987		subdev_8255_cleanup(dev, dev->subdevices + 2);
988
989	if (dev->irq)
990		free_irq(dev->irq, dev);
991
992	if (devpriv) {
993		if (devpriv->pci_dev) {
994			if (dev->iobase) {
995				comedi_pci_disable(devpriv->pci_dev);
996			}
997			pci_dev_put(devpriv->pci_dev);
998		}
999	}
1000
1001	return 0;
1002}
1003
1004static int get_resources(struct comedi_device *dev, unsigned int res_mask,
1005			 unsigned char owner)
1006{
1007	int ok;
1008	unsigned int i;
1009	unsigned int b;
1010	unsigned int claimed;
1011	unsigned long irqflags;
1012
1013	ok = 1;
1014	claimed = 0;
1015	spin_lock_irqsave(&devpriv->res_spinlock, irqflags);
1016	for (b = 1, i = 0; (i < NUM_RESOURCES)
1017	     && (res_mask != 0); b <<= 1, i++) {
1018		if ((res_mask & b) != 0) {
1019			res_mask &= ~b;
1020			if (devpriv->res_owner[i] == OWNER_NONE) {
1021				devpriv->res_owner[i] = owner;
1022				claimed |= b;
1023			} else if (devpriv->res_owner[i] != owner) {
1024				for (b = 1, i = 0; claimed != 0; b <<= 1, i++) {
1025					if ((claimed & b) != 0) {
1026						devpriv->res_owner[i]
1027						    = OWNER_NONE;
1028						claimed &= ~b;
1029					}
1030				}
1031				ok = 0;
1032				break;
1033			}
1034		}
1035	}
1036	spin_unlock_irqrestore(&devpriv->res_spinlock, irqflags);
1037	return ok;
1038}
1039
1040static inline int get_one_resource(struct comedi_device *dev,
1041				   unsigned int resource, unsigned char owner)
1042{
1043	return get_resources(dev, (1U << resource), owner);
1044}
1045
1046static void put_resources(struct comedi_device *dev, unsigned int res_mask,
1047			  unsigned char owner)
1048{
1049	unsigned int i;
1050	unsigned int b;
1051	unsigned long irqflags;
1052
1053	spin_lock_irqsave(&devpriv->res_spinlock, irqflags);
1054	for (b = 1, i = 0; (i < NUM_RESOURCES)
1055	     && (res_mask != 0); b <<= 1, i++) {
1056		if ((res_mask & b) != 0) {
1057			res_mask &= ~b;
1058			if (devpriv->res_owner[i] == owner) {
1059				devpriv->res_owner[i] = OWNER_NONE;
1060			}
1061		}
1062	}
1063	spin_unlock_irqrestore(&devpriv->res_spinlock, irqflags);
1064}
1065
1066static inline void put_one_resource(struct comedi_device *dev,
1067				    unsigned int resource, unsigned char owner)
1068{
1069	put_resources(dev, (1U << resource), owner);
1070}
1071
1072static inline void put_all_resources(struct comedi_device *dev,
1073				     unsigned char owner)
1074{
1075	put_resources(dev, (1U << NUM_RESOURCES) - 1, owner);
1076}
1077
1078/*
1079 *  COMEDI_SUBD_AI instruction;
1080 */
1081static int pci230_ai_rinsn(struct comedi_device *dev,
1082			   struct comedi_subdevice *s, struct comedi_insn *insn,
1083			   unsigned int *data)
1084{
1085	unsigned int n, i;
1086	unsigned int chan, range, aref;
1087	unsigned int gainshift;
1088	unsigned int status;
1089	unsigned short adccon, adcen;
1090
1091	/* Unpack channel and range. */
1092	chan = CR_CHAN(insn->chanspec);
1093	range = CR_RANGE(insn->chanspec);
1094	aref = CR_AREF(insn->chanspec);
1095	if (aref == AREF_DIFF) {
1096		/* Differential. */
1097		if (chan >= s->n_chan / 2) {
1098			DPRINTK("comedi%d: amplc_pci230: ai_rinsn: "
1099				"differential channel number out of range "
1100				"0 to %u\n", dev->minor, (s->n_chan / 2) - 1);
1101			return -EINVAL;
1102		}
1103	}
1104
1105	/* Use Z2-CT2 as a conversion trigger instead of the built-in
1106	 * software trigger, as otherwise triggering of differential channels
1107	 * doesn't work properly for some versions of PCI230/260.  Also set
1108	 * FIFO mode because the ADC busy bit only works for software triggers.
1109	 */
1110	adccon = PCI230_ADC_TRIG_Z2CT2 | PCI230_ADC_FIFO_EN;
1111	/* Set Z2-CT2 output low to avoid any false triggers. */
1112	i8254_set_mode(devpriv->iobase1 + PCI230_Z2_CT_BASE, 0, 2, I8254_MODE0);
1113	devpriv->ai_bipolar = pci230_ai_bipolar[range];
1114	if (aref == AREF_DIFF) {
1115		/* Differential. */
1116		gainshift = chan * 2;
1117		if (devpriv->hwver == 0) {
1118			/* Original PCI230/260 expects both inputs of the
1119			 * differential channel to be enabled. */
1120			adcen = 3 << gainshift;
1121		} else {
1122			/* PCI230+/260+ expects only one input of the
1123			 * differential channel to be enabled. */
1124			adcen = 1 << gainshift;
1125		}
1126		adccon |= PCI230_ADC_IM_DIF;
1127	} else {
1128		/* Single ended. */
1129		adcen = 1 << chan;
1130		gainshift = chan & ~1;
1131		adccon |= PCI230_ADC_IM_SE;
1132	}
1133	devpriv->adcg = (devpriv->adcg & ~(3 << gainshift))
1134	    | (pci230_ai_gain[range] << gainshift);
1135	if (devpriv->ai_bipolar) {
1136		adccon |= PCI230_ADC_IR_BIP;
1137	} else {
1138		adccon |= PCI230_ADC_IR_UNI;
1139	}
1140
1141	/* Enable only this channel in the scan list - otherwise by default
1142	 * we'll get one sample from each channel. */
1143	outw(adcen, dev->iobase + PCI230_ADCEN);
1144
1145	/* Set gain for channel. */
1146	outw(devpriv->adcg, dev->iobase + PCI230_ADCG);
1147
1148	/* Specify uni/bip, se/diff, conversion source, and reset FIFO. */
1149	devpriv->adccon = adccon;
1150	outw(adccon | PCI230_ADC_FIFO_RESET, dev->iobase + PCI230_ADCCON);
1151
1152	/* Convert n samples */
1153	for (n = 0; n < insn->n; n++) {
1154		/* Trigger conversion by toggling Z2-CT2 output (finish with
1155		 * output high). */
1156		i8254_set_mode(devpriv->iobase1 + PCI230_Z2_CT_BASE, 0, 2,
1157			       I8254_MODE0);
1158		i8254_set_mode(devpriv->iobase1 + PCI230_Z2_CT_BASE, 0, 2,
1159			       I8254_MODE1);
1160
1161#define TIMEOUT 100
1162		/* wait for conversion to end */
1163		for (i = 0; i < TIMEOUT; i++) {
1164			status = inw(dev->iobase + PCI230_ADCCON);
1165			if (!(status & PCI230_ADC_FIFO_EMPTY))
1166				break;
1167			udelay(1);
1168		}
1169		if (i == TIMEOUT) {
1170			/* printk() should be used instead of printk()
1171			 * whenever the code can be called from real-time. */
1172			printk("timeout\n");
1173			return -ETIMEDOUT;
1174		}
1175
1176		/* read data */
1177		data[n] = pci230_ai_read(dev);
1178	}
1179
1180	/* return the number of samples read/written */
1181	return n;
1182}
1183
1184/*
1185 *  COMEDI_SUBD_AO instructions;
1186 */
1187static int pci230_ao_winsn(struct comedi_device *dev,
1188			   struct comedi_subdevice *s, struct comedi_insn *insn,
1189			   unsigned int *data)
1190{
1191	int i;
1192	int chan, range;
1193
1194	/* Unpack channel and range. */
1195	chan = CR_CHAN(insn->chanspec);
1196	range = CR_RANGE(insn->chanspec);
1197
1198	/* Set range - see analogue output range table; 0 => unipolar 10V,
1199	 * 1 => bipolar +/-10V range scale */
1200	devpriv->ao_bipolar = pci230_ao_bipolar[range];
1201	outw(range, dev->iobase + PCI230_DACCON);
1202
1203	/* Writing a list of values to an AO channel is probably not
1204	 * very useful, but that's how the interface is defined. */
1205	for (i = 0; i < insn->n; i++) {
1206		/* Write value to DAC and store it. */
1207		pci230_ao_write_nofifo(dev, data[i], chan);
1208	}
1209
1210	/* return the number of samples read/written */
1211	return i;
1212}
1213
1214/* AO subdevices should have a read insn as well as a write insn.
1215 * Usually this means copying a value stored in devpriv. */
1216static int pci230_ao_rinsn(struct comedi_device *dev,
1217			   struct comedi_subdevice *s, struct comedi_insn *insn,
1218			   unsigned int *data)
1219{
1220	int i;
1221	int chan = CR_CHAN(insn->chanspec);
1222
1223	for (i = 0; i < insn->n; i++)
1224		data[i] = devpriv->ao_readback[chan];
1225
1226	return i;
1227}
1228
1229static int pci230_ao_cmdtest(struct comedi_device *dev,
1230			     struct comedi_subdevice *s, struct comedi_cmd *cmd)
1231{
1232	int err = 0;
1233	unsigned int tmp;
1234
1235	/* cmdtest tests a particular command to see if it is valid.
1236	 * Using the cmdtest ioctl, a user can create a valid cmd
1237	 * and then have it executes by the cmd ioctl.
1238	 *
1239	 * cmdtest returns 1,2,3,4 or 0, depending on which tests
1240	 * the command passes. */
1241
1242	/* Step 1: make sure trigger sources are trivially valid.
1243	 * "invalid source" returned by comedilib to user mode process
1244	 * if this fails. */
1245
1246	tmp = cmd->start_src;
1247	cmd->start_src &= TRIG_INT;
1248	if (!cmd->start_src || tmp != cmd->start_src)
1249		err++;
1250
1251	tmp = cmd->scan_begin_src;
1252	if ((thisboard->min_hwver > 0) && (devpriv->hwver >= 2)) {
1253		/*
1254		 * For PCI230+ hardware version 2 onwards, allow external
1255		 * trigger from EXTTRIG/EXTCONVCLK input (PCI230+ pin 25).
1256		 *
1257		 * FIXME: The permitted scan_begin_src values shouldn't depend
1258		 * on devpriv->hwver (the detected card's actual hardware
1259		 * version).  They should only depend on thisboard->min_hwver
1260		 * (the static capabilities of the configured card).  To fix
1261		 * it, a new card model, e.g. "pci230+2" would have to be
1262		 * defined with min_hwver set to 2.  It doesn't seem worth it
1263		 * for this alone.  At the moment, please consider
1264		 * scan_begin_src==TRIG_EXT support to be a bonus rather than a
1265		 * guarantee!
1266		 */
1267		cmd->scan_begin_src &= TRIG_TIMER | TRIG_INT | TRIG_EXT;
1268	} else {
1269		cmd->scan_begin_src &= TRIG_TIMER | TRIG_INT;
1270	}
1271	if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
1272		err++;
1273
1274	tmp = cmd->convert_src;
1275	cmd->convert_src &= TRIG_NOW;
1276	if (!cmd->convert_src || tmp != cmd->convert_src)
1277		err++;
1278
1279	tmp = cmd->scan_end_src;
1280	cmd->scan_end_src &= TRIG_COUNT;
1281	if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
1282		err++;
1283
1284	tmp = cmd->stop_src;
1285	cmd->stop_src &= TRIG_COUNT | TRIG_NONE;
1286	if (!cmd->stop_src || tmp != cmd->stop_src)
1287		err++;
1288
1289	if (err)
1290		return 1;
1291
1292	/* Step 2: make sure trigger sources are unique and mutually compatible
1293	 * "source conflict" returned by comedilib to user mode process
1294	 * if this fails. */
1295
1296	/* these tests are true if more than one _src bit is set */
1297	if ((cmd->start_src & (cmd->start_src - 1)) != 0)
1298		err++;
1299	if ((cmd->scan_begin_src & (cmd->scan_begin_src - 1)) != 0)
1300		err++;
1301	if ((cmd->convert_src & (cmd->convert_src - 1)) != 0)
1302		err++;
1303	if ((cmd->scan_end_src & (cmd->scan_end_src - 1)) != 0)
1304		err++;
1305	if ((cmd->stop_src & (cmd->stop_src - 1)) != 0)
1306		err++;
1307
1308	if (err)
1309		return 2;
1310
1311	/* Step 3: make sure arguments are trivially compatible.
1312	 * "invalid argument" returned by comedilib to user mode process
1313	 * if this fails. */
1314
1315	if (cmd->start_arg != 0) {
1316		cmd->start_arg = 0;
1317		err++;
1318	}
1319#define MAX_SPEED_AO	8000	/* 8000 ns => 125 kHz */
1320#define MIN_SPEED_AO	4294967295u	/* 4294967295ns = 4.29s */
1321			/*- Comedi limit due to unsigned int cmd.  Driver limit
1322			 * = 2^16 (16bit * counter) * 1000000ns (1kHz onboard
1323			 * clock) = 65.536s */
1324
1325	switch (cmd->scan_begin_src) {
1326	case TRIG_TIMER:
1327		if (cmd->scan_begin_arg < MAX_SPEED_AO) {
1328			cmd->scan_begin_arg = MAX_SPEED_AO;
1329			err++;
1330		}
1331		if (cmd->scan_begin_arg > MIN_SPEED_AO) {
1332			cmd->scan_begin_arg = MIN_SPEED_AO;
1333			err++;
1334		}
1335		break;
1336	case TRIG_EXT:
1337		/* External trigger - for PCI230+ hardware version 2 onwards. */
1338		/* Trigger number must be 0. */
1339		if ((cmd->scan_begin_arg & ~CR_FLAGS_MASK) != 0) {
1340			cmd->scan_begin_arg = COMBINE(cmd->scan_begin_arg, 0,
1341						      ~CR_FLAGS_MASK);
1342			err++;
1343		}
1344		/* The only flags allowed are CR_EDGE and CR_INVERT.  The
1345		 * CR_EDGE flag is ignored. */
1346		if ((cmd->scan_begin_arg
1347		     & (CR_FLAGS_MASK & ~(CR_EDGE | CR_INVERT))) != 0) {
1348			cmd->scan_begin_arg =
1349			    COMBINE(cmd->scan_begin_arg, 0,
1350				    CR_FLAGS_MASK & ~(CR_EDGE | CR_INVERT));
1351			err++;
1352		}
1353		break;
1354	default:
1355		if (cmd->scan_begin_arg != 0) {
1356			cmd->scan_begin_arg = 0;
1357			err++;
1358		}
1359		break;
1360	}
1361
1362	if (cmd->scan_end_arg != cmd->chanlist_len) {
1363		cmd->scan_end_arg = cmd->chanlist_len;
1364		err++;
1365	}
1366	if (cmd->stop_src == TRIG_NONE) {
1367		/* TRIG_NONE */
1368		if (cmd->stop_arg != 0) {
1369			cmd->stop_arg = 0;
1370			err++;
1371		}
1372	}
1373
1374	if (err)
1375		return 3;
1376
1377	/* Step 4: fix up any arguments.
1378	 * "argument conflict" returned by comedilib to user mode process
1379	 * if this fails. */
1380
1381	if (cmd->scan_begin_src == TRIG_TIMER) {
1382		tmp = cmd->scan_begin_arg;
1383		pci230_ns_to_single_timer(&cmd->scan_begin_arg,
1384					  cmd->flags & TRIG_ROUND_MASK);
1385		if (tmp != cmd->scan_begin_arg)
1386			err++;
1387	}
1388
1389	if (err)
1390		return 4;
1391
1392	/* Step 5: check channel list if it exists. */
1393
1394	if (cmd->chanlist && cmd->chanlist_len > 0) {
1395		enum {
1396			seq_err = (1 << 0),
1397			range_err = (1 << 1)
1398		};
1399		unsigned int errors;
1400		unsigned int n;
1401		unsigned int chan, prev_chan;
1402		unsigned int range, first_range;
1403
1404		prev_chan = CR_CHAN(cmd->chanlist[0]);
1405		first_range = CR_RANGE(cmd->chanlist[0]);
1406		errors = 0;
1407		for (n = 1; n < cmd->chanlist_len; n++) {
1408			chan = CR_CHAN(cmd->chanlist[n]);
1409			range = CR_RANGE(cmd->chanlist[n]);
1410			/* Channel numbers must strictly increase. */
1411			if (chan < prev_chan) {
1412				errors |= seq_err;
1413			}
1414			/* Ranges must be the same. */
1415			if (range != first_range) {
1416				errors |= range_err;
1417			}
1418			prev_chan = chan;
1419		}
1420		if (errors != 0) {
1421			err++;
1422			if ((errors & seq_err) != 0) {
1423				DPRINTK("comedi%d: amplc_pci230: ao_cmdtest: "
1424					"channel numbers must increase\n",
1425					dev->minor);
1426			}
1427			if ((errors & range_err) != 0) {
1428				DPRINTK("comedi%d: amplc_pci230: ao_cmdtest: "
1429					"channels must have the same range\n",
1430					dev->minor);
1431			}
1432		}
1433	}
1434
1435	if (err)
1436		return 5;
1437
1438	return 0;
1439}
1440
1441static int pci230_ao_inttrig_scan_begin(struct comedi_device *dev,
1442					struct comedi_subdevice *s,
1443					unsigned int trig_num)
1444{
1445	unsigned long irqflags;
1446
1447	if (trig_num != 0)
1448		return -EINVAL;
1449
1450	spin_lock_irqsave(&devpriv->ao_stop_spinlock, irqflags);
1451	if (test_bit(AO_CMD_STARTED, &devpriv->state)) {
1452		/* Perform scan. */
1453		if (devpriv->hwver < 2) {
1454			/* Not using DAC FIFO. */
1455			spin_unlock_irqrestore(&devpriv->ao_stop_spinlock,
1456					       irqflags);
1457			pci230_handle_ao_nofifo(dev, s);
1458			comedi_event(dev, s);
1459		} else {
1460			/* Using DAC FIFO. */
1461			/* Read DACSWTRIG register to trigger conversion. */
1462			inw(dev->iobase + PCI230P2_DACSWTRIG);
1463			spin_unlock_irqrestore(&devpriv->ao_stop_spinlock,
1464					       irqflags);
1465		}
1466		/* Delay.  Should driver be responsible for this? */
1467		/* XXX TODO: See if DAC busy bit can be used. */
1468		udelay(8);
1469	}
1470
1471	return 1;
1472}
1473
1474static void pci230_ao_start(struct comedi_device *dev,
1475			    struct comedi_subdevice *s)
1476{
1477	struct comedi_async *async = s->async;
1478	struct comedi_cmd *cmd = &async->cmd;
1479	unsigned long irqflags;
1480
1481	set_bit(AO_CMD_STARTED, &devpriv->state);
1482	if (!devpriv->ao_continuous && (devpriv->ao_scan_count == 0)) {
1483		/* An empty acquisition! */
1484		async->events |= COMEDI_CB_EOA;
1485		pci230_ao_stop(dev, s);
1486		comedi_event(dev, s);
1487	} else {
1488		if (devpriv->hwver >= 2) {
1489			/* Using DAC FIFO. */
1490			unsigned short scantrig;
1491			int run;
1492
1493			/* Preload FIFO data. */
1494			run = pci230_handle_ao_fifo(dev, s);
1495			comedi_event(dev, s);
1496			if (!run) {
1497				/* Stopped. */
1498				return;
1499			}
1500			/* Set scan trigger source. */
1501			switch (cmd->scan_begin_src) {
1502			case TRIG_TIMER:
1503				scantrig = PCI230P2_DAC_TRIG_Z2CT1;
1504				break;
1505			case TRIG_EXT:
1506				/* Trigger on EXTTRIG/EXTCONVCLK pin. */
1507				if ((cmd->scan_begin_arg & CR_INVERT) == 0) {
1508					/* +ve edge */
1509					scantrig = PCI230P2_DAC_TRIG_EXTP;
1510				} else {
1511					/* -ve edge */
1512					scantrig = PCI230P2_DAC_TRIG_EXTN;
1513				}
1514				break;
1515			case TRIG_INT:
1516				scantrig = PCI230P2_DAC_TRIG_SW;
1517				break;
1518			default:
1519				/* Shouldn't get here. */
1520				scantrig = PCI230P2_DAC_TRIG_NONE;
1521				break;
1522			}
1523			devpriv->daccon = (devpriv->daccon
1524					   & ~PCI230P2_DAC_TRIG_MASK) |
1525			    scantrig;
1526			outw(devpriv->daccon, dev->iobase + PCI230_DACCON);
1527
1528		}
1529		switch (cmd->scan_begin_src) {
1530		case TRIG_TIMER:
1531			if (devpriv->hwver < 2) {
1532				/* Not using DAC FIFO. */
1533				/* Enable CT1 timer interrupt. */
1534				spin_lock_irqsave(&devpriv->isr_spinlock,
1535						  irqflags);
1536				devpriv->int_en |= PCI230_INT_ZCLK_CT1;
1537				devpriv->ier |= PCI230_INT_ZCLK_CT1;
1538				outb(devpriv->ier,
1539				     devpriv->iobase1 + PCI230_INT_SCE);
1540				spin_unlock_irqrestore(&devpriv->isr_spinlock,
1541						       irqflags);
1542			}
1543			/* Set CT1 gate high to start counting. */
1544			outb(GAT_CONFIG(1, GAT_VCC),
1545			     devpriv->iobase1 + PCI230_ZGAT_SCE);
1546			break;
1547		case TRIG_INT:
1548			async->inttrig = pci230_ao_inttrig_scan_begin;
1549			break;
1550		}
1551		if (devpriv->hwver >= 2) {
1552			/* Using DAC FIFO.  Enable DAC FIFO interrupt. */
1553			spin_lock_irqsave(&devpriv->isr_spinlock, irqflags);
1554			devpriv->int_en |= PCI230P2_INT_DAC;
1555			devpriv->ier |= PCI230P2_INT_DAC;
1556			outb(devpriv->ier, devpriv->iobase1 + PCI230_INT_SCE);
1557			spin_unlock_irqrestore(&devpriv->isr_spinlock,
1558					       irqflags);
1559		}
1560	}
1561}
1562
1563static int pci230_ao_inttrig_start(struct comedi_device *dev,
1564				   struct comedi_subdevice *s,
1565				   unsigned int trig_num)
1566{
1567	if (trig_num != 0)
1568		return -EINVAL;
1569
1570	s->async->inttrig = NULLFUNC;
1571	pci230_ao_start(dev, s);
1572
1573	return 1;
1574}
1575
1576static int pci230_ao_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
1577{
1578	unsigned short daccon;
1579	unsigned int range;
1580
1581	/* Get the command. */
1582	struct comedi_cmd *cmd = &s->async->cmd;
1583
1584	if (cmd->scan_begin_src == TRIG_TIMER) {
1585		/* Claim Z2-CT1. */
1586		if (!get_one_resource(dev, RES_Z2CT1, OWNER_AOCMD)) {
1587			return -EBUSY;
1588		}
1589	}
1590
1591	/* Get number of scans required. */
1592	if (cmd->stop_src == TRIG_COUNT) {
1593		devpriv->ao_scan_count = cmd->stop_arg;
1594		devpriv->ao_continuous = 0;
1595	} else {
1596		/* TRIG_NONE, user calls cancel. */
1597		devpriv->ao_scan_count = 0;
1598		devpriv->ao_continuous = 1;
1599	}
1600
1601	/* Set range - see analogue output range table; 0 => unipolar 10V,
1602	 * 1 => bipolar +/-10V range scale */
1603	range = CR_RANGE(cmd->chanlist[0]);
1604	devpriv->ao_bipolar = pci230_ao_bipolar[range];
1605	daccon = devpriv->ao_bipolar ? PCI230_DAC_OR_BIP : PCI230_DAC_OR_UNI;
1606	/* Use DAC FIFO for hardware version 2 onwards. */
1607	if (devpriv->hwver >= 2) {
1608		unsigned short dacen;
1609		unsigned int i;
1610
1611		dacen = 0;
1612		for (i = 0; i < cmd->chanlist_len; i++) {
1613			dacen |= 1 << CR_CHAN(cmd->chanlist[i]);
1614		}
1615		/* Set channel scan list. */
1616		outw(dacen, dev->iobase + PCI230P2_DACEN);
1617		/*
1618		 * Enable DAC FIFO.
1619		 * Set DAC scan source to 'none'.
1620		 * Set DAC FIFO interrupt trigger level to 'not half full'.
1621		 * Reset DAC FIFO and clear underrun.
1622		 *
1623		 * N.B. DAC FIFO interrupts are currently disabled.
1624		 */
1625		daccon |= PCI230P2_DAC_FIFO_EN | PCI230P2_DAC_FIFO_RESET
1626		    | PCI230P2_DAC_FIFO_UNDERRUN_CLEAR
1627		    | PCI230P2_DAC_TRIG_NONE | PCI230P2_DAC_INT_FIFO_NHALF;
1628	}
1629
1630	/* Set DACCON. */
1631	outw(daccon, dev->iobase + PCI230_DACCON);
1632	/* Preserve most of DACCON apart from write-only, transient bits. */
1633	devpriv->daccon = daccon
1634	    & ~(PCI230P2_DAC_FIFO_RESET | PCI230P2_DAC_FIFO_UNDERRUN_CLEAR);
1635
1636	if (cmd->scan_begin_src == TRIG_TIMER) {
1637		/* Set the counter timer 1 to the specified scan frequency. */
1638		/* cmd->scan_begin_arg is sampling period in ns */
1639		/* gate it off for now. */
1640		outb(GAT_CONFIG(1, GAT_GND),
1641		     devpriv->iobase1 + PCI230_ZGAT_SCE);
1642		pci230_ct_setup_ns_mode(dev, 1, I8254_MODE3,
1643					cmd->scan_begin_arg,
1644					cmd->flags & TRIG_ROUND_MASK);
1645	}
1646
1647	/* N.B. cmd->start_src == TRIG_INT */
1648	s->async->inttrig = pci230_ao_inttrig_start;
1649
1650	return 0;
1651}
1652
1653static int pci230_ai_check_scan_period(struct comedi_cmd *cmd)
1654{
1655	unsigned int min_scan_period, chanlist_len;
1656	int err = 0;
1657
1658	chanlist_len = cmd->chanlist_len;
1659	if (cmd->chanlist_len == 0) {
1660		chanlist_len = 1;
1661	}
1662	min_scan_period = chanlist_len * cmd->convert_arg;
1663	if ((min_scan_period < chanlist_len)
1664	    || (min_scan_period < cmd->convert_arg)) {
1665		/* Arithmetic overflow. */
1666		min_scan_period = UINT_MAX;
1667		err++;
1668	}
1669	if (cmd->scan_begin_arg < min_scan_period) {
1670		cmd->scan_begin_arg = min_scan_period;
1671		err++;
1672	}
1673
1674	return !err;
1675}
1676
1677static int pci230_ai_cmdtest(struct comedi_device *dev,
1678			     struct comedi_subdevice *s, struct comedi_cmd *cmd)
1679{
1680	int err = 0;
1681	unsigned int tmp;
1682
1683	/* cmdtest tests a particular command to see if it is valid.
1684	 * Using the cmdtest ioctl, a user can create a valid cmd
1685	 * and then have it executes by the cmd ioctl.
1686	 *
1687	 * cmdtest returns 1,2,3,4,5 or 0, depending on which tests
1688	 * the command passes. */
1689
1690	/* Step 1: make sure trigger sources are trivially valid.
1691	 * "invalid source" returned by comedilib to user mode process
1692	 * if this fails. */
1693
1694	tmp = cmd->start_src;
1695	cmd->start_src &= TRIG_NOW | TRIG_INT;
1696	if (!cmd->start_src || tmp != cmd->start_src)
1697		err++;
1698
1699	tmp = cmd->scan_begin_src;
1700	/* Unfortunately, we cannot trigger a scan off an external source
1701	 * on the PCI260 board, since it uses the PPIC0 (DIO) input, which
1702	 * isn't present on the PCI260.  For PCI260+ we can use the
1703	 * EXTTRIG/EXTCONVCLK input on pin 17 instead. */
1704	if ((thisboard->have_dio) || (thisboard->min_hwver > 0)) {
1705		cmd->scan_begin_src &= TRIG_FOLLOW | TRIG_TIMER | TRIG_INT
1706		    | TRIG_EXT;
1707	} else {
1708		cmd->scan_begin_src &= TRIG_FOLLOW | TRIG_TIMER | TRIG_INT;
1709	}
1710	if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
1711		err++;
1712
1713	tmp = cmd->convert_src;
1714	cmd->convert_src &= TRIG_TIMER | TRIG_INT | TRIG_EXT;
1715	if (!cmd->convert_src || tmp != cmd->convert_src)
1716		err++;
1717
1718	tmp = cmd->scan_end_src;
1719	cmd->scan_end_src &= TRIG_COUNT;
1720	if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
1721		err++;
1722
1723	tmp = cmd->stop_src;
1724	cmd->stop_src &= TRIG_COUNT | TRIG_NONE;
1725	if (!cmd->stop_src || tmp != cmd->stop_src)
1726		err++;
1727
1728	if (err)
1729		return 1;
1730
1731	/* Step 2: make sure trigger sources are unique and mutually compatible
1732	 * "source conflict" returned by comedilib to user mode process
1733	 * if this fails. */
1734
1735	/* these tests are true if more than one _src bit is set */
1736	if ((cmd->start_src & (cmd->start_src - 1)) != 0)
1737		err++;
1738	if ((cmd->scan_begin_src & (cmd->scan_begin_src - 1)) != 0)
1739		err++;
1740	if ((cmd->convert_src & (cmd->convert_src - 1)) != 0)
1741		err++;
1742	if ((cmd->scan_end_src & (cmd->scan_end_src - 1)) != 0)
1743		err++;
1744	if ((cmd->stop_src & (cmd->stop_src - 1)) != 0)
1745		err++;
1746
1747	/* If scan_begin_src is not TRIG_FOLLOW, then a monostable will be
1748	 * set up to generate a fixed number of timed conversion pulses. */
1749	if ((cmd->scan_begin_src != TRIG_FOLLOW)
1750	    && (cmd->convert_src != TRIG_TIMER))
1751		err++;
1752
1753	if (err)
1754		return 2;
1755
1756	/* Step 3: make sure arguments are trivially compatible.
1757	 * "invalid argument" returned by comedilib to user mode process
1758	 * if this fails. */
1759
1760	if (cmd->start_arg != 0) {
1761		cmd->start_arg = 0;
1762		err++;
1763	}
1764#define MAX_SPEED_AI_SE		3200	/* PCI230 SE:   3200 ns => 312.5 kHz */
1765#define MAX_SPEED_AI_DIFF	8000	/* PCI230 DIFF: 8000 ns => 125 kHz */
1766#define MAX_SPEED_AI_PLUS	4000	/* PCI230+:     4000 ns => 250 kHz */
1767#define MIN_SPEED_AI	4294967295u	/* 4294967295ns = 4.29s */
1768			/*- Comedi limit due to unsigned int cmd.  Driver limit
1769			 * = 2^16 (16bit * counter) * 1000000ns (1kHz onboard
1770			 * clock) = 65.536s */
1771
1772	if (cmd->convert_src == TRIG_TIMER) {
1773		unsigned int max_speed_ai;
1774
1775		if (devpriv->hwver == 0) {
1776			/* PCI230 or PCI260.  Max speed depends whether
1777			 * single-ended or pseudo-differential. */
1778			if (cmd->chanlist && (cmd->chanlist_len > 0)) {
1779				/* Peek analogue reference of first channel. */
1780				if (CR_AREF(cmd->chanlist[0]) == AREF_DIFF) {
1781					max_speed_ai = MAX_SPEED_AI_DIFF;
1782				} else {
1783					max_speed_ai = MAX_SPEED_AI_SE;
1784				}
1785			} else {
1786				/* No channel list.  Assume single-ended. */
1787				max_speed_ai = MAX_SPEED_AI_SE;
1788			}
1789		} else {
1790			/* PCI230+ or PCI260+. */
1791			max_speed_ai = MAX_SPEED_AI_PLUS;
1792		}
1793
1794		if (cmd->convert_arg < max_speed_ai) {
1795			cmd->convert_arg = max_speed_ai;
1796			err++;
1797		}
1798		if (cmd->convert_arg > MIN_SPEED_AI) {
1799			cmd->convert_arg = MIN_SPEED_AI;
1800			err++;
1801		}
1802	} else if (cmd->convert_src == TRIG_EXT) {
1803		/*
1804		 * external trigger
1805		 *
1806		 * convert_arg == (CR_EDGE | 0)
1807		 *                => trigger on +ve edge.
1808		 * convert_arg == (CR_EDGE | CR_INVERT | 0)
1809		 *                => trigger on -ve edge.
1810		 */
1811		if ((cmd->convert_arg & CR_FLAGS_MASK) != 0) {
1812			/* Trigger number must be 0. */
1813			if ((cmd->convert_arg & ~CR_FLAGS_MASK) != 0) {
1814				cmd->convert_arg = COMBINE(cmd->convert_arg, 0,
1815							   ~CR_FLAGS_MASK);
1816				err++;
1817			}
1818			/* The only flags allowed are CR_INVERT and CR_EDGE.
1819			 * CR_EDGE is required. */
1820			if ((cmd->convert_arg & (CR_FLAGS_MASK & ~CR_INVERT))
1821			    != CR_EDGE) {
1822				/* Set CR_EDGE, preserve CR_INVERT. */
1823				cmd->convert_arg =
1824				    COMBINE(cmd->start_arg, (CR_EDGE | 0),
1825					    CR_FLAGS_MASK & ~CR_INVERT);
1826				err++;
1827			}
1828		} else {
1829			/* Backwards compatibility with previous versions. */
1830			/* convert_arg == 0 => trigger on -ve edge. */
1831			/* convert_arg == 1 => trigger on +ve edge. */
1832			if (cmd->convert_arg > 1) {
1833				/* Default to trigger on +ve edge. */
1834				cmd->convert_arg = 1;
1835				err++;
1836			}
1837		}
1838	} else {
1839		if (cmd->convert_arg != 0) {
1840			cmd->convert_arg = 0;
1841			err++;
1842		}
1843	}
1844
1845	if (cmd->scan_end_arg != cmd->chanlist_len) {
1846		cmd->scan_end_arg = cmd->chanlist_len;
1847		err++;
1848	}
1849
1850	if (cmd->stop_src == TRIG_NONE) {
1851		if (cmd->stop_arg != 0) {
1852			cmd->stop_arg = 0;
1853			err++;
1854		}
1855	}
1856
1857	if (cmd->scan_begin_src == TRIG_EXT) {
1858		/* external "trigger" to begin each scan
1859		 * scan_begin_arg==0 => use PPC0 input -> gate of CT0 -> gate
1860		 * of CT2 (sample convert trigger is CT2) */
1861		if ((cmd->scan_begin_arg & ~CR_FLAGS_MASK) != 0) {
1862			cmd->scan_begin_arg = COMBINE(cmd->scan_begin_arg, 0,
1863						      ~CR_FLAGS_MASK);
1864			err++;
1865		}
1866		/* The only flag allowed is CR_EDGE, which is ignored. */
1867		if ((cmd->scan_begin_arg & CR_FLAGS_MASK & ~CR_EDGE) != 0) {
1868			cmd->scan_begin_arg = COMBINE(cmd->scan_begin_arg, 0,
1869						      CR_FLAGS_MASK & ~CR_EDGE);
1870			err++;
1871		}
1872	} else if (cmd->scan_begin_src == TRIG_TIMER) {
1873		/* N.B. cmd->convert_arg is also TRIG_TIMER */
1874		if (!pci230_ai_check_scan_period(cmd)) {
1875			err++;
1876		}
1877	} else {
1878		if (cmd->scan_begin_arg != 0) {
1879			cmd->scan_begin_arg = 0;
1880			err++;
1881		}
1882	}
1883
1884	if (err)
1885		return 3;
1886
1887	/* Step 4: fix up any arguments.
1888	 * "argument conflict" returned by comedilib to user mode process
1889	 * if this fails. */
1890
1891	if (cmd->convert_src == TRIG_TIMER) {
1892		tmp = cmd->convert_arg;
1893		pci230_ns_to_single_timer(&cmd->convert_arg,
1894					  cmd->flags & TRIG_ROUND_MASK);
1895		if (tmp != cmd->convert_arg)
1896			err++;
1897	}
1898
1899	if (cmd->scan_begin_src == TRIG_TIMER) {
1900		/* N.B. cmd->convert_arg is also TRIG_TIMER */
1901		tmp = cmd->scan_begin_arg;
1902		pci230_ns_to_single_timer(&cmd->scan_begin_arg,
1903					  cmd->flags & TRIG_ROUND_MASK);
1904		if (!pci230_ai_check_scan_period(cmd)) {
1905			/* Was below minimum required.  Round up. */
1906			pci230_ns_to_single_timer(&cmd->scan_begin_arg,
1907						  TRIG_ROUND_UP);
1908			pci230_ai_check_scan_period(cmd);
1909		}
1910		if (tmp != cmd->scan_begin_arg)
1911			err++;
1912	}
1913
1914	if (err)
1915		return 4;
1916
1917	/* Step 5: check channel list if it exists. */
1918
1919	if (cmd->chanlist && cmd->chanlist_len > 0) {
1920		enum {
1921			seq_err = 1 << 0,
1922			rangepair_err = 1 << 1,
1923			polarity_err = 1 << 2,
1924			aref_err = 1 << 3,
1925			diffchan_err = 1 << 4,
1926			buggy_chan0_err = 1 << 5
1927		};
1928		unsigned int errors;
1929		unsigned int chan, prev_chan;
1930		unsigned int range, prev_range;
1931		unsigned int polarity, prev_polarity;
1932		unsigned int aref, prev_aref;
1933		unsigned int subseq_len;
1934		unsigned int n;
1935
1936		subseq_len = 0;
1937		errors = 0;
1938		prev_chan = prev_aref = prev_range = prev_polarity = 0;
1939		for (n = 0; n < cmd->chanlist_len; n++) {
1940			chan = CR_CHAN(cmd->chanlist[n]);
1941			range = CR_RANGE(cmd->chanlist[n]);
1942			aref = CR_AREF(cmd->chanlist[n]);
1943			polarity = pci230_ai_bipolar[range];
1944			/* Only the first half of the channels are available if
1945			 * differential.  (These are remapped in software.  In
1946			 * hardware, only the even channels are available.) */
1947			if ((aref == AREF_DIFF)
1948			    && (chan >= (s->n_chan / 2))) {
1949				errors |= diffchan_err;
1950			}
1951			if (n > 0) {
1952				/* Channel numbers must strictly increase or
1953				 * subsequence must repeat exactly. */
1954				if ((chan <= prev_chan)
1955				    && (subseq_len == 0)) {
1956					subseq_len = n;
1957				}
1958				if ((subseq_len > 0)
1959				    && (cmd->chanlist[n] !=
1960					cmd->chanlist[n % subseq_len])) {
1961					errors |= seq_err;
1962				}
1963				/* Channels must have same AREF. */
1964				if (aref != prev_aref) {
1965					errors |= aref_err;
1966				}
1967				/* Channel ranges must have same polarity. */
1968				if (polarity != prev_polarity) {
1969					errors |= polarity_err;
1970				}
1971				/* Single-ended channel pairs must have same
1972				 * range.  */
1973				if ((aref != AREF_DIFF)
1974				    && (((chan ^ prev_chan) & ~1) == 0)
1975				    && (range != prev_range)) {
1976					errors |= rangepair_err;
1977				}
1978			}
1979			prev_chan = chan;
1980			prev_range = range;
1981			prev_aref = aref;
1982			prev_polarity = polarity;
1983		}
1984		if (subseq_len == 0) {
1985			/* Subsequence is whole sequence. */
1986			subseq_len = n;
1987		}
1988		/* If channel list is a repeating subsequence, need a whole
1989		 * number of repeats. */
1990		if ((n % subseq_len) != 0) {
1991			errors |= seq_err;
1992		}
1993		if ((devpriv->hwver > 0) && (devpriv->hwver < 4)) {
1994			/*
1995			 * Buggy PCI230+ or PCI260+ requires channel 0 to be
1996			 * (first) in the sequence if the sequence contains
1997			 * more than one channel.  Hardware versions 1 and 2
1998			 * have the bug.  There is no hardware version 3.
1999			 *
2000			 * Actually, there are two firmwares that report
2001			 * themselves as hardware version 1 (the boards
2002			 * have different ADC chips with slightly different
2003			 * timing requirements, which was supposed to be
2004			 * invisible to software).  The first one doesn't
2005			 * seem to have the bug, but the second one
2006			 * does, and we can't tell them apart!
2007			 */
2008			if ((subseq_len > 1)
2009			    && (CR_CHAN(cmd->chanlist[0]) != 0)) {
2010				errors |= buggy_chan0_err;
2011			}
2012		}
2013		if (errors != 0) {
2014			err++;
2015			if ((errors & seq_err) != 0) {
2016				DPRINTK("comedi%d: amplc_pci230: ai_cmdtest: "
2017					"channel numbers must increase or "
2018					"sequence must repeat exactly\n",
2019					dev->minor);
2020			}
2021			if ((errors & rangepair_err) != 0) {
2022				DPRINTK("comedi%d: amplc_pci230: ai_cmdtest: "
2023					"single-ended channel pairs must "
2024					"have the same range\n", dev->minor);
2025			}
2026			if ((errors & polarity_err) != 0) {
2027				DPRINTK("comedi%d: amplc_pci230: ai_cmdtest: "
2028					"channel sequence ranges must be all "
2029					"bipolar or all unipolar\n",
2030					dev->minor);
2031			}
2032			if ((errors & aref_err) != 0) {
2033				DPRINTK("comedi%d: amplc_pci230: ai_cmdtest: "
2034					"channel sequence analogue references "
2035					"must be all the same (single-ended "
2036					"or differential)\n", dev->minor);
2037			}
2038			if ((errors & diffchan_err) != 0) {
2039				DPRINTK("comedi%d: amplc_pci230: ai_cmdtest: "
2040					"differential channel number out of "
2041					"range 0 to %u\n", dev->minor,
2042					(s->n_chan / 2) - 1);
2043			}
2044			if ((errors & buggy_chan0_err) != 0) {
2045				/* Use printk instead of DPRINTK here. */
2046				printk("comedi: comedi%d: amplc_pci230: "
2047				       "ai_cmdtest: Buggy PCI230+/260+ "
2048				       "h/w version %u requires first channel "
2049				       "of multi-channel sequence to be 0 "
2050				       "(corrected in h/w version 4)\n",
2051				       dev->minor, devpriv->hwver);
2052			}
2053		}
2054	}
2055
2056	if (err)
2057		return 5;
2058
2059	return 0;
2060}
2061
2062static void pci230_ai_update_fifo_trigger_level(struct comedi_device *dev,
2063						struct comedi_subdevice *s)
2064{
2065	struct comedi_cmd *cmd = &s->async->cmd;
2066	unsigned int scanlen = cmd->scan_end_arg;
2067	unsigned int wake;
2068	unsigned short triglev;
2069	unsigned short adccon;
2070
2071	if ((cmd->flags & TRIG_WAKE_EOS) != 0) {
2072		/* Wake at end of scan. */
2073		wake = scanlen - devpriv->ai_scan_pos;
2074	} else {
2075		if (devpriv->ai_continuous
2076		    || (devpriv->ai_scan_count >= PCI230_ADC_FIFOLEVEL_HALFFULL)
2077		    || (scanlen >= PCI230_ADC_FIFOLEVEL_HALFFULL)) {
2078			wake = PCI230_ADC_FIFOLEVEL_HALFFULL;
2079		} else {
2080			wake = (devpriv->ai_scan_count * scanlen)
2081			    - devpriv->ai_scan_pos;
2082		}
2083	}
2084	if (wake >= PCI230_ADC_FIFOLEVEL_HALFFULL) {
2085		triglev = PCI230_ADC_INT_FIFO_HALF;
2086	} else {
2087		if ((wake > 1) && (devpriv->hwver > 0)) {
2088			/* PCI230+/260+ programmable FIFO interrupt level. */
2089			if (devpriv->adcfifothresh != wake) {
2090				devpriv->adcfifothresh = wake;
2091				outw(wake, dev->iobase + PCI230P_ADCFFTH);
2092			}
2093			triglev = PCI230P_ADC_INT_FIFO_THRESH;
2094		} else {
2095			triglev = PCI230_ADC_INT_FIFO_NEMPTY;
2096		}
2097	}
2098	adccon = (devpriv->adccon & ~PCI230_ADC_INT_FIFO_MASK) | triglev;
2099	if (adccon != devpriv->adccon) {
2100		devpriv->adccon = adccon;
2101		outw(adccon, dev->iobase + PCI230_ADCCON);
2102	}
2103}
2104
2105static int pci230_ai_inttrig_convert(struct comedi_device *dev,
2106				     struct comedi_subdevice *s,
2107				     unsigned int trig_num)
2108{
2109	unsigned long irqflags;
2110
2111	if (trig_num != 0)
2112		return -EINVAL;
2113
2114	spin_lock_irqsave(&devpriv->ai_stop_spinlock, irqflags);
2115	if (test_bit(AI_CMD_STARTED, &devpriv->state)) {
2116		unsigned int delayus;
2117
2118		/* Trigger conversion by toggling Z2-CT2 output.  Finish
2119		 * with output high. */
2120		i8254_set_mode(devpriv->iobase1 + PCI230_Z2_CT_BASE, 0, 2,
2121			       I8254_MODE0);
2122		i8254_set_mode(devpriv->iobase1 + PCI230_Z2_CT_BASE, 0, 2,
2123			       I8254_MODE1);
2124		/* Delay.  Should driver be responsible for this?  An
2125		 * alternative would be to wait until conversion is complete,
2126		 * but we can't tell when it's complete because the ADC busy
2127		 * bit has a different meaning when FIFO enabled (and when
2128		 * FIFO not enabled, it only works for software triggers). */
2129		if (((devpriv->adccon & PCI230_ADC_IM_MASK)
2130		     == PCI230_ADC_IM_DIF)
2131		    && (devpriv->hwver == 0)) {
2132			/* PCI230/260 in differential mode */
2133			delayus = 8;
2134		} else {
2135			/* single-ended or PCI230+/260+ */
2136			delayus = 4;
2137		}
2138		spin_unlock_irqrestore(&devpriv->ai_stop_spinlock, irqflags);
2139		udelay(delayus);
2140	} else {
2141		spin_unlock_irqrestore(&devpriv->ai_stop_spinlock, irqflags);
2142	}
2143
2144	return 1;
2145}
2146
2147static int pci230_ai_inttrig_scan_begin(struct comedi_device *dev,
2148					struct comedi_subdevice *s,
2149					unsigned int trig_num)
2150{
2151	unsigned long irqflags;
2152	unsigned char zgat;
2153
2154	if (trig_num != 0)
2155		return -EINVAL;
2156
2157	spin_lock_irqsave(&devpriv->ai_stop_spinlock, irqflags);
2158	if (test_bit(AI_CMD_STARTED, &devpriv->state)) {
2159		/* Trigger scan by waggling CT0 gate source. */
2160		zgat = GAT_CONFIG(0, GAT_GND);
2161		outb(zgat, devpriv->iobase1 + PCI230_ZGAT_SCE);
2162		zgat = GAT_CONFIG(0, GAT_VCC);
2163		outb(zgat, devpriv->iobase1 + PCI230_ZGAT_SCE);
2164	}
2165	spin_unlock_irqrestore(&devpriv->ai_stop_spinlock, irqflags);
2166
2167	return 1;
2168}
2169
2170static void pci230_ai_start(struct comedi_device *dev,
2171			    struct comedi_subdevice *s)
2172{
2173	unsigned long irqflags;
2174	unsigned short conv;
2175	struct comedi_async *async = s->async;
2176	struct comedi_cmd *cmd = &async->cmd;
2177
2178	set_bit(AI_CMD_STARTED, &devpriv->state);
2179	if (!devpriv->ai_continuous && (devpriv->ai_scan_count == 0)) {
2180		/* An empty acquisition! */
2181		async->events |= COMEDI_CB_EOA;
2182		pci230_ai_stop(dev, s);
2183		comedi_event(dev, s);
2184	} else {
2185		/* Enable ADC FIFO trigger level interrupt. */
2186		spin_lock_irqsave(&devpriv->isr_spinlock, irqflags);
2187		devpriv->int_en |= PCI230_INT_ADC;
2188		devpriv->ier |= PCI230_INT_ADC;
2189		outb(devpriv->ier, devpriv->iobase1 + PCI230_INT_SCE);
2190		spin_unlock_irqrestore(&devpriv->isr_spinlock, irqflags);
2191
2192		/* Update conversion trigger source which is currently set
2193		 * to CT2 output, which is currently stuck high. */
2194		switch (cmd->convert_src) {
2195		default:
2196			conv = PCI230_ADC_TRIG_NONE;
2197			break;
2198		case TRIG_TIMER:
2199			/* Using CT2 output. */
2200			conv = PCI230_ADC_TRIG_Z2CT2;
2201			break;
2202		case TRIG_EXT:
2203			if ((cmd->convert_arg & CR_EDGE) != 0) {
2204				if ((cmd->convert_arg & CR_INVERT) == 0) {
2205					/* Trigger on +ve edge. */
2206					conv = PCI230_ADC_TRIG_EXTP;
2207				} else {
2208					/* Trigger on -ve edge. */
2209					conv = PCI230_ADC_TRIG_EXTN;
2210				}
2211			} else {
2212				/* Backwards compatibility. */
2213				if (cmd->convert_arg != 0) {
2214					/* Trigger on +ve edge. */
2215					conv = PCI230_ADC_TRIG_EXTP;
2216				} else {
2217					/* Trigger on -ve edge. */
2218					conv = PCI230_ADC_TRIG_EXTN;
2219				}
2220			}
2221			break;
2222		case TRIG_INT:
2223			/* Use CT2 output for software trigger due to problems
2224			 * in differential mode on PCI230/260. */
2225			conv = PCI230_ADC_TRIG_Z2CT2;
2226			break;
2227		}
2228		devpriv->adccon = (devpriv->adccon & ~PCI230_ADC_TRIG_MASK)
2229		    | conv;
2230		outw(devpriv->adccon, dev->iobase + PCI230_ADCCON);
2231		if (cmd->convert_src == TRIG_INT) {
2232			async->inttrig = pci230_ai_inttrig_convert;
2233		}
2234		/* Update FIFO interrupt trigger level, which is currently
2235		 * set to "full".  */
2236		pci230_ai_update_fifo_trigger_level(dev, s);
2237		if (cmd->convert_src == TRIG_TIMER) {
2238			/* Update timer gates. */
2239			unsigned char zgat;
2240
2241			if (cmd->scan_begin_src != TRIG_FOLLOW) {
2242				/* Conversion timer CT2 needs to be gated by
2243				 * inverted output of monostable CT2. */
2244				zgat = GAT_CONFIG(2, GAT_NOUTNM2);
2245			} else {
2246				/* Conversion timer CT2 needs to be gated on
2247				 * continuously. */
2248				zgat = GAT_CONFIG(2, GAT_VCC);
2249			}
2250			outb(zgat, devpriv->iobase1 + PCI230_ZGAT_SCE);
2251			if (cmd->scan_begin_src != TRIG_FOLLOW) {
2252				/* Set monostable CT0 trigger source. */
2253				switch (cmd->scan_begin_src) {
2254				default:
2255					zgat = GAT_CONFIG(0, GAT_VCC);
2256					break;
2257				case TRIG_EXT:
2258					/*
2259					 * For CT0 on PCI230, the external
2260					 * trigger (gate) signal comes from
2261					 * PPC0, which is channel 16 of the DIO
2262					 * subdevice.  The application needs to
2263					 * configure this as an input in order
2264					 * to use it as an external scan
2265					 * trigger.
2266					 */
2267					zgat = GAT_CONFIG(0, GAT_EXT);
2268					break;
2269				case TRIG_TIMER:
2270					/*
2271					 * Monostable CT0 triggered by rising
2272					 * edge on inverted output of CT1
2273					 * (falling edge on CT1).
2274					 */
2275					zgat = GAT_CONFIG(0, GAT_NOUTNM2);
2276					break;
2277				case TRIG_INT:
2278					/*
2279					 * Monostable CT0 is triggered by
2280					 * inttrig function waggling the CT0
2281					 * gate source.
2282					 */
2283					zgat = GAT_CONFIG(0, GAT_VCC);
2284					break;
2285				}
2286				outb(zgat, devpriv->iobase1 + PCI230_ZGAT_SCE);
2287				switch (cmd->scan_begin_src) {
2288				case TRIG_TIMER:
2289					/* Scan period timer CT1 needs to be
2290					 * gated on to start counting. */
2291					zgat = GAT_CONFIG(1, GAT_VCC);
2292					outb(zgat, devpriv->iobase1
2293					     + PCI230_ZGAT_SCE);
2294					break;
2295				case TRIG_INT:
2296					async->inttrig =
2297					    pci230_ai_inttrig_scan_begin;
2298					break;
2299				}
2300			}
2301		} else if (cmd->convert_src != TRIG_INT) {
2302			/* No longer need Z2-CT2. */
2303			put_one_resource(dev, RES_Z2CT2, OWNER_AICMD);
2304		}
2305	}
2306}
2307
2308static int pci230_ai_inttrig_start(struct comedi_device *dev,
2309				   struct comedi_subdevice *s,
2310				   unsigned int trig_num)
2311{
2312	if (trig_num != 0)
2313		return -EINVAL;
2314
2315	s->async->inttrig = NULLFUNC;
2316	pci230_ai_start(dev, s);
2317
2318	return 1;
2319}
2320
2321static int pci230_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
2322{
2323	unsigned int i, chan, range, diff;
2324	unsigned int res_mask;
2325	unsigned short adccon, adcen;
2326	unsigned char zgat;
2327
2328	/* Get the command. */
2329	struct comedi_async *async = s->async;
2330	struct comedi_cmd *cmd = &async->cmd;
2331
2332	/*
2333	 * Determine which shared resources are needed.
2334	 */
2335	res_mask = 0;
2336	/* Need Z2-CT2 to supply a conversion trigger source at a high
2337	 * logic level, even if not doing timed conversions. */
2338	res_mask |= (1U << RES_Z2CT2);
2339	if (cmd->scan_begin_src != TRIG_FOLLOW) {
2340		/* Using Z2-CT0 monostable to gate Z2-CT2 conversion timer */
2341		res_mask |= (1U << RES_Z2CT0);
2342		if (cmd->scan_begin_src == TRIG_TIMER) {
2343			/* Using Z2-CT1 for scan frequency */
2344			res_mask |= (1U << RES_Z2CT1);
2345		}
2346	}
2347	/* Claim resources. */
2348	if (!get_resources(dev, res_mask, OWNER_AICMD)) {
2349		return -EBUSY;
2350	}
2351
2352	/* Get number of scans required. */
2353	if (cmd->stop_src == TRIG_COUNT) {
2354		devpriv->ai_scan_count = cmd->stop_arg;
2355		devpriv->ai_continuous = 0;
2356	} else {
2357		/* TRIG_NONE, user calls cancel. */
2358		devpriv->ai_scan_count = 0;
2359		devpriv->ai_continuous = 1;
2360	}
2361	devpriv->ai_scan_pos = 0;	/* Position within scan. */
2362
2363	/* Steps;
2364	 * - Set channel scan list.
2365	 * - Set channel gains.
2366	 * - Enable and reset FIFO, specify uni/bip, se/diff, and set
2367	 *   start conversion source to point to something at a high logic
2368	 *   level (we use the output of counter/timer 2 for this purpose.
2369	 * - PAUSE to allow things to settle down.
2370	 * - Reset the FIFO again because it needs resetting twice and there
2371	 *   may have been a false conversion trigger on some versions of
2372	 *   PCI230/260 due to the start conversion source being set to a
2373	 *   high logic level.
2374	 * - Enable ADC FIFO level interrupt.
2375	 * - Set actual conversion trigger source and FIFO interrupt trigger
2376	 *   level.
2377	 * - If convert_src is TRIG_TIMER, set up the timers.
2378	 */
2379
2380	adccon = PCI230_ADC_FIFO_EN;
2381	adcen = 0;
2382
2383	if (CR_AREF(cmd->chanlist[0]) == AREF_DIFF) {
2384		/* Differential - all channels must be differential. */
2385		diff = 1;
2386		adccon |= PCI230_ADC_IM_DIF;
2387	} else {
2388		/* Single ended - all channels must be single-ended. */
2389		diff = 0;
2390		adccon |= PCI230_ADC_IM_SE;
2391	}
2392
2393	range = CR_RANGE(cmd->chanlist[0]);
2394	devpriv->ai_bipolar = pci230_ai_bipolar[range];
2395	if (devpriv->ai_bipolar) {
2396		adccon |= PCI230_ADC_IR_BIP;
2397	} else {
2398		adccon |= PCI230_ADC_IR_UNI;
2399	}
2400	for (i = 0; i < cmd->chanlist_len; i++) {
2401		unsigned int gainshift;
2402
2403		chan = CR_CHAN(cmd->chanlist[i]);
2404		range = CR_RANGE(cmd->chanlist[i]);
2405		if (diff) {
2406			gainshift = 2 * chan;
2407			if (devpriv->hwver == 0) {
2408				/* Original PCI230/260 expects both inputs of
2409				 * the differential channel to be enabled. */
2410				adcen |= 3 << gainshift;
2411			} else {
2412				/* PCI230+/260+ expects only one input of the
2413				 * differential channel to be enabled. */
2414				adcen |= 1 << gainshift;
2415			}
2416		} else {
2417			gainshift = (chan & ~1);
2418			adcen |= 1 << chan;
2419		}
2420		devpriv->adcg = (devpriv->adcg & ~(3 << gainshift))
2421		    | (pci230_ai_gain[range] << gainshift);
2422	}
2423
2424	/* Set channel scan list. */
2425	outw(adcen, dev->iobase + PCI230_ADCEN);
2426
2427	/* Set channel gains. */
2428	outw(devpriv->adcg, dev->iobase + PCI230_ADCG);
2429
2430	/* Set counter/timer 2 output high for use as the initial start
2431	 * conversion source. */
2432	i8254_set_mode(devpriv->iobase1 + PCI230_Z2_CT_BASE, 0, 2, I8254_MODE1);
2433
2434	/* Temporarily use CT2 output as conversion trigger source and
2435	 * temporarily set FIFO interrupt trigger level to 'full'. */
2436	adccon |= PCI230_ADC_INT_FIFO_FULL | PCI230_ADC_TRIG_Z2CT2;
2437
2438	/* Enable and reset FIFO, specify FIFO trigger level full, specify
2439	 * uni/bip, se/diff, and temporarily set the start conversion source
2440	 * to CT2 output.  Note that CT2 output is currently high, and this
2441	 * will produce a false conversion trigger on some versions of the
2442	 * PCI230/260, but that will be dealt with later. */
2443	devpriv->adccon = adccon;
2444	outw(adccon | PCI230_ADC_FIFO_RESET, dev->iobase + PCI230_ADCCON);
2445
2446	/* Delay */
2447	/* Failure to include this will result in the first few channels'-worth
2448	 * of data being corrupt, normally manifesting itself by large negative
2449	 * voltages. It seems the board needs time to settle between the first
2450	 * FIFO reset (above) and the second FIFO reset (below). Setting the
2451	 * channel gains and scan list _before_ the first FIFO reset also
2452	 * helps, though only slightly. */
2453	udelay(25);
2454
2455	/* Reset FIFO again. */
2456	outw(adccon | PCI230_ADC_FIFO_RESET, dev->iobase + PCI230_ADCCON);
2457
2458	if (cmd->convert_src == TRIG_TIMER) {
2459		/* Set up CT2 as conversion timer, but gate it off for now.
2460		 * Note, counter/timer output 2 can be monitored on the
2461		 * connector: PCI230 pin 21, PCI260 pin 18. */
2462		zgat = GAT_CONFIG(2, GAT_GND);
2463		outb(zgat, devpriv->iobase1 + PCI230_ZGAT_SCE);
2464		/* Set counter/timer 2 to the specified conversion period. */
2465		pci230_ct_setup_ns_mode(dev, 2, I8254_MODE3, cmd->convert_arg,
2466					cmd->flags & TRIG_ROUND_MASK);
2467		if (cmd->scan_begin_src != TRIG_FOLLOW) {
2468			/*
2469			 * Set up monostable on CT0 output for scan timing.  A
2470			 * rising edge on the trigger (gate) input of CT0 will
2471			 * trigger the monostable, causing its output to go low
2472			 * for the configured period.  The period depends on
2473			 * the conversion period and the number of conversions
2474			 * in the scan.
2475			 *
2476			 * Set the trigger high before setting up the
2477			 * monostable to stop it triggering.  The trigger
2478			 * source will be changed later.
2479			 */
2480			zgat = GAT_CONFIG(0, GAT_VCC);
2481			outb(zgat, devpriv->iobase1 + PCI230_ZGAT_SCE);
2482			pci230_ct_setup_ns_mode(dev, 0, I8254_MODE1,
2483						((uint64_t) cmd->convert_arg
2484						 * cmd->scan_end_arg),
2485						TRIG_ROUND_UP);
2486			if (cmd->scan_begin_src == TRIG_TIMER) {
2487				/*
2488				 * Monostable on CT0 will be triggered by
2489				 * output of CT1 at configured scan frequency.
2490				 *
2491				 * Set up CT1 but gate it off for now.
2492				 */
2493				zgat = GAT_CONFIG(1, GAT_GND);
2494				outb(zgat, devpriv->iobase1 + PCI230_ZGAT_SCE);
2495				pci230_ct_setup_ns_mode(dev, 1, I8254_MODE3,
2496							cmd->scan_begin_arg,
2497							cmd->
2498							flags &
2499							TRIG_ROUND_MASK);
2500			}
2501		}
2502	}
2503
2504	if (cmd->start_src == TRIG_INT) {
2505		s->async->inttrig = pci230_ai_inttrig_start;
2506	} else {
2507		/* TRIG_NOW */
2508		pci230_ai_start(dev, s);
2509	}
2510
2511	return 0;
2512}
2513
2514static unsigned int divide_ns(uint64_t ns, unsigned int timebase,
2515			      unsigned int round_mode)
2516{
2517	uint64_t div;
2518	unsigned int rem;
2519
2520	div = ns;
2521	rem = do_div(div, timebase);
2522	round_mode &= TRIG_ROUND_MASK;
2523	switch (round_mode) {
2524	default:
2525	case TRIG_ROUND_NEAREST:
2526		div += (rem + (timebase / 2)) / timebase;
2527		break;
2528	case TRIG_ROUND_DOWN:
2529		break;
2530	case TRIG_ROUND_UP:
2531		div += (rem + timebase - 1) / timebase;
2532		break;
2533	}
2534	return div > UINT_MAX ? UINT_MAX : (unsigned int)div;
2535}
2536
2537/* Given desired period in ns, returns the required internal clock source
2538 * and gets the initial count. */
2539static unsigned int pci230_choose_clk_count(uint64_t ns, unsigned int *count,
2540					    unsigned int round_mode)
2541{
2542	unsigned int clk_src, cnt;
2543
2544	for (clk_src = CLK_10MHZ;; clk_src++) {
2545		cnt = divide_ns(ns, pci230_timebase[clk_src], round_mode);
2546		if ((cnt <= 65536) || (clk_src == CLK_1KHZ)) {
2547			break;
2548		}
2549	}
2550	*count = cnt;
2551	return clk_src;
2552}
2553
2554static void pci230_ns_to_single_timer(unsigned int *ns, unsigned int round)
2555{
2556	unsigned int count;
2557	unsigned int clk_src;
2558
2559	clk_src = pci230_choose_clk_count(*ns, &count, round);
2560	*ns = count * pci230_timebase[clk_src];
2561	return;
2562}
2563
2564static void pci230_ct_setup_ns_mode(struct comedi_device *dev, unsigned int ct,
2565				    unsigned int mode, uint64_t ns,
2566				    unsigned int round)
2567{
2568	unsigned int clk_src;
2569	unsigned int count;
2570
2571	/* Set mode. */
2572	i8254_set_mode(devpriv->iobase1 + PCI230_Z2_CT_BASE, 0, ct, mode);
2573	/* Determine clock source and count. */
2574	clk_src = pci230_choose_clk_count(ns, &count, round);
2575	/* Program clock source. */
2576	outb(CLK_CONFIG(ct, clk_src), devpriv->iobase1 + PCI230_ZCLK_SCE);
2577	/* Set initial count. */
2578	if (count >= 65536) {
2579		count = 0;
2580	}
2581	i8254_write(devpriv->iobase1 + PCI230_Z2_CT_BASE, 0, ct, count);
2582}
2583
2584static void pci230_cancel_ct(struct comedi_device *dev, unsigned int ct)
2585{
2586	i8254_set_mode(devpriv->iobase1 + PCI230_Z2_CT_BASE, 0, ct,
2587		       I8254_MODE1);
2588	/* Counter ct, 8254 mode 1, initial count not written. */
2589}
2590
2591/* Interrupt handler */
2592static irqreturn_t pci230_interrupt(int irq, void *d)
2593{
2594	unsigned char status_int, valid_status_int;
2595	struct comedi_device *dev = (struct comedi_device *)d;
2596	struct comedi_subdevice *s;
2597	unsigned long irqflags;
2598
2599	/* Read interrupt status/enable register. */
2600	status_int = inb(devpriv->iobase1 + PCI230_INT_STAT);
2601
2602	if (status_int == PCI230_INT_DISABLE) {
2603		return IRQ_NONE;
2604	}
2605
2606	spin_lock_irqsave(&devpriv->isr_spinlock, irqflags);
2607	valid_status_int = devpriv->int_en & status_int;
2608	/* Disable triggered interrupts.
2609	 * (Only those interrupts that need re-enabling, are, later in the
2610	 * handler).  */
2611	devpriv->ier = devpriv->int_en & ~status_int;
2612	outb(devpriv->ier, devpriv->iobase1 + PCI230_INT_SCE);
2613	devpriv->intr_running = 1;
2614	devpriv->intr_cpuid = THISCPU;
2615	spin_unlock_irqrestore(&devpriv->isr_spinlock, irqflags);
2616
2617	/*
2618	 * Check the source of interrupt and handle it.
2619	 * The PCI230 can cope with concurrent ADC, DAC, PPI C0 and C3
2620	 * interrupts.  However, at present (Comedi-0.7.60) does not allow
2621	 * concurrent execution of commands, instructions or a mixture of the
2622	 * two.
2623	 */
2624
2625	if ((valid_status_int & PCI230_INT_ZCLK_CT1) != 0) {
2626		s = dev->write_subdev;
2627		pci230_handle_ao_nofifo(dev, s);
2628		comedi_event(dev, s);
2629	}
2630
2631	if ((valid_status_int & PCI230P2_INT_DAC) != 0) {
2632		s = dev->write_subdev;
2633		pci230_handle_ao_fifo(dev, s);
2634		comedi_event(dev, s);
2635	}
2636
2637	if ((valid_status_int & PCI230_INT_ADC) != 0) {
2638		s = dev->read_subdev;
2639		pci230_handle_ai(dev, s);
2640		comedi_event(dev, s);
2641	}
2642
2643	/* Reenable interrupts. */
2644	spin_lock_irqsave(&devpriv->isr_spinlock, irqflags);
2645	if (devpriv->ier != devpriv->int_en) {
2646		devpriv->ier = devpriv->int_en;
2647		outb(devpriv->ier, devpriv->iobase1 + PCI230_INT_SCE);
2648	}
2649	devpriv->intr_running = 0;
2650	spin_unlock_irqrestore(&devpriv->isr_spinlock, irqflags);
2651
2652	return IRQ_HANDLED;
2653}
2654
2655static void pci230_handle_ao_nofifo(struct comedi_device *dev,
2656				    struct comedi_subdevice *s)
2657{
2658	short data;
2659	int i, ret;
2660	struct comedi_async *async = s->async;
2661	struct comedi_cmd *cmd = &async->cmd;
2662
2663	if (!devpriv->ao_continuous && (devpriv->ao_scan_count == 0)) {
2664		return;
2665	}
2666
2667	for (i = 0; i < cmd->chanlist_len; i++) {
2668		/* Read sample from Comedi's circular buffer. */
2669		ret = comedi_buf_get(s->async, &data);
2670		if (ret == 0) {
2671			s->async->events |= COMEDI_CB_OVERFLOW;
2672			pci230_ao_stop(dev, s);
2673			comedi_error(dev, "AO buffer underrun");
2674			return;
2675		}
2676		/* Write value to DAC. */
2677		pci230_ao_write_nofifo(dev, data, CR_CHAN(cmd->chanlist[i]));
2678	}
2679
2680	async->events |= COMEDI_CB_BLOCK | COMEDI_CB_EOS;
2681	if (!devpriv->ao_continuous) {
2682		devpriv->ao_scan_count--;
2683		if (devpriv->ao_scan_count == 0) {
2684			/* End of acquisition. */
2685			async->events |= COMEDI_CB_EOA;
2686			pci230_ao_stop(dev, s);
2687		}
2688	}
2689}
2690
2691/* Loads DAC FIFO (if using it) from buffer. */
2692/* Returns 0 if AO finished due to completion or error, 1 if still going. */
2693static int pci230_handle_ao_fifo(struct comedi_device *dev,
2694				 struct comedi_subdevice *s)
2695{
2696	struct comedi_async *async = s->async;
2697	struct comedi_cmd *cmd = &async->cmd;
2698	unsigned int num_scans;
2699	unsigned int room;
2700	unsigned short dacstat;
2701	unsigned int i, n;
2702	unsigned int bytes_per_scan;
2703	unsigned int events = 0;
2704	int running;
2705
2706	/* Get DAC FIFO status. */
2707	dacstat = inw(dev->iobase + PCI230_DACCON);
2708
2709	/* Determine number of scans available in buffer. */
2710	bytes_per_scan = cmd->chanlist_len * sizeof(short);
2711	num_scans = comedi_buf_read_n_available(async) / bytes_per_scan;
2712	if (!devpriv->ao_continuous) {
2713		/* Fixed number of scans. */
2714		if (num_scans > devpriv->ao_scan_count) {
2715			num_scans = devpriv->ao_scan_count;
2716		}
2717		if (devpriv->ao_scan_count == 0) {
2718			/* End of acquisition. */
2719			events |= COMEDI_CB_EOA;
2720		}
2721	}
2722	if (events == 0) {
2723		/* Check for FIFO underrun. */
2724		if ((dacstat & PCI230P2_DAC_FIFO_UNDERRUN_LATCHED) != 0) {
2725			comedi_error(dev, "AO FIFO underrun");
2726			events |= COMEDI_CB_OVERFLOW | COMEDI_CB_ERROR;
2727		}
2728		/* Check for buffer underrun if FIFO less than half full
2729		 * (otherwise there will be loads of "DAC FIFO not half full"
2730		 * interrupts). */
2731		if ((num_scans == 0)
2732		    && ((dacstat & PCI230P2_DAC_FIFO_HALF) == 0)) {
2733			comedi_error(dev, "AO buffer underrun");
2734			events |= COMEDI_CB_OVERFLOW | COMEDI_CB_ERROR;
2735		}
2736	}
2737	if (events == 0) {
2738		/* Determine how much room is in the FIFO (in samples). */
2739		if ((dacstat & PCI230P2_DAC_FIFO_FULL) != 0) {
2740			room = PCI230P2_DAC_FIFOROOM_FULL;
2741		} else if ((dacstat & PCI230P2_DAC_FIFO_HALF) != 0) {
2742			room = PCI230P2_DAC_FIFOROOM_HALFTOFULL;
2743		} else if ((dacstat & PCI230P2_DAC_FIFO_EMPTY) != 0) {
2744			room = PCI230P2_DAC_FIFOROOM_EMPTY;
2745		} else {
2746			room = PCI230P2_DAC_FIFOROOM_ONETOHALF;
2747		}
2748		/* Convert room to number of scans that can be added. */
2749		room /= cmd->chanlist_len;
2750		/* Determine number of scans to process. */
2751		if (num_scans > room) {
2752			num_scans = room;
2753		}
2754		/* Process scans. */
2755		for (n = 0; n < num_scans; n++) {
2756			for (i = 0; i < cmd->chanlist_len; i++) {
2757				short datum;
2758
2759				comedi_buf_get(async, &datum);
2760				pci230_ao_write_fifo(dev, datum,
2761						     CR_CHAN(cmd->chanlist[i]));
2762			}
2763		}
2764		events |= COMEDI_CB_EOS | COMEDI_CB_BLOCK;
2765		if (!devpriv->ao_continuous) {
2766			devpriv->ao_scan_count -= num_scans;
2767			if (devpriv->ao_scan_count == 0) {
2768				/* All data for the command has been written
2769				 * to FIFO.  Set FIFO interrupt trigger level
2770				 * to 'empty'. */
2771				devpriv->daccon = (devpriv->daccon
2772						   &
2773						   ~PCI230P2_DAC_INT_FIFO_MASK)
2774				    | PCI230P2_DAC_INT_FIFO_EMPTY;
2775				outw(devpriv->daccon,
2776				     dev->iobase + PCI230_DACCON);
2777			}
2778		}
2779		/* Check if FIFO underrun occurred while writing to FIFO. */
2780		dacstat = inw(dev->iobase + PCI230_DACCON);
2781		if ((dacstat & PCI230P2_DAC_FIFO_UNDERRUN_LATCHED) != 0) {
2782			comedi_error(dev, "AO FIFO underrun");
2783			events |= COMEDI_CB_OVERFLOW | COMEDI_CB_ERROR;
2784		}
2785	}
2786	if ((events & (COMEDI_CB_EOA | COMEDI_CB_ERROR | COMEDI_CB_OVERFLOW))
2787	    != 0) {
2788		/* Stopping AO due to completion or error. */
2789		pci230_ao_stop(dev, s);
2790		running = 0;
2791	} else {
2792		running = 1;
2793	}
2794	async->events |= events;
2795	return running;
2796}
2797
2798static void pci230_handle_ai(struct comedi_device *dev,
2799			     struct comedi_subdevice *s)
2800{
2801	unsigned int events = 0;
2802	unsigned int status_fifo;
2803	unsigned int i;
2804	unsigned int todo;
2805	unsigned int fifoamount;
2806	struct comedi_async *async = s->async;
2807	unsigned int scanlen = async->cmd.scan_end_arg;
2808
2809	/* Determine number of samples to read. */
2810	if (devpriv->ai_continuous) {
2811		todo = PCI230_ADC_FIFOLEVEL_HALFFULL;
2812	} else if (devpriv->ai_scan_count == 0) {
2813		todo = 0;
2814	} else if ((devpriv->ai_scan_count > PCI230_ADC_FIFOLEVEL_HALFFULL)
2815		   || (scanlen > PCI230_ADC_FIFOLEVEL_HALFFULL)) {
2816		todo = PCI230_ADC_FIFOLEVEL_HALFFULL;
2817	} else {
2818		todo = (devpriv->ai_scan_count * scanlen)
2819		    - devpriv->ai_scan_pos;
2820		if (todo > PCI230_ADC_FIFOLEVEL_HALFFULL) {
2821			todo = PCI230_ADC_FIFOLEVEL_HALFFULL;
2822		}
2823	}
2824
2825	if (todo == 0) {
2826		return;
2827	}
2828
2829	fifoamount = 0;
2830	for (i = 0; i < todo; i++) {
2831		if (fifoamount == 0) {
2832			/* Read FIFO state. */
2833			status_fifo = inw(dev->iobase + PCI230_ADCCON);
2834
2835			if ((status_fifo & PCI230_ADC_FIFO_FULL_LATCHED) != 0) {
2836				/* Report error otherwise FIFO overruns will go
2837				 * unnoticed by the caller. */
2838				comedi_error(dev, "AI FIFO overrun");
2839				events |= COMEDI_CB_OVERFLOW | COMEDI_CB_ERROR;
2840				break;
2841			} else if ((status_fifo & PCI230_ADC_FIFO_EMPTY) != 0) {
2842				/* FIFO empty. */
2843				break;
2844			} else if ((status_fifo & PCI230_ADC_FIFO_HALF) != 0) {
2845				/* FIFO half full. */
2846				fifoamount = PCI230_ADC_FIFOLEVEL_HALFFULL;
2847			} else {
2848				/* FIFO not empty. */
2849				if (devpriv->hwver > 0) {
2850					/* Read PCI230+/260+ ADC FIFO level. */
2851					fifoamount = inw(dev->iobase
2852							 + PCI230P_ADCFFLEV);
2853					if (fifoamount == 0) {
2854						/* Shouldn't happen. */
2855						break;
2856					}
2857				} else {
2858					fifoamount = 1;
2859				}
2860			}
2861		}
2862
2863		/* Read sample and store in Comedi's circular buffer. */
2864		if (comedi_buf_put(async, pci230_ai_read(dev)) == 0) {
2865			events |= COMEDI_CB_ERROR | COMEDI_CB_OVERFLOW;
2866			comedi_error(dev, "AI buffer overflow");
2867			break;
2868		}
2869		fifoamount--;
2870		devpriv->ai_scan_pos++;
2871		if (devpriv->ai_scan_pos == scanlen) {
2872			/* End of scan. */
2873			devpriv->ai_scan_pos = 0;
2874			devpriv->ai_scan_count--;
2875			async->events |= COMEDI_CB_EOS;
2876		}
2877	}
2878
2879	if (!devpriv->ai_continuous && (devpriv->ai_scan_count == 0)) {
2880		/* End of acquisition. */
2881		events |= COMEDI_CB_EOA;
2882	} else {
2883		/* More samples required, tell Comedi to block. */
2884		events |= COMEDI_CB_BLOCK;
2885	}
2886	async->events |= events;
2887
2888	if ((async->events & (COMEDI_CB_EOA | COMEDI_CB_ERROR |
2889			      COMEDI_CB_OVERFLOW)) != 0) {
2890		/* disable hardware conversions */
2891		pci230_ai_stop(dev, s);
2892	} else {
2893		/* update FIFO interrupt trigger level */
2894		pci230_ai_update_fifo_trigger_level(dev, s);
2895	}
2896}
2897
2898static void pci230_ao_stop(struct comedi_device *dev,
2899			   struct comedi_subdevice *s)
2900{
2901	unsigned long irqflags;
2902	unsigned char intsrc;
2903	int started;
2904	struct comedi_cmd *cmd;
2905
2906	spin_lock_irqsave(&devpriv->ao_stop_spinlock, irqflags);
2907	started = test_and_clear_bit(AO_CMD_STARTED, &devpriv->state);
2908	spin_unlock_irqrestore(&devpriv->ao_stop_spinlock, irqflags);
2909	if (!started) {
2910		return;
2911	}
2912
2913	cmd = &s->async->cmd;
2914	if (cmd->scan_begin_src == TRIG_TIMER) {
2915		/* Stop scan rate generator. */
2916		pci230_cancel_ct(dev, 1);
2917	}
2918
2919	/* Determine interrupt source. */
2920	if (devpriv->hwver < 2) {
2921		/* Not using DAC FIFO.  Using CT1 interrupt. */
2922		intsrc = PCI230_INT_ZCLK_CT1;
2923	} else {
2924		/* Using DAC FIFO interrupt. */
2925		intsrc = PCI230P2_INT_DAC;
2926	}
2927	/* Disable interrupt and wait for interrupt routine to finish running
2928	 * unless we are called from the interrupt routine. */
2929	spin_lock_irqsave(&devpriv->isr_spinlock, irqflags);
2930	devpriv->int_en &= ~intsrc;
2931	while (devpriv->intr_running && devpriv->intr_cpuid != THISCPU) {
2932		spin_unlock_irqrestore(&devpriv->isr_spinlock, irqflags);
2933		spin_lock_irqsave(&devpriv->isr_spinlock, irqflags);
2934	}
2935	if (devpriv->ier != devpriv->int_en) {
2936		devpriv->ier = devpriv->int_en;
2937		outb(devpriv->ier, devpriv->iobase1 + PCI230_INT_SCE);
2938	}
2939	spin_unlock_irqrestore(&devpriv->isr_spinlock, irqflags);
2940
2941	if (devpriv->hwver >= 2) {
2942		/* Using DAC FIFO.  Reset FIFO, clear underrun error,
2943		 * disable FIFO. */
2944		devpriv->daccon &= PCI230_DAC_OR_MASK;
2945		outw(devpriv->daccon | PCI230P2_DAC_FIFO_RESET
2946		     | PCI230P2_DAC_FIFO_UNDERRUN_CLEAR,
2947		     dev->iobase + PCI230_DACCON);
2948	}
2949
2950	/* Release resources. */
2951	put_all_resources(dev, OWNER_AOCMD);
2952}
2953
2954static int pci230_ao_cancel(struct comedi_device *dev,
2955			    struct comedi_subdevice *s)
2956{
2957	pci230_ao_stop(dev, s);
2958	return 0;
2959}
2960
2961static void pci230_ai_stop(struct comedi_device *dev,
2962			   struct comedi_subdevice *s)
2963{
2964	unsigned long irqflags;
2965	struct comedi_cmd *cmd;
2966	int started;
2967
2968	spin_lock_irqsave(&devpriv->ai_stop_spinlock, irqflags);
2969	started = test_and_clear_bit(AI_CMD_STARTED, &devpriv->state);
2970	spin_unlock_irqrestore(&devpriv->ai_stop_spinlock, irqflags);
2971	if (!started) {
2972		return;
2973	}
2974
2975	cmd = &s->async->cmd;
2976	if (cmd->convert_src == TRIG_TIMER) {
2977		/* Stop conversion rate generator. */
2978		pci230_cancel_ct(dev, 2);
2979	}
2980	if (cmd->scan_begin_src != TRIG_FOLLOW) {
2981		/* Stop scan period monostable. */
2982		pci230_cancel_ct(dev, 0);
2983	}
2984
2985	spin_lock_irqsave(&devpriv->isr_spinlock, irqflags);
2986	/* Disable ADC interrupt and wait for interrupt routine to finish
2987	 * running unless we are called from the interrupt routine. */
2988	devpriv->int_en &= ~PCI230_INT_ADC;
2989	while (devpriv->intr_running && devpriv->intr_cpuid != THISCPU) {
2990		spin_unlock_irqrestore(&devpriv->isr_spinlock, irqflags);
2991		spin_lock_irqsave(&devpriv->isr_spinlock, irqflags);
2992	}
2993	if (devpriv->ier != devpriv->int_en) {
2994		devpriv->ier = devpriv->int_en;
2995		outb(devpriv->ier, devpriv->iobase1 + PCI230_INT_SCE);
2996	}
2997	spin_unlock_irqrestore(&devpriv->isr_spinlock, irqflags);
2998
2999	/* Reset FIFO, disable FIFO and set start conversion source to none.
3000	 * Keep se/diff and bip/uni settings */
3001	devpriv->adccon = (devpriv->adccon & (PCI230_ADC_IR_MASK
3002					      | PCI230_ADC_IM_MASK)) |
3003	    PCI230_ADC_TRIG_NONE;
3004	outw(devpriv->adccon | PCI230_ADC_FIFO_RESET,
3005	     dev->iobase + PCI230_ADCCON);
3006
3007	/* Release resources. */
3008	put_all_resources(dev, OWNER_AICMD);
3009}
3010
3011static int pci230_ai_cancel(struct comedi_device *dev,
3012			    struct comedi_subdevice *s)
3013{
3014	pci230_ai_stop(dev, s);
3015	return 0;
3016}
3017