staging: comedi: remove inline alloc_private()
[deliverable/linux.git] / drivers / staging / comedi / drivers / amplc_pci230.c
1 /*
2 comedi/drivers/amplc_pci230.c
3 Driver for Amplicon PCI230 and PCI260 Multifunction I/O boards.
4
5 Copyright (C) 2001 Allan Willcox <allanwillcox@ozemail.com.au>
6
7 COMEDI - Linux Control and Measurement Device Interface
8 Copyright (C) 2000 David A. Schleef <ds@schleef.org>
9
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 2 of the License, or
13 (at your option) any later version.
14
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
19
20 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 <allanwillcox@ozemail.com.au>,
28 Steve D Sharples <steve.sharples@nottingham.ac.uk>,
29 Ian Abbott <abbotti@mev.co.uk>
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. */
503 struct pci230_private {
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] = {
544 [CLK_10MHZ] = TIMEBASE_10MHZ,
545 [CLK_1MHZ] = TIMEBASE_1MHZ,
546 [CLK_100KHZ] = TIMEBASE_100KHZ,
547 [CLK_10KHZ] = TIMEBASE_10KHZ,
548 [CLK_1KHZ] = TIMEBASE_1KHZ,
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)
628 ? PCI230_DACOUT1
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 */
835 adccon = PCI230_ADC_TRIG_Z2CT2 | PCI230_ADC_FIFO_EN;
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;
875 outw(adccon | PCI230_ADC_FIFO_RESET, dev->iobase + PCI230_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) {
1020 cmd->scan_begin_arg = MAX_SPEED_AO;
1021 err++;
1022 }
1023 if (cmd->scan_begin_arg > MIN_SPEED_AO) {
1024 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,
1042 CR_FLAGS_MASK & ~(CR_EDGE | CR_INVERT));
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;
1177 outw(devpriv->daccon | PCI230P2_DAC_FIFO_RESET
1178 | PCI230P2_DAC_FIFO_UNDERRUN_CLEAR,
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)
1267 room = PCI230P2_DAC_FIFOROOM_FULL;
1268 else if ((dacstat & PCI230P2_DAC_FIFO_HALF) != 0)
1269 room = PCI230P2_DAC_FIFOROOM_HALFTOFULL;
1270 else if ((dacstat & PCI230P2_DAC_FIFO_EMPTY) != 0)
1271 room = PCI230P2_DAC_FIFOROOM_EMPTY;
1272 else
1273 room = PCI230P2_DAC_FIFOROOM_ONETOHALF;
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 &
1298 ~PCI230P2_DAC_INT_FIFO_MASK)
1299 | PCI230P2_DAC_INT_FIFO_EMPTY;
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
1410 & ~PCI230P2_DAC_TRIG_MASK) |
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 */
1512 daccon |= PCI230P2_DAC_FIFO_EN | PCI230P2_DAC_FIFO_RESET
1513 | PCI230P2_DAC_FIFO_UNDERRUN_CLEAR
1514 | PCI230P2_DAC_TRIG_NONE | PCI230P2_DAC_INT_FIFO_NHALF;
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
1521 & ~(PCI230P2_DAC_FIFO_RESET | PCI230P2_DAC_FIFO_UNDERRUN_CLEAR);
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,
1595 TRIG_TIMER | TRIG_INT | TRIG_EXT);
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),
1691 CR_FLAGS_MASK & ~CR_INVERT);
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
1939 || (devpriv->ai_scan_count >= PCI230_ADC_FIFOLEVEL_HALFFULL)
1940 || (scanlen >= PCI230_ADC_FIFOLEVEL_HALFFULL)) {
1941 wake = 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)) |
2074 PCI230_ADC_TRIG_NONE;
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) {
2247 todo = PCI230_ADC_FIFOLEVEL_HALFFULL;
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)) {
2252 todo = PCI230_ADC_FIFOLEVEL_HALFFULL;
2253 } else {
2254 todo = (devpriv->ai_scan_count * scanlen)
2255 - devpriv->ai_scan_pos;
2256 if (todo > PCI230_ADC_FIFOLEVEL_HALFFULL)
2257 todo = PCI230_ADC_FIFOLEVEL_HALFFULL;
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'. */
2442 adccon |= PCI230_ADC_INT_FIFO_FULL | PCI230_ADC_TRIG_Z2CT2;
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
2664 devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL);
2665 if (!devpriv)
2666 return -ENOMEM;
2667 dev->private = devpriv;
2668
2669 spin_lock_init(&devpriv->isr_spinlock);
2670 spin_lock_init(&devpriv->res_spinlock);
2671 spin_lock_init(&devpriv->ai_stop_spinlock);
2672 spin_lock_init(&devpriv->ao_stop_spinlock);
2673 return 0;
2674 }
2675
2676 /* Common part of attach and attach_pci. */
2677 static int pci230_attach_common(struct comedi_device *dev,
2678 struct pci_dev *pci_dev)
2679 {
2680 const struct pci230_board *thisboard = comedi_board(dev);
2681 struct pci230_private *devpriv = dev->private;
2682 struct comedi_subdevice *s;
2683 unsigned long iobase1, iobase2;
2684 /* PCI230's I/O spaces 1 and 2 respectively. */
2685 int irq_hdl, rc;
2686
2687 comedi_set_hw_dev(dev, &pci_dev->dev);
2688
2689 dev->board_name = thisboard->name;
2690 /* Enable PCI device and reserve I/O spaces. */
2691 if (comedi_pci_enable(pci_dev, "amplc_pci230") < 0) {
2692 dev_err(dev->class_dev,
2693 "failed to enable PCI device and request regions\n");
2694 return -EIO;
2695 }
2696 /* Read base addresses of the PCI230's two I/O regions from PCI
2697 * configuration register. */
2698 iobase1 = pci_resource_start(pci_dev, 2);
2699 iobase2 = pci_resource_start(pci_dev, 3);
2700 dev_dbg(dev->class_dev,
2701 "%s I/O region 1 0x%04lx I/O region 2 0x%04lx\n",
2702 dev->board_name, iobase1, iobase2);
2703 devpriv->iobase1 = iobase1;
2704 dev->iobase = iobase2;
2705 /* Read bits of DACCON register - only the output range. */
2706 devpriv->daccon = inw(dev->iobase + PCI230_DACCON) & PCI230_DAC_OR_MASK;
2707 /* Read hardware version register and set extended function register
2708 * if they exist. */
2709 if (pci_resource_len(pci_dev, 3) >= 32) {
2710 unsigned short extfunc = 0;
2711
2712 devpriv->hwver = inw(dev->iobase + PCI230P_HWVER);
2713 if (devpriv->hwver < thisboard->min_hwver) {
2714 dev_err(dev->class_dev,
2715 "%s - bad hardware version - got %u, need %u\n",
2716 dev->board_name, devpriv->hwver,
2717 thisboard->min_hwver);
2718 return -EIO;
2719 }
2720 if (devpriv->hwver > 0) {
2721 if (!thisboard->have_dio) {
2722 /* No DIO ports. Route counters' external gates
2723 * to the EXTTRIG signal (PCI260+ pin 17).
2724 * (Otherwise, they would be routed to DIO
2725 * inputs PC0, PC1 and PC2 which don't exist
2726 * on PCI260[+].) */
2727 extfunc |= PCI230P_EXTFUNC_GAT_EXTTRIG;
2728 }
2729 if ((thisboard->ao_chans > 0)
2730 && (devpriv->hwver >= 2)) {
2731 /* Enable DAC FIFO functionality. */
2732 extfunc |= PCI230P2_EXTFUNC_DACFIFO;
2733 }
2734 }
2735 outw(extfunc, dev->iobase + PCI230P_EXTFUNC);
2736 if ((extfunc & PCI230P2_EXTFUNC_DACFIFO) != 0) {
2737 /* Temporarily enable DAC FIFO, reset it and disable
2738 * FIFO wraparound. */
2739 outw(devpriv->daccon | PCI230P2_DAC_FIFO_EN
2740 | PCI230P2_DAC_FIFO_RESET,
2741 dev->iobase + PCI230_DACCON);
2742 /* Clear DAC FIFO channel enable register. */
2743 outw(0, dev->iobase + PCI230P2_DACEN);
2744 /* Disable DAC FIFO. */
2745 outw(devpriv->daccon, dev->iobase + PCI230_DACCON);
2746 }
2747 }
2748 /* Disable board's interrupts. */
2749 outb(0, devpriv->iobase1 + PCI230_INT_SCE);
2750 /* Set ADC to a reasonable state. */
2751 devpriv->adcg = 0;
2752 devpriv->adccon = PCI230_ADC_TRIG_NONE | PCI230_ADC_IM_SE
2753 | PCI230_ADC_IR_BIP;
2754 outw(1 << 0, dev->iobase + PCI230_ADCEN);
2755 outw(devpriv->adcg, dev->iobase + PCI230_ADCG);
2756 outw(devpriv->adccon | PCI230_ADC_FIFO_RESET,
2757 dev->iobase + PCI230_ADCCON);
2758 /* Register the interrupt handler. */
2759 irq_hdl = request_irq(pci_dev->irq, pci230_interrupt,
2760 IRQF_SHARED, "amplc_pci230", dev);
2761 if (irq_hdl < 0) {
2762 dev_warn(dev->class_dev,
2763 "unable to register irq %u, commands will not be available\n",
2764 pci_dev->irq);
2765 } else {
2766 dev->irq = pci_dev->irq;
2767 dev_dbg(dev->class_dev, "registered irq %u\n", pci_dev->irq);
2768 }
2769
2770 rc = comedi_alloc_subdevices(dev, 3);
2771 if (rc)
2772 return rc;
2773
2774 s = &dev->subdevices[0];
2775 /* analog input subdevice */
2776 s->type = COMEDI_SUBD_AI;
2777 s->subdev_flags = SDF_READABLE | SDF_DIFF | SDF_GROUND;
2778 s->n_chan = thisboard->ai_chans;
2779 s->maxdata = (1 << thisboard->ai_bits) - 1;
2780 s->range_table = &pci230_ai_range;
2781 s->insn_read = &pci230_ai_rinsn;
2782 s->len_chanlist = 256; /* but there are restrictions. */
2783 /* Only register commands if the interrupt handler is installed. */
2784 if (irq_hdl == 0) {
2785 dev->read_subdev = s;
2786 s->subdev_flags |= SDF_CMD_READ;
2787 s->do_cmd = &pci230_ai_cmd;
2788 s->do_cmdtest = &pci230_ai_cmdtest;
2789 s->cancel = pci230_ai_cancel;
2790 }
2791 s = &dev->subdevices[1];
2792 /* analog output subdevice */
2793 if (thisboard->ao_chans > 0) {
2794 s->type = COMEDI_SUBD_AO;
2795 s->subdev_flags = SDF_WRITABLE | SDF_GROUND;
2796 s->n_chan = thisboard->ao_chans;
2797 s->maxdata = (1 << thisboard->ao_bits) - 1;
2798 s->range_table = &pci230_ao_range;
2799 s->insn_write = &pci230_ao_winsn;
2800 s->insn_read = &pci230_ao_rinsn;
2801 s->len_chanlist = thisboard->ao_chans;
2802 /* Only register commands if the interrupt handler is
2803 * installed. */
2804 if (irq_hdl == 0) {
2805 dev->write_subdev = s;
2806 s->subdev_flags |= SDF_CMD_WRITE;
2807 s->do_cmd = &pci230_ao_cmd;
2808 s->do_cmdtest = &pci230_ao_cmdtest;
2809 s->cancel = pci230_ao_cancel;
2810 }
2811 } else {
2812 s->type = COMEDI_SUBD_UNUSED;
2813 }
2814 s = &dev->subdevices[2];
2815 /* digital i/o subdevice */
2816 if (thisboard->have_dio) {
2817 rc = subdev_8255_init(dev, s, NULL,
2818 (devpriv->iobase1 + PCI230_PPI_X_BASE));
2819 if (rc < 0)
2820 return rc;
2821 } else {
2822 s->type = COMEDI_SUBD_UNUSED;
2823 }
2824 dev_info(dev->class_dev, "attached\n");
2825 return 1;
2826 }
2827
2828 static int pci230_attach(struct comedi_device *dev, struct comedi_devconfig *it)
2829 {
2830 const struct pci230_board *thisboard = comedi_board(dev);
2831 struct pci_dev *pci_dev;
2832 int rc;
2833
2834 dev_info(dev->class_dev, "amplc_pci230: attach %s %d,%d\n",
2835 thisboard->name, it->options[0], it->options[1]);
2836
2837 rc = pci230_alloc_private(dev);
2838 if (rc)
2839 return rc;
2840
2841 pci_dev = pci230_find_pci_dev(dev, it);
2842 if (!pci_dev)
2843 return -EIO;
2844 return pci230_attach_common(dev, pci_dev);
2845 }
2846
2847 static int __devinit pci230_attach_pci(struct comedi_device *dev,
2848 struct pci_dev *pci_dev)
2849 {
2850 int rc;
2851
2852 dev_info(dev->class_dev, "amplc_pci230: attach pci %s\n",
2853 pci_name(pci_dev));
2854
2855 rc = pci230_alloc_private(dev);
2856 if (rc)
2857 return rc;
2858
2859 dev->board_ptr = pci230_find_pci_board(pci_dev);
2860 if (dev->board_ptr == NULL) {
2861 dev_err(dev->class_dev,
2862 "amplc_pci230: BUG! cannot determine board type!\n");
2863 return -EINVAL;
2864 }
2865 /*
2866 * Need to 'get' the PCI device to match the 'put' in pci230_detach().
2867 * TODO: Remove the pci_dev_get() and matching pci_dev_put() once
2868 * support for manual attachment of PCI devices via pci230_attach()
2869 * has been removed.
2870 */
2871 pci_dev_get(pci_dev);
2872 return pci230_attach_common(dev, pci_dev);
2873 }
2874
2875 static void pci230_detach(struct comedi_device *dev)
2876 {
2877 const struct pci230_board *thisboard = comedi_board(dev);
2878 struct pci_dev *pcidev = comedi_to_pci_dev(dev);
2879
2880 if (dev->subdevices && thisboard->have_dio)
2881 subdev_8255_cleanup(dev, &dev->subdevices[2]);
2882 if (dev->irq)
2883 free_irq(dev->irq, dev);
2884 if (pcidev) {
2885 if (dev->iobase)
2886 comedi_pci_disable(pcidev);
2887 pci_dev_put(pcidev);
2888 }
2889 }
2890
2891 static struct comedi_driver amplc_pci230_driver = {
2892 .driver_name = "amplc_pci230",
2893 .module = THIS_MODULE,
2894 .attach = pci230_attach,
2895 .attach_pci = pci230_attach_pci,
2896 .detach = pci230_detach,
2897 .board_name = &pci230_boards[0].name,
2898 .offset = sizeof(pci230_boards[0]),
2899 .num_names = ARRAY_SIZE(pci230_boards),
2900 };
2901
2902 static int __devinit amplc_pci230_pci_probe(struct pci_dev *dev,
2903 const struct pci_device_id *ent)
2904 {
2905 return comedi_pci_auto_config(dev, &amplc_pci230_driver);
2906 }
2907
2908 static void __devexit amplc_pci230_pci_remove(struct pci_dev *dev)
2909 {
2910 comedi_pci_auto_unconfig(dev);
2911 }
2912
2913 static DEFINE_PCI_DEVICE_TABLE(amplc_pci230_pci_table) = {
2914 { PCI_DEVICE(PCI_VENDOR_ID_AMPLICON, PCI_DEVICE_ID_PCI230) },
2915 { PCI_DEVICE(PCI_VENDOR_ID_AMPLICON, PCI_DEVICE_ID_PCI260) },
2916 { 0 }
2917 };
2918 MODULE_DEVICE_TABLE(pci, amplc_pci230_pci_table);
2919
2920 static struct pci_driver amplc_pci230_pci_driver = {
2921 .name = "amplc_pci230",
2922 .id_table = amplc_pci230_pci_table,
2923 .probe = amplc_pci230_pci_probe,
2924 .remove = __devexit_p(amplc_pci230_pci_remove)
2925 };
2926 module_comedi_pci_driver(amplc_pci230_driver, amplc_pci230_pci_driver);
2927
2928 MODULE_AUTHOR("Comedi http://www.comedi.org");
2929 MODULE_DESCRIPTION("Comedi low-level driver");
2930 MODULE_LICENSE("GPL");
This page took 0.09269 seconds and 5 git commands to generate.