Merge tag 'iommu-updates-v3.8' of git://git.kernel.org/pub/scm/linux/kernel/git/joro...
[cascardo/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 "comedi_fc.h"
197 #include "8253.h"
198 #include "8255.h"
199
200 /* PCI230 PCI configuration register information */
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         /* Step 1 : check if triggers are trivially valid */
962
963         err |= cfc_check_trigger_src(&cmd->start_src, TRIG_INT);
964
965         tmp = TRIG_TIMER | TRIG_INT;
966         if ((thisboard->min_hwver > 0) && (devpriv->hwver >= 2)) {
967                 /*
968                  * For PCI230+ hardware version 2 onwards, allow external
969                  * trigger from EXTTRIG/EXTCONVCLK input (PCI230+ pin 25).
970                  *
971                  * FIXME: The permitted scan_begin_src values shouldn't depend
972                  * on devpriv->hwver (the detected card's actual hardware
973                  * version).  They should only depend on thisboard->min_hwver
974                  * (the static capabilities of the configured card).  To fix
975                  * it, a new card model, e.g. "pci230+2" would have to be
976                  * defined with min_hwver set to 2.  It doesn't seem worth it
977                  * for this alone.  At the moment, please consider
978                  * scan_begin_src==TRIG_EXT support to be a bonus rather than a
979                  * guarantee!
980                  */
981                 tmp |= TRIG_EXT;
982         }
983         err |= cfc_check_trigger_src(&cmd->scan_begin_src, tmp);
984
985         err |= cfc_check_trigger_src(&cmd->convert_src, TRIG_NOW);
986         err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
987         err |= cfc_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE);
988
989         if (err)
990                 return 1;
991
992         /* Step 2a : make sure trigger sources are unique */
993
994         err |= cfc_check_trigger_is_unique(cmd->scan_begin_src);
995         err |= cfc_check_trigger_is_unique(cmd->stop_src);
996
997         /* Step 2b : and mutually compatible */
998
999         if (err)
1000                 return 2;
1001
1002         /* Step 3: check if arguments are trivially valid */
1003
1004         err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0);
1005
1006 #define MAX_SPEED_AO    8000    /* 8000 ns => 125 kHz */
1007 #define MIN_SPEED_AO    4294967295u     /* 4294967295ns = 4.29s */
1008                         /*- Comedi limit due to unsigned int cmd.  Driver limit
1009                          * = 2^16 (16bit * counter) * 1000000ns (1kHz onboard
1010                          * clock) = 65.536s */
1011
1012         switch (cmd->scan_begin_src) {
1013         case TRIG_TIMER:
1014                 err |= cfc_check_trigger_arg_min(&cmd->scan_begin_arg,
1015                                                  MAX_SPEED_AO);
1016                 err |= cfc_check_trigger_arg_max(&cmd->scan_begin_arg,
1017                                                  MIN_SPEED_AO);
1018                 break;
1019         case TRIG_EXT:
1020                 /* External trigger - for PCI230+ hardware version 2 onwards. */
1021                 /* Trigger number must be 0. */
1022                 if ((cmd->scan_begin_arg & ~CR_FLAGS_MASK) != 0) {
1023                         cmd->scan_begin_arg = COMBINE(cmd->scan_begin_arg, 0,
1024                                                       ~CR_FLAGS_MASK);
1025                         err |= -EINVAL;
1026                 }
1027                 /* The only flags allowed are CR_EDGE and CR_INVERT.  The
1028                  * CR_EDGE flag is ignored. */
1029                 if ((cmd->scan_begin_arg
1030                      & (CR_FLAGS_MASK & ~(CR_EDGE | CR_INVERT))) != 0) {
1031                         cmd->scan_begin_arg = COMBINE(cmd->scan_begin_arg, 0,
1032                                                       CR_FLAGS_MASK &
1033                                                       ~(CR_EDGE | CR_INVERT));
1034                         err |= -EINVAL;
1035                 }
1036                 break;
1037         default:
1038                 err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, 0);
1039                 break;
1040         }
1041
1042         err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len);
1043
1044         if (cmd->stop_src == TRIG_NONE)
1045                 err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0);
1046
1047         if (err)
1048                 return 3;
1049
1050         /* Step 4: fix up any arguments.
1051          * "argument conflict" returned by comedilib to user mode process
1052          * if this fails. */
1053
1054         if (cmd->scan_begin_src == TRIG_TIMER) {
1055                 tmp = cmd->scan_begin_arg;
1056                 pci230_ns_to_single_timer(&cmd->scan_begin_arg,
1057                                           cmd->flags & TRIG_ROUND_MASK);
1058                 if (tmp != cmd->scan_begin_arg)
1059                         err++;
1060         }
1061
1062         if (err)
1063                 return 4;
1064
1065         /* Step 5: check channel list if it exists. */
1066
1067         if (cmd->chanlist && cmd->chanlist_len > 0) {
1068                 enum {
1069                         seq_err = (1 << 0),
1070                         range_err = (1 << 1)
1071                 };
1072                 unsigned int errors;
1073                 unsigned int n;
1074                 unsigned int chan, prev_chan;
1075                 unsigned int range, first_range;
1076
1077                 prev_chan = CR_CHAN(cmd->chanlist[0]);
1078                 first_range = CR_RANGE(cmd->chanlist[0]);
1079                 errors = 0;
1080                 for (n = 1; n < cmd->chanlist_len; n++) {
1081                         chan = CR_CHAN(cmd->chanlist[n]);
1082                         range = CR_RANGE(cmd->chanlist[n]);
1083                         /* Channel numbers must strictly increase. */
1084                         if (chan < prev_chan)
1085                                 errors |= seq_err;
1086
1087                         /* Ranges must be the same. */
1088                         if (range != first_range)
1089                                 errors |= range_err;
1090
1091                         prev_chan = chan;
1092                 }
1093                 if (errors != 0) {
1094                         err++;
1095                         if ((errors & seq_err) != 0) {
1096                                 DPRINTK("comedi%d: amplc_pci230: ao_cmdtest: "
1097                                         "channel numbers must increase\n",
1098                                         dev->minor);
1099                         }
1100                         if ((errors & range_err) != 0) {
1101                                 DPRINTK("comedi%d: amplc_pci230: ao_cmdtest: "
1102                                         "channels must have the same range\n",
1103                                         dev->minor);
1104                         }
1105                 }
1106         }
1107
1108         if (err)
1109                 return 5;
1110
1111         return 0;
1112 }
1113
1114 static void pci230_ao_stop(struct comedi_device *dev,
1115                            struct comedi_subdevice *s)
1116 {
1117         struct pci230_private *devpriv = dev->private;
1118         unsigned long irqflags;
1119         unsigned char intsrc;
1120         int started;
1121         struct comedi_cmd *cmd;
1122
1123         spin_lock_irqsave(&devpriv->ao_stop_spinlock, irqflags);
1124         started = test_and_clear_bit(AO_CMD_STARTED, &devpriv->state);
1125         spin_unlock_irqrestore(&devpriv->ao_stop_spinlock, irqflags);
1126         if (!started)
1127                 return;
1128         cmd = &s->async->cmd;
1129         if (cmd->scan_begin_src == TRIG_TIMER) {
1130                 /* Stop scan rate generator. */
1131                 pci230_cancel_ct(dev, 1);
1132         }
1133         /* Determine interrupt source. */
1134         if (devpriv->hwver < 2) {
1135                 /* Not using DAC FIFO.  Using CT1 interrupt. */
1136                 intsrc = PCI230_INT_ZCLK_CT1;
1137         } else {
1138                 /* Using DAC FIFO interrupt. */
1139                 intsrc = PCI230P2_INT_DAC;
1140         }
1141         /* Disable interrupt and wait for interrupt routine to finish running
1142          * unless we are called from the interrupt routine. */
1143         spin_lock_irqsave(&devpriv->isr_spinlock, irqflags);
1144         devpriv->int_en &= ~intsrc;
1145         while (devpriv->intr_running && devpriv->intr_cpuid != THISCPU) {
1146                 spin_unlock_irqrestore(&devpriv->isr_spinlock, irqflags);
1147                 spin_lock_irqsave(&devpriv->isr_spinlock, irqflags);
1148         }
1149         if (devpriv->ier != devpriv->int_en) {
1150                 devpriv->ier = devpriv->int_en;
1151                 outb(devpriv->ier, devpriv->iobase1 + PCI230_INT_SCE);
1152         }
1153         spin_unlock_irqrestore(&devpriv->isr_spinlock, irqflags);
1154         if (devpriv->hwver >= 2) {
1155                 /* Using DAC FIFO.  Reset FIFO, clear underrun error,
1156                  * disable FIFO. */
1157                 devpriv->daccon &= PCI230_DAC_OR_MASK;
1158                 outw(devpriv->daccon | PCI230P2_DAC_FIFO_RESET
1159                      | PCI230P2_DAC_FIFO_UNDERRUN_CLEAR,
1160                      dev->iobase + PCI230_DACCON);
1161         }
1162         /* Release resources. */
1163         put_all_resources(dev, OWNER_AOCMD);
1164 }
1165
1166 static void pci230_handle_ao_nofifo(struct comedi_device *dev,
1167                                     struct comedi_subdevice *s)
1168 {
1169         struct pci230_private *devpriv = dev->private;
1170         short data;
1171         int i, ret;
1172         struct comedi_async *async = s->async;
1173         struct comedi_cmd *cmd = &async->cmd;
1174
1175         if (!devpriv->ao_continuous && (devpriv->ao_scan_count == 0))
1176                 return;
1177         for (i = 0; i < cmd->chanlist_len; i++) {
1178                 /* Read sample from Comedi's circular buffer. */
1179                 ret = comedi_buf_get(s->async, &data);
1180                 if (ret == 0) {
1181                         s->async->events |= COMEDI_CB_OVERFLOW;
1182                         pci230_ao_stop(dev, s);
1183                         comedi_error(dev, "AO buffer underrun");
1184                         return;
1185                 }
1186                 /* Write value to DAC. */
1187                 pci230_ao_write_nofifo(dev, data, CR_CHAN(cmd->chanlist[i]));
1188         }
1189         async->events |= COMEDI_CB_BLOCK | COMEDI_CB_EOS;
1190         if (!devpriv->ao_continuous) {
1191                 devpriv->ao_scan_count--;
1192                 if (devpriv->ao_scan_count == 0) {
1193                         /* End of acquisition. */
1194                         async->events |= COMEDI_CB_EOA;
1195                         pci230_ao_stop(dev, s);
1196                 }
1197         }
1198 }
1199
1200 /* Loads DAC FIFO (if using it) from buffer. */
1201 /* Returns 0 if AO finished due to completion or error, 1 if still going. */
1202 static int pci230_handle_ao_fifo(struct comedi_device *dev,
1203                                  struct comedi_subdevice *s)
1204 {
1205         struct pci230_private *devpriv = dev->private;
1206         struct comedi_async *async = s->async;
1207         struct comedi_cmd *cmd = &async->cmd;
1208         unsigned int num_scans;
1209         unsigned int room;
1210         unsigned short dacstat;
1211         unsigned int i, n;
1212         unsigned int bytes_per_scan;
1213         unsigned int events = 0;
1214         int running;
1215
1216         /* Get DAC FIFO status. */
1217         dacstat = inw(dev->iobase + PCI230_DACCON);
1218         /* Determine number of scans available in buffer. */
1219         bytes_per_scan = cmd->chanlist_len * sizeof(short);
1220         num_scans = comedi_buf_read_n_available(async) / bytes_per_scan;
1221         if (!devpriv->ao_continuous) {
1222                 /* Fixed number of scans. */
1223                 if (num_scans > devpriv->ao_scan_count)
1224                         num_scans = devpriv->ao_scan_count;
1225                 if (devpriv->ao_scan_count == 0) {
1226                         /* End of acquisition. */
1227                         events |= COMEDI_CB_EOA;
1228                 }
1229         }
1230         if (events == 0) {
1231                 /* Check for FIFO underrun. */
1232                 if ((dacstat & PCI230P2_DAC_FIFO_UNDERRUN_LATCHED) != 0) {
1233                         comedi_error(dev, "AO FIFO underrun");
1234                         events |= COMEDI_CB_OVERFLOW | COMEDI_CB_ERROR;
1235                 }
1236                 /* Check for buffer underrun if FIFO less than half full
1237                  * (otherwise there will be loads of "DAC FIFO not half full"
1238                  * interrupts). */
1239                 if ((num_scans == 0)
1240                     && ((dacstat & PCI230P2_DAC_FIFO_HALF) == 0)) {
1241                         comedi_error(dev, "AO buffer underrun");
1242                         events |= COMEDI_CB_OVERFLOW | COMEDI_CB_ERROR;
1243                 }
1244         }
1245         if (events == 0) {
1246                 /* Determine how much room is in the FIFO (in samples). */
1247                 if ((dacstat & PCI230P2_DAC_FIFO_FULL) != 0)
1248                         room = PCI230P2_DAC_FIFOROOM_FULL;
1249                 else if ((dacstat & PCI230P2_DAC_FIFO_HALF) != 0)
1250                         room = PCI230P2_DAC_FIFOROOM_HALFTOFULL;
1251                 else if ((dacstat & PCI230P2_DAC_FIFO_EMPTY) != 0)
1252                         room = PCI230P2_DAC_FIFOROOM_EMPTY;
1253                 else
1254                         room = PCI230P2_DAC_FIFOROOM_ONETOHALF;
1255                 /* Convert room to number of scans that can be added. */
1256                 room /= cmd->chanlist_len;
1257                 /* Determine number of scans to process. */
1258                 if (num_scans > room)
1259                         num_scans = room;
1260                 /* Process scans. */
1261                 for (n = 0; n < num_scans; n++) {
1262                         for (i = 0; i < cmd->chanlist_len; i++) {
1263                                 short datum;
1264
1265                                 comedi_buf_get(async, &datum);
1266                                 pci230_ao_write_fifo(dev, datum,
1267                                                      CR_CHAN(cmd->chanlist[i]));
1268                         }
1269                 }
1270                 events |= COMEDI_CB_EOS | COMEDI_CB_BLOCK;
1271                 if (!devpriv->ao_continuous) {
1272                         devpriv->ao_scan_count -= num_scans;
1273                         if (devpriv->ao_scan_count == 0) {
1274                                 /* All data for the command has been written
1275                                  * to FIFO.  Set FIFO interrupt trigger level
1276                                  * to 'empty'. */
1277                                 devpriv->daccon = (devpriv->daccon
1278                                                    &
1279                                                    ~PCI230P2_DAC_INT_FIFO_MASK)
1280                                     | PCI230P2_DAC_INT_FIFO_EMPTY;
1281                                 outw(devpriv->daccon,
1282                                      dev->iobase + PCI230_DACCON);
1283                         }
1284                 }
1285                 /* Check if FIFO underrun occurred while writing to FIFO. */
1286                 dacstat = inw(dev->iobase + PCI230_DACCON);
1287                 if ((dacstat & PCI230P2_DAC_FIFO_UNDERRUN_LATCHED) != 0) {
1288                         comedi_error(dev, "AO FIFO underrun");
1289                         events |= COMEDI_CB_OVERFLOW | COMEDI_CB_ERROR;
1290                 }
1291         }
1292         if ((events & (COMEDI_CB_EOA | COMEDI_CB_ERROR | COMEDI_CB_OVERFLOW))
1293             != 0) {
1294                 /* Stopping AO due to completion or error. */
1295                 pci230_ao_stop(dev, s);
1296                 running = 0;
1297         } else {
1298                 running = 1;
1299         }
1300         async->events |= events;
1301         return running;
1302 }
1303
1304 static int pci230_ao_inttrig_scan_begin(struct comedi_device *dev,
1305                                         struct comedi_subdevice *s,
1306                                         unsigned int trig_num)
1307 {
1308         struct pci230_private *devpriv = dev->private;
1309         unsigned long irqflags;
1310
1311         if (trig_num != 0)
1312                 return -EINVAL;
1313
1314         spin_lock_irqsave(&devpriv->ao_stop_spinlock, irqflags);
1315         if (test_bit(AO_CMD_STARTED, &devpriv->state)) {
1316                 /* Perform scan. */
1317                 if (devpriv->hwver < 2) {
1318                         /* Not using DAC FIFO. */
1319                         spin_unlock_irqrestore(&devpriv->ao_stop_spinlock,
1320                                                irqflags);
1321                         pci230_handle_ao_nofifo(dev, s);
1322                         comedi_event(dev, s);
1323                 } else {
1324                         /* Using DAC FIFO. */
1325                         /* Read DACSWTRIG register to trigger conversion. */
1326                         inw(dev->iobase + PCI230P2_DACSWTRIG);
1327                         spin_unlock_irqrestore(&devpriv->ao_stop_spinlock,
1328                                                irqflags);
1329                 }
1330                 /* Delay.  Should driver be responsible for this? */
1331                 /* XXX TODO: See if DAC busy bit can be used. */
1332                 udelay(8);
1333         } else {
1334                 spin_unlock_irqrestore(&devpriv->ao_stop_spinlock, irqflags);
1335         }
1336
1337         return 1;
1338 }
1339
1340 static void pci230_ao_start(struct comedi_device *dev,
1341                             struct comedi_subdevice *s)
1342 {
1343         struct pci230_private *devpriv = dev->private;
1344         struct comedi_async *async = s->async;
1345         struct comedi_cmd *cmd = &async->cmd;
1346         unsigned long irqflags;
1347
1348         set_bit(AO_CMD_STARTED, &devpriv->state);
1349         if (!devpriv->ao_continuous && (devpriv->ao_scan_count == 0)) {
1350                 /* An empty acquisition! */
1351                 async->events |= COMEDI_CB_EOA;
1352                 pci230_ao_stop(dev, s);
1353                 comedi_event(dev, s);
1354         } else {
1355                 if (devpriv->hwver >= 2) {
1356                         /* Using DAC FIFO. */
1357                         unsigned short scantrig;
1358                         int run;
1359
1360                         /* Preload FIFO data. */
1361                         run = pci230_handle_ao_fifo(dev, s);
1362                         comedi_event(dev, s);
1363                         if (!run) {
1364                                 /* Stopped. */
1365                                 return;
1366                         }
1367                         /* Set scan trigger source. */
1368                         switch (cmd->scan_begin_src) {
1369                         case TRIG_TIMER:
1370                                 scantrig = PCI230P2_DAC_TRIG_Z2CT1;
1371                                 break;
1372                         case TRIG_EXT:
1373                                 /* Trigger on EXTTRIG/EXTCONVCLK pin. */
1374                                 if ((cmd->scan_begin_arg & CR_INVERT) == 0) {
1375                                         /* +ve edge */
1376                                         scantrig = PCI230P2_DAC_TRIG_EXTP;
1377                                 } else {
1378                                         /* -ve edge */
1379                                         scantrig = PCI230P2_DAC_TRIG_EXTN;
1380                                 }
1381                                 break;
1382                         case TRIG_INT:
1383                                 scantrig = PCI230P2_DAC_TRIG_SW;
1384                                 break;
1385                         default:
1386                                 /* Shouldn't get here. */
1387                                 scantrig = PCI230P2_DAC_TRIG_NONE;
1388                                 break;
1389                         }
1390                         devpriv->daccon = (devpriv->daccon
1391                                            & ~PCI230P2_DAC_TRIG_MASK) |
1392                             scantrig;
1393                         outw(devpriv->daccon, dev->iobase + PCI230_DACCON);
1394
1395                 }
1396                 switch (cmd->scan_begin_src) {
1397                 case TRIG_TIMER:
1398                         if (devpriv->hwver < 2) {
1399                                 /* Not using DAC FIFO. */
1400                                 /* Enable CT1 timer interrupt. */
1401                                 spin_lock_irqsave(&devpriv->isr_spinlock,
1402                                                   irqflags);
1403                                 devpriv->int_en |= PCI230_INT_ZCLK_CT1;
1404                                 devpriv->ier |= PCI230_INT_ZCLK_CT1;
1405                                 outb(devpriv->ier,
1406                                      devpriv->iobase1 + PCI230_INT_SCE);
1407                                 spin_unlock_irqrestore(&devpriv->isr_spinlock,
1408                                                        irqflags);
1409                         }
1410                         /* Set CT1 gate high to start counting. */
1411                         outb(GAT_CONFIG(1, GAT_VCC),
1412                              devpriv->iobase1 + PCI230_ZGAT_SCE);
1413                         break;
1414                 case TRIG_INT:
1415                         async->inttrig = pci230_ao_inttrig_scan_begin;
1416                         break;
1417                 }
1418                 if (devpriv->hwver >= 2) {
1419                         /* Using DAC FIFO.  Enable DAC FIFO interrupt. */
1420                         spin_lock_irqsave(&devpriv->isr_spinlock, irqflags);
1421                         devpriv->int_en |= PCI230P2_INT_DAC;
1422                         devpriv->ier |= PCI230P2_INT_DAC;
1423                         outb(devpriv->ier, devpriv->iobase1 + PCI230_INT_SCE);
1424                         spin_unlock_irqrestore(&devpriv->isr_spinlock,
1425                                                irqflags);
1426                 }
1427         }
1428 }
1429
1430 static int pci230_ao_inttrig_start(struct comedi_device *dev,
1431                                    struct comedi_subdevice *s,
1432                                    unsigned int trig_num)
1433 {
1434         if (trig_num != 0)
1435                 return -EINVAL;
1436
1437         s->async->inttrig = NULL;
1438         pci230_ao_start(dev, s);
1439
1440         return 1;
1441 }
1442
1443 static int pci230_ao_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
1444 {
1445         struct pci230_private *devpriv = dev->private;
1446         unsigned short daccon;
1447         unsigned int range;
1448
1449         /* Get the command. */
1450         struct comedi_cmd *cmd = &s->async->cmd;
1451
1452         if (cmd->scan_begin_src == TRIG_TIMER) {
1453                 /* Claim Z2-CT1. */
1454                 if (!get_one_resource(dev, RES_Z2CT1, OWNER_AOCMD))
1455                         return -EBUSY;
1456
1457         }
1458
1459         /* Get number of scans required. */
1460         if (cmd->stop_src == TRIG_COUNT) {
1461                 devpriv->ao_scan_count = cmd->stop_arg;
1462                 devpriv->ao_continuous = 0;
1463         } else {
1464                 /* TRIG_NONE, user calls cancel. */
1465                 devpriv->ao_scan_count = 0;
1466                 devpriv->ao_continuous = 1;
1467         }
1468
1469         /* Set range - see analogue output range table; 0 => unipolar 10V,
1470          * 1 => bipolar +/-10V range scale */
1471         range = CR_RANGE(cmd->chanlist[0]);
1472         devpriv->ao_bipolar = pci230_ao_bipolar[range];
1473         daccon = devpriv->ao_bipolar ? PCI230_DAC_OR_BIP : PCI230_DAC_OR_UNI;
1474         /* Use DAC FIFO for hardware version 2 onwards. */
1475         if (devpriv->hwver >= 2) {
1476                 unsigned short dacen;
1477                 unsigned int i;
1478
1479                 dacen = 0;
1480                 for (i = 0; i < cmd->chanlist_len; i++)
1481                         dacen |= 1 << CR_CHAN(cmd->chanlist[i]);
1482
1483                 /* Set channel scan list. */
1484                 outw(dacen, dev->iobase + PCI230P2_DACEN);
1485                 /*
1486                  * Enable DAC FIFO.
1487                  * Set DAC scan source to 'none'.
1488                  * Set DAC FIFO interrupt trigger level to 'not half full'.
1489                  * Reset DAC FIFO and clear underrun.
1490                  *
1491                  * N.B. DAC FIFO interrupts are currently disabled.
1492                  */
1493                 daccon |= PCI230P2_DAC_FIFO_EN | PCI230P2_DAC_FIFO_RESET
1494                     | PCI230P2_DAC_FIFO_UNDERRUN_CLEAR
1495                     | PCI230P2_DAC_TRIG_NONE | PCI230P2_DAC_INT_FIFO_NHALF;
1496         }
1497
1498         /* Set DACCON. */
1499         outw(daccon, dev->iobase + PCI230_DACCON);
1500         /* Preserve most of DACCON apart from write-only, transient bits. */
1501         devpriv->daccon = daccon
1502             & ~(PCI230P2_DAC_FIFO_RESET | PCI230P2_DAC_FIFO_UNDERRUN_CLEAR);
1503
1504         if (cmd->scan_begin_src == TRIG_TIMER) {
1505                 /* Set the counter timer 1 to the specified scan frequency. */
1506                 /* cmd->scan_begin_arg is sampling period in ns */
1507                 /* gate it off for now. */
1508                 outb(GAT_CONFIG(1, GAT_GND),
1509                      devpriv->iobase1 + PCI230_ZGAT_SCE);
1510                 pci230_ct_setup_ns_mode(dev, 1, I8254_MODE3,
1511                                         cmd->scan_begin_arg,
1512                                         cmd->flags & TRIG_ROUND_MASK);
1513         }
1514
1515         /* N.B. cmd->start_src == TRIG_INT */
1516         s->async->inttrig = pci230_ao_inttrig_start;
1517
1518         return 0;
1519 }
1520
1521 static int pci230_ao_cancel(struct comedi_device *dev,
1522                             struct comedi_subdevice *s)
1523 {
1524         pci230_ao_stop(dev, s);
1525         return 0;
1526 }
1527
1528 static int pci230_ai_check_scan_period(struct comedi_cmd *cmd)
1529 {
1530         unsigned int min_scan_period, chanlist_len;
1531         int err = 0;
1532
1533         chanlist_len = cmd->chanlist_len;
1534         if (cmd->chanlist_len == 0)
1535                 chanlist_len = 1;
1536
1537         min_scan_period = chanlist_len * cmd->convert_arg;
1538         if ((min_scan_period < chanlist_len)
1539             || (min_scan_period < cmd->convert_arg)) {
1540                 /* Arithmetic overflow. */
1541                 min_scan_period = UINT_MAX;
1542                 err++;
1543         }
1544         if (cmd->scan_begin_arg < min_scan_period) {
1545                 cmd->scan_begin_arg = min_scan_period;
1546                 err++;
1547         }
1548
1549         return !err;
1550 }
1551
1552 static int pci230_ai_cmdtest(struct comedi_device *dev,
1553                              struct comedi_subdevice *s, struct comedi_cmd *cmd)
1554 {
1555         const struct pci230_board *thisboard = comedi_board(dev);
1556         struct pci230_private *devpriv = dev->private;
1557         int err = 0;
1558         unsigned int tmp;
1559
1560         /* Step 1 : check if triggers are trivially valid */
1561
1562         err |= cfc_check_trigger_src(&cmd->start_src, TRIG_NOW | TRIG_INT);
1563
1564         tmp = TRIG_FOLLOW | TRIG_TIMER | TRIG_INT;
1565         if ((thisboard->have_dio) || (thisboard->min_hwver > 0)) {
1566                 /*
1567                  * Unfortunately, we cannot trigger a scan off an external
1568                  * source on the PCI260 board, since it uses the PPIC0 (DIO)
1569                  * input, which isn't present on the PCI260.  For PCI260+
1570                  * we can use the EXTTRIG/EXTCONVCLK input on pin 17 instead.
1571                  */
1572                 tmp |= TRIG_EXT;
1573         }
1574         err |= cfc_check_trigger_src(&cmd->scan_begin_src, tmp);
1575         err |= cfc_check_trigger_src(&cmd->convert_src,
1576                                         TRIG_TIMER | TRIG_INT | TRIG_EXT);
1577         err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
1578         err |= cfc_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE);
1579
1580         if (err)
1581                 return 1;
1582
1583         /* Step 2a : make sure trigger sources are unique */
1584
1585         err |= cfc_check_trigger_is_unique(cmd->start_src);
1586         err |= cfc_check_trigger_is_unique(cmd->scan_begin_src);
1587         err |= cfc_check_trigger_is_unique(cmd->convert_src);
1588         err |= cfc_check_trigger_is_unique(cmd->stop_src);
1589
1590         /* Step 2b : and mutually compatible */
1591
1592         /*
1593          * If scan_begin_src is not TRIG_FOLLOW, then a monostable will be
1594          * set up to generate a fixed number of timed conversion pulses.
1595          */
1596         if ((cmd->scan_begin_src != TRIG_FOLLOW)
1597             && (cmd->convert_src != TRIG_TIMER))
1598                 err |= -EINVAL;
1599
1600         if (err)
1601                 return 2;
1602
1603         /* Step 3: check if arguments are trivially valid */
1604
1605         err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0);
1606
1607 #define MAX_SPEED_AI_SE         3200    /* PCI230 SE:   3200 ns => 312.5 kHz */
1608 #define MAX_SPEED_AI_DIFF       8000    /* PCI230 DIFF: 8000 ns => 125 kHz */
1609 #define MAX_SPEED_AI_PLUS       4000    /* PCI230+:     4000 ns => 250 kHz */
1610 #define MIN_SPEED_AI    4294967295u     /* 4294967295ns = 4.29s */
1611                         /*- Comedi limit due to unsigned int cmd.  Driver limit
1612                          * = 2^16 (16bit * counter) * 1000000ns (1kHz onboard
1613                          * clock) = 65.536s */
1614
1615         if (cmd->convert_src == TRIG_TIMER) {
1616                 unsigned int max_speed_ai;
1617
1618                 if (devpriv->hwver == 0) {
1619                         /* PCI230 or PCI260.  Max speed depends whether
1620                          * single-ended or pseudo-differential. */
1621                         if (cmd->chanlist && (cmd->chanlist_len > 0)) {
1622                                 /* Peek analogue reference of first channel. */
1623                                 if (CR_AREF(cmd->chanlist[0]) == AREF_DIFF)
1624                                         max_speed_ai = MAX_SPEED_AI_DIFF;
1625                                 else
1626                                         max_speed_ai = MAX_SPEED_AI_SE;
1627
1628                         } else {
1629                                 /* No channel list.  Assume single-ended. */
1630                                 max_speed_ai = MAX_SPEED_AI_SE;
1631                         }
1632                 } else {
1633                         /* PCI230+ or PCI260+. */
1634                         max_speed_ai = MAX_SPEED_AI_PLUS;
1635                 }
1636
1637                 err |= cfc_check_trigger_arg_min(&cmd->convert_arg,
1638                                                  max_speed_ai);
1639                 err |= cfc_check_trigger_arg_max(&cmd->convert_arg,
1640                                                  MIN_SPEED_AI);
1641         } else if (cmd->convert_src == TRIG_EXT) {
1642                 /*
1643                  * external trigger
1644                  *
1645                  * convert_arg == (CR_EDGE | 0)
1646                  *                => trigger on +ve edge.
1647                  * convert_arg == (CR_EDGE | CR_INVERT | 0)
1648                  *                => trigger on -ve edge.
1649                  */
1650                 if ((cmd->convert_arg & CR_FLAGS_MASK) != 0) {
1651                         /* Trigger number must be 0. */
1652                         if ((cmd->convert_arg & ~CR_FLAGS_MASK) != 0) {
1653                                 cmd->convert_arg = COMBINE(cmd->convert_arg, 0,
1654                                                            ~CR_FLAGS_MASK);
1655                                 err |= -EINVAL;
1656                         }
1657                         /* The only flags allowed are CR_INVERT and CR_EDGE.
1658                          * CR_EDGE is required. */
1659                         if ((cmd->convert_arg & (CR_FLAGS_MASK & ~CR_INVERT))
1660                             != CR_EDGE) {
1661                                 /* Set CR_EDGE, preserve CR_INVERT. */
1662                                 cmd->convert_arg = COMBINE(cmd->start_arg,
1663                                                            (CR_EDGE | 0),
1664                                                            CR_FLAGS_MASK &
1665                                                            ~CR_INVERT);
1666                                 err |= -EINVAL;
1667                         }
1668                 } else {
1669                         /* Backwards compatibility with previous versions. */
1670                         /* convert_arg == 0 => trigger on -ve edge. */
1671                         /* convert_arg == 1 => trigger on +ve edge. */
1672                         err |= cfc_check_trigger_arg_max(&cmd->convert_arg, 1);
1673                 }
1674         } else {
1675                 err |= cfc_check_trigger_arg_is(&cmd->convert_arg, 0);
1676         }
1677
1678         err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len);
1679
1680         if (cmd->stop_src == TRIG_NONE)
1681                 err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0);
1682
1683         if (cmd->scan_begin_src == TRIG_EXT) {
1684                 /* external "trigger" to begin each scan
1685                  * scan_begin_arg==0 => use PPC0 input -> gate of CT0 -> gate
1686                  * of CT2 (sample convert trigger is CT2) */
1687                 if ((cmd->scan_begin_arg & ~CR_FLAGS_MASK) != 0) {
1688                         cmd->scan_begin_arg = COMBINE(cmd->scan_begin_arg, 0,
1689                                                       ~CR_FLAGS_MASK);
1690                         err |= -EINVAL;
1691                 }
1692                 /* The only flag allowed is CR_EDGE, which is ignored. */
1693                 if ((cmd->scan_begin_arg & CR_FLAGS_MASK & ~CR_EDGE) != 0) {
1694                         cmd->scan_begin_arg = COMBINE(cmd->scan_begin_arg, 0,
1695                                                       CR_FLAGS_MASK & ~CR_EDGE);
1696                         err |= -EINVAL;
1697                 }
1698         } else if (cmd->scan_begin_src == TRIG_TIMER) {
1699                 /* N.B. cmd->convert_arg is also TRIG_TIMER */
1700                 if (!pci230_ai_check_scan_period(cmd))
1701                         err |= -EINVAL;
1702
1703         } else {
1704                 err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, 0);
1705         }
1706
1707         if (err)
1708                 return 3;
1709
1710         /* Step 4: fix up any arguments.
1711          * "argument conflict" returned by comedilib to user mode process
1712          * if this fails. */
1713
1714         if (cmd->convert_src == TRIG_TIMER) {
1715                 tmp = cmd->convert_arg;
1716                 pci230_ns_to_single_timer(&cmd->convert_arg,
1717                                           cmd->flags & TRIG_ROUND_MASK);
1718                 if (tmp != cmd->convert_arg)
1719                         err++;
1720         }
1721
1722         if (cmd->scan_begin_src == TRIG_TIMER) {
1723                 /* N.B. cmd->convert_arg is also TRIG_TIMER */
1724                 tmp = cmd->scan_begin_arg;
1725                 pci230_ns_to_single_timer(&cmd->scan_begin_arg,
1726                                           cmd->flags & TRIG_ROUND_MASK);
1727                 if (!pci230_ai_check_scan_period(cmd)) {
1728                         /* Was below minimum required.  Round up. */
1729                         pci230_ns_to_single_timer(&cmd->scan_begin_arg,
1730                                                   TRIG_ROUND_UP);
1731                         pci230_ai_check_scan_period(cmd);
1732                 }
1733                 if (tmp != cmd->scan_begin_arg)
1734                         err++;
1735         }
1736
1737         if (err)
1738                 return 4;
1739
1740         /* Step 5: check channel list if it exists. */
1741
1742         if (cmd->chanlist && cmd->chanlist_len > 0) {
1743                 enum {
1744                         seq_err = 1 << 0,
1745                         rangepair_err = 1 << 1,
1746                         polarity_err = 1 << 2,
1747                         aref_err = 1 << 3,
1748                         diffchan_err = 1 << 4,
1749                         buggy_chan0_err = 1 << 5
1750                 };
1751                 unsigned int errors;
1752                 unsigned int chan, prev_chan;
1753                 unsigned int range, prev_range;
1754                 unsigned int polarity, prev_polarity;
1755                 unsigned int aref, prev_aref;
1756                 unsigned int subseq_len;
1757                 unsigned int n;
1758
1759                 subseq_len = 0;
1760                 errors = 0;
1761                 prev_chan = prev_aref = prev_range = prev_polarity = 0;
1762                 for (n = 0; n < cmd->chanlist_len; n++) {
1763                         chan = CR_CHAN(cmd->chanlist[n]);
1764                         range = CR_RANGE(cmd->chanlist[n]);
1765                         aref = CR_AREF(cmd->chanlist[n]);
1766                         polarity = pci230_ai_bipolar[range];
1767                         /* Only the first half of the channels are available if
1768                          * differential.  (These are remapped in software.  In
1769                          * hardware, only the even channels are available.) */
1770                         if ((aref == AREF_DIFF)
1771                             && (chan >= (s->n_chan / 2))) {
1772                                 errors |= diffchan_err;
1773                         }
1774                         if (n > 0) {
1775                                 /* Channel numbers must strictly increase or
1776                                  * subsequence must repeat exactly. */
1777                                 if ((chan <= prev_chan)
1778                                     && (subseq_len == 0)) {
1779                                         subseq_len = n;
1780                                 }
1781                                 if ((subseq_len > 0)
1782                                     && (cmd->chanlist[n] !=
1783                                         cmd->chanlist[n % subseq_len])) {
1784                                         errors |= seq_err;
1785                                 }
1786                                 /* Channels must have same AREF. */
1787                                 if (aref != prev_aref)
1788                                         errors |= aref_err;
1789
1790                                 /* Channel ranges must have same polarity. */
1791                                 if (polarity != prev_polarity)
1792                                         errors |= polarity_err;
1793
1794                                 /* Single-ended channel pairs must have same
1795                                  * range.  */
1796                                 if ((aref != AREF_DIFF)
1797                                     && (((chan ^ prev_chan) & ~1) == 0)
1798                                     && (range != prev_range)) {
1799                                         errors |= rangepair_err;
1800                                 }
1801                         }
1802                         prev_chan = chan;
1803                         prev_range = range;
1804                         prev_aref = aref;
1805                         prev_polarity = polarity;
1806                 }
1807                 if (subseq_len == 0) {
1808                         /* Subsequence is whole sequence. */
1809                         subseq_len = n;
1810                 }
1811                 /* If channel list is a repeating subsequence, need a whole
1812                  * number of repeats. */
1813                 if ((n % subseq_len) != 0)
1814                         errors |= seq_err;
1815
1816                 if ((devpriv->hwver > 0) && (devpriv->hwver < 4)) {
1817                         /*
1818                          * Buggy PCI230+ or PCI260+ requires channel 0 to be
1819                          * (first) in the sequence if the sequence contains
1820                          * more than one channel.  Hardware versions 1 and 2
1821                          * have the bug.  There is no hardware version 3.
1822                          *
1823                          * Actually, there are two firmwares that report
1824                          * themselves as hardware version 1 (the boards
1825                          * have different ADC chips with slightly different
1826                          * timing requirements, which was supposed to be
1827                          * invisible to software).  The first one doesn't
1828                          * seem to have the bug, but the second one
1829                          * does, and we can't tell them apart!
1830                          */
1831                         if ((subseq_len > 1)
1832                             && (CR_CHAN(cmd->chanlist[0]) != 0)) {
1833                                 errors |= buggy_chan0_err;
1834                         }
1835                 }
1836                 if (errors != 0) {
1837                         err++;
1838                         if ((errors & seq_err) != 0) {
1839                                 DPRINTK("comedi%d: amplc_pci230: ai_cmdtest: "
1840                                         "channel numbers must increase or "
1841                                         "sequence must repeat exactly\n",
1842                                         dev->minor);
1843                         }
1844                         if ((errors & rangepair_err) != 0) {
1845                                 DPRINTK("comedi%d: amplc_pci230: ai_cmdtest: "
1846                                         "single-ended channel pairs must "
1847                                         "have the same range\n", dev->minor);
1848                         }
1849                         if ((errors & polarity_err) != 0) {
1850                                 DPRINTK("comedi%d: amplc_pci230: ai_cmdtest: "
1851                                         "channel sequence ranges must be all "
1852                                         "bipolar or all unipolar\n",
1853                                         dev->minor);
1854                         }
1855                         if ((errors & aref_err) != 0) {
1856                                 DPRINTK("comedi%d: amplc_pci230: ai_cmdtest: "
1857                                         "channel sequence analogue references "
1858                                         "must be all the same (single-ended "
1859                                         "or differential)\n", dev->minor);
1860                         }
1861                         if ((errors & diffchan_err) != 0) {
1862                                 DPRINTK("comedi%d: amplc_pci230: ai_cmdtest: "
1863                                         "differential channel number out of "
1864                                         "range 0 to %u\n", dev->minor,
1865                                         (s->n_chan / 2) - 1);
1866                         }
1867                         if ((errors & buggy_chan0_err) != 0) {
1868                                 dev_info(dev->class_dev,
1869                                          "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",
1870                                          devpriv->hwver);
1871                         }
1872                 }
1873         }
1874
1875         if (err)
1876                 return 5;
1877
1878         return 0;
1879 }
1880
1881 static void pci230_ai_update_fifo_trigger_level(struct comedi_device *dev,
1882                                                 struct comedi_subdevice *s)
1883 {
1884         struct pci230_private *devpriv = dev->private;
1885         struct comedi_cmd *cmd = &s->async->cmd;
1886         unsigned int scanlen = cmd->scan_end_arg;
1887         unsigned int wake;
1888         unsigned short triglev;
1889         unsigned short adccon;
1890
1891         if ((cmd->flags & TRIG_WAKE_EOS) != 0) {
1892                 /* Wake at end of scan. */
1893                 wake = scanlen - devpriv->ai_scan_pos;
1894         } else {
1895                 if (devpriv->ai_continuous
1896                     || (devpriv->ai_scan_count >= PCI230_ADC_FIFOLEVEL_HALFFULL)
1897                     || (scanlen >= PCI230_ADC_FIFOLEVEL_HALFFULL)) {
1898                         wake = PCI230_ADC_FIFOLEVEL_HALFFULL;
1899                 } else {
1900                         wake = (devpriv->ai_scan_count * scanlen)
1901                             - devpriv->ai_scan_pos;
1902                 }
1903         }
1904         if (wake >= PCI230_ADC_FIFOLEVEL_HALFFULL) {
1905                 triglev = PCI230_ADC_INT_FIFO_HALF;
1906         } else {
1907                 if ((wake > 1) && (devpriv->hwver > 0)) {
1908                         /* PCI230+/260+ programmable FIFO interrupt level. */
1909                         if (devpriv->adcfifothresh != wake) {
1910                                 devpriv->adcfifothresh = wake;
1911                                 outw(wake, dev->iobase + PCI230P_ADCFFTH);
1912                         }
1913                         triglev = PCI230P_ADC_INT_FIFO_THRESH;
1914                 } else {
1915                         triglev = PCI230_ADC_INT_FIFO_NEMPTY;
1916                 }
1917         }
1918         adccon = (devpriv->adccon & ~PCI230_ADC_INT_FIFO_MASK) | triglev;
1919         if (adccon != devpriv->adccon) {
1920                 devpriv->adccon = adccon;
1921                 outw(adccon, dev->iobase + PCI230_ADCCON);
1922         }
1923 }
1924
1925 static int pci230_ai_inttrig_convert(struct comedi_device *dev,
1926                                      struct comedi_subdevice *s,
1927                                      unsigned int trig_num)
1928 {
1929         struct pci230_private *devpriv = dev->private;
1930         unsigned long irqflags;
1931
1932         if (trig_num != 0)
1933                 return -EINVAL;
1934
1935         spin_lock_irqsave(&devpriv->ai_stop_spinlock, irqflags);
1936         if (test_bit(AI_CMD_STARTED, &devpriv->state)) {
1937                 unsigned int delayus;
1938
1939                 /* Trigger conversion by toggling Z2-CT2 output.  Finish
1940                  * with output high. */
1941                 i8254_set_mode(devpriv->iobase1 + PCI230_Z2_CT_BASE, 0, 2,
1942                                I8254_MODE0);
1943                 i8254_set_mode(devpriv->iobase1 + PCI230_Z2_CT_BASE, 0, 2,
1944                                I8254_MODE1);
1945                 /* Delay.  Should driver be responsible for this?  An
1946                  * alternative would be to wait until conversion is complete,
1947                  * but we can't tell when it's complete because the ADC busy
1948                  * bit has a different meaning when FIFO enabled (and when
1949                  * FIFO not enabled, it only works for software triggers). */
1950                 if (((devpriv->adccon & PCI230_ADC_IM_MASK)
1951                      == PCI230_ADC_IM_DIF)
1952                     && (devpriv->hwver == 0)) {
1953                         /* PCI230/260 in differential mode */
1954                         delayus = 8;
1955                 } else {
1956                         /* single-ended or PCI230+/260+ */
1957                         delayus = 4;
1958                 }
1959                 spin_unlock_irqrestore(&devpriv->ai_stop_spinlock, irqflags);
1960                 udelay(delayus);
1961         } else {
1962                 spin_unlock_irqrestore(&devpriv->ai_stop_spinlock, irqflags);
1963         }
1964
1965         return 1;
1966 }
1967
1968 static int pci230_ai_inttrig_scan_begin(struct comedi_device *dev,
1969                                         struct comedi_subdevice *s,
1970                                         unsigned int trig_num)
1971 {
1972         struct pci230_private *devpriv = dev->private;
1973         unsigned long irqflags;
1974         unsigned char zgat;
1975
1976         if (trig_num != 0)
1977                 return -EINVAL;
1978
1979         spin_lock_irqsave(&devpriv->ai_stop_spinlock, irqflags);
1980         if (test_bit(AI_CMD_STARTED, &devpriv->state)) {
1981                 /* Trigger scan by waggling CT0 gate source. */
1982                 zgat = GAT_CONFIG(0, GAT_GND);
1983                 outb(zgat, devpriv->iobase1 + PCI230_ZGAT_SCE);
1984                 zgat = GAT_CONFIG(0, GAT_VCC);
1985                 outb(zgat, devpriv->iobase1 + PCI230_ZGAT_SCE);
1986         }
1987         spin_unlock_irqrestore(&devpriv->ai_stop_spinlock, irqflags);
1988
1989         return 1;
1990 }
1991
1992 static void pci230_ai_stop(struct comedi_device *dev,
1993                            struct comedi_subdevice *s)
1994 {
1995         struct pci230_private *devpriv = dev->private;
1996         unsigned long irqflags;
1997         struct comedi_cmd *cmd;
1998         int started;
1999
2000         spin_lock_irqsave(&devpriv->ai_stop_spinlock, irqflags);
2001         started = test_and_clear_bit(AI_CMD_STARTED, &devpriv->state);
2002         spin_unlock_irqrestore(&devpriv->ai_stop_spinlock, irqflags);
2003         if (!started)
2004                 return;
2005         cmd = &s->async->cmd;
2006         if (cmd->convert_src == TRIG_TIMER) {
2007                 /* Stop conversion rate generator. */
2008                 pci230_cancel_ct(dev, 2);
2009         }
2010         if (cmd->scan_begin_src != TRIG_FOLLOW) {
2011                 /* Stop scan period monostable. */
2012                 pci230_cancel_ct(dev, 0);
2013         }
2014         spin_lock_irqsave(&devpriv->isr_spinlock, irqflags);
2015         /* Disable ADC interrupt and wait for interrupt routine to finish
2016          * running unless we are called from the interrupt routine. */
2017         devpriv->int_en &= ~PCI230_INT_ADC;
2018         while (devpriv->intr_running && devpriv->intr_cpuid != THISCPU) {
2019                 spin_unlock_irqrestore(&devpriv->isr_spinlock, irqflags);
2020                 spin_lock_irqsave(&devpriv->isr_spinlock, irqflags);
2021         }
2022         if (devpriv->ier != devpriv->int_en) {
2023                 devpriv->ier = devpriv->int_en;
2024                 outb(devpriv->ier, devpriv->iobase1 + PCI230_INT_SCE);
2025         }
2026         spin_unlock_irqrestore(&devpriv->isr_spinlock, irqflags);
2027         /* Reset FIFO, disable FIFO and set start conversion source to none.
2028          * Keep se/diff and bip/uni settings */
2029         devpriv->adccon = (devpriv->adccon & (PCI230_ADC_IR_MASK
2030                                               | PCI230_ADC_IM_MASK)) |
2031             PCI230_ADC_TRIG_NONE;
2032         outw(devpriv->adccon | PCI230_ADC_FIFO_RESET,
2033              dev->iobase + PCI230_ADCCON);
2034         /* Release resources. */
2035         put_all_resources(dev, OWNER_AICMD);
2036 }
2037
2038 static void pci230_ai_start(struct comedi_device *dev,
2039                             struct comedi_subdevice *s)
2040 {
2041         struct pci230_private *devpriv = dev->private;
2042         unsigned long irqflags;
2043         unsigned short conv;
2044         struct comedi_async *async = s->async;
2045         struct comedi_cmd *cmd = &async->cmd;
2046
2047         set_bit(AI_CMD_STARTED, &devpriv->state);
2048         if (!devpriv->ai_continuous && (devpriv->ai_scan_count == 0)) {
2049                 /* An empty acquisition! */
2050                 async->events |= COMEDI_CB_EOA;
2051                 pci230_ai_stop(dev, s);
2052                 comedi_event(dev, s);
2053         } else {
2054                 /* Enable ADC FIFO trigger level interrupt. */
2055                 spin_lock_irqsave(&devpriv->isr_spinlock, irqflags);
2056                 devpriv->int_en |= PCI230_INT_ADC;
2057                 devpriv->ier |= PCI230_INT_ADC;
2058                 outb(devpriv->ier, devpriv->iobase1 + PCI230_INT_SCE);
2059                 spin_unlock_irqrestore(&devpriv->isr_spinlock, irqflags);
2060
2061                 /* Update conversion trigger source which is currently set
2062                  * to CT2 output, which is currently stuck high. */
2063                 switch (cmd->convert_src) {
2064                 default:
2065                         conv = PCI230_ADC_TRIG_NONE;
2066                         break;
2067                 case TRIG_TIMER:
2068                         /* Using CT2 output. */
2069                         conv = PCI230_ADC_TRIG_Z2CT2;
2070                         break;
2071                 case TRIG_EXT:
2072                         if ((cmd->convert_arg & CR_EDGE) != 0) {
2073                                 if ((cmd->convert_arg & CR_INVERT) == 0) {
2074                                         /* Trigger on +ve edge. */
2075                                         conv = PCI230_ADC_TRIG_EXTP;
2076                                 } else {
2077                                         /* Trigger on -ve edge. */
2078                                         conv = PCI230_ADC_TRIG_EXTN;
2079                                 }
2080                         } else {
2081                                 /* Backwards compatibility. */
2082                                 if (cmd->convert_arg != 0) {
2083                                         /* Trigger on +ve edge. */
2084                                         conv = PCI230_ADC_TRIG_EXTP;
2085                                 } else {
2086                                         /* Trigger on -ve edge. */
2087                                         conv = PCI230_ADC_TRIG_EXTN;
2088                                 }
2089                         }
2090                         break;
2091                 case TRIG_INT:
2092                         /* Use CT2 output for software trigger due to problems
2093                          * in differential mode on PCI230/260. */
2094                         conv = PCI230_ADC_TRIG_Z2CT2;
2095                         break;
2096                 }
2097                 devpriv->adccon = (devpriv->adccon & ~PCI230_ADC_TRIG_MASK)
2098                     | conv;
2099                 outw(devpriv->adccon, dev->iobase + PCI230_ADCCON);
2100                 if (cmd->convert_src == TRIG_INT)
2101                         async->inttrig = pci230_ai_inttrig_convert;
2102
2103                 /* Update FIFO interrupt trigger level, which is currently
2104                  * set to "full".  */
2105                 pci230_ai_update_fifo_trigger_level(dev, s);
2106                 if (cmd->convert_src == TRIG_TIMER) {
2107                         /* Update timer gates. */
2108                         unsigned char zgat;
2109
2110                         if (cmd->scan_begin_src != TRIG_FOLLOW) {
2111                                 /* Conversion timer CT2 needs to be gated by
2112                                  * inverted output of monostable CT2. */
2113                                 zgat = GAT_CONFIG(2, GAT_NOUTNM2);
2114                         } else {
2115                                 /* Conversion timer CT2 needs to be gated on
2116                                  * continuously. */
2117                                 zgat = GAT_CONFIG(2, GAT_VCC);
2118                         }
2119                         outb(zgat, devpriv->iobase1 + PCI230_ZGAT_SCE);
2120                         if (cmd->scan_begin_src != TRIG_FOLLOW) {
2121                                 /* Set monostable CT0 trigger source. */
2122                                 switch (cmd->scan_begin_src) {
2123                                 default:
2124                                         zgat = GAT_CONFIG(0, GAT_VCC);
2125                                         break;
2126                                 case TRIG_EXT:
2127                                         /*
2128                                          * For CT0 on PCI230, the external
2129                                          * trigger (gate) signal comes from
2130                                          * PPC0, which is channel 16 of the DIO
2131                                          * subdevice.  The application needs to
2132                                          * configure this as an input in order
2133                                          * to use it as an external scan
2134                                          * trigger.
2135                                          */
2136                                         zgat = GAT_CONFIG(0, GAT_EXT);
2137                                         break;
2138                                 case TRIG_TIMER:
2139                                         /*
2140                                          * Monostable CT0 triggered by rising
2141                                          * edge on inverted output of CT1
2142                                          * (falling edge on CT1).
2143                                          */
2144                                         zgat = GAT_CONFIG(0, GAT_NOUTNM2);
2145                                         break;
2146                                 case TRIG_INT:
2147                                         /*
2148                                          * Monostable CT0 is triggered by
2149                                          * inttrig function waggling the CT0
2150                                          * gate source.
2151                                          */
2152                                         zgat = GAT_CONFIG(0, GAT_VCC);
2153                                         break;
2154                                 }
2155                                 outb(zgat, devpriv->iobase1 + PCI230_ZGAT_SCE);
2156                                 switch (cmd->scan_begin_src) {
2157                                 case TRIG_TIMER:
2158                                         /* Scan period timer CT1 needs to be
2159                                          * gated on to start counting. */
2160                                         zgat = GAT_CONFIG(1, GAT_VCC);
2161                                         outb(zgat, devpriv->iobase1
2162                                              + PCI230_ZGAT_SCE);
2163                                         break;
2164                                 case TRIG_INT:
2165                                         async->inttrig =
2166                                             pci230_ai_inttrig_scan_begin;
2167                                         break;
2168                                 }
2169                         }
2170                 } else if (cmd->convert_src != TRIG_INT) {
2171                         /* No longer need Z2-CT2. */
2172                         put_one_resource(dev, RES_Z2CT2, OWNER_AICMD);
2173                 }
2174         }
2175 }
2176
2177 static int pci230_ai_inttrig_start(struct comedi_device *dev,
2178                                    struct comedi_subdevice *s,
2179                                    unsigned int trig_num)
2180 {
2181         if (trig_num != 0)
2182                 return -EINVAL;
2183
2184         s->async->inttrig = NULL;
2185         pci230_ai_start(dev, s);
2186
2187         return 1;
2188 }
2189
2190 static void pci230_handle_ai(struct comedi_device *dev,
2191                              struct comedi_subdevice *s)
2192 {
2193         struct pci230_private *devpriv = dev->private;
2194         unsigned int events = 0;
2195         unsigned int status_fifo;
2196         unsigned int i;
2197         unsigned int todo;
2198         unsigned int fifoamount;
2199         struct comedi_async *async = s->async;
2200         unsigned int scanlen = async->cmd.scan_end_arg;
2201
2202         /* Determine number of samples to read. */
2203         if (devpriv->ai_continuous) {
2204                 todo = PCI230_ADC_FIFOLEVEL_HALFFULL;
2205         } else if (devpriv->ai_scan_count == 0) {
2206                 todo = 0;
2207         } else if ((devpriv->ai_scan_count > PCI230_ADC_FIFOLEVEL_HALFFULL)
2208                    || (scanlen > PCI230_ADC_FIFOLEVEL_HALFFULL)) {
2209                 todo = PCI230_ADC_FIFOLEVEL_HALFFULL;
2210         } else {
2211                 todo = (devpriv->ai_scan_count * scanlen)
2212                     - devpriv->ai_scan_pos;
2213                 if (todo > PCI230_ADC_FIFOLEVEL_HALFFULL)
2214                         todo = PCI230_ADC_FIFOLEVEL_HALFFULL;
2215         }
2216         if (todo == 0)
2217                 return;
2218         fifoamount = 0;
2219         for (i = 0; i < todo; i++) {
2220                 if (fifoamount == 0) {
2221                         /* Read FIFO state. */
2222                         status_fifo = inw(dev->iobase + PCI230_ADCCON);
2223                         if ((status_fifo & PCI230_ADC_FIFO_FULL_LATCHED) != 0) {
2224                                 /* Report error otherwise FIFO overruns will go
2225                                  * unnoticed by the caller. */
2226                                 comedi_error(dev, "AI FIFO overrun");
2227                                 events |= COMEDI_CB_OVERFLOW | COMEDI_CB_ERROR;
2228                                 break;
2229                         } else if ((status_fifo & PCI230_ADC_FIFO_EMPTY) != 0) {
2230                                 /* FIFO empty. */
2231                                 break;
2232                         } else if ((status_fifo & PCI230_ADC_FIFO_HALF) != 0) {
2233                                 /* FIFO half full. */
2234                                 fifoamount = PCI230_ADC_FIFOLEVEL_HALFFULL;
2235                         } else {
2236                                 /* FIFO not empty. */
2237                                 if (devpriv->hwver > 0) {
2238                                         /* Read PCI230+/260+ ADC FIFO level. */
2239                                         fifoamount = inw(dev->iobase
2240                                                          + PCI230P_ADCFFLEV);
2241                                         if (fifoamount == 0) {
2242                                                 /* Shouldn't happen. */
2243                                                 break;
2244                                         }
2245                                 } else {
2246                                         fifoamount = 1;
2247                                 }
2248                         }
2249                 }
2250                 /* Read sample and store in Comedi's circular buffer. */
2251                 if (comedi_buf_put(async, pci230_ai_read(dev)) == 0) {
2252                         events |= COMEDI_CB_ERROR | COMEDI_CB_OVERFLOW;
2253                         comedi_error(dev, "AI buffer overflow");
2254                         break;
2255                 }
2256                 fifoamount--;
2257                 devpriv->ai_scan_pos++;
2258                 if (devpriv->ai_scan_pos == scanlen) {
2259                         /* End of scan. */
2260                         devpriv->ai_scan_pos = 0;
2261                         devpriv->ai_scan_count--;
2262                         async->events |= COMEDI_CB_EOS;
2263                 }
2264         }
2265         if (!devpriv->ai_continuous && (devpriv->ai_scan_count == 0)) {
2266                 /* End of acquisition. */
2267                 events |= COMEDI_CB_EOA;
2268         } else {
2269                 /* More samples required, tell Comedi to block. */
2270                 events |= COMEDI_CB_BLOCK;
2271         }
2272         async->events |= events;
2273         if ((async->events & (COMEDI_CB_EOA | COMEDI_CB_ERROR |
2274                               COMEDI_CB_OVERFLOW)) != 0) {
2275                 /* disable hardware conversions */
2276                 pci230_ai_stop(dev, s);
2277         } else {
2278                 /* update FIFO interrupt trigger level */
2279                 pci230_ai_update_fifo_trigger_level(dev, s);
2280         }
2281 }
2282
2283 static int pci230_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
2284 {
2285         struct pci230_private *devpriv = dev->private;
2286         unsigned int i, chan, range, diff;
2287         unsigned int res_mask;
2288         unsigned short adccon, adcen;
2289         unsigned char zgat;
2290
2291         /* Get the command. */
2292         struct comedi_async *async = s->async;
2293         struct comedi_cmd *cmd = &async->cmd;
2294
2295         /*
2296          * Determine which shared resources are needed.
2297          */
2298         res_mask = 0;
2299         /* Need Z2-CT2 to supply a conversion trigger source at a high
2300          * logic level, even if not doing timed conversions. */
2301         res_mask |= (1U << RES_Z2CT2);
2302         if (cmd->scan_begin_src != TRIG_FOLLOW) {
2303                 /* Using Z2-CT0 monostable to gate Z2-CT2 conversion timer */
2304                 res_mask |= (1U << RES_Z2CT0);
2305                 if (cmd->scan_begin_src == TRIG_TIMER) {
2306                         /* Using Z2-CT1 for scan frequency */
2307                         res_mask |= (1U << RES_Z2CT1);
2308                 }
2309         }
2310         /* Claim resources. */
2311         if (!get_resources(dev, res_mask, OWNER_AICMD))
2312                 return -EBUSY;
2313
2314
2315         /* Get number of scans required. */
2316         if (cmd->stop_src == TRIG_COUNT) {
2317                 devpriv->ai_scan_count = cmd->stop_arg;
2318                 devpriv->ai_continuous = 0;
2319         } else {
2320                 /* TRIG_NONE, user calls cancel. */
2321                 devpriv->ai_scan_count = 0;
2322                 devpriv->ai_continuous = 1;
2323         }
2324         devpriv->ai_scan_pos = 0;       /* Position within scan. */
2325
2326         /* Steps;
2327          * - Set channel scan list.
2328          * - Set channel gains.
2329          * - Enable and reset FIFO, specify uni/bip, se/diff, and set
2330          *   start conversion source to point to something at a high logic
2331          *   level (we use the output of counter/timer 2 for this purpose.
2332          * - PAUSE to allow things to settle down.
2333          * - Reset the FIFO again because it needs resetting twice and there
2334          *   may have been a false conversion trigger on some versions of
2335          *   PCI230/260 due to the start conversion source being set to a
2336          *   high logic level.
2337          * - Enable ADC FIFO level interrupt.
2338          * - Set actual conversion trigger source and FIFO interrupt trigger
2339          *   level.
2340          * - If convert_src is TRIG_TIMER, set up the timers.
2341          */
2342
2343         adccon = PCI230_ADC_FIFO_EN;
2344         adcen = 0;
2345
2346         if (CR_AREF(cmd->chanlist[0]) == AREF_DIFF) {
2347                 /* Differential - all channels must be differential. */
2348                 diff = 1;
2349                 adccon |= PCI230_ADC_IM_DIF;
2350         } else {
2351                 /* Single ended - all channels must be single-ended. */
2352                 diff = 0;
2353                 adccon |= PCI230_ADC_IM_SE;
2354         }
2355
2356         range = CR_RANGE(cmd->chanlist[0]);
2357         devpriv->ai_bipolar = pci230_ai_bipolar[range];
2358         if (devpriv->ai_bipolar)
2359                 adccon |= PCI230_ADC_IR_BIP;
2360         else
2361                 adccon |= PCI230_ADC_IR_UNI;
2362
2363         for (i = 0; i < cmd->chanlist_len; i++) {
2364                 unsigned int gainshift;
2365
2366                 chan = CR_CHAN(cmd->chanlist[i]);
2367                 range = CR_RANGE(cmd->chanlist[i]);
2368                 if (diff) {
2369                         gainshift = 2 * chan;
2370                         if (devpriv->hwver == 0) {
2371                                 /* Original PCI230/260 expects both inputs of
2372                                  * the differential channel to be enabled. */
2373                                 adcen |= 3 << gainshift;
2374                         } else {
2375                                 /* PCI230+/260+ expects only one input of the
2376                                  * differential channel to be enabled. */
2377                                 adcen |= 1 << gainshift;
2378                         }
2379                 } else {
2380                         gainshift = (chan & ~1);
2381                         adcen |= 1 << chan;
2382                 }
2383                 devpriv->adcg = (devpriv->adcg & ~(3 << gainshift))
2384                     | (pci230_ai_gain[range] << gainshift);
2385         }
2386
2387         /* Set channel scan list. */
2388         outw(adcen, dev->iobase + PCI230_ADCEN);
2389
2390         /* Set channel gains. */
2391         outw(devpriv->adcg, dev->iobase + PCI230_ADCG);
2392
2393         /* Set counter/timer 2 output high for use as the initial start
2394          * conversion source. */
2395         i8254_set_mode(devpriv->iobase1 + PCI230_Z2_CT_BASE, 0, 2, I8254_MODE1);
2396
2397         /* Temporarily use CT2 output as conversion trigger source and
2398          * temporarily set FIFO interrupt trigger level to 'full'. */
2399         adccon |= PCI230_ADC_INT_FIFO_FULL | PCI230_ADC_TRIG_Z2CT2;
2400
2401         /* Enable and reset FIFO, specify FIFO trigger level full, specify
2402          * uni/bip, se/diff, and temporarily set the start conversion source
2403          * to CT2 output.  Note that CT2 output is currently high, and this
2404          * will produce a false conversion trigger on some versions of the
2405          * PCI230/260, but that will be dealt with later. */
2406         devpriv->adccon = adccon;
2407         outw(adccon | PCI230_ADC_FIFO_RESET, dev->iobase + PCI230_ADCCON);
2408
2409         /* Delay */
2410         /* Failure to include this will result in the first few channels'-worth
2411          * of data being corrupt, normally manifesting itself by large negative
2412          * voltages. It seems the board needs time to settle between the first
2413          * FIFO reset (above) and the second FIFO reset (below). Setting the
2414          * channel gains and scan list _before_ the first FIFO reset also
2415          * helps, though only slightly. */
2416         udelay(25);
2417
2418         /* Reset FIFO again. */
2419         outw(adccon | PCI230_ADC_FIFO_RESET, dev->iobase + PCI230_ADCCON);
2420
2421         if (cmd->convert_src == TRIG_TIMER) {
2422                 /* Set up CT2 as conversion timer, but gate it off for now.
2423                  * Note, counter/timer output 2 can be monitored on the
2424                  * connector: PCI230 pin 21, PCI260 pin 18. */
2425                 zgat = GAT_CONFIG(2, GAT_GND);
2426                 outb(zgat, devpriv->iobase1 + PCI230_ZGAT_SCE);
2427                 /* Set counter/timer 2 to the specified conversion period. */
2428                 pci230_ct_setup_ns_mode(dev, 2, I8254_MODE3, cmd->convert_arg,
2429                                         cmd->flags & TRIG_ROUND_MASK);
2430                 if (cmd->scan_begin_src != TRIG_FOLLOW) {
2431                         /*
2432                          * Set up monostable on CT0 output for scan timing.  A
2433                          * rising edge on the trigger (gate) input of CT0 will
2434                          * trigger the monostable, causing its output to go low
2435                          * for the configured period.  The period depends on
2436                          * the conversion period and the number of conversions
2437                          * in the scan.
2438                          *
2439                          * Set the trigger high before setting up the
2440                          * monostable to stop it triggering.  The trigger
2441                          * source will be changed later.
2442                          */
2443                         zgat = GAT_CONFIG(0, GAT_VCC);
2444                         outb(zgat, devpriv->iobase1 + PCI230_ZGAT_SCE);
2445                         pci230_ct_setup_ns_mode(dev, 0, I8254_MODE1,
2446                                                 ((uint64_t) cmd->convert_arg
2447                                                  * cmd->scan_end_arg),
2448                                                 TRIG_ROUND_UP);
2449                         if (cmd->scan_begin_src == TRIG_TIMER) {
2450                                 /*
2451                                  * Monostable on CT0 will be triggered by
2452                                  * output of CT1 at configured scan frequency.
2453                                  *
2454                                  * Set up CT1 but gate it off for now.
2455                                  */
2456                                 zgat = GAT_CONFIG(1, GAT_GND);
2457                                 outb(zgat, devpriv->iobase1 + PCI230_ZGAT_SCE);
2458                                 pci230_ct_setup_ns_mode(dev, 1, I8254_MODE3,
2459                                                         cmd->scan_begin_arg,
2460                                                         cmd->
2461                                                         flags &
2462                                                         TRIG_ROUND_MASK);
2463                         }
2464                 }
2465         }
2466
2467         if (cmd->start_src == TRIG_INT) {
2468                 s->async->inttrig = pci230_ai_inttrig_start;
2469         } else {
2470                 /* TRIG_NOW */
2471                 pci230_ai_start(dev, s);
2472         }
2473
2474         return 0;
2475 }
2476
2477 static int pci230_ai_cancel(struct comedi_device *dev,
2478                             struct comedi_subdevice *s)
2479 {
2480         pci230_ai_stop(dev, s);
2481         return 0;
2482 }
2483
2484 /* Interrupt handler */
2485 static irqreturn_t pci230_interrupt(int irq, void *d)
2486 {
2487         unsigned char status_int, valid_status_int;
2488         struct comedi_device *dev = (struct comedi_device *)d;
2489         struct pci230_private *devpriv = dev->private;
2490         struct comedi_subdevice *s;
2491         unsigned long irqflags;
2492
2493         /* Read interrupt status/enable register. */
2494         status_int = inb(devpriv->iobase1 + PCI230_INT_STAT);
2495
2496         if (status_int == PCI230_INT_DISABLE)
2497                 return IRQ_NONE;
2498
2499
2500         spin_lock_irqsave(&devpriv->isr_spinlock, irqflags);
2501         valid_status_int = devpriv->int_en & status_int;
2502         /* Disable triggered interrupts.
2503          * (Only those interrupts that need re-enabling, are, later in the
2504          * handler).  */
2505         devpriv->ier = devpriv->int_en & ~status_int;
2506         outb(devpriv->ier, devpriv->iobase1 + PCI230_INT_SCE);
2507         devpriv->intr_running = 1;
2508         devpriv->intr_cpuid = THISCPU;
2509         spin_unlock_irqrestore(&devpriv->isr_spinlock, irqflags);
2510
2511         /*
2512          * Check the source of interrupt and handle it.
2513          * The PCI230 can cope with concurrent ADC, DAC, PPI C0 and C3
2514          * interrupts.  However, at present (Comedi-0.7.60) does not allow
2515          * concurrent execution of commands, instructions or a mixture of the
2516          * two.
2517          */
2518
2519         if ((valid_status_int & PCI230_INT_ZCLK_CT1) != 0) {
2520                 s = dev->write_subdev;
2521                 pci230_handle_ao_nofifo(dev, s);
2522                 comedi_event(dev, s);
2523         }
2524
2525         if ((valid_status_int & PCI230P2_INT_DAC) != 0) {
2526                 s = dev->write_subdev;
2527                 pci230_handle_ao_fifo(dev, s);
2528                 comedi_event(dev, s);
2529         }
2530
2531         if ((valid_status_int & PCI230_INT_ADC) != 0) {
2532                 s = dev->read_subdev;
2533                 pci230_handle_ai(dev, s);
2534                 comedi_event(dev, s);
2535         }
2536
2537         /* Reenable interrupts. */
2538         spin_lock_irqsave(&devpriv->isr_spinlock, irqflags);
2539         if (devpriv->ier != devpriv->int_en) {
2540                 devpriv->ier = devpriv->int_en;
2541                 outb(devpriv->ier, devpriv->iobase1 + PCI230_INT_SCE);
2542         }
2543         devpriv->intr_running = 0;
2544         spin_unlock_irqrestore(&devpriv->isr_spinlock, irqflags);
2545
2546         return IRQ_HANDLED;
2547 }
2548
2549 /* Check if PCI device matches a specific board. */
2550 static bool pci230_match_pci_board(const struct pci230_board *board,
2551                                    struct pci_dev *pci_dev)
2552 {
2553         /* assume pci_dev->device != PCI_DEVICE_ID_INVALID */
2554         if (board->id != pci_dev->device)
2555                 return false;
2556         if (board->min_hwver == 0)
2557                 return true;
2558         /* Looking for a '+' model.  First check length of registers. */
2559         if (pci_resource_len(pci_dev, 3) < 32)
2560                 return false;   /* Not a '+' model. */
2561         /* TODO: temporarily enable PCI device and read the hardware version
2562          * register.  For now, assume it's okay. */
2563         return true;
2564 }
2565
2566 /* Look for board matching PCI device. */
2567 static const struct pci230_board *pci230_find_pci_board(struct pci_dev *pci_dev)
2568 {
2569         unsigned int i;
2570
2571         for (i = 0; i < ARRAY_SIZE(pci230_boards); i++)
2572                 if (pci230_match_pci_board(&pci230_boards[i], pci_dev))
2573                         return &pci230_boards[i];
2574         return NULL;
2575 }
2576
2577 /* Look for PCI device matching requested board name, bus and slot. */
2578 static struct pci_dev *pci230_find_pci_dev(struct comedi_device *dev,
2579                                            struct comedi_devconfig *it)
2580 {
2581         const struct pci230_board *thisboard = comedi_board(dev);
2582         struct pci_dev *pci_dev = NULL;
2583         int bus = it->options[0];
2584         int slot = it->options[1];
2585
2586         for_each_pci_dev(pci_dev) {
2587                 /* Check vendor ID (same for all supported PCI boards). */
2588                 if (pci_dev->vendor != PCI_VENDOR_ID_AMPLICON)
2589                         continue;
2590                 /* If bus/slot specified, check them. */
2591                 if ((bus || slot) &&
2592                     (bus != pci_dev->bus->number ||
2593                      slot != PCI_SLOT(pci_dev->devfn)))
2594                         continue;
2595                 if (thisboard->id == PCI_DEVICE_ID_INVALID) {
2596                         /* Wildcard board matches any supported PCI board. */
2597                         const struct pci230_board *foundboard;
2598
2599                         foundboard = pci230_find_pci_board(pci_dev);
2600                         if (foundboard == NULL)
2601                                 continue;
2602                         /* Replace wildcard board_ptr. */
2603                         dev->board_ptr = foundboard;
2604                 } else {
2605                         /* Need to match a specific board. */
2606                         if (!pci230_match_pci_board(thisboard, pci_dev))
2607                                 continue;
2608                 }
2609                 return pci_dev;
2610         }
2611         dev_err(dev->class_dev,
2612                 "No supported board found! (req. bus %d, slot %d)\n",
2613                 bus, slot);
2614         return NULL;
2615 }
2616
2617 static int pci230_alloc_private(struct comedi_device *dev)
2618 {
2619         struct pci230_private *devpriv;
2620
2621         devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL);
2622         if (!devpriv)
2623                 return -ENOMEM;
2624         dev->private = devpriv;
2625
2626         spin_lock_init(&devpriv->isr_spinlock);
2627         spin_lock_init(&devpriv->res_spinlock);
2628         spin_lock_init(&devpriv->ai_stop_spinlock);
2629         spin_lock_init(&devpriv->ao_stop_spinlock);
2630         return 0;
2631 }
2632
2633 /* Common part of attach and auto_attach. */
2634 static int pci230_attach_common(struct comedi_device *dev,
2635                                 struct pci_dev *pci_dev)
2636 {
2637         const struct pci230_board *thisboard = comedi_board(dev);
2638         struct pci230_private *devpriv = dev->private;
2639         struct comedi_subdevice *s;
2640         unsigned long iobase1, iobase2;
2641         /* PCI230's I/O spaces 1 and 2 respectively. */
2642         int irq_hdl, rc;
2643
2644         comedi_set_hw_dev(dev, &pci_dev->dev);
2645
2646         dev->board_name = thisboard->name;
2647         /* Enable PCI device and reserve I/O spaces. */
2648         if (comedi_pci_enable(pci_dev, "amplc_pci230") < 0) {
2649                 dev_err(dev->class_dev,
2650                         "failed to enable PCI device and request regions\n");
2651                 return -EIO;
2652         }
2653         /* Read base addresses of the PCI230's two I/O regions from PCI
2654          * configuration register. */
2655         iobase1 = pci_resource_start(pci_dev, 2);
2656         iobase2 = pci_resource_start(pci_dev, 3);
2657         dev_dbg(dev->class_dev,
2658                 "%s I/O region 1 0x%04lx I/O region 2 0x%04lx\n",
2659                 dev->board_name, iobase1, iobase2);
2660         devpriv->iobase1 = iobase1;
2661         dev->iobase = iobase2;
2662         /* Read bits of DACCON register - only the output range. */
2663         devpriv->daccon = inw(dev->iobase + PCI230_DACCON) & PCI230_DAC_OR_MASK;
2664         /* Read hardware version register and set extended function register
2665          * if they exist. */
2666         if (pci_resource_len(pci_dev, 3) >= 32) {
2667                 unsigned short extfunc = 0;
2668
2669                 devpriv->hwver = inw(dev->iobase + PCI230P_HWVER);
2670                 if (devpriv->hwver < thisboard->min_hwver) {
2671                         dev_err(dev->class_dev,
2672                                 "%s - bad hardware version - got %u, need %u\n",
2673                                 dev->board_name, devpriv->hwver,
2674                                 thisboard->min_hwver);
2675                         return -EIO;
2676                 }
2677                 if (devpriv->hwver > 0) {
2678                         if (!thisboard->have_dio) {
2679                                 /* No DIO ports.  Route counters' external gates
2680                                  * to the EXTTRIG signal (PCI260+ pin 17).
2681                                  * (Otherwise, they would be routed to DIO
2682                                  * inputs PC0, PC1 and PC2 which don't exist
2683                                  * on PCI260[+].) */
2684                                 extfunc |= PCI230P_EXTFUNC_GAT_EXTTRIG;
2685                         }
2686                         if ((thisboard->ao_chans > 0)
2687                             && (devpriv->hwver >= 2)) {
2688                                 /* Enable DAC FIFO functionality. */
2689                                 extfunc |= PCI230P2_EXTFUNC_DACFIFO;
2690                         }
2691                 }
2692                 outw(extfunc, dev->iobase + PCI230P_EXTFUNC);
2693                 if ((extfunc & PCI230P2_EXTFUNC_DACFIFO) != 0) {
2694                         /* Temporarily enable DAC FIFO, reset it and disable
2695                          * FIFO wraparound. */
2696                         outw(devpriv->daccon | PCI230P2_DAC_FIFO_EN
2697                              | PCI230P2_DAC_FIFO_RESET,
2698                              dev->iobase + PCI230_DACCON);
2699                         /* Clear DAC FIFO channel enable register. */
2700                         outw(0, dev->iobase + PCI230P2_DACEN);
2701                         /* Disable DAC FIFO. */
2702                         outw(devpriv->daccon, dev->iobase + PCI230_DACCON);
2703                 }
2704         }
2705         /* Disable board's interrupts. */
2706         outb(0, devpriv->iobase1 + PCI230_INT_SCE);
2707         /* Set ADC to a reasonable state. */
2708         devpriv->adcg = 0;
2709         devpriv->adccon = PCI230_ADC_TRIG_NONE | PCI230_ADC_IM_SE
2710             | PCI230_ADC_IR_BIP;
2711         outw(1 << 0, dev->iobase + PCI230_ADCEN);
2712         outw(devpriv->adcg, dev->iobase + PCI230_ADCG);
2713         outw(devpriv->adccon | PCI230_ADC_FIFO_RESET,
2714              dev->iobase + PCI230_ADCCON);
2715         /* Register the interrupt handler. */
2716         irq_hdl = request_irq(pci_dev->irq, pci230_interrupt,
2717                               IRQF_SHARED, "amplc_pci230", dev);
2718         if (irq_hdl < 0) {
2719                 dev_warn(dev->class_dev,
2720                          "unable to register irq %u, commands will not be available\n",
2721                          pci_dev->irq);
2722         } else {
2723                 dev->irq = pci_dev->irq;
2724                 dev_dbg(dev->class_dev, "registered irq %u\n", pci_dev->irq);
2725         }
2726
2727         rc = comedi_alloc_subdevices(dev, 3);
2728         if (rc)
2729                 return rc;
2730
2731         s = &dev->subdevices[0];
2732         /* analog input subdevice */
2733         s->type = COMEDI_SUBD_AI;
2734         s->subdev_flags = SDF_READABLE | SDF_DIFF | SDF_GROUND;
2735         s->n_chan = thisboard->ai_chans;
2736         s->maxdata = (1 << thisboard->ai_bits) - 1;
2737         s->range_table = &pci230_ai_range;
2738         s->insn_read = &pci230_ai_rinsn;
2739         s->len_chanlist = 256;  /* but there are restrictions. */
2740         /* Only register commands if the interrupt handler is installed. */
2741         if (irq_hdl == 0) {
2742                 dev->read_subdev = s;
2743                 s->subdev_flags |= SDF_CMD_READ;
2744                 s->do_cmd = &pci230_ai_cmd;
2745                 s->do_cmdtest = &pci230_ai_cmdtest;
2746                 s->cancel = pci230_ai_cancel;
2747         }
2748         s = &dev->subdevices[1];
2749         /* analog output subdevice */
2750         if (thisboard->ao_chans > 0) {
2751                 s->type = COMEDI_SUBD_AO;
2752                 s->subdev_flags = SDF_WRITABLE | SDF_GROUND;
2753                 s->n_chan = thisboard->ao_chans;
2754                 s->maxdata = (1 << thisboard->ao_bits) - 1;
2755                 s->range_table = &pci230_ao_range;
2756                 s->insn_write = &pci230_ao_winsn;
2757                 s->insn_read = &pci230_ao_rinsn;
2758                 s->len_chanlist = thisboard->ao_chans;
2759                 /* Only register commands if the interrupt handler is
2760                  * installed. */
2761                 if (irq_hdl == 0) {
2762                         dev->write_subdev = s;
2763                         s->subdev_flags |= SDF_CMD_WRITE;
2764                         s->do_cmd = &pci230_ao_cmd;
2765                         s->do_cmdtest = &pci230_ao_cmdtest;
2766                         s->cancel = pci230_ao_cancel;
2767                 }
2768         } else {
2769                 s->type = COMEDI_SUBD_UNUSED;
2770         }
2771         s = &dev->subdevices[2];
2772         /* digital i/o subdevice */
2773         if (thisboard->have_dio) {
2774                 rc = subdev_8255_init(dev, s, NULL,
2775                                       (devpriv->iobase1 + PCI230_PPI_X_BASE));
2776                 if (rc < 0)
2777                         return rc;
2778         } else {
2779                 s->type = COMEDI_SUBD_UNUSED;
2780         }
2781         dev_info(dev->class_dev, "attached\n");
2782         return 1;
2783 }
2784
2785 static int pci230_attach(struct comedi_device *dev, struct comedi_devconfig *it)
2786 {
2787         const struct pci230_board *thisboard = comedi_board(dev);
2788         struct pci_dev *pci_dev;
2789         int rc;
2790
2791         dev_info(dev->class_dev, "amplc_pci230: attach %s %d,%d\n",
2792                  thisboard->name, it->options[0], it->options[1]);
2793
2794         rc = pci230_alloc_private(dev);
2795         if (rc)
2796                 return rc;
2797
2798         pci_dev = pci230_find_pci_dev(dev, it);
2799         if (!pci_dev)
2800                 return -EIO;
2801         return pci230_attach_common(dev, pci_dev);
2802 }
2803
2804 static int pci230_auto_attach(struct comedi_device *dev,
2805                                         unsigned long context_unused)
2806 {
2807         struct pci_dev *pci_dev = comedi_to_pci_dev(dev);
2808         int rc;
2809
2810         dev_info(dev->class_dev, "amplc_pci230: attach pci %s\n",
2811                  pci_name(pci_dev));
2812
2813         rc = pci230_alloc_private(dev);
2814         if (rc)
2815                 return rc;
2816
2817         dev->board_ptr = pci230_find_pci_board(pci_dev);
2818         if (dev->board_ptr == NULL) {
2819                 dev_err(dev->class_dev,
2820                         "amplc_pci230: BUG! cannot determine board type!\n");
2821                 return -EINVAL;
2822         }
2823         /*
2824          * Need to 'get' the PCI device to match the 'put' in pci230_detach().
2825          * TODO: Remove the pci_dev_get() and matching pci_dev_put() once
2826          * support for manual attachment of PCI devices via pci230_attach()
2827          * has been removed.
2828          */
2829         pci_dev_get(pci_dev);
2830         return pci230_attach_common(dev, pci_dev);
2831 }
2832
2833 static void pci230_detach(struct comedi_device *dev)
2834 {
2835         const struct pci230_board *thisboard = comedi_board(dev);
2836         struct pci_dev *pcidev = comedi_to_pci_dev(dev);
2837
2838         if (dev->subdevices && thisboard->have_dio)
2839                 subdev_8255_cleanup(dev, &dev->subdevices[2]);
2840         if (dev->irq)
2841                 free_irq(dev->irq, dev);
2842         if (pcidev) {
2843                 if (dev->iobase)
2844                         comedi_pci_disable(pcidev);
2845                 pci_dev_put(pcidev);
2846         }
2847 }
2848
2849 static struct comedi_driver amplc_pci230_driver = {
2850         .driver_name    = "amplc_pci230",
2851         .module         = THIS_MODULE,
2852         .attach         = pci230_attach,
2853         .auto_attach    = pci230_auto_attach,
2854         .detach         = pci230_detach,
2855         .board_name     = &pci230_boards[0].name,
2856         .offset         = sizeof(pci230_boards[0]),
2857         .num_names      = ARRAY_SIZE(pci230_boards),
2858 };
2859
2860 static int amplc_pci230_pci_probe(struct pci_dev *dev,
2861                                             const struct pci_device_id *ent)
2862 {
2863         return comedi_pci_auto_config(dev, &amplc_pci230_driver);
2864 }
2865
2866 static void amplc_pci230_pci_remove(struct pci_dev *dev)
2867 {
2868         comedi_pci_auto_unconfig(dev);
2869 }
2870
2871 static DEFINE_PCI_DEVICE_TABLE(amplc_pci230_pci_table) = {
2872         { PCI_DEVICE(PCI_VENDOR_ID_AMPLICON, PCI_DEVICE_ID_PCI230) },
2873         { PCI_DEVICE(PCI_VENDOR_ID_AMPLICON, PCI_DEVICE_ID_PCI260) },
2874         { 0 }
2875 };
2876 MODULE_DEVICE_TABLE(pci, amplc_pci230_pci_table);
2877
2878 static struct pci_driver amplc_pci230_pci_driver = {
2879         .name           = "amplc_pci230",
2880         .id_table       = amplc_pci230_pci_table,
2881         .probe          = amplc_pci230_pci_probe,
2882         .remove         = amplc_pci230_pci_remove
2883 };
2884 module_comedi_pci_driver(amplc_pci230_driver, amplc_pci230_pci_driver);
2885
2886 MODULE_AUTHOR("Comedi http://www.comedi.org");
2887 MODULE_DESCRIPTION("Comedi low-level driver");
2888 MODULE_LICENSE("GPL");