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

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

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