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