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