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