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