Version:  2.0.40 2.2.26 2.4.37 3.11 3.12 3.13 3.14 3.15 3.16 3.17 3.18 3.19 4.0 4.1 4.2 4.3 4.4 4.5 4.6 4.7 4.8

Linux/drivers/staging/comedi/drivers/amplc_pci230.c

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

This page was automatically generated by LXR 0.3.1 (source).  •  Linux is a registered trademark of Linus Torvalds  •  Contact us