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