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