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