OSDN Git Service

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