Version:  2.0.40 2.2.26 2.4.37 3.1 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

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

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