amplc_pci230.c revision 859171ca92f2865453b4b2e17bf679c67044a833
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
620static int __devinit driver_amplc_pci230_pci_probe(struct pci_dev *dev,
621						   const struct pci_device_id
622						   *ent)
623{
624	return comedi_pci_auto_config(dev, driver_amplc_pci230.driver_name);
625}
626
627static void __devexit driver_amplc_pci230_pci_remove(struct pci_dev *dev)
628{
629	comedi_pci_auto_unconfig(dev);
630}
631
632static struct pci_driver driver_amplc_pci230_pci_driver = {
633	.id_table = pci230_pci_table,
634	.probe = &driver_amplc_pci230_pci_probe,
635	.remove = __devexit_p(&driver_amplc_pci230_pci_remove)
636};
637
638static int __init driver_amplc_pci230_init_module(void)
639{
640	int retval;
641
642	retval = comedi_driver_register(&driver_amplc_pci230);
643	if (retval < 0)
644		return retval;
645
646	driver_amplc_pci230_pci_driver.name =
647	    (char *)driver_amplc_pci230.driver_name;
648	return pci_register_driver(&driver_amplc_pci230_pci_driver);
649}
650
651static void __exit driver_amplc_pci230_cleanup_module(void)
652{
653	pci_unregister_driver(&driver_amplc_pci230_pci_driver);
654	comedi_driver_unregister(&driver_amplc_pci230);
655}
656
657module_init(driver_amplc_pci230_init_module);
658module_exit(driver_amplc_pci230_cleanup_module);
659
660static int pci230_ai_rinsn(struct comedi_device *dev,
661			   struct comedi_subdevice *s, struct comedi_insn *insn,
662			   unsigned int *data);
663static int pci230_ao_winsn(struct comedi_device *dev,
664			   struct comedi_subdevice *s, struct comedi_insn *insn,
665			   unsigned int *data);
666static int pci230_ao_rinsn(struct comedi_device *dev,
667			   struct comedi_subdevice *s, struct comedi_insn *insn,
668			   unsigned int *data);
669static void pci230_ct_setup_ns_mode(struct comedi_device *dev, unsigned int ct,
670				    unsigned int mode, uint64_t ns,
671				    unsigned int round);
672static void pci230_ns_to_single_timer(unsigned int *ns, unsigned int round);
673static void pci230_cancel_ct(struct comedi_device *dev, unsigned int ct);
674static irqreturn_t pci230_interrupt(int irq, void *d);
675static int pci230_ao_cmdtest(struct comedi_device *dev,
676			     struct comedi_subdevice *s,
677			     struct comedi_cmd *cmd);
678static int pci230_ao_cmd(struct comedi_device *dev, struct comedi_subdevice *s);
679static int pci230_ao_cancel(struct comedi_device *dev,
680			    struct comedi_subdevice *s);
681static void pci230_ao_stop(struct comedi_device *dev,
682			   struct comedi_subdevice *s);
683static void pci230_handle_ao_nofifo(struct comedi_device *dev,
684				    struct comedi_subdevice *s);
685static int pci230_handle_ao_fifo(struct comedi_device *dev,
686				 struct comedi_subdevice *s);
687static int pci230_ai_cmdtest(struct comedi_device *dev,
688			     struct comedi_subdevice *s,
689			     struct comedi_cmd *cmd);
690static int pci230_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s);
691static int pci230_ai_cancel(struct comedi_device *dev,
692			    struct comedi_subdevice *s);
693static void pci230_ai_stop(struct comedi_device *dev,
694			   struct comedi_subdevice *s);
695static void pci230_handle_ai(struct comedi_device *dev,
696			     struct comedi_subdevice *s);
697
698static short pci230_ai_read(struct comedi_device *dev)
699{
700	/* Read sample. */
701	short data = (short)inw(dev->iobase + PCI230_ADCDATA);
702
703	/* PCI230 is 12 bit - stored in upper bits of 16 bit register (lower
704	 * four bits reserved for expansion). */
705	/* PCI230+ is 16 bit AI. */
706	data = data >> (16 - thisboard->ai_bits);
707
708	/* If a bipolar range was specified, mangle it (twos
709	 * complement->straight binary). */
710	if (devpriv->ai_bipolar)
711		data ^= 1 << (thisboard->ai_bits - 1);
712
713	return data;
714}
715
716static inline unsigned short pci230_ao_mangle_datum(struct comedi_device *dev,
717						    short datum)
718{
719	/* If a bipolar range was specified, mangle it (straight binary->twos
720	 * complement). */
721	if (devpriv->ao_bipolar)
722		datum ^= 1 << (thisboard->ao_bits - 1);
723
724
725	/* PCI230 is 12 bit - stored in upper bits of 16 bit register (lower
726	 * four bits reserved for expansion). */
727	/* PCI230+ is also 12 bit AO. */
728	datum <<= (16 - thisboard->ao_bits);
729	return (unsigned short)datum;
730}
731
732static inline void pci230_ao_write_nofifo(struct comedi_device *dev,
733					  short datum, unsigned int chan)
734{
735	/* Store unmangled datum to be read back later. */
736	devpriv->ao_readback[chan] = datum;
737
738	/* Write mangled datum to appropriate DACOUT register. */
739	outw(pci230_ao_mangle_datum(dev, datum), dev->iobase + (((chan) == 0)
740								? PCI230_DACOUT1
741								:
742								PCI230_DACOUT2));
743}
744
745static inline void pci230_ao_write_fifo(struct comedi_device *dev, short datum,
746					unsigned int chan)
747{
748	/* Store unmangled datum to be read back later. */
749	devpriv->ao_readback[chan] = datum;
750
751	/* Write mangled datum to appropriate DACDATA register. */
752	outw(pci230_ao_mangle_datum(dev, datum),
753	     dev->iobase + PCI230P2_DACDATA);
754}
755
756/*
757 * Attach is called by the Comedi core to configure the driver
758 * for a particular board.  If you specified a board_name array
759 * in the driver structure, dev->board_ptr contains that
760 * address.
761 */
762static int pci230_attach(struct comedi_device *dev, struct comedi_devconfig *it)
763{
764	struct comedi_subdevice *s;
765	unsigned long iobase1, iobase2;
766	/* PCI230's I/O spaces 1 and 2 respectively. */
767	struct pci_dev *pci_dev = NULL;
768	int i = 0, irq_hdl, rc;
769
770	printk("comedi%d: amplc_pci230: attach %s %d,%d\n", dev->minor,
771	       thisboard->name, it->options[0], it->options[1]);
772
773	/* Allocate the private structure area using alloc_private().
774	 * Macro defined in comedidev.h - memsets struct fields to 0. */
775	if ((alloc_private(dev, sizeof(struct pci230_private))) < 0)
776		return -ENOMEM;
777
778	spin_lock_init(&devpriv->isr_spinlock);
779	spin_lock_init(&devpriv->res_spinlock);
780	spin_lock_init(&devpriv->ai_stop_spinlock);
781	spin_lock_init(&devpriv->ao_stop_spinlock);
782	/* Find card */
783	for_each_pci_dev(pci_dev) {
784		if (it->options[0] || it->options[1]) {
785			/* Match against bus/slot options. */
786			if (it->options[0] != pci_dev->bus->number ||
787			    it->options[1] != PCI_SLOT(pci_dev->devfn))
788				continue;
789		}
790		if (pci_dev->vendor != PCI_VENDOR_ID_AMPLICON)
791			continue;
792		if (thisboard->id == PCI_DEVICE_ID_INVALID) {
793			/* The name was specified as "amplc_pci230" which is
794			 * used to match any supported device.  Replace the
795			 * current dev->board_ptr with one that matches the
796			 * PCI device ID. */
797			for (i = 0; i < n_pci230_boards; i++) {
798				if (pci_dev->device == pci230_boards[i].id) {
799					if (pci230_boards[i].min_hwver > 0) {
800						/* Check for a '+' model.
801						 * First check length of
802						 * registers. */
803						if (pci_resource_len(pci_dev, 3)
804						    < 32) {
805							/* Not a '+' model. */
806							continue;
807						}
808						/* TODO: temporarily enable the
809						 * PCI device and read the
810						 * hardware version register.
811						 * For now assume it's okay. */
812					}
813					/* Change board_ptr to matched board */
814					dev->board_ptr = &pci230_boards[i];
815					break;
816				}
817			}
818			if (i < n_pci230_boards)
819				break;
820		} else {
821			/* The name was specified as a specific device name.
822			 * The current dev->board_ptr is correct.  Check
823			 * whether it matches the PCI device ID. */
824			if (thisboard->id == pci_dev->device) {
825				/* Check minimum hardware version. */
826				if (thisboard->min_hwver > 0) {
827					/* Looking for a '+' model.  First
828					 * check length of registers. */
829					if (pci_resource_len(pci_dev, 3) < 32) {
830						/* Not a '+' model. */
831						continue;
832					}
833					/* TODO: temporarily enable the PCI
834					 * device and read the hardware version
835					 * register.  For now, assume it's
836					 * okay. */
837					break;
838				} else {
839					break;
840				}
841			}
842		}
843	}
844	if (!pci_dev) {
845		printk("comedi%d: No %s card found\n", dev->minor,
846		       thisboard->name);
847		return -EIO;
848	}
849	devpriv->pci_dev = pci_dev;
850
851	/*
852	 * Initialize dev->board_name.
853	 */
854	dev->board_name = thisboard->name;
855
856	/* Enable PCI device and reserve I/O spaces. */
857	if (comedi_pci_enable(pci_dev, "amplc_pci230") < 0) {
858		printk("comedi%d: failed to enable PCI device "
859		       "and request regions\n", dev->minor);
860		return -EIO;
861	}
862
863	/* Read base addresses of the PCI230's two I/O regions from PCI
864	 * configuration register. */
865	iobase1 = pci_resource_start(pci_dev, 2);
866	iobase2 = pci_resource_start(pci_dev, 3);
867
868	printk("comedi%d: %s I/O region 1 0x%04lx I/O region 2 0x%04lx\n",
869	       dev->minor, dev->board_name, iobase1, iobase2);
870
871	devpriv->iobase1 = iobase1;
872	dev->iobase = iobase2;
873
874	/* Read bits of DACCON register - only the output range. */
875	devpriv->daccon = inw(dev->iobase + PCI230_DACCON) & PCI230_DAC_OR_MASK;
876
877	/* Read hardware version register and set extended function register
878	 * if they exist. */
879	if (pci_resource_len(pci_dev, 3) >= 32) {
880		unsigned short extfunc = 0;
881
882		devpriv->hwver = inw(dev->iobase + PCI230P_HWVER);
883		if (devpriv->hwver < thisboard->min_hwver) {
884			printk("comedi%d: %s - bad hardware version "
885			       "- got %u, need %u\n", dev->minor,
886			       dev->board_name, devpriv->hwver,
887			       thisboard->min_hwver);
888			return -EIO;
889		}
890		if (devpriv->hwver > 0) {
891			if (!thisboard->have_dio) {
892				/* No DIO ports.  Route counters' external gates
893				 * to the EXTTRIG signal (PCI260+ pin 17).
894				 * (Otherwise, they would be routed to DIO
895				 * inputs PC0, PC1 and PC2 which don't exist
896				 * on PCI260[+].) */
897				extfunc |= PCI230P_EXTFUNC_GAT_EXTTRIG;
898			}
899			if ((thisboard->ao_chans > 0)
900			    && (devpriv->hwver >= 2)) {
901				/* Enable DAC FIFO functionality. */
902				extfunc |= PCI230P2_EXTFUNC_DACFIFO;
903			}
904		}
905		outw(extfunc, dev->iobase + PCI230P_EXTFUNC);
906		if ((extfunc & PCI230P2_EXTFUNC_DACFIFO) != 0) {
907			/* Temporarily enable DAC FIFO, reset it and disable
908			 * FIFO wraparound. */
909			outw(devpriv->daccon | PCI230P2_DAC_FIFO_EN
910			     | PCI230P2_DAC_FIFO_RESET,
911			     dev->iobase + PCI230_DACCON);
912			/* Clear DAC FIFO channel enable register. */
913			outw(0, dev->iobase + PCI230P2_DACEN);
914			/* Disable DAC FIFO. */
915			outw(devpriv->daccon, dev->iobase + PCI230_DACCON);
916		}
917	}
918
919	/* Disable board's interrupts. */
920	outb(0, devpriv->iobase1 + PCI230_INT_SCE);
921
922	/* Set ADC to a reasonable state. */
923	devpriv->adcg = 0;
924	devpriv->adccon = PCI230_ADC_TRIG_NONE | PCI230_ADC_IM_SE
925	    | PCI230_ADC_IR_BIP;
926	outw(1 << 0, dev->iobase + PCI230_ADCEN);
927	outw(devpriv->adcg, dev->iobase + PCI230_ADCG);
928	outw(devpriv->adccon | PCI230_ADC_FIFO_RESET,
929	     dev->iobase + PCI230_ADCCON);
930
931	/* Register the interrupt handler. */
932	irq_hdl = request_irq(devpriv->pci_dev->irq, pci230_interrupt,
933			      IRQF_SHARED, "amplc_pci230", dev);
934	if (irq_hdl < 0) {
935		printk("comedi%d: unable to register irq, "
936		       "commands will not be available %d\n", dev->minor,
937		       devpriv->pci_dev->irq);
938	} else {
939		dev->irq = devpriv->pci_dev->irq;
940		printk("comedi%d: registered irq %u\n", dev->minor,
941		       devpriv->pci_dev->irq);
942	}
943
944	/*
945	 * Allocate the subdevice structures.  alloc_subdevice() is a
946	 * convenient macro defined in comedidev.h.
947	 */
948	if (alloc_subdevices(dev, 3) < 0)
949		return -ENOMEM;
950
951	s = dev->subdevices + 0;
952	/* analog input subdevice */
953	s->type = COMEDI_SUBD_AI;
954	s->subdev_flags = SDF_READABLE | SDF_DIFF | SDF_GROUND;
955	s->n_chan = thisboard->ai_chans;
956	s->maxdata = (1 << thisboard->ai_bits) - 1;
957	s->range_table = &pci230_ai_range;
958	s->insn_read = &pci230_ai_rinsn;
959	s->len_chanlist = 256;	/* but there are restrictions. */
960	/* Only register commands if the interrupt handler is installed. */
961	if (irq_hdl == 0) {
962		dev->read_subdev = s;
963		s->subdev_flags |= SDF_CMD_READ;
964		s->do_cmd = &pci230_ai_cmd;
965		s->do_cmdtest = &pci230_ai_cmdtest;
966		s->cancel = pci230_ai_cancel;
967	}
968
969	s = dev->subdevices + 1;
970	/* analog output subdevice */
971	if (thisboard->ao_chans > 0) {
972		s->type = COMEDI_SUBD_AO;
973		s->subdev_flags = SDF_WRITABLE | SDF_GROUND;
974		s->n_chan = thisboard->ao_chans;
975		s->maxdata = (1 << thisboard->ao_bits) - 1;
976		s->range_table = &pci230_ao_range;
977		s->insn_write = &pci230_ao_winsn;
978		s->insn_read = &pci230_ao_rinsn;
979		s->len_chanlist = thisboard->ao_chans;
980		/* Only register commands if the interrupt handler is
981		 * installed. */
982		if (irq_hdl == 0) {
983			dev->write_subdev = s;
984			s->subdev_flags |= SDF_CMD_WRITE;
985			s->do_cmd = &pci230_ao_cmd;
986			s->do_cmdtest = &pci230_ao_cmdtest;
987			s->cancel = pci230_ao_cancel;
988		}
989	} else {
990		s->type = COMEDI_SUBD_UNUSED;
991	}
992
993	s = dev->subdevices + 2;
994	/* digital i/o subdevice */
995	if (thisboard->have_dio) {
996		rc = subdev_8255_init(dev, s, NULL,
997				      (devpriv->iobase1 + PCI230_PPI_X_BASE));
998		if (rc < 0)
999			return rc;
1000	} else {
1001		s->type = COMEDI_SUBD_UNUSED;
1002	}
1003
1004	printk("comedi%d: attached\n", dev->minor);
1005
1006	return 1;
1007}
1008
1009/*
1010 * _detach is called to deconfigure a device.  It should deallocate
1011 * resources.
1012 * This function is also called when _attach() fails, so it should be
1013 * careful not to release resources that were not necessarily
1014 * allocated by _attach().  dev->private and dev->subdevices are
1015 * deallocated automatically by the core.
1016 */
1017static int pci230_detach(struct comedi_device *dev)
1018{
1019	printk("comedi%d: amplc_pci230: remove\n", dev->minor);
1020
1021	if (dev->subdevices && thisboard->have_dio)
1022		/* Clean up dio subdevice. */
1023		subdev_8255_cleanup(dev, dev->subdevices + 2);
1024
1025	if (dev->irq)
1026		free_irq(dev->irq, dev);
1027
1028	if (devpriv) {
1029		if (devpriv->pci_dev) {
1030			if (dev->iobase)
1031				comedi_pci_disable(devpriv->pci_dev);
1032
1033			pci_dev_put(devpriv->pci_dev);
1034		}
1035	}
1036
1037	return 0;
1038}
1039
1040static int get_resources(struct comedi_device *dev, unsigned int res_mask,
1041			 unsigned char owner)
1042{
1043	int ok;
1044	unsigned int i;
1045	unsigned int b;
1046	unsigned int claimed;
1047	unsigned long irqflags;
1048
1049	ok = 1;
1050	claimed = 0;
1051	spin_lock_irqsave(&devpriv->res_spinlock, irqflags);
1052	for (b = 1, i = 0; (i < NUM_RESOURCES)
1053	     && (res_mask != 0); b <<= 1, i++) {
1054		if ((res_mask & b) != 0) {
1055			res_mask &= ~b;
1056			if (devpriv->res_owner[i] == OWNER_NONE) {
1057				devpriv->res_owner[i] = owner;
1058				claimed |= b;
1059			} else if (devpriv->res_owner[i] != owner) {
1060				for (b = 1, i = 0; claimed != 0; b <<= 1, i++) {
1061					if ((claimed & b) != 0) {
1062						devpriv->res_owner[i]
1063						    = OWNER_NONE;
1064						claimed &= ~b;
1065					}
1066				}
1067				ok = 0;
1068				break;
1069			}
1070		}
1071	}
1072	spin_unlock_irqrestore(&devpriv->res_spinlock, irqflags);
1073	return ok;
1074}
1075
1076static inline int get_one_resource(struct comedi_device *dev,
1077				   unsigned int resource, unsigned char owner)
1078{
1079	return get_resources(dev, (1U << resource), owner);
1080}
1081
1082static void put_resources(struct comedi_device *dev, unsigned int res_mask,
1083			  unsigned char owner)
1084{
1085	unsigned int i;
1086	unsigned int b;
1087	unsigned long irqflags;
1088
1089	spin_lock_irqsave(&devpriv->res_spinlock, irqflags);
1090	for (b = 1, i = 0; (i < NUM_RESOURCES)
1091	     && (res_mask != 0); b <<= 1, i++) {
1092		if ((res_mask & b) != 0) {
1093			res_mask &= ~b;
1094			if (devpriv->res_owner[i] == owner)
1095				devpriv->res_owner[i] = OWNER_NONE;
1096
1097		}
1098	}
1099	spin_unlock_irqrestore(&devpriv->res_spinlock, irqflags);
1100}
1101
1102static inline void put_one_resource(struct comedi_device *dev,
1103				    unsigned int resource, unsigned char owner)
1104{
1105	put_resources(dev, (1U << resource), owner);
1106}
1107
1108static inline void put_all_resources(struct comedi_device *dev,
1109				     unsigned char owner)
1110{
1111	put_resources(dev, (1U << NUM_RESOURCES) - 1, owner);
1112}
1113
1114/*
1115 *  COMEDI_SUBD_AI instruction;
1116 */
1117static int pci230_ai_rinsn(struct comedi_device *dev,
1118			   struct comedi_subdevice *s, struct comedi_insn *insn,
1119			   unsigned int *data)
1120{
1121	unsigned int n, i;
1122	unsigned int chan, range, aref;
1123	unsigned int gainshift;
1124	unsigned int status;
1125	unsigned short adccon, adcen;
1126
1127	/* Unpack channel and range. */
1128	chan = CR_CHAN(insn->chanspec);
1129	range = CR_RANGE(insn->chanspec);
1130	aref = CR_AREF(insn->chanspec);
1131	if (aref == AREF_DIFF) {
1132		/* Differential. */
1133		if (chan >= s->n_chan / 2) {
1134			DPRINTK("comedi%d: amplc_pci230: ai_rinsn: "
1135				"differential channel number out of range "
1136				"0 to %u\n", dev->minor, (s->n_chan / 2) - 1);
1137			return -EINVAL;
1138		}
1139	}
1140
1141	/* Use Z2-CT2 as a conversion trigger instead of the built-in
1142	 * software trigger, as otherwise triggering of differential channels
1143	 * doesn't work properly for some versions of PCI230/260.  Also set
1144	 * FIFO mode because the ADC busy bit only works for software triggers.
1145	 */
1146	adccon = PCI230_ADC_TRIG_Z2CT2 | PCI230_ADC_FIFO_EN;
1147	/* Set Z2-CT2 output low to avoid any false triggers. */
1148	i8254_set_mode(devpriv->iobase1 + PCI230_Z2_CT_BASE, 0, 2, I8254_MODE0);
1149	devpriv->ai_bipolar = pci230_ai_bipolar[range];
1150	if (aref == AREF_DIFF) {
1151		/* Differential. */
1152		gainshift = chan * 2;
1153		if (devpriv->hwver == 0) {
1154			/* Original PCI230/260 expects both inputs of the
1155			 * differential channel to be enabled. */
1156			adcen = 3 << gainshift;
1157		} else {
1158			/* PCI230+/260+ expects only one input of the
1159			 * differential channel to be enabled. */
1160			adcen = 1 << gainshift;
1161		}
1162		adccon |= PCI230_ADC_IM_DIF;
1163	} else {
1164		/* Single ended. */
1165		adcen = 1 << chan;
1166		gainshift = chan & ~1;
1167		adccon |= PCI230_ADC_IM_SE;
1168	}
1169	devpriv->adcg = (devpriv->adcg & ~(3 << gainshift))
1170	    | (pci230_ai_gain[range] << gainshift);
1171	if (devpriv->ai_bipolar)
1172		adccon |= PCI230_ADC_IR_BIP;
1173	else
1174		adccon |= PCI230_ADC_IR_UNI;
1175
1176
1177	/* Enable only this channel in the scan list - otherwise by default
1178	 * we'll get one sample from each channel. */
1179	outw(adcen, dev->iobase + PCI230_ADCEN);
1180
1181	/* Set gain for channel. */
1182	outw(devpriv->adcg, dev->iobase + PCI230_ADCG);
1183
1184	/* Specify uni/bip, se/diff, conversion source, and reset FIFO. */
1185	devpriv->adccon = adccon;
1186	outw(adccon | PCI230_ADC_FIFO_RESET, dev->iobase + PCI230_ADCCON);
1187
1188	/* Convert n samples */
1189	for (n = 0; n < insn->n; n++) {
1190		/* Trigger conversion by toggling Z2-CT2 output (finish with
1191		 * output high). */
1192		i8254_set_mode(devpriv->iobase1 + PCI230_Z2_CT_BASE, 0, 2,
1193			       I8254_MODE0);
1194		i8254_set_mode(devpriv->iobase1 + PCI230_Z2_CT_BASE, 0, 2,
1195			       I8254_MODE1);
1196
1197#define TIMEOUT 100
1198		/* wait for conversion to end */
1199		for (i = 0; i < TIMEOUT; i++) {
1200			status = inw(dev->iobase + PCI230_ADCCON);
1201			if (!(status & PCI230_ADC_FIFO_EMPTY))
1202				break;
1203			udelay(1);
1204		}
1205		if (i == TIMEOUT) {
1206			/* printk() should be used instead of printk()
1207			 * whenever the code can be called from real-time. */
1208			printk("timeout\n");
1209			return -ETIMEDOUT;
1210		}
1211
1212		/* read data */
1213		data[n] = pci230_ai_read(dev);
1214	}
1215
1216	/* return the number of samples read/written */
1217	return n;
1218}
1219
1220/*
1221 *  COMEDI_SUBD_AO instructions;
1222 */
1223static int pci230_ao_winsn(struct comedi_device *dev,
1224			   struct comedi_subdevice *s, struct comedi_insn *insn,
1225			   unsigned int *data)
1226{
1227	int i;
1228	int chan, range;
1229
1230	/* Unpack channel and range. */
1231	chan = CR_CHAN(insn->chanspec);
1232	range = CR_RANGE(insn->chanspec);
1233
1234	/* Set range - see analogue output range table; 0 => unipolar 10V,
1235	 * 1 => bipolar +/-10V range scale */
1236	devpriv->ao_bipolar = pci230_ao_bipolar[range];
1237	outw(range, dev->iobase + PCI230_DACCON);
1238
1239	/* Writing a list of values to an AO channel is probably not
1240	 * very useful, but that's how the interface is defined. */
1241	for (i = 0; i < insn->n; i++) {
1242		/* Write value to DAC and store it. */
1243		pci230_ao_write_nofifo(dev, data[i], chan);
1244	}
1245
1246	/* return the number of samples read/written */
1247	return i;
1248}
1249
1250/* AO subdevices should have a read insn as well as a write insn.
1251 * Usually this means copying a value stored in devpriv. */
1252static int pci230_ao_rinsn(struct comedi_device *dev,
1253			   struct comedi_subdevice *s, struct comedi_insn *insn,
1254			   unsigned int *data)
1255{
1256	int i;
1257	int chan = CR_CHAN(insn->chanspec);
1258
1259	for (i = 0; i < insn->n; i++)
1260		data[i] = devpriv->ao_readback[chan];
1261
1262	return i;
1263}
1264
1265static int pci230_ao_cmdtest(struct comedi_device *dev,
1266			     struct comedi_subdevice *s, struct comedi_cmd *cmd)
1267{
1268	int err = 0;
1269	unsigned int tmp;
1270
1271	/* cmdtest tests a particular command to see if it is valid.
1272	 * Using the cmdtest ioctl, a user can create a valid cmd
1273	 * and then have it executes by the cmd ioctl.
1274	 *
1275	 * cmdtest returns 1,2,3,4 or 0, depending on which tests
1276	 * the command passes. */
1277
1278	/* Step 1: make sure trigger sources are trivially valid.
1279	 * "invalid source" returned by comedilib to user mode process
1280	 * if this fails. */
1281
1282	tmp = cmd->start_src;
1283	cmd->start_src &= TRIG_INT;
1284	if (!cmd->start_src || tmp != cmd->start_src)
1285		err++;
1286
1287	tmp = cmd->scan_begin_src;
1288	if ((thisboard->min_hwver > 0) && (devpriv->hwver >= 2)) {
1289		/*
1290		 * For PCI230+ hardware version 2 onwards, allow external
1291		 * trigger from EXTTRIG/EXTCONVCLK input (PCI230+ pin 25).
1292		 *
1293		 * FIXME: The permitted scan_begin_src values shouldn't depend
1294		 * on devpriv->hwver (the detected card's actual hardware
1295		 * version).  They should only depend on thisboard->min_hwver
1296		 * (the static capabilities of the configured card).  To fix
1297		 * it, a new card model, e.g. "pci230+2" would have to be
1298		 * defined with min_hwver set to 2.  It doesn't seem worth it
1299		 * for this alone.  At the moment, please consider
1300		 * scan_begin_src==TRIG_EXT support to be a bonus rather than a
1301		 * guarantee!
1302		 */
1303		cmd->scan_begin_src &= TRIG_TIMER | TRIG_INT | TRIG_EXT;
1304	} else {
1305		cmd->scan_begin_src &= TRIG_TIMER | TRIG_INT;
1306	}
1307	if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
1308		err++;
1309
1310	tmp = cmd->convert_src;
1311	cmd->convert_src &= TRIG_NOW;
1312	if (!cmd->convert_src || tmp != cmd->convert_src)
1313		err++;
1314
1315	tmp = cmd->scan_end_src;
1316	cmd->scan_end_src &= TRIG_COUNT;
1317	if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
1318		err++;
1319
1320	tmp = cmd->stop_src;
1321	cmd->stop_src &= TRIG_COUNT | TRIG_NONE;
1322	if (!cmd->stop_src || tmp != cmd->stop_src)
1323		err++;
1324
1325	if (err)
1326		return 1;
1327
1328	/* Step 2: make sure trigger sources are unique and mutually compatible
1329	 * "source conflict" returned by comedilib to user mode process
1330	 * if this fails. */
1331
1332	/* these tests are true if more than one _src bit is set */
1333	if ((cmd->start_src & (cmd->start_src - 1)) != 0)
1334		err++;
1335	if ((cmd->scan_begin_src & (cmd->scan_begin_src - 1)) != 0)
1336		err++;
1337	if ((cmd->convert_src & (cmd->convert_src - 1)) != 0)
1338		err++;
1339	if ((cmd->scan_end_src & (cmd->scan_end_src - 1)) != 0)
1340		err++;
1341	if ((cmd->stop_src & (cmd->stop_src - 1)) != 0)
1342		err++;
1343
1344	if (err)
1345		return 2;
1346
1347	/* Step 3: make sure arguments are trivially compatible.
1348	 * "invalid argument" returned by comedilib to user mode process
1349	 * if this fails. */
1350
1351	if (cmd->start_arg != 0) {
1352		cmd->start_arg = 0;
1353		err++;
1354	}
1355#define MAX_SPEED_AO	8000	/* 8000 ns => 125 kHz */
1356#define MIN_SPEED_AO	4294967295u	/* 4294967295ns = 4.29s */
1357			/*- Comedi limit due to unsigned int cmd.  Driver limit
1358			 * = 2^16 (16bit * counter) * 1000000ns (1kHz onboard
1359			 * clock) = 65.536s */
1360
1361	switch (cmd->scan_begin_src) {
1362	case TRIG_TIMER:
1363		if (cmd->scan_begin_arg < MAX_SPEED_AO) {
1364			cmd->scan_begin_arg = MAX_SPEED_AO;
1365			err++;
1366		}
1367		if (cmd->scan_begin_arg > MIN_SPEED_AO) {
1368			cmd->scan_begin_arg = MIN_SPEED_AO;
1369			err++;
1370		}
1371		break;
1372	case TRIG_EXT:
1373		/* External trigger - for PCI230+ hardware version 2 onwards. */
1374		/* Trigger number must be 0. */
1375		if ((cmd->scan_begin_arg & ~CR_FLAGS_MASK) != 0) {
1376			cmd->scan_begin_arg = COMBINE(cmd->scan_begin_arg, 0,
1377						      ~CR_FLAGS_MASK);
1378			err++;
1379		}
1380		/* The only flags allowed are CR_EDGE and CR_INVERT.  The
1381		 * CR_EDGE flag is ignored. */
1382		if ((cmd->scan_begin_arg
1383		     & (CR_FLAGS_MASK & ~(CR_EDGE | CR_INVERT))) != 0) {
1384			cmd->scan_begin_arg =
1385			    COMBINE(cmd->scan_begin_arg, 0,
1386				    CR_FLAGS_MASK & ~(CR_EDGE | CR_INVERT));
1387			err++;
1388		}
1389		break;
1390	default:
1391		if (cmd->scan_begin_arg != 0) {
1392			cmd->scan_begin_arg = 0;
1393			err++;
1394		}
1395		break;
1396	}
1397
1398	if (cmd->scan_end_arg != cmd->chanlist_len) {
1399		cmd->scan_end_arg = cmd->chanlist_len;
1400		err++;
1401	}
1402	if (cmd->stop_src == TRIG_NONE) {
1403		/* TRIG_NONE */
1404		if (cmd->stop_arg != 0) {
1405			cmd->stop_arg = 0;
1406			err++;
1407		}
1408	}
1409
1410	if (err)
1411		return 3;
1412
1413	/* Step 4: fix up any arguments.
1414	 * "argument conflict" returned by comedilib to user mode process
1415	 * if this fails. */
1416
1417	if (cmd->scan_begin_src == TRIG_TIMER) {
1418		tmp = cmd->scan_begin_arg;
1419		pci230_ns_to_single_timer(&cmd->scan_begin_arg,
1420					  cmd->flags & TRIG_ROUND_MASK);
1421		if (tmp != cmd->scan_begin_arg)
1422			err++;
1423	}
1424
1425	if (err)
1426		return 4;
1427
1428	/* Step 5: check channel list if it exists. */
1429
1430	if (cmd->chanlist && cmd->chanlist_len > 0) {
1431		enum {
1432			seq_err = (1 << 0),
1433			range_err = (1 << 1)
1434		};
1435		unsigned int errors;
1436		unsigned int n;
1437		unsigned int chan, prev_chan;
1438		unsigned int range, first_range;
1439
1440		prev_chan = CR_CHAN(cmd->chanlist[0]);
1441		first_range = CR_RANGE(cmd->chanlist[0]);
1442		errors = 0;
1443		for (n = 1; n < cmd->chanlist_len; n++) {
1444			chan = CR_CHAN(cmd->chanlist[n]);
1445			range = CR_RANGE(cmd->chanlist[n]);
1446			/* Channel numbers must strictly increase. */
1447			if (chan < prev_chan)
1448				errors |= seq_err;
1449
1450			/* Ranges must be the same. */
1451			if (range != first_range)
1452				errors |= range_err;
1453
1454			prev_chan = chan;
1455		}
1456		if (errors != 0) {
1457			err++;
1458			if ((errors & seq_err) != 0) {
1459				DPRINTK("comedi%d: amplc_pci230: ao_cmdtest: "
1460					"channel numbers must increase\n",
1461					dev->minor);
1462			}
1463			if ((errors & range_err) != 0) {
1464				DPRINTK("comedi%d: amplc_pci230: ao_cmdtest: "
1465					"channels must have the same range\n",
1466					dev->minor);
1467			}
1468		}
1469	}
1470
1471	if (err)
1472		return 5;
1473
1474	return 0;
1475}
1476
1477static int pci230_ao_inttrig_scan_begin(struct comedi_device *dev,
1478					struct comedi_subdevice *s,
1479					unsigned int trig_num)
1480{
1481	unsigned long irqflags;
1482
1483	if (trig_num != 0)
1484		return -EINVAL;
1485
1486	spin_lock_irqsave(&devpriv->ao_stop_spinlock, irqflags);
1487	if (test_bit(AO_CMD_STARTED, &devpriv->state)) {
1488		/* Perform scan. */
1489		if (devpriv->hwver < 2) {
1490			/* Not using DAC FIFO. */
1491			spin_unlock_irqrestore(&devpriv->ao_stop_spinlock,
1492					       irqflags);
1493			pci230_handle_ao_nofifo(dev, s);
1494			comedi_event(dev, s);
1495		} else {
1496			/* Using DAC FIFO. */
1497			/* Read DACSWTRIG register to trigger conversion. */
1498			inw(dev->iobase + PCI230P2_DACSWTRIG);
1499			spin_unlock_irqrestore(&devpriv->ao_stop_spinlock,
1500					       irqflags);
1501		}
1502		/* Delay.  Should driver be responsible for this? */
1503		/* XXX TODO: See if DAC busy bit can be used. */
1504		udelay(8);
1505	}
1506
1507	return 1;
1508}
1509
1510static void pci230_ao_start(struct comedi_device *dev,
1511			    struct comedi_subdevice *s)
1512{
1513	struct comedi_async *async = s->async;
1514	struct comedi_cmd *cmd = &async->cmd;
1515	unsigned long irqflags;
1516
1517	set_bit(AO_CMD_STARTED, &devpriv->state);
1518	if (!devpriv->ao_continuous && (devpriv->ao_scan_count == 0)) {
1519		/* An empty acquisition! */
1520		async->events |= COMEDI_CB_EOA;
1521		pci230_ao_stop(dev, s);
1522		comedi_event(dev, s);
1523	} else {
1524		if (devpriv->hwver >= 2) {
1525			/* Using DAC FIFO. */
1526			unsigned short scantrig;
1527			int run;
1528
1529			/* Preload FIFO data. */
1530			run = pci230_handle_ao_fifo(dev, s);
1531			comedi_event(dev, s);
1532			if (!run) {
1533				/* Stopped. */
1534				return;
1535			}
1536			/* Set scan trigger source. */
1537			switch (cmd->scan_begin_src) {
1538			case TRIG_TIMER:
1539				scantrig = PCI230P2_DAC_TRIG_Z2CT1;
1540				break;
1541			case TRIG_EXT:
1542				/* Trigger on EXTTRIG/EXTCONVCLK pin. */
1543				if ((cmd->scan_begin_arg & CR_INVERT) == 0) {
1544					/* +ve edge */
1545					scantrig = PCI230P2_DAC_TRIG_EXTP;
1546				} else {
1547					/* -ve edge */
1548					scantrig = PCI230P2_DAC_TRIG_EXTN;
1549				}
1550				break;
1551			case TRIG_INT:
1552				scantrig = PCI230P2_DAC_TRIG_SW;
1553				break;
1554			default:
1555				/* Shouldn't get here. */
1556				scantrig = PCI230P2_DAC_TRIG_NONE;
1557				break;
1558			}
1559			devpriv->daccon = (devpriv->daccon
1560					   & ~PCI230P2_DAC_TRIG_MASK) |
1561			    scantrig;
1562			outw(devpriv->daccon, dev->iobase + PCI230_DACCON);
1563
1564		}
1565		switch (cmd->scan_begin_src) {
1566		case TRIG_TIMER:
1567			if (devpriv->hwver < 2) {
1568				/* Not using DAC FIFO. */
1569				/* Enable CT1 timer interrupt. */
1570				spin_lock_irqsave(&devpriv->isr_spinlock,
1571						  irqflags);
1572				devpriv->int_en |= PCI230_INT_ZCLK_CT1;
1573				devpriv->ier |= PCI230_INT_ZCLK_CT1;
1574				outb(devpriv->ier,
1575				     devpriv->iobase1 + PCI230_INT_SCE);
1576				spin_unlock_irqrestore(&devpriv->isr_spinlock,
1577						       irqflags);
1578			}
1579			/* Set CT1 gate high to start counting. */
1580			outb(GAT_CONFIG(1, GAT_VCC),
1581			     devpriv->iobase1 + PCI230_ZGAT_SCE);
1582			break;
1583		case TRIG_INT:
1584			async->inttrig = pci230_ao_inttrig_scan_begin;
1585			break;
1586		}
1587		if (devpriv->hwver >= 2) {
1588			/* Using DAC FIFO.  Enable DAC FIFO interrupt. */
1589			spin_lock_irqsave(&devpriv->isr_spinlock, irqflags);
1590			devpriv->int_en |= PCI230P2_INT_DAC;
1591			devpriv->ier |= PCI230P2_INT_DAC;
1592			outb(devpriv->ier, devpriv->iobase1 + PCI230_INT_SCE);
1593			spin_unlock_irqrestore(&devpriv->isr_spinlock,
1594					       irqflags);
1595		}
1596	}
1597}
1598
1599static int pci230_ao_inttrig_start(struct comedi_device *dev,
1600				   struct comedi_subdevice *s,
1601				   unsigned int trig_num)
1602{
1603	if (trig_num != 0)
1604		return -EINVAL;
1605
1606	s->async->inttrig = NULLFUNC;
1607	pci230_ao_start(dev, s);
1608
1609	return 1;
1610}
1611
1612static int pci230_ao_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
1613{
1614	unsigned short daccon;
1615	unsigned int range;
1616
1617	/* Get the command. */
1618	struct comedi_cmd *cmd = &s->async->cmd;
1619
1620	if (cmd->scan_begin_src == TRIG_TIMER) {
1621		/* Claim Z2-CT1. */
1622		if (!get_one_resource(dev, RES_Z2CT1, OWNER_AOCMD))
1623			return -EBUSY;
1624
1625	}
1626
1627	/* Get number of scans required. */
1628	if (cmd->stop_src == TRIG_COUNT) {
1629		devpriv->ao_scan_count = cmd->stop_arg;
1630		devpriv->ao_continuous = 0;
1631	} else {
1632		/* TRIG_NONE, user calls cancel. */
1633		devpriv->ao_scan_count = 0;
1634		devpriv->ao_continuous = 1;
1635	}
1636
1637	/* Set range - see analogue output range table; 0 => unipolar 10V,
1638	 * 1 => bipolar +/-10V range scale */
1639	range = CR_RANGE(cmd->chanlist[0]);
1640	devpriv->ao_bipolar = pci230_ao_bipolar[range];
1641	daccon = devpriv->ao_bipolar ? PCI230_DAC_OR_BIP : PCI230_DAC_OR_UNI;
1642	/* Use DAC FIFO for hardware version 2 onwards. */
1643	if (devpriv->hwver >= 2) {
1644		unsigned short dacen;
1645		unsigned int i;
1646
1647		dacen = 0;
1648		for (i = 0; i < cmd->chanlist_len; i++)
1649			dacen |= 1 << CR_CHAN(cmd->chanlist[i]);
1650
1651		/* Set channel scan list. */
1652		outw(dacen, dev->iobase + PCI230P2_DACEN);
1653		/*
1654		 * Enable DAC FIFO.
1655		 * Set DAC scan source to 'none'.
1656		 * Set DAC FIFO interrupt trigger level to 'not half full'.
1657		 * Reset DAC FIFO and clear underrun.
1658		 *
1659		 * N.B. DAC FIFO interrupts are currently disabled.
1660		 */
1661		daccon |= PCI230P2_DAC_FIFO_EN | PCI230P2_DAC_FIFO_RESET
1662		    | PCI230P2_DAC_FIFO_UNDERRUN_CLEAR
1663		    | PCI230P2_DAC_TRIG_NONE | PCI230P2_DAC_INT_FIFO_NHALF;
1664	}
1665
1666	/* Set DACCON. */
1667	outw(daccon, dev->iobase + PCI230_DACCON);
1668	/* Preserve most of DACCON apart from write-only, transient bits. */
1669	devpriv->daccon = daccon
1670	    & ~(PCI230P2_DAC_FIFO_RESET | PCI230P2_DAC_FIFO_UNDERRUN_CLEAR);
1671
1672	if (cmd->scan_begin_src == TRIG_TIMER) {
1673		/* Set the counter timer 1 to the specified scan frequency. */
1674		/* cmd->scan_begin_arg is sampling period in ns */
1675		/* gate it off for now. */
1676		outb(GAT_CONFIG(1, GAT_GND),
1677		     devpriv->iobase1 + PCI230_ZGAT_SCE);
1678		pci230_ct_setup_ns_mode(dev, 1, I8254_MODE3,
1679					cmd->scan_begin_arg,
1680					cmd->flags & TRIG_ROUND_MASK);
1681	}
1682
1683	/* N.B. cmd->start_src == TRIG_INT */
1684	s->async->inttrig = pci230_ao_inttrig_start;
1685
1686	return 0;
1687}
1688
1689static int pci230_ai_check_scan_period(struct comedi_cmd *cmd)
1690{
1691	unsigned int min_scan_period, chanlist_len;
1692	int err = 0;
1693
1694	chanlist_len = cmd->chanlist_len;
1695	if (cmd->chanlist_len == 0)
1696		chanlist_len = 1;
1697
1698	min_scan_period = chanlist_len * cmd->convert_arg;
1699	if ((min_scan_period < chanlist_len)
1700	    || (min_scan_period < cmd->convert_arg)) {
1701		/* Arithmetic overflow. */
1702		min_scan_period = UINT_MAX;
1703		err++;
1704	}
1705	if (cmd->scan_begin_arg < min_scan_period) {
1706		cmd->scan_begin_arg = min_scan_period;
1707		err++;
1708	}
1709
1710	return !err;
1711}
1712
1713static int pci230_ai_cmdtest(struct comedi_device *dev,
1714			     struct comedi_subdevice *s, struct comedi_cmd *cmd)
1715{
1716	int err = 0;
1717	unsigned int tmp;
1718
1719	/* cmdtest tests a particular command to see if it is valid.
1720	 * Using the cmdtest ioctl, a user can create a valid cmd
1721	 * and then have it executes by the cmd ioctl.
1722	 *
1723	 * cmdtest returns 1,2,3,4,5 or 0, depending on which tests
1724	 * the command passes. */
1725
1726	/* Step 1: make sure trigger sources are trivially valid.
1727	 * "invalid source" returned by comedilib to user mode process
1728	 * if this fails. */
1729
1730	tmp = cmd->start_src;
1731	cmd->start_src &= TRIG_NOW | TRIG_INT;
1732	if (!cmd->start_src || tmp != cmd->start_src)
1733		err++;
1734
1735	tmp = cmd->scan_begin_src;
1736	/* Unfortunately, we cannot trigger a scan off an external source
1737	 * on the PCI260 board, since it uses the PPIC0 (DIO) input, which
1738	 * isn't present on the PCI260.  For PCI260+ we can use the
1739	 * EXTTRIG/EXTCONVCLK input on pin 17 instead. */
1740	if ((thisboard->have_dio) || (thisboard->min_hwver > 0)) {
1741		cmd->scan_begin_src &= TRIG_FOLLOW | TRIG_TIMER | TRIG_INT
1742		    | TRIG_EXT;
1743	} else {
1744		cmd->scan_begin_src &= TRIG_FOLLOW | TRIG_TIMER | TRIG_INT;
1745	}
1746	if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
1747		err++;
1748
1749	tmp = cmd->convert_src;
1750	cmd->convert_src &= TRIG_TIMER | TRIG_INT | TRIG_EXT;
1751	if (!cmd->convert_src || tmp != cmd->convert_src)
1752		err++;
1753
1754	tmp = cmd->scan_end_src;
1755	cmd->scan_end_src &= TRIG_COUNT;
1756	if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
1757		err++;
1758
1759	tmp = cmd->stop_src;
1760	cmd->stop_src &= TRIG_COUNT | TRIG_NONE;
1761	if (!cmd->stop_src || tmp != cmd->stop_src)
1762		err++;
1763
1764	if (err)
1765		return 1;
1766
1767	/* Step 2: make sure trigger sources are unique and mutually compatible
1768	 * "source conflict" returned by comedilib to user mode process
1769	 * if this fails. */
1770
1771	/* these tests are true if more than one _src bit is set */
1772	if ((cmd->start_src & (cmd->start_src - 1)) != 0)
1773		err++;
1774	if ((cmd->scan_begin_src & (cmd->scan_begin_src - 1)) != 0)
1775		err++;
1776	if ((cmd->convert_src & (cmd->convert_src - 1)) != 0)
1777		err++;
1778	if ((cmd->scan_end_src & (cmd->scan_end_src - 1)) != 0)
1779		err++;
1780	if ((cmd->stop_src & (cmd->stop_src - 1)) != 0)
1781		err++;
1782
1783	/* If scan_begin_src is not TRIG_FOLLOW, then a monostable will be
1784	 * set up to generate a fixed number of timed conversion pulses. */
1785	if ((cmd->scan_begin_src != TRIG_FOLLOW)
1786	    && (cmd->convert_src != TRIG_TIMER))
1787		err++;
1788
1789	if (err)
1790		return 2;
1791
1792	/* Step 3: make sure arguments are trivially compatible.
1793	 * "invalid argument" returned by comedilib to user mode process
1794	 * if this fails. */
1795
1796	if (cmd->start_arg != 0) {
1797		cmd->start_arg = 0;
1798		err++;
1799	}
1800#define MAX_SPEED_AI_SE		3200	/* PCI230 SE:   3200 ns => 312.5 kHz */
1801#define MAX_SPEED_AI_DIFF	8000	/* PCI230 DIFF: 8000 ns => 125 kHz */
1802#define MAX_SPEED_AI_PLUS	4000	/* PCI230+:     4000 ns => 250 kHz */
1803#define MIN_SPEED_AI	4294967295u	/* 4294967295ns = 4.29s */
1804			/*- Comedi limit due to unsigned int cmd.  Driver limit
1805			 * = 2^16 (16bit * counter) * 1000000ns (1kHz onboard
1806			 * clock) = 65.536s */
1807
1808	if (cmd->convert_src == TRIG_TIMER) {
1809		unsigned int max_speed_ai;
1810
1811		if (devpriv->hwver == 0) {
1812			/* PCI230 or PCI260.  Max speed depends whether
1813			 * single-ended or pseudo-differential. */
1814			if (cmd->chanlist && (cmd->chanlist_len > 0)) {
1815				/* Peek analogue reference of first channel. */
1816				if (CR_AREF(cmd->chanlist[0]) == AREF_DIFF)
1817					max_speed_ai = MAX_SPEED_AI_DIFF;
1818				else
1819					max_speed_ai = MAX_SPEED_AI_SE;
1820
1821			} else {
1822				/* No channel list.  Assume single-ended. */
1823				max_speed_ai = MAX_SPEED_AI_SE;
1824			}
1825		} else {
1826			/* PCI230+ or PCI260+. */
1827			max_speed_ai = MAX_SPEED_AI_PLUS;
1828		}
1829
1830		if (cmd->convert_arg < max_speed_ai) {
1831			cmd->convert_arg = max_speed_ai;
1832			err++;
1833		}
1834		if (cmd->convert_arg > MIN_SPEED_AI) {
1835			cmd->convert_arg = MIN_SPEED_AI;
1836			err++;
1837		}
1838	} else if (cmd->convert_src == TRIG_EXT) {
1839		/*
1840		 * external trigger
1841		 *
1842		 * convert_arg == (CR_EDGE | 0)
1843		 *                => trigger on +ve edge.
1844		 * convert_arg == (CR_EDGE | CR_INVERT | 0)
1845		 *                => trigger on -ve edge.
1846		 */
1847		if ((cmd->convert_arg & CR_FLAGS_MASK) != 0) {
1848			/* Trigger number must be 0. */
1849			if ((cmd->convert_arg & ~CR_FLAGS_MASK) != 0) {
1850				cmd->convert_arg = COMBINE(cmd->convert_arg, 0,
1851							   ~CR_FLAGS_MASK);
1852				err++;
1853			}
1854			/* The only flags allowed are CR_INVERT and CR_EDGE.
1855			 * CR_EDGE is required. */
1856			if ((cmd->convert_arg & (CR_FLAGS_MASK & ~CR_INVERT))
1857			    != CR_EDGE) {
1858				/* Set CR_EDGE, preserve CR_INVERT. */
1859				cmd->convert_arg =
1860				    COMBINE(cmd->start_arg, (CR_EDGE | 0),
1861					    CR_FLAGS_MASK & ~CR_INVERT);
1862				err++;
1863			}
1864		} else {
1865			/* Backwards compatibility with previous versions. */
1866			/* convert_arg == 0 => trigger on -ve edge. */
1867			/* convert_arg == 1 => trigger on +ve edge. */
1868			if (cmd->convert_arg > 1) {
1869				/* Default to trigger on +ve edge. */
1870				cmd->convert_arg = 1;
1871				err++;
1872			}
1873		}
1874	} else {
1875		if (cmd->convert_arg != 0) {
1876			cmd->convert_arg = 0;
1877			err++;
1878		}
1879	}
1880
1881	if (cmd->scan_end_arg != cmd->chanlist_len) {
1882		cmd->scan_end_arg = cmd->chanlist_len;
1883		err++;
1884	}
1885
1886	if (cmd->stop_src == TRIG_NONE) {
1887		if (cmd->stop_arg != 0) {
1888			cmd->stop_arg = 0;
1889			err++;
1890		}
1891	}
1892
1893	if (cmd->scan_begin_src == TRIG_EXT) {
1894		/* external "trigger" to begin each scan
1895		 * scan_begin_arg==0 => use PPC0 input -> gate of CT0 -> gate
1896		 * of CT2 (sample convert trigger is CT2) */
1897		if ((cmd->scan_begin_arg & ~CR_FLAGS_MASK) != 0) {
1898			cmd->scan_begin_arg = COMBINE(cmd->scan_begin_arg, 0,
1899						      ~CR_FLAGS_MASK);
1900			err++;
1901		}
1902		/* The only flag allowed is CR_EDGE, which is ignored. */
1903		if ((cmd->scan_begin_arg & CR_FLAGS_MASK & ~CR_EDGE) != 0) {
1904			cmd->scan_begin_arg = COMBINE(cmd->scan_begin_arg, 0,
1905						      CR_FLAGS_MASK & ~CR_EDGE);
1906			err++;
1907		}
1908	} else if (cmd->scan_begin_src == TRIG_TIMER) {
1909		/* N.B. cmd->convert_arg is also TRIG_TIMER */
1910		if (!pci230_ai_check_scan_period(cmd))
1911			err++;
1912
1913	} else {
1914		if (cmd->scan_begin_arg != 0) {
1915			cmd->scan_begin_arg = 0;
1916			err++;
1917		}
1918	}
1919
1920	if (err)
1921		return 3;
1922
1923	/* Step 4: fix up any arguments.
1924	 * "argument conflict" returned by comedilib to user mode process
1925	 * if this fails. */
1926
1927	if (cmd->convert_src == TRIG_TIMER) {
1928		tmp = cmd->convert_arg;
1929		pci230_ns_to_single_timer(&cmd->convert_arg,
1930					  cmd->flags & TRIG_ROUND_MASK);
1931		if (tmp != cmd->convert_arg)
1932			err++;
1933	}
1934
1935	if (cmd->scan_begin_src == TRIG_TIMER) {
1936		/* N.B. cmd->convert_arg is also TRIG_TIMER */
1937		tmp = cmd->scan_begin_arg;
1938		pci230_ns_to_single_timer(&cmd->scan_begin_arg,
1939					  cmd->flags & TRIG_ROUND_MASK);
1940		if (!pci230_ai_check_scan_period(cmd)) {
1941			/* Was below minimum required.  Round up. */
1942			pci230_ns_to_single_timer(&cmd->scan_begin_arg,
1943						  TRIG_ROUND_UP);
1944			pci230_ai_check_scan_period(cmd);
1945		}
1946		if (tmp != cmd->scan_begin_arg)
1947			err++;
1948	}
1949
1950	if (err)
1951		return 4;
1952
1953	/* Step 5: check channel list if it exists. */
1954
1955	if (cmd->chanlist && cmd->chanlist_len > 0) {
1956		enum {
1957			seq_err = 1 << 0,
1958			rangepair_err = 1 << 1,
1959			polarity_err = 1 << 2,
1960			aref_err = 1 << 3,
1961			diffchan_err = 1 << 4,
1962			buggy_chan0_err = 1 << 5
1963		};
1964		unsigned int errors;
1965		unsigned int chan, prev_chan;
1966		unsigned int range, prev_range;
1967		unsigned int polarity, prev_polarity;
1968		unsigned int aref, prev_aref;
1969		unsigned int subseq_len;
1970		unsigned int n;
1971
1972		subseq_len = 0;
1973		errors = 0;
1974		prev_chan = prev_aref = prev_range = prev_polarity = 0;
1975		for (n = 0; n < cmd->chanlist_len; n++) {
1976			chan = CR_CHAN(cmd->chanlist[n]);
1977			range = CR_RANGE(cmd->chanlist[n]);
1978			aref = CR_AREF(cmd->chanlist[n]);
1979			polarity = pci230_ai_bipolar[range];
1980			/* Only the first half of the channels are available if
1981			 * differential.  (These are remapped in software.  In
1982			 * hardware, only the even channels are available.) */
1983			if ((aref == AREF_DIFF)
1984			    && (chan >= (s->n_chan / 2))) {
1985				errors |= diffchan_err;
1986			}
1987			if (n > 0) {
1988				/* Channel numbers must strictly increase or
1989				 * subsequence must repeat exactly. */
1990				if ((chan <= prev_chan)
1991				    && (subseq_len == 0)) {
1992					subseq_len = n;
1993				}
1994				if ((subseq_len > 0)
1995				    && (cmd->chanlist[n] !=
1996					cmd->chanlist[n % subseq_len])) {
1997					errors |= seq_err;
1998				}
1999				/* Channels must have same AREF. */
2000				if (aref != prev_aref)
2001					errors |= aref_err;
2002
2003				/* Channel ranges must have same polarity. */
2004				if (polarity != prev_polarity)
2005					errors |= polarity_err;
2006
2007				/* Single-ended channel pairs must have same
2008				 * range.  */
2009				if ((aref != AREF_DIFF)
2010				    && (((chan ^ prev_chan) & ~1) == 0)
2011				    && (range != prev_range)) {
2012					errors |= rangepair_err;
2013				}
2014			}
2015			prev_chan = chan;
2016			prev_range = range;
2017			prev_aref = aref;
2018			prev_polarity = polarity;
2019		}
2020		if (subseq_len == 0) {
2021			/* Subsequence is whole sequence. */
2022			subseq_len = n;
2023		}
2024		/* If channel list is a repeating subsequence, need a whole
2025		 * number of repeats. */
2026		if ((n % subseq_len) != 0)
2027			errors |= seq_err;
2028
2029		if ((devpriv->hwver > 0) && (devpriv->hwver < 4)) {
2030			/*
2031			 * Buggy PCI230+ or PCI260+ requires channel 0 to be
2032			 * (first) in the sequence if the sequence contains
2033			 * more than one channel.  Hardware versions 1 and 2
2034			 * have the bug.  There is no hardware version 3.
2035			 *
2036			 * Actually, there are two firmwares that report
2037			 * themselves as hardware version 1 (the boards
2038			 * have different ADC chips with slightly different
2039			 * timing requirements, which was supposed to be
2040			 * invisible to software).  The first one doesn't
2041			 * seem to have the bug, but the second one
2042			 * does, and we can't tell them apart!
2043			 */
2044			if ((subseq_len > 1)
2045			    && (CR_CHAN(cmd->chanlist[0]) != 0)) {
2046				errors |= buggy_chan0_err;
2047			}
2048		}
2049		if (errors != 0) {
2050			err++;
2051			if ((errors & seq_err) != 0) {
2052				DPRINTK("comedi%d: amplc_pci230: ai_cmdtest: "
2053					"channel numbers must increase or "
2054					"sequence must repeat exactly\n",
2055					dev->minor);
2056			}
2057			if ((errors & rangepair_err) != 0) {
2058				DPRINTK("comedi%d: amplc_pci230: ai_cmdtest: "
2059					"single-ended channel pairs must "
2060					"have the same range\n", dev->minor);
2061			}
2062			if ((errors & polarity_err) != 0) {
2063				DPRINTK("comedi%d: amplc_pci230: ai_cmdtest: "
2064					"channel sequence ranges must be all "
2065					"bipolar or all unipolar\n",
2066					dev->minor);
2067			}
2068			if ((errors & aref_err) != 0) {
2069				DPRINTK("comedi%d: amplc_pci230: ai_cmdtest: "
2070					"channel sequence analogue references "
2071					"must be all the same (single-ended "
2072					"or differential)\n", dev->minor);
2073			}
2074			if ((errors & diffchan_err) != 0) {
2075				DPRINTK("comedi%d: amplc_pci230: ai_cmdtest: "
2076					"differential channel number out of "
2077					"range 0 to %u\n", dev->minor,
2078					(s->n_chan / 2) - 1);
2079			}
2080			if ((errors & buggy_chan0_err) != 0) {
2081				/* Use printk instead of DPRINTK here. */
2082				printk("comedi: comedi%d: amplc_pci230: "
2083				       "ai_cmdtest: Buggy PCI230+/260+ "
2084				       "h/w version %u requires first channel "
2085				       "of multi-channel sequence to be 0 "
2086				       "(corrected in h/w version 4)\n",
2087				       dev->minor, devpriv->hwver);
2088			}
2089		}
2090	}
2091
2092	if (err)
2093		return 5;
2094
2095	return 0;
2096}
2097
2098static void pci230_ai_update_fifo_trigger_level(struct comedi_device *dev,
2099						struct comedi_subdevice *s)
2100{
2101	struct comedi_cmd *cmd = &s->async->cmd;
2102	unsigned int scanlen = cmd->scan_end_arg;
2103	unsigned int wake;
2104	unsigned short triglev;
2105	unsigned short adccon;
2106
2107	if ((cmd->flags & TRIG_WAKE_EOS) != 0) {
2108		/* Wake at end of scan. */
2109		wake = scanlen - devpriv->ai_scan_pos;
2110	} else {
2111		if (devpriv->ai_continuous
2112		    || (devpriv->ai_scan_count >= PCI230_ADC_FIFOLEVEL_HALFFULL)
2113		    || (scanlen >= PCI230_ADC_FIFOLEVEL_HALFFULL)) {
2114			wake = PCI230_ADC_FIFOLEVEL_HALFFULL;
2115		} else {
2116			wake = (devpriv->ai_scan_count * scanlen)
2117			    - devpriv->ai_scan_pos;
2118		}
2119	}
2120	if (wake >= PCI230_ADC_FIFOLEVEL_HALFFULL) {
2121		triglev = PCI230_ADC_INT_FIFO_HALF;
2122	} else {
2123		if ((wake > 1) && (devpriv->hwver > 0)) {
2124			/* PCI230+/260+ programmable FIFO interrupt level. */
2125			if (devpriv->adcfifothresh != wake) {
2126				devpriv->adcfifothresh = wake;
2127				outw(wake, dev->iobase + PCI230P_ADCFFTH);
2128			}
2129			triglev = PCI230P_ADC_INT_FIFO_THRESH;
2130		} else {
2131			triglev = PCI230_ADC_INT_FIFO_NEMPTY;
2132		}
2133	}
2134	adccon = (devpriv->adccon & ~PCI230_ADC_INT_FIFO_MASK) | triglev;
2135	if (adccon != devpriv->adccon) {
2136		devpriv->adccon = adccon;
2137		outw(adccon, dev->iobase + PCI230_ADCCON);
2138	}
2139}
2140
2141static int pci230_ai_inttrig_convert(struct comedi_device *dev,
2142				     struct comedi_subdevice *s,
2143				     unsigned int trig_num)
2144{
2145	unsigned long irqflags;
2146
2147	if (trig_num != 0)
2148		return -EINVAL;
2149
2150	spin_lock_irqsave(&devpriv->ai_stop_spinlock, irqflags);
2151	if (test_bit(AI_CMD_STARTED, &devpriv->state)) {
2152		unsigned int delayus;
2153
2154		/* Trigger conversion by toggling Z2-CT2 output.  Finish
2155		 * with output high. */
2156		i8254_set_mode(devpriv->iobase1 + PCI230_Z2_CT_BASE, 0, 2,
2157			       I8254_MODE0);
2158		i8254_set_mode(devpriv->iobase1 + PCI230_Z2_CT_BASE, 0, 2,
2159			       I8254_MODE1);
2160		/* Delay.  Should driver be responsible for this?  An
2161		 * alternative would be to wait until conversion is complete,
2162		 * but we can't tell when it's complete because the ADC busy
2163		 * bit has a different meaning when FIFO enabled (and when
2164		 * FIFO not enabled, it only works for software triggers). */
2165		if (((devpriv->adccon & PCI230_ADC_IM_MASK)
2166		     == PCI230_ADC_IM_DIF)
2167		    && (devpriv->hwver == 0)) {
2168			/* PCI230/260 in differential mode */
2169			delayus = 8;
2170		} else {
2171			/* single-ended or PCI230+/260+ */
2172			delayus = 4;
2173		}
2174		spin_unlock_irqrestore(&devpriv->ai_stop_spinlock, irqflags);
2175		udelay(delayus);
2176	} else {
2177		spin_unlock_irqrestore(&devpriv->ai_stop_spinlock, irqflags);
2178	}
2179
2180	return 1;
2181}
2182
2183static int pci230_ai_inttrig_scan_begin(struct comedi_device *dev,
2184					struct comedi_subdevice *s,
2185					unsigned int trig_num)
2186{
2187	unsigned long irqflags;
2188	unsigned char zgat;
2189
2190	if (trig_num != 0)
2191		return -EINVAL;
2192
2193	spin_lock_irqsave(&devpriv->ai_stop_spinlock, irqflags);
2194	if (test_bit(AI_CMD_STARTED, &devpriv->state)) {
2195		/* Trigger scan by waggling CT0 gate source. */
2196		zgat = GAT_CONFIG(0, GAT_GND);
2197		outb(zgat, devpriv->iobase1 + PCI230_ZGAT_SCE);
2198		zgat = GAT_CONFIG(0, GAT_VCC);
2199		outb(zgat, devpriv->iobase1 + PCI230_ZGAT_SCE);
2200	}
2201	spin_unlock_irqrestore(&devpriv->ai_stop_spinlock, irqflags);
2202
2203	return 1;
2204}
2205
2206static void pci230_ai_start(struct comedi_device *dev,
2207			    struct comedi_subdevice *s)
2208{
2209	unsigned long irqflags;
2210	unsigned short conv;
2211	struct comedi_async *async = s->async;
2212	struct comedi_cmd *cmd = &async->cmd;
2213
2214	set_bit(AI_CMD_STARTED, &devpriv->state);
2215	if (!devpriv->ai_continuous && (devpriv->ai_scan_count == 0)) {
2216		/* An empty acquisition! */
2217		async->events |= COMEDI_CB_EOA;
2218		pci230_ai_stop(dev, s);
2219		comedi_event(dev, s);
2220	} else {
2221		/* Enable ADC FIFO trigger level interrupt. */
2222		spin_lock_irqsave(&devpriv->isr_spinlock, irqflags);
2223		devpriv->int_en |= PCI230_INT_ADC;
2224		devpriv->ier |= PCI230_INT_ADC;
2225		outb(devpriv->ier, devpriv->iobase1 + PCI230_INT_SCE);
2226		spin_unlock_irqrestore(&devpriv->isr_spinlock, irqflags);
2227
2228		/* Update conversion trigger source which is currently set
2229		 * to CT2 output, which is currently stuck high. */
2230		switch (cmd->convert_src) {
2231		default:
2232			conv = PCI230_ADC_TRIG_NONE;
2233			break;
2234		case TRIG_TIMER:
2235			/* Using CT2 output. */
2236			conv = PCI230_ADC_TRIG_Z2CT2;
2237			break;
2238		case TRIG_EXT:
2239			if ((cmd->convert_arg & CR_EDGE) != 0) {
2240				if ((cmd->convert_arg & CR_INVERT) == 0) {
2241					/* Trigger on +ve edge. */
2242					conv = PCI230_ADC_TRIG_EXTP;
2243				} else {
2244					/* Trigger on -ve edge. */
2245					conv = PCI230_ADC_TRIG_EXTN;
2246				}
2247			} else {
2248				/* Backwards compatibility. */
2249				if (cmd->convert_arg != 0) {
2250					/* Trigger on +ve edge. */
2251					conv = PCI230_ADC_TRIG_EXTP;
2252				} else {
2253					/* Trigger on -ve edge. */
2254					conv = PCI230_ADC_TRIG_EXTN;
2255				}
2256			}
2257			break;
2258		case TRIG_INT:
2259			/* Use CT2 output for software trigger due to problems
2260			 * in differential mode on PCI230/260. */
2261			conv = PCI230_ADC_TRIG_Z2CT2;
2262			break;
2263		}
2264		devpriv->adccon = (devpriv->adccon & ~PCI230_ADC_TRIG_MASK)
2265		    | conv;
2266		outw(devpriv->adccon, dev->iobase + PCI230_ADCCON);
2267		if (cmd->convert_src == TRIG_INT)
2268			async->inttrig = pci230_ai_inttrig_convert;
2269
2270		/* Update FIFO interrupt trigger level, which is currently
2271		 * set to "full".  */
2272		pci230_ai_update_fifo_trigger_level(dev, s);
2273		if (cmd->convert_src == TRIG_TIMER) {
2274			/* Update timer gates. */
2275			unsigned char zgat;
2276
2277			if (cmd->scan_begin_src != TRIG_FOLLOW) {
2278				/* Conversion timer CT2 needs to be gated by
2279				 * inverted output of monostable CT2. */
2280				zgat = GAT_CONFIG(2, GAT_NOUTNM2);
2281			} else {
2282				/* Conversion timer CT2 needs to be gated on
2283				 * continuously. */
2284				zgat = GAT_CONFIG(2, GAT_VCC);
2285			}
2286			outb(zgat, devpriv->iobase1 + PCI230_ZGAT_SCE);
2287			if (cmd->scan_begin_src != TRIG_FOLLOW) {
2288				/* Set monostable CT0 trigger source. */
2289				switch (cmd->scan_begin_src) {
2290				default:
2291					zgat = GAT_CONFIG(0, GAT_VCC);
2292					break;
2293				case TRIG_EXT:
2294					/*
2295					 * For CT0 on PCI230, the external
2296					 * trigger (gate) signal comes from
2297					 * PPC0, which is channel 16 of the DIO
2298					 * subdevice.  The application needs to
2299					 * configure this as an input in order
2300					 * to use it as an external scan
2301					 * trigger.
2302					 */
2303					zgat = GAT_CONFIG(0, GAT_EXT);
2304					break;
2305				case TRIG_TIMER:
2306					/*
2307					 * Monostable CT0 triggered by rising
2308					 * edge on inverted output of CT1
2309					 * (falling edge on CT1).
2310					 */
2311					zgat = GAT_CONFIG(0, GAT_NOUTNM2);
2312					break;
2313				case TRIG_INT:
2314					/*
2315					 * Monostable CT0 is triggered by
2316					 * inttrig function waggling the CT0
2317					 * gate source.
2318					 */
2319					zgat = GAT_CONFIG(0, GAT_VCC);
2320					break;
2321				}
2322				outb(zgat, devpriv->iobase1 + PCI230_ZGAT_SCE);
2323				switch (cmd->scan_begin_src) {
2324				case TRIG_TIMER:
2325					/* Scan period timer CT1 needs to be
2326					 * gated on to start counting. */
2327					zgat = GAT_CONFIG(1, GAT_VCC);
2328					outb(zgat, devpriv->iobase1
2329					     + PCI230_ZGAT_SCE);
2330					break;
2331				case TRIG_INT:
2332					async->inttrig =
2333					    pci230_ai_inttrig_scan_begin;
2334					break;
2335				}
2336			}
2337		} else if (cmd->convert_src != TRIG_INT) {
2338			/* No longer need Z2-CT2. */
2339			put_one_resource(dev, RES_Z2CT2, OWNER_AICMD);
2340		}
2341	}
2342}
2343
2344static int pci230_ai_inttrig_start(struct comedi_device *dev,
2345				   struct comedi_subdevice *s,
2346				   unsigned int trig_num)
2347{
2348	if (trig_num != 0)
2349		return -EINVAL;
2350
2351	s->async->inttrig = NULLFUNC;
2352	pci230_ai_start(dev, s);
2353
2354	return 1;
2355}
2356
2357static int pci230_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
2358{
2359	unsigned int i, chan, range, diff;
2360	unsigned int res_mask;
2361	unsigned short adccon, adcen;
2362	unsigned char zgat;
2363
2364	/* Get the command. */
2365	struct comedi_async *async = s->async;
2366	struct comedi_cmd *cmd = &async->cmd;
2367
2368	/*
2369	 * Determine which shared resources are needed.
2370	 */
2371	res_mask = 0;
2372	/* Need Z2-CT2 to supply a conversion trigger source at a high
2373	 * logic level, even if not doing timed conversions. */
2374	res_mask |= (1U << RES_Z2CT2);
2375	if (cmd->scan_begin_src != TRIG_FOLLOW) {
2376		/* Using Z2-CT0 monostable to gate Z2-CT2 conversion timer */
2377		res_mask |= (1U << RES_Z2CT0);
2378		if (cmd->scan_begin_src == TRIG_TIMER) {
2379			/* Using Z2-CT1 for scan frequency */
2380			res_mask |= (1U << RES_Z2CT1);
2381		}
2382	}
2383	/* Claim resources. */
2384	if (!get_resources(dev, res_mask, OWNER_AICMD))
2385		return -EBUSY;
2386
2387
2388	/* Get number of scans required. */
2389	if (cmd->stop_src == TRIG_COUNT) {
2390		devpriv->ai_scan_count = cmd->stop_arg;
2391		devpriv->ai_continuous = 0;
2392	} else {
2393		/* TRIG_NONE, user calls cancel. */
2394		devpriv->ai_scan_count = 0;
2395		devpriv->ai_continuous = 1;
2396	}
2397	devpriv->ai_scan_pos = 0;	/* Position within scan. */
2398
2399	/* Steps;
2400	 * - Set channel scan list.
2401	 * - Set channel gains.
2402	 * - Enable and reset FIFO, specify uni/bip, se/diff, and set
2403	 *   start conversion source to point to something at a high logic
2404	 *   level (we use the output of counter/timer 2 for this purpose.
2405	 * - PAUSE to allow things to settle down.
2406	 * - Reset the FIFO again because it needs resetting twice and there
2407	 *   may have been a false conversion trigger on some versions of
2408	 *   PCI230/260 due to the start conversion source being set to a
2409	 *   high logic level.
2410	 * - Enable ADC FIFO level interrupt.
2411	 * - Set actual conversion trigger source and FIFO interrupt trigger
2412	 *   level.
2413	 * - If convert_src is TRIG_TIMER, set up the timers.
2414	 */
2415
2416	adccon = PCI230_ADC_FIFO_EN;
2417	adcen = 0;
2418
2419	if (CR_AREF(cmd->chanlist[0]) == AREF_DIFF) {
2420		/* Differential - all channels must be differential. */
2421		diff = 1;
2422		adccon |= PCI230_ADC_IM_DIF;
2423	} else {
2424		/* Single ended - all channels must be single-ended. */
2425		diff = 0;
2426		adccon |= PCI230_ADC_IM_SE;
2427	}
2428
2429	range = CR_RANGE(cmd->chanlist[0]);
2430	devpriv->ai_bipolar = pci230_ai_bipolar[range];
2431	if (devpriv->ai_bipolar)
2432		adccon |= PCI230_ADC_IR_BIP;
2433	else
2434		adccon |= PCI230_ADC_IR_UNI;
2435
2436	for (i = 0; i < cmd->chanlist_len; i++) {
2437		unsigned int gainshift;
2438
2439		chan = CR_CHAN(cmd->chanlist[i]);
2440		range = CR_RANGE(cmd->chanlist[i]);
2441		if (diff) {
2442			gainshift = 2 * chan;
2443			if (devpriv->hwver == 0) {
2444				/* Original PCI230/260 expects both inputs of
2445				 * the differential channel to be enabled. */
2446				adcen |= 3 << gainshift;
2447			} else {
2448				/* PCI230+/260+ expects only one input of the
2449				 * differential channel to be enabled. */
2450				adcen |= 1 << gainshift;
2451			}
2452		} else {
2453			gainshift = (chan & ~1);
2454			adcen |= 1 << chan;
2455		}
2456		devpriv->adcg = (devpriv->adcg & ~(3 << gainshift))
2457		    | (pci230_ai_gain[range] << gainshift);
2458	}
2459
2460	/* Set channel scan list. */
2461	outw(adcen, dev->iobase + PCI230_ADCEN);
2462
2463	/* Set channel gains. */
2464	outw(devpriv->adcg, dev->iobase + PCI230_ADCG);
2465
2466	/* Set counter/timer 2 output high for use as the initial start
2467	 * conversion source. */
2468	i8254_set_mode(devpriv->iobase1 + PCI230_Z2_CT_BASE, 0, 2, I8254_MODE1);
2469
2470	/* Temporarily use CT2 output as conversion trigger source and
2471	 * temporarily set FIFO interrupt trigger level to 'full'. */
2472	adccon |= PCI230_ADC_INT_FIFO_FULL | PCI230_ADC_TRIG_Z2CT2;
2473
2474	/* Enable and reset FIFO, specify FIFO trigger level full, specify
2475	 * uni/bip, se/diff, and temporarily set the start conversion source
2476	 * to CT2 output.  Note that CT2 output is currently high, and this
2477	 * will produce a false conversion trigger on some versions of the
2478	 * PCI230/260, but that will be dealt with later. */
2479	devpriv->adccon = adccon;
2480	outw(adccon | PCI230_ADC_FIFO_RESET, dev->iobase + PCI230_ADCCON);
2481
2482	/* Delay */
2483	/* Failure to include this will result in the first few channels'-worth
2484	 * of data being corrupt, normally manifesting itself by large negative
2485	 * voltages. It seems the board needs time to settle between the first
2486	 * FIFO reset (above) and the second FIFO reset (below). Setting the
2487	 * channel gains and scan list _before_ the first FIFO reset also
2488	 * helps, though only slightly. */
2489	udelay(25);
2490
2491	/* Reset FIFO again. */
2492	outw(adccon | PCI230_ADC_FIFO_RESET, dev->iobase + PCI230_ADCCON);
2493
2494	if (cmd->convert_src == TRIG_TIMER) {
2495		/* Set up CT2 as conversion timer, but gate it off for now.
2496		 * Note, counter/timer output 2 can be monitored on the
2497		 * connector: PCI230 pin 21, PCI260 pin 18. */
2498		zgat = GAT_CONFIG(2, GAT_GND);
2499		outb(zgat, devpriv->iobase1 + PCI230_ZGAT_SCE);
2500		/* Set counter/timer 2 to the specified conversion period. */
2501		pci230_ct_setup_ns_mode(dev, 2, I8254_MODE3, cmd->convert_arg,
2502					cmd->flags & TRIG_ROUND_MASK);
2503		if (cmd->scan_begin_src != TRIG_FOLLOW) {
2504			/*
2505			 * Set up monostable on CT0 output for scan timing.  A
2506			 * rising edge on the trigger (gate) input of CT0 will
2507			 * trigger the monostable, causing its output to go low
2508			 * for the configured period.  The period depends on
2509			 * the conversion period and the number of conversions
2510			 * in the scan.
2511			 *
2512			 * Set the trigger high before setting up the
2513			 * monostable to stop it triggering.  The trigger
2514			 * source will be changed later.
2515			 */
2516			zgat = GAT_CONFIG(0, GAT_VCC);
2517			outb(zgat, devpriv->iobase1 + PCI230_ZGAT_SCE);
2518			pci230_ct_setup_ns_mode(dev, 0, I8254_MODE1,
2519						((uint64_t) cmd->convert_arg
2520						 * cmd->scan_end_arg),
2521						TRIG_ROUND_UP);
2522			if (cmd->scan_begin_src == TRIG_TIMER) {
2523				/*
2524				 * Monostable on CT0 will be triggered by
2525				 * output of CT1 at configured scan frequency.
2526				 *
2527				 * Set up CT1 but gate it off for now.
2528				 */
2529				zgat = GAT_CONFIG(1, GAT_GND);
2530				outb(zgat, devpriv->iobase1 + PCI230_ZGAT_SCE);
2531				pci230_ct_setup_ns_mode(dev, 1, I8254_MODE3,
2532							cmd->scan_begin_arg,
2533							cmd->
2534							flags &
2535							TRIG_ROUND_MASK);
2536			}
2537		}
2538	}
2539
2540	if (cmd->start_src == TRIG_INT) {
2541		s->async->inttrig = pci230_ai_inttrig_start;
2542	} else {
2543		/* TRIG_NOW */
2544		pci230_ai_start(dev, s);
2545	}
2546
2547	return 0;
2548}
2549
2550static unsigned int divide_ns(uint64_t ns, unsigned int timebase,
2551			      unsigned int round_mode)
2552{
2553	uint64_t div;
2554	unsigned int rem;
2555
2556	div = ns;
2557	rem = do_div(div, timebase);
2558	round_mode &= TRIG_ROUND_MASK;
2559	switch (round_mode) {
2560	default:
2561	case TRIG_ROUND_NEAREST:
2562		div += (rem + (timebase / 2)) / timebase;
2563		break;
2564	case TRIG_ROUND_DOWN:
2565		break;
2566	case TRIG_ROUND_UP:
2567		div += (rem + timebase - 1) / timebase;
2568		break;
2569	}
2570	return div > UINT_MAX ? UINT_MAX : (unsigned int)div;
2571}
2572
2573/* Given desired period in ns, returns the required internal clock source
2574 * and gets the initial count. */
2575static unsigned int pci230_choose_clk_count(uint64_t ns, unsigned int *count,
2576					    unsigned int round_mode)
2577{
2578	unsigned int clk_src, cnt;
2579
2580	for (clk_src = CLK_10MHZ;; clk_src++) {
2581		cnt = divide_ns(ns, pci230_timebase[clk_src], round_mode);
2582		if ((cnt <= 65536) || (clk_src == CLK_1KHZ))
2583			break;
2584
2585	}
2586	*count = cnt;
2587	return clk_src;
2588}
2589
2590static void pci230_ns_to_single_timer(unsigned int *ns, unsigned int round)
2591{
2592	unsigned int count;
2593	unsigned int clk_src;
2594
2595	clk_src = pci230_choose_clk_count(*ns, &count, round);
2596	*ns = count * pci230_timebase[clk_src];
2597	return;
2598}
2599
2600static void pci230_ct_setup_ns_mode(struct comedi_device *dev, unsigned int ct,
2601				    unsigned int mode, uint64_t ns,
2602				    unsigned int round)
2603{
2604	unsigned int clk_src;
2605	unsigned int count;
2606
2607	/* Set mode. */
2608	i8254_set_mode(devpriv->iobase1 + PCI230_Z2_CT_BASE, 0, ct, mode);
2609	/* Determine clock source and count. */
2610	clk_src = pci230_choose_clk_count(ns, &count, round);
2611	/* Program clock source. */
2612	outb(CLK_CONFIG(ct, clk_src), devpriv->iobase1 + PCI230_ZCLK_SCE);
2613	/* Set initial count. */
2614	if (count >= 65536)
2615		count = 0;
2616
2617	i8254_write(devpriv->iobase1 + PCI230_Z2_CT_BASE, 0, ct, count);
2618}
2619
2620static void pci230_cancel_ct(struct comedi_device *dev, unsigned int ct)
2621{
2622	i8254_set_mode(devpriv->iobase1 + PCI230_Z2_CT_BASE, 0, ct,
2623		       I8254_MODE1);
2624	/* Counter ct, 8254 mode 1, initial count not written. */
2625}
2626
2627/* Interrupt handler */
2628static irqreturn_t pci230_interrupt(int irq, void *d)
2629{
2630	unsigned char status_int, valid_status_int;
2631	struct comedi_device *dev = (struct comedi_device *)d;
2632	struct comedi_subdevice *s;
2633	unsigned long irqflags;
2634
2635	/* Read interrupt status/enable register. */
2636	status_int = inb(devpriv->iobase1 + PCI230_INT_STAT);
2637
2638	if (status_int == PCI230_INT_DISABLE)
2639		return IRQ_NONE;
2640
2641
2642	spin_lock_irqsave(&devpriv->isr_spinlock, irqflags);
2643	valid_status_int = devpriv->int_en & status_int;
2644	/* Disable triggered interrupts.
2645	 * (Only those interrupts that need re-enabling, are, later in the
2646	 * handler).  */
2647	devpriv->ier = devpriv->int_en & ~status_int;
2648	outb(devpriv->ier, devpriv->iobase1 + PCI230_INT_SCE);
2649	devpriv->intr_running = 1;
2650	devpriv->intr_cpuid = THISCPU;
2651	spin_unlock_irqrestore(&devpriv->isr_spinlock, irqflags);
2652
2653	/*
2654	 * Check the source of interrupt and handle it.
2655	 * The PCI230 can cope with concurrent ADC, DAC, PPI C0 and C3
2656	 * interrupts.  However, at present (Comedi-0.7.60) does not allow
2657	 * concurrent execution of commands, instructions or a mixture of the
2658	 * two.
2659	 */
2660
2661	if ((valid_status_int & PCI230_INT_ZCLK_CT1) != 0) {
2662		s = dev->write_subdev;
2663		pci230_handle_ao_nofifo(dev, s);
2664		comedi_event(dev, s);
2665	}
2666
2667	if ((valid_status_int & PCI230P2_INT_DAC) != 0) {
2668		s = dev->write_subdev;
2669		pci230_handle_ao_fifo(dev, s);
2670		comedi_event(dev, s);
2671	}
2672
2673	if ((valid_status_int & PCI230_INT_ADC) != 0) {
2674		s = dev->read_subdev;
2675		pci230_handle_ai(dev, s);
2676		comedi_event(dev, s);
2677	}
2678
2679	/* Reenable interrupts. */
2680	spin_lock_irqsave(&devpriv->isr_spinlock, irqflags);
2681	if (devpriv->ier != devpriv->int_en) {
2682		devpriv->ier = devpriv->int_en;
2683		outb(devpriv->ier, devpriv->iobase1 + PCI230_INT_SCE);
2684	}
2685	devpriv->intr_running = 0;
2686	spin_unlock_irqrestore(&devpriv->isr_spinlock, irqflags);
2687
2688	return IRQ_HANDLED;
2689}
2690
2691static void pci230_handle_ao_nofifo(struct comedi_device *dev,
2692				    struct comedi_subdevice *s)
2693{
2694	short data;
2695	int i, ret;
2696	struct comedi_async *async = s->async;
2697	struct comedi_cmd *cmd = &async->cmd;
2698
2699	if (!devpriv->ao_continuous && (devpriv->ao_scan_count == 0))
2700		return;
2701
2702
2703	for (i = 0; i < cmd->chanlist_len; i++) {
2704		/* Read sample from Comedi's circular buffer. */
2705		ret = comedi_buf_get(s->async, &data);
2706		if (ret == 0) {
2707			s->async->events |= COMEDI_CB_OVERFLOW;
2708			pci230_ao_stop(dev, s);
2709			comedi_error(dev, "AO buffer underrun");
2710			return;
2711		}
2712		/* Write value to DAC. */
2713		pci230_ao_write_nofifo(dev, data, CR_CHAN(cmd->chanlist[i]));
2714	}
2715
2716	async->events |= COMEDI_CB_BLOCK | COMEDI_CB_EOS;
2717	if (!devpriv->ao_continuous) {
2718		devpriv->ao_scan_count--;
2719		if (devpriv->ao_scan_count == 0) {
2720			/* End of acquisition. */
2721			async->events |= COMEDI_CB_EOA;
2722			pci230_ao_stop(dev, s);
2723		}
2724	}
2725}
2726
2727/* Loads DAC FIFO (if using it) from buffer. */
2728/* Returns 0 if AO finished due to completion or error, 1 if still going. */
2729static int pci230_handle_ao_fifo(struct comedi_device *dev,
2730				 struct comedi_subdevice *s)
2731{
2732	struct comedi_async *async = s->async;
2733	struct comedi_cmd *cmd = &async->cmd;
2734	unsigned int num_scans;
2735	unsigned int room;
2736	unsigned short dacstat;
2737	unsigned int i, n;
2738	unsigned int bytes_per_scan;
2739	unsigned int events = 0;
2740	int running;
2741
2742	/* Get DAC FIFO status. */
2743	dacstat = inw(dev->iobase + PCI230_DACCON);
2744
2745	/* Determine number of scans available in buffer. */
2746	bytes_per_scan = cmd->chanlist_len * sizeof(short);
2747	num_scans = comedi_buf_read_n_available(async) / bytes_per_scan;
2748	if (!devpriv->ao_continuous) {
2749		/* Fixed number of scans. */
2750		if (num_scans > devpriv->ao_scan_count)
2751			num_scans = devpriv->ao_scan_count;
2752
2753		if (devpriv->ao_scan_count == 0) {
2754			/* End of acquisition. */
2755			events |= COMEDI_CB_EOA;
2756		}
2757	}
2758	if (events == 0) {
2759		/* Check for FIFO underrun. */
2760		if ((dacstat & PCI230P2_DAC_FIFO_UNDERRUN_LATCHED) != 0) {
2761			comedi_error(dev, "AO FIFO underrun");
2762			events |= COMEDI_CB_OVERFLOW | COMEDI_CB_ERROR;
2763		}
2764		/* Check for buffer underrun if FIFO less than half full
2765		 * (otherwise there will be loads of "DAC FIFO not half full"
2766		 * interrupts). */
2767		if ((num_scans == 0)
2768		    && ((dacstat & PCI230P2_DAC_FIFO_HALF) == 0)) {
2769			comedi_error(dev, "AO buffer underrun");
2770			events |= COMEDI_CB_OVERFLOW | COMEDI_CB_ERROR;
2771		}
2772	}
2773	if (events == 0) {
2774		/* Determine how much room is in the FIFO (in samples). */
2775		if ((dacstat & PCI230P2_DAC_FIFO_FULL) != 0)
2776			room = PCI230P2_DAC_FIFOROOM_FULL;
2777		else if ((dacstat & PCI230P2_DAC_FIFO_HALF) != 0)
2778			room = PCI230P2_DAC_FIFOROOM_HALFTOFULL;
2779		else if ((dacstat & PCI230P2_DAC_FIFO_EMPTY) != 0)
2780			room = PCI230P2_DAC_FIFOROOM_EMPTY;
2781		else
2782			room = PCI230P2_DAC_FIFOROOM_ONETOHALF;
2783
2784		/* Convert room to number of scans that can be added. */
2785		room /= cmd->chanlist_len;
2786		/* Determine number of scans to process. */
2787		if (num_scans > room)
2788			num_scans = room;
2789
2790		/* Process scans. */
2791		for (n = 0; n < num_scans; n++) {
2792			for (i = 0; i < cmd->chanlist_len; i++) {
2793				short datum;
2794
2795				comedi_buf_get(async, &datum);
2796				pci230_ao_write_fifo(dev, datum,
2797						     CR_CHAN(cmd->chanlist[i]));
2798			}
2799		}
2800		events |= COMEDI_CB_EOS | COMEDI_CB_BLOCK;
2801		if (!devpriv->ao_continuous) {
2802			devpriv->ao_scan_count -= num_scans;
2803			if (devpriv->ao_scan_count == 0) {
2804				/* All data for the command has been written
2805				 * to FIFO.  Set FIFO interrupt trigger level
2806				 * to 'empty'. */
2807				devpriv->daccon = (devpriv->daccon
2808						   &
2809						   ~PCI230P2_DAC_INT_FIFO_MASK)
2810				    | PCI230P2_DAC_INT_FIFO_EMPTY;
2811				outw(devpriv->daccon,
2812				     dev->iobase + PCI230_DACCON);
2813			}
2814		}
2815		/* Check if FIFO underrun occurred while writing to FIFO. */
2816		dacstat = inw(dev->iobase + PCI230_DACCON);
2817		if ((dacstat & PCI230P2_DAC_FIFO_UNDERRUN_LATCHED) != 0) {
2818			comedi_error(dev, "AO FIFO underrun");
2819			events |= COMEDI_CB_OVERFLOW | COMEDI_CB_ERROR;
2820		}
2821	}
2822	if ((events & (COMEDI_CB_EOA | COMEDI_CB_ERROR | COMEDI_CB_OVERFLOW))
2823	    != 0) {
2824		/* Stopping AO due to completion or error. */
2825		pci230_ao_stop(dev, s);
2826		running = 0;
2827	} else {
2828		running = 1;
2829	}
2830	async->events |= events;
2831	return running;
2832}
2833
2834static void pci230_handle_ai(struct comedi_device *dev,
2835			     struct comedi_subdevice *s)
2836{
2837	unsigned int events = 0;
2838	unsigned int status_fifo;
2839	unsigned int i;
2840	unsigned int todo;
2841	unsigned int fifoamount;
2842	struct comedi_async *async = s->async;
2843	unsigned int scanlen = async->cmd.scan_end_arg;
2844
2845	/* Determine number of samples to read. */
2846	if (devpriv->ai_continuous) {
2847		todo = PCI230_ADC_FIFOLEVEL_HALFFULL;
2848	} else if (devpriv->ai_scan_count == 0) {
2849		todo = 0;
2850	} else if ((devpriv->ai_scan_count > PCI230_ADC_FIFOLEVEL_HALFFULL)
2851		   || (scanlen > PCI230_ADC_FIFOLEVEL_HALFFULL)) {
2852		todo = PCI230_ADC_FIFOLEVEL_HALFFULL;
2853	} else {
2854		todo = (devpriv->ai_scan_count * scanlen)
2855		    - devpriv->ai_scan_pos;
2856		if (todo > PCI230_ADC_FIFOLEVEL_HALFFULL)
2857			todo = PCI230_ADC_FIFOLEVEL_HALFFULL;
2858
2859	}
2860
2861	if (todo == 0)
2862		return;
2863
2864
2865	fifoamount = 0;
2866	for (i = 0; i < todo; i++) {
2867		if (fifoamount == 0) {
2868			/* Read FIFO state. */
2869			status_fifo = inw(dev->iobase + PCI230_ADCCON);
2870
2871			if ((status_fifo & PCI230_ADC_FIFO_FULL_LATCHED) != 0) {
2872				/* Report error otherwise FIFO overruns will go
2873				 * unnoticed by the caller. */
2874				comedi_error(dev, "AI FIFO overrun");
2875				events |= COMEDI_CB_OVERFLOW | COMEDI_CB_ERROR;
2876				break;
2877			} else if ((status_fifo & PCI230_ADC_FIFO_EMPTY) != 0) {
2878				/* FIFO empty. */
2879				break;
2880			} else if ((status_fifo & PCI230_ADC_FIFO_HALF) != 0) {
2881				/* FIFO half full. */
2882				fifoamount = PCI230_ADC_FIFOLEVEL_HALFFULL;
2883			} else {
2884				/* FIFO not empty. */
2885				if (devpriv->hwver > 0) {
2886					/* Read PCI230+/260+ ADC FIFO level. */
2887					fifoamount = inw(dev->iobase
2888							 + PCI230P_ADCFFLEV);
2889					if (fifoamount == 0) {
2890						/* Shouldn't happen. */
2891						break;
2892					}
2893				} else {
2894					fifoamount = 1;
2895				}
2896			}
2897		}
2898
2899		/* Read sample and store in Comedi's circular buffer. */
2900		if (comedi_buf_put(async, pci230_ai_read(dev)) == 0) {
2901			events |= COMEDI_CB_ERROR | COMEDI_CB_OVERFLOW;
2902			comedi_error(dev, "AI buffer overflow");
2903			break;
2904		}
2905		fifoamount--;
2906		devpriv->ai_scan_pos++;
2907		if (devpriv->ai_scan_pos == scanlen) {
2908			/* End of scan. */
2909			devpriv->ai_scan_pos = 0;
2910			devpriv->ai_scan_count--;
2911			async->events |= COMEDI_CB_EOS;
2912		}
2913	}
2914
2915	if (!devpriv->ai_continuous && (devpriv->ai_scan_count == 0)) {
2916		/* End of acquisition. */
2917		events |= COMEDI_CB_EOA;
2918	} else {
2919		/* More samples required, tell Comedi to block. */
2920		events |= COMEDI_CB_BLOCK;
2921	}
2922	async->events |= events;
2923
2924	if ((async->events & (COMEDI_CB_EOA | COMEDI_CB_ERROR |
2925			      COMEDI_CB_OVERFLOW)) != 0) {
2926		/* disable hardware conversions */
2927		pci230_ai_stop(dev, s);
2928	} else {
2929		/* update FIFO interrupt trigger level */
2930		pci230_ai_update_fifo_trigger_level(dev, s);
2931	}
2932}
2933
2934static void pci230_ao_stop(struct comedi_device *dev,
2935			   struct comedi_subdevice *s)
2936{
2937	unsigned long irqflags;
2938	unsigned char intsrc;
2939	int started;
2940	struct comedi_cmd *cmd;
2941
2942	spin_lock_irqsave(&devpriv->ao_stop_spinlock, irqflags);
2943	started = test_and_clear_bit(AO_CMD_STARTED, &devpriv->state);
2944	spin_unlock_irqrestore(&devpriv->ao_stop_spinlock, irqflags);
2945	if (!started)
2946		return;
2947
2948
2949	cmd = &s->async->cmd;
2950	if (cmd->scan_begin_src == TRIG_TIMER) {
2951		/* Stop scan rate generator. */
2952		pci230_cancel_ct(dev, 1);
2953	}
2954
2955	/* Determine interrupt source. */
2956	if (devpriv->hwver < 2) {
2957		/* Not using DAC FIFO.  Using CT1 interrupt. */
2958		intsrc = PCI230_INT_ZCLK_CT1;
2959	} else {
2960		/* Using DAC FIFO interrupt. */
2961		intsrc = PCI230P2_INT_DAC;
2962	}
2963	/* Disable interrupt and wait for interrupt routine to finish running
2964	 * unless we are called from the interrupt routine. */
2965	spin_lock_irqsave(&devpriv->isr_spinlock, irqflags);
2966	devpriv->int_en &= ~intsrc;
2967	while (devpriv->intr_running && devpriv->intr_cpuid != THISCPU) {
2968		spin_unlock_irqrestore(&devpriv->isr_spinlock, irqflags);
2969		spin_lock_irqsave(&devpriv->isr_spinlock, irqflags);
2970	}
2971	if (devpriv->ier != devpriv->int_en) {
2972		devpriv->ier = devpriv->int_en;
2973		outb(devpriv->ier, devpriv->iobase1 + PCI230_INT_SCE);
2974	}
2975	spin_unlock_irqrestore(&devpriv->isr_spinlock, irqflags);
2976
2977	if (devpriv->hwver >= 2) {
2978		/* Using DAC FIFO.  Reset FIFO, clear underrun error,
2979		 * disable FIFO. */
2980		devpriv->daccon &= PCI230_DAC_OR_MASK;
2981		outw(devpriv->daccon | PCI230P2_DAC_FIFO_RESET
2982		     | PCI230P2_DAC_FIFO_UNDERRUN_CLEAR,
2983		     dev->iobase + PCI230_DACCON);
2984	}
2985
2986	/* Release resources. */
2987	put_all_resources(dev, OWNER_AOCMD);
2988}
2989
2990static int pci230_ao_cancel(struct comedi_device *dev,
2991			    struct comedi_subdevice *s)
2992{
2993	pci230_ao_stop(dev, s);
2994	return 0;
2995}
2996
2997static void pci230_ai_stop(struct comedi_device *dev,
2998			   struct comedi_subdevice *s)
2999{
3000	unsigned long irqflags;
3001	struct comedi_cmd *cmd;
3002	int started;
3003
3004	spin_lock_irqsave(&devpriv->ai_stop_spinlock, irqflags);
3005	started = test_and_clear_bit(AI_CMD_STARTED, &devpriv->state);
3006	spin_unlock_irqrestore(&devpriv->ai_stop_spinlock, irqflags);
3007	if (!started)
3008		return;
3009
3010
3011	cmd = &s->async->cmd;
3012	if (cmd->convert_src == TRIG_TIMER) {
3013		/* Stop conversion rate generator. */
3014		pci230_cancel_ct(dev, 2);
3015	}
3016	if (cmd->scan_begin_src != TRIG_FOLLOW) {
3017		/* Stop scan period monostable. */
3018		pci230_cancel_ct(dev, 0);
3019	}
3020
3021	spin_lock_irqsave(&devpriv->isr_spinlock, irqflags);
3022	/* Disable ADC interrupt and wait for interrupt routine to finish
3023	 * running unless we are called from the interrupt routine. */
3024	devpriv->int_en &= ~PCI230_INT_ADC;
3025	while (devpriv->intr_running && devpriv->intr_cpuid != THISCPU) {
3026		spin_unlock_irqrestore(&devpriv->isr_spinlock, irqflags);
3027		spin_lock_irqsave(&devpriv->isr_spinlock, irqflags);
3028	}
3029	if (devpriv->ier != devpriv->int_en) {
3030		devpriv->ier = devpriv->int_en;
3031		outb(devpriv->ier, devpriv->iobase1 + PCI230_INT_SCE);
3032	}
3033	spin_unlock_irqrestore(&devpriv->isr_spinlock, irqflags);
3034
3035	/* Reset FIFO, disable FIFO and set start conversion source to none.
3036	 * Keep se/diff and bip/uni settings */
3037	devpriv->adccon = (devpriv->adccon & (PCI230_ADC_IR_MASK
3038					      | PCI230_ADC_IM_MASK)) |
3039	    PCI230_ADC_TRIG_NONE;
3040	outw(devpriv->adccon | PCI230_ADC_FIFO_RESET,
3041	     dev->iobase + PCI230_ADCCON);
3042
3043	/* Release resources. */
3044	put_all_resources(dev, OWNER_AICMD);
3045}
3046
3047static int pci230_ai_cancel(struct comedi_device *dev,
3048			    struct comedi_subdevice *s)
3049{
3050	pci230_ai_stop(dev, s);
3051	return 0;
3052}
3053
3054MODULE_AUTHOR("Comedi http://www.comedi.org");
3055MODULE_DESCRIPTION("Comedi low-level driver");
3056MODULE_LICENSE("GPL");
3057