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