Version:  2.0.40 2.2.26 2.4.37 3.2 3.3 3.4 3.5 3.6 3.7 3.8 3.9 3.10 3.11 3.12 3.13 3.14 3.15 3.16 3.17 3.18

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

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