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

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

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