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