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