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