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