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