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