Merge 3.9-rc5 into staging-next
[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 <linux/pci.h>
192 #include <linux/delay.h>
193 #include <linux/interrupt.h>
194
195 #include "../comedidev.h"
196
197 #include "comedi_fc.h"
198 #include "8253.h"
199 #include "8255.h"
200
201 /* PCI230 PCI configuration register information */
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: check if arguments are trivially valid */
1004
1005 err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0);
1006
1007 #define MAX_SPEED_AO 8000 /* 8000 ns => 125 kHz */
1008 #define MIN_SPEED_AO 4294967295u /* 4294967295ns = 4.29s */
1009 /*- Comedi limit due to unsigned int cmd. Driver limit
1010 * = 2^16 (16bit * counter) * 1000000ns (1kHz onboard
1011 * clock) = 65.536s */
1012
1013 switch (cmd->scan_begin_src) {
1014 case TRIG_TIMER:
1015 err |= cfc_check_trigger_arg_min(&cmd->scan_begin_arg,
1016 MAX_SPEED_AO);
1017 err |= cfc_check_trigger_arg_max(&cmd->scan_begin_arg,
1018 MIN_SPEED_AO);
1019 break;
1020 case TRIG_EXT:
1021 /* External trigger - for PCI230+ hardware version 2 onwards. */
1022 /* Trigger number must be 0. */
1023 if ((cmd->scan_begin_arg & ~CR_FLAGS_MASK) != 0) {
1024 cmd->scan_begin_arg = COMBINE(cmd->scan_begin_arg, 0,
1025 ~CR_FLAGS_MASK);
1026 err |= -EINVAL;
1027 }
1028 /* The only flags allowed are CR_EDGE and CR_INVERT. The
1029 * CR_EDGE flag is ignored. */
1030 if ((cmd->scan_begin_arg
1031 & (CR_FLAGS_MASK & ~(CR_EDGE | CR_INVERT))) != 0) {
1032 cmd->scan_begin_arg = COMBINE(cmd->scan_begin_arg, 0,
1033 CR_FLAGS_MASK &
1034 ~(CR_EDGE | CR_INVERT));
1035 err |= -EINVAL;
1036 }
1037 break;
1038 default:
1039 err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, 0);
1040 break;
1041 }
1042
1043 err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len);
1044
1045 if (cmd->stop_src == TRIG_NONE)
1046 err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0);
1047
1048 if (err)
1049 return 3;
1050
1051 /* Step 4: fix up any arguments.
1052 * "argument conflict" returned by comedilib to user mode process
1053 * if this fails. */
1054
1055 if (cmd->scan_begin_src == TRIG_TIMER) {
1056 tmp = cmd->scan_begin_arg;
1057 pci230_ns_to_single_timer(&cmd->scan_begin_arg,
1058 cmd->flags & TRIG_ROUND_MASK);
1059 if (tmp != cmd->scan_begin_arg)
1060 err++;
1061 }
1062
1063 if (err)
1064 return 4;
1065
1066 /* Step 5: check channel list if it exists. */
1067
1068 if (cmd->chanlist && cmd->chanlist_len > 0) {
1069 enum {
1070 seq_err = (1 << 0),
1071 range_err = (1 << 1)
1072 };
1073 unsigned int errors;
1074 unsigned int n;
1075 unsigned int chan, prev_chan;
1076 unsigned int range, first_range;
1077
1078 prev_chan = CR_CHAN(cmd->chanlist[0]);
1079 first_range = CR_RANGE(cmd->chanlist[0]);
1080 errors = 0;
1081 for (n = 1; n < cmd->chanlist_len; n++) {
1082 chan = CR_CHAN(cmd->chanlist[n]);
1083 range = CR_RANGE(cmd->chanlist[n]);
1084 /* Channel numbers must strictly increase. */
1085 if (chan < prev_chan)
1086 errors |= seq_err;
1087
1088 /* Ranges must be the same. */
1089 if (range != first_range)
1090 errors |= range_err;
1091
1092 prev_chan = chan;
1093 }
1094 if (errors != 0) {
1095 err++;
1096 if ((errors & seq_err) != 0) {
1097 DPRINTK("comedi%d: amplc_pci230: ao_cmdtest: "
1098 "channel numbers must increase\n",
1099 dev->minor);
1100 }
1101 if ((errors & range_err) != 0) {
1102 DPRINTK("comedi%d: amplc_pci230: ao_cmdtest: "
1103 "channels must have the same range\n",
1104 dev->minor);
1105 }
1106 }
1107 }
1108
1109 if (err)
1110 return 5;
1111
1112 return 0;
1113 }
1114
1115 static void pci230_ao_stop(struct comedi_device *dev,
1116 struct comedi_subdevice *s)
1117 {
1118 struct pci230_private *devpriv = dev->private;
1119 unsigned long irqflags;
1120 unsigned char intsrc;
1121 int started;
1122 struct comedi_cmd *cmd;
1123
1124 spin_lock_irqsave(&devpriv->ao_stop_spinlock, irqflags);
1125 started = test_and_clear_bit(AO_CMD_STARTED, &devpriv->state);
1126 spin_unlock_irqrestore(&devpriv->ao_stop_spinlock, irqflags);
1127 if (!started)
1128 return;
1129 cmd = &s->async->cmd;
1130 if (cmd->scan_begin_src == TRIG_TIMER) {
1131 /* Stop scan rate generator. */
1132 pci230_cancel_ct(dev, 1);
1133 }
1134 /* Determine interrupt source. */
1135 if (devpriv->hwver < 2) {
1136 /* Not using DAC FIFO. Using CT1 interrupt. */
1137 intsrc = PCI230_INT_ZCLK_CT1;
1138 } else {
1139 /* Using DAC FIFO interrupt. */
1140 intsrc = PCI230P2_INT_DAC;
1141 }
1142 /* Disable interrupt and wait for interrupt routine to finish running
1143 * unless we are called from the interrupt routine. */
1144 spin_lock_irqsave(&devpriv->isr_spinlock, irqflags);
1145 devpriv->int_en &= ~intsrc;
1146 while (devpriv->intr_running && devpriv->intr_cpuid != THISCPU) {
1147 spin_unlock_irqrestore(&devpriv->isr_spinlock, irqflags);
1148 spin_lock_irqsave(&devpriv->isr_spinlock, irqflags);
1149 }
1150 if (devpriv->ier != devpriv->int_en) {
1151 devpriv->ier = devpriv->int_en;
1152 outb(devpriv->ier, devpriv->iobase1 + PCI230_INT_SCE);
1153 }
1154 spin_unlock_irqrestore(&devpriv->isr_spinlock, irqflags);
1155 if (devpriv->hwver >= 2) {
1156 /* Using DAC FIFO. Reset FIFO, clear underrun error,
1157 * disable FIFO. */
1158 devpriv->daccon &= PCI230_DAC_OR_MASK;
1159 outw(devpriv->daccon | PCI230P2_DAC_FIFO_RESET
1160 | PCI230P2_DAC_FIFO_UNDERRUN_CLEAR,
1161 dev->iobase + PCI230_DACCON);
1162 }
1163 /* Release resources. */
1164 put_all_resources(dev, OWNER_AOCMD);
1165 }
1166
1167 static void pci230_handle_ao_nofifo(struct comedi_device *dev,
1168 struct comedi_subdevice *s)
1169 {
1170 struct pci230_private *devpriv = dev->private;
1171 short data;
1172 int i, ret;
1173 struct comedi_async *async = s->async;
1174 struct comedi_cmd *cmd = &async->cmd;
1175
1176 if (!devpriv->ao_continuous && (devpriv->ao_scan_count == 0))
1177 return;
1178 for (i = 0; i < cmd->chanlist_len; i++) {
1179 /* Read sample from Comedi's circular buffer. */
1180 ret = comedi_buf_get(s->async, &data);
1181 if (ret == 0) {
1182 s->async->events |= COMEDI_CB_OVERFLOW;
1183 pci230_ao_stop(dev, s);
1184 comedi_error(dev, "AO buffer underrun");
1185 return;
1186 }
1187 /* Write value to DAC. */
1188 pci230_ao_write_nofifo(dev, data, CR_CHAN(cmd->chanlist[i]));
1189 }
1190 async->events |= COMEDI_CB_BLOCK | COMEDI_CB_EOS;
1191 if (!devpriv->ao_continuous) {
1192 devpriv->ao_scan_count--;
1193 if (devpriv->ao_scan_count == 0) {
1194 /* End of acquisition. */
1195 async->events |= COMEDI_CB_EOA;
1196 pci230_ao_stop(dev, s);
1197 }
1198 }
1199 }
1200
1201 /* Loads DAC FIFO (if using it) from buffer. */
1202 /* Returns 0 if AO finished due to completion or error, 1 if still going. */
1203 static int pci230_handle_ao_fifo(struct comedi_device *dev,
1204 struct comedi_subdevice *s)
1205 {
1206 struct pci230_private *devpriv = dev->private;
1207 struct comedi_async *async = s->async;
1208 struct comedi_cmd *cmd = &async->cmd;
1209 unsigned int num_scans;
1210 unsigned int room;
1211 unsigned short dacstat;
1212 unsigned int i, n;
1213 unsigned int bytes_per_scan;
1214 unsigned int events = 0;
1215 int running;
1216
1217 /* Get DAC FIFO status. */
1218 dacstat = inw(dev->iobase + PCI230_DACCON);
1219 /* Determine number of scans available in buffer. */
1220 bytes_per_scan = cmd->chanlist_len * sizeof(short);
1221 num_scans = comedi_buf_read_n_available(async) / bytes_per_scan;
1222 if (!devpriv->ao_continuous) {
1223 /* Fixed number of scans. */
1224 if (num_scans > devpriv->ao_scan_count)
1225 num_scans = devpriv->ao_scan_count;
1226 if (devpriv->ao_scan_count == 0) {
1227 /* End of acquisition. */
1228 events |= COMEDI_CB_EOA;
1229 }
1230 }
1231 if (events == 0) {
1232 /* Check for FIFO underrun. */
1233 if ((dacstat & PCI230P2_DAC_FIFO_UNDERRUN_LATCHED) != 0) {
1234 comedi_error(dev, "AO FIFO underrun");
1235 events |= COMEDI_CB_OVERFLOW | COMEDI_CB_ERROR;
1236 }
1237 /* Check for buffer underrun if FIFO less than half full
1238 * (otherwise there will be loads of "DAC FIFO not half full"
1239 * interrupts). */
1240 if ((num_scans == 0)
1241 && ((dacstat & PCI230P2_DAC_FIFO_HALF) == 0)) {
1242 comedi_error(dev, "AO buffer underrun");
1243 events |= COMEDI_CB_OVERFLOW | COMEDI_CB_ERROR;
1244 }
1245 }
1246 if (events == 0) {
1247 /* Determine how much room is in the FIFO (in samples). */
1248 if ((dacstat & PCI230P2_DAC_FIFO_FULL) != 0)
1249 room = PCI230P2_DAC_FIFOROOM_FULL;
1250 else if ((dacstat & PCI230P2_DAC_FIFO_HALF) != 0)
1251 room = PCI230P2_DAC_FIFOROOM_HALFTOFULL;
1252 else if ((dacstat & PCI230P2_DAC_FIFO_EMPTY) != 0)
1253 room = PCI230P2_DAC_FIFOROOM_EMPTY;
1254 else
1255 room = PCI230P2_DAC_FIFOROOM_ONETOHALF;
1256 /* Convert room to number of scans that can be added. */
1257 room /= cmd->chanlist_len;
1258 /* Determine number of scans to process. */
1259 if (num_scans > room)
1260 num_scans = room;
1261 /* Process scans. */
1262 for (n = 0; n < num_scans; n++) {
1263 for (i = 0; i < cmd->chanlist_len; i++) {
1264 short datum;
1265
1266 comedi_buf_get(async, &datum);
1267 pci230_ao_write_fifo(dev, datum,
1268 CR_CHAN(cmd->chanlist[i]));
1269 }
1270 }
1271 events |= COMEDI_CB_EOS | COMEDI_CB_BLOCK;
1272 if (!devpriv->ao_continuous) {
1273 devpriv->ao_scan_count -= num_scans;
1274 if (devpriv->ao_scan_count == 0) {
1275 /* All data for the command has been written
1276 * to FIFO. Set FIFO interrupt trigger level
1277 * to 'empty'. */
1278 devpriv->daccon = (devpriv->daccon
1279 &
1280 ~PCI230P2_DAC_INT_FIFO_MASK)
1281 | PCI230P2_DAC_INT_FIFO_EMPTY;
1282 outw(devpriv->daccon,
1283 dev->iobase + PCI230_DACCON);
1284 }
1285 }
1286 /* Check if FIFO underrun occurred while writing to FIFO. */
1287 dacstat = inw(dev->iobase + PCI230_DACCON);
1288 if ((dacstat & PCI230P2_DAC_FIFO_UNDERRUN_LATCHED) != 0) {
1289 comedi_error(dev, "AO FIFO underrun");
1290 events |= COMEDI_CB_OVERFLOW | COMEDI_CB_ERROR;
1291 }
1292 }
1293 if ((events & (COMEDI_CB_EOA | COMEDI_CB_ERROR | COMEDI_CB_OVERFLOW))
1294 != 0) {
1295 /* Stopping AO due to completion or error. */
1296 pci230_ao_stop(dev, s);
1297 running = 0;
1298 } else {
1299 running = 1;
1300 }
1301 async->events |= events;
1302 return running;
1303 }
1304
1305 static int pci230_ao_inttrig_scan_begin(struct comedi_device *dev,
1306 struct comedi_subdevice *s,
1307 unsigned int trig_num)
1308 {
1309 struct pci230_private *devpriv = dev->private;
1310 unsigned long irqflags;
1311
1312 if (trig_num != 0)
1313 return -EINVAL;
1314
1315 spin_lock_irqsave(&devpriv->ao_stop_spinlock, irqflags);
1316 if (test_bit(AO_CMD_STARTED, &devpriv->state)) {
1317 /* Perform scan. */
1318 if (devpriv->hwver < 2) {
1319 /* Not using DAC FIFO. */
1320 spin_unlock_irqrestore(&devpriv->ao_stop_spinlock,
1321 irqflags);
1322 pci230_handle_ao_nofifo(dev, s);
1323 comedi_event(dev, s);
1324 } else {
1325 /* Using DAC FIFO. */
1326 /* Read DACSWTRIG register to trigger conversion. */
1327 inw(dev->iobase + PCI230P2_DACSWTRIG);
1328 spin_unlock_irqrestore(&devpriv->ao_stop_spinlock,
1329 irqflags);
1330 }
1331 /* Delay. Should driver be responsible for this? */
1332 /* XXX TODO: See if DAC busy bit can be used. */
1333 udelay(8);
1334 } else {
1335 spin_unlock_irqrestore(&devpriv->ao_stop_spinlock, irqflags);
1336 }
1337
1338 return 1;
1339 }
1340
1341 static void pci230_ao_start(struct comedi_device *dev,
1342 struct comedi_subdevice *s)
1343 {
1344 struct pci230_private *devpriv = dev->private;
1345 struct comedi_async *async = s->async;
1346 struct comedi_cmd *cmd = &async->cmd;
1347 unsigned long irqflags;
1348
1349 set_bit(AO_CMD_STARTED, &devpriv->state);
1350 if (!devpriv->ao_continuous && (devpriv->ao_scan_count == 0)) {
1351 /* An empty acquisition! */
1352 async->events |= COMEDI_CB_EOA;
1353 pci230_ao_stop(dev, s);
1354 comedi_event(dev, s);
1355 } else {
1356 if (devpriv->hwver >= 2) {
1357 /* Using DAC FIFO. */
1358 unsigned short scantrig;
1359 int run;
1360
1361 /* Preload FIFO data. */
1362 run = pci230_handle_ao_fifo(dev, s);
1363 comedi_event(dev, s);
1364 if (!run) {
1365 /* Stopped. */
1366 return;
1367 }
1368 /* Set scan trigger source. */
1369 switch (cmd->scan_begin_src) {
1370 case TRIG_TIMER:
1371 scantrig = PCI230P2_DAC_TRIG_Z2CT1;
1372 break;
1373 case TRIG_EXT:
1374 /* Trigger on EXTTRIG/EXTCONVCLK pin. */
1375 if ((cmd->scan_begin_arg & CR_INVERT) == 0) {
1376 /* +ve edge */
1377 scantrig = PCI230P2_DAC_TRIG_EXTP;
1378 } else {
1379 /* -ve edge */
1380 scantrig = PCI230P2_DAC_TRIG_EXTN;
1381 }
1382 break;
1383 case TRIG_INT:
1384 scantrig = PCI230P2_DAC_TRIG_SW;
1385 break;
1386 default:
1387 /* Shouldn't get here. */
1388 scantrig = PCI230P2_DAC_TRIG_NONE;
1389 break;
1390 }
1391 devpriv->daccon = (devpriv->daccon
1392 & ~PCI230P2_DAC_TRIG_MASK) |
1393 scantrig;
1394 outw(devpriv->daccon, dev->iobase + PCI230_DACCON);
1395
1396 }
1397 switch (cmd->scan_begin_src) {
1398 case TRIG_TIMER:
1399 if (devpriv->hwver < 2) {
1400 /* Not using DAC FIFO. */
1401 /* Enable CT1 timer interrupt. */
1402 spin_lock_irqsave(&devpriv->isr_spinlock,
1403 irqflags);
1404 devpriv->int_en |= PCI230_INT_ZCLK_CT1;
1405 devpriv->ier |= PCI230_INT_ZCLK_CT1;
1406 outb(devpriv->ier,
1407 devpriv->iobase1 + PCI230_INT_SCE);
1408 spin_unlock_irqrestore(&devpriv->isr_spinlock,
1409 irqflags);
1410 }
1411 /* Set CT1 gate high to start counting. */
1412 outb(GAT_CONFIG(1, GAT_VCC),
1413 devpriv->iobase1 + PCI230_ZGAT_SCE);
1414 break;
1415 case TRIG_INT:
1416 async->inttrig = pci230_ao_inttrig_scan_begin;
1417 break;
1418 }
1419 if (devpriv->hwver >= 2) {
1420 /* Using DAC FIFO. Enable DAC FIFO interrupt. */
1421 spin_lock_irqsave(&devpriv->isr_spinlock, irqflags);
1422 devpriv->int_en |= PCI230P2_INT_DAC;
1423 devpriv->ier |= PCI230P2_INT_DAC;
1424 outb(devpriv->ier, devpriv->iobase1 + PCI230_INT_SCE);
1425 spin_unlock_irqrestore(&devpriv->isr_spinlock,
1426 irqflags);
1427 }
1428 }
1429 }
1430
1431 static int pci230_ao_inttrig_start(struct comedi_device *dev,
1432 struct comedi_subdevice *s,
1433 unsigned int trig_num)
1434 {
1435 if (trig_num != 0)
1436 return -EINVAL;
1437
1438 s->async->inttrig = NULL;
1439 pci230_ao_start(dev, s);
1440
1441 return 1;
1442 }
1443
1444 static int pci230_ao_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
1445 {
1446 struct pci230_private *devpriv = dev->private;
1447 unsigned short daccon;
1448 unsigned int range;
1449
1450 /* Get the command. */
1451 struct comedi_cmd *cmd = &s->async->cmd;
1452
1453 if (cmd->scan_begin_src == TRIG_TIMER) {
1454 /* Claim Z2-CT1. */
1455 if (!get_one_resource(dev, RES_Z2CT1, OWNER_AOCMD))
1456 return -EBUSY;
1457
1458 }
1459
1460 /* Get number of scans required. */
1461 if (cmd->stop_src == TRIG_COUNT) {
1462 devpriv->ao_scan_count = cmd->stop_arg;
1463 devpriv->ao_continuous = 0;
1464 } else {
1465 /* TRIG_NONE, user calls cancel. */
1466 devpriv->ao_scan_count = 0;
1467 devpriv->ao_continuous = 1;
1468 }
1469
1470 /* Set range - see analogue output range table; 0 => unipolar 10V,
1471 * 1 => bipolar +/-10V range scale */
1472 range = CR_RANGE(cmd->chanlist[0]);
1473 devpriv->ao_bipolar = pci230_ao_bipolar[range];
1474 daccon = devpriv->ao_bipolar ? PCI230_DAC_OR_BIP : PCI230_DAC_OR_UNI;
1475 /* Use DAC FIFO for hardware version 2 onwards. */
1476 if (devpriv->hwver >= 2) {
1477 unsigned short dacen;
1478 unsigned int i;
1479
1480 dacen = 0;
1481 for (i = 0; i < cmd->chanlist_len; i++)
1482 dacen |= 1 << CR_CHAN(cmd->chanlist[i]);
1483
1484 /* Set channel scan list. */
1485 outw(dacen, dev->iobase + PCI230P2_DACEN);
1486 /*
1487 * Enable DAC FIFO.
1488 * Set DAC scan source to 'none'.
1489 * Set DAC FIFO interrupt trigger level to 'not half full'.
1490 * Reset DAC FIFO and clear underrun.
1491 *
1492 * N.B. DAC FIFO interrupts are currently disabled.
1493 */
1494 daccon |= PCI230P2_DAC_FIFO_EN | PCI230P2_DAC_FIFO_RESET
1495 | PCI230P2_DAC_FIFO_UNDERRUN_CLEAR
1496 | PCI230P2_DAC_TRIG_NONE | PCI230P2_DAC_INT_FIFO_NHALF;
1497 }
1498
1499 /* Set DACCON. */
1500 outw(daccon, dev->iobase + PCI230_DACCON);
1501 /* Preserve most of DACCON apart from write-only, transient bits. */
1502 devpriv->daccon = daccon
1503 & ~(PCI230P2_DAC_FIFO_RESET | PCI230P2_DAC_FIFO_UNDERRUN_CLEAR);
1504
1505 if (cmd->scan_begin_src == TRIG_TIMER) {
1506 /* Set the counter timer 1 to the specified scan frequency. */
1507 /* cmd->scan_begin_arg is sampling period in ns */
1508 /* gate it off for now. */
1509 outb(GAT_CONFIG(1, GAT_GND),
1510 devpriv->iobase1 + PCI230_ZGAT_SCE);
1511 pci230_ct_setup_ns_mode(dev, 1, I8254_MODE3,
1512 cmd->scan_begin_arg,
1513 cmd->flags & TRIG_ROUND_MASK);
1514 }
1515
1516 /* N.B. cmd->start_src == TRIG_INT */
1517 s->async->inttrig = pci230_ao_inttrig_start;
1518
1519 return 0;
1520 }
1521
1522 static int pci230_ao_cancel(struct comedi_device *dev,
1523 struct comedi_subdevice *s)
1524 {
1525 pci230_ao_stop(dev, s);
1526 return 0;
1527 }
1528
1529 static int pci230_ai_check_scan_period(struct comedi_cmd *cmd)
1530 {
1531 unsigned int min_scan_period, chanlist_len;
1532 int err = 0;
1533
1534 chanlist_len = cmd->chanlist_len;
1535 if (cmd->chanlist_len == 0)
1536 chanlist_len = 1;
1537
1538 min_scan_period = chanlist_len * cmd->convert_arg;
1539 if ((min_scan_period < chanlist_len)
1540 || (min_scan_period < cmd->convert_arg)) {
1541 /* Arithmetic overflow. */
1542 min_scan_period = UINT_MAX;
1543 err++;
1544 }
1545 if (cmd->scan_begin_arg < min_scan_period) {
1546 cmd->scan_begin_arg = min_scan_period;
1547 err++;
1548 }
1549
1550 return !err;
1551 }
1552
1553 static int pci230_ai_cmdtest(struct comedi_device *dev,
1554 struct comedi_subdevice *s, struct comedi_cmd *cmd)
1555 {
1556 const struct pci230_board *thisboard = comedi_board(dev);
1557 struct pci230_private *devpriv = dev->private;
1558 int err = 0;
1559 unsigned int tmp;
1560
1561 /* Step 1 : check if triggers are trivially valid */
1562
1563 err |= cfc_check_trigger_src(&cmd->start_src, TRIG_NOW | TRIG_INT);
1564
1565 tmp = TRIG_FOLLOW | TRIG_TIMER | TRIG_INT;
1566 if ((thisboard->have_dio) || (thisboard->min_hwver > 0)) {
1567 /*
1568 * Unfortunately, we cannot trigger a scan off an external
1569 * source on the PCI260 board, since it uses the PPIC0 (DIO)
1570 * input, which isn't present on the PCI260. For PCI260+
1571 * we can use the EXTTRIG/EXTCONVCLK input on pin 17 instead.
1572 */
1573 tmp |= TRIG_EXT;
1574 }
1575 err |= cfc_check_trigger_src(&cmd->scan_begin_src, tmp);
1576 err |= cfc_check_trigger_src(&cmd->convert_src,
1577 TRIG_TIMER | TRIG_INT | TRIG_EXT);
1578 err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
1579 err |= cfc_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE);
1580
1581 if (err)
1582 return 1;
1583
1584 /* Step 2a : make sure trigger sources are unique */
1585
1586 err |= cfc_check_trigger_is_unique(cmd->start_src);
1587 err |= cfc_check_trigger_is_unique(cmd->scan_begin_src);
1588 err |= cfc_check_trigger_is_unique(cmd->convert_src);
1589 err |= cfc_check_trigger_is_unique(cmd->stop_src);
1590
1591 /* Step 2b : and mutually compatible */
1592
1593 /*
1594 * If scan_begin_src is not TRIG_FOLLOW, then a monostable will be
1595 * set up to generate a fixed number of timed conversion pulses.
1596 */
1597 if ((cmd->scan_begin_src != TRIG_FOLLOW)
1598 && (cmd->convert_src != TRIG_TIMER))
1599 err |= -EINVAL;
1600
1601 if (err)
1602 return 2;
1603
1604 /* Step 3: check if arguments are trivially valid */
1605
1606 err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0);
1607
1608 #define MAX_SPEED_AI_SE 3200 /* PCI230 SE: 3200 ns => 312.5 kHz */
1609 #define MAX_SPEED_AI_DIFF 8000 /* PCI230 DIFF: 8000 ns => 125 kHz */
1610 #define MAX_SPEED_AI_PLUS 4000 /* PCI230+: 4000 ns => 250 kHz */
1611 #define MIN_SPEED_AI 4294967295u /* 4294967295ns = 4.29s */
1612 /*- Comedi limit due to unsigned int cmd. Driver limit
1613 * = 2^16 (16bit * counter) * 1000000ns (1kHz onboard
1614 * clock) = 65.536s */
1615
1616 if (cmd->convert_src == TRIG_TIMER) {
1617 unsigned int max_speed_ai;
1618
1619 if (devpriv->hwver == 0) {
1620 /* PCI230 or PCI260. Max speed depends whether
1621 * single-ended or pseudo-differential. */
1622 if (cmd->chanlist && (cmd->chanlist_len > 0)) {
1623 /* Peek analogue reference of first channel. */
1624 if (CR_AREF(cmd->chanlist[0]) == AREF_DIFF)
1625 max_speed_ai = MAX_SPEED_AI_DIFF;
1626 else
1627 max_speed_ai = MAX_SPEED_AI_SE;
1628
1629 } else {
1630 /* No channel list. Assume single-ended. */
1631 max_speed_ai = MAX_SPEED_AI_SE;
1632 }
1633 } else {
1634 /* PCI230+ or PCI260+. */
1635 max_speed_ai = MAX_SPEED_AI_PLUS;
1636 }
1637
1638 err |= cfc_check_trigger_arg_min(&cmd->convert_arg,
1639 max_speed_ai);
1640 err |= cfc_check_trigger_arg_max(&cmd->convert_arg,
1641 MIN_SPEED_AI);
1642 } else if (cmd->convert_src == TRIG_EXT) {
1643 /*
1644 * external trigger
1645 *
1646 * convert_arg == (CR_EDGE | 0)
1647 * => trigger on +ve edge.
1648 * convert_arg == (CR_EDGE | CR_INVERT | 0)
1649 * => trigger on -ve edge.
1650 */
1651 if ((cmd->convert_arg & CR_FLAGS_MASK) != 0) {
1652 /* Trigger number must be 0. */
1653 if ((cmd->convert_arg & ~CR_FLAGS_MASK) != 0) {
1654 cmd->convert_arg = COMBINE(cmd->convert_arg, 0,
1655 ~CR_FLAGS_MASK);
1656 err |= -EINVAL;
1657 }
1658 /* The only flags allowed are CR_INVERT and CR_EDGE.
1659 * CR_EDGE is required. */
1660 if ((cmd->convert_arg & (CR_FLAGS_MASK & ~CR_INVERT))
1661 != CR_EDGE) {
1662 /* Set CR_EDGE, preserve CR_INVERT. */
1663 cmd->convert_arg = COMBINE(cmd->start_arg,
1664 (CR_EDGE | 0),
1665 CR_FLAGS_MASK &
1666 ~CR_INVERT);
1667 err |= -EINVAL;
1668 }
1669 } else {
1670 /* Backwards compatibility with previous versions. */
1671 /* convert_arg == 0 => trigger on -ve edge. */
1672 /* convert_arg == 1 => trigger on +ve edge. */
1673 err |= cfc_check_trigger_arg_max(&cmd->convert_arg, 1);
1674 }
1675 } else {
1676 err |= cfc_check_trigger_arg_is(&cmd->convert_arg, 0);
1677 }
1678
1679 err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len);
1680
1681 if (cmd->stop_src == TRIG_NONE)
1682 err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0);
1683
1684 if (cmd->scan_begin_src == TRIG_EXT) {
1685 /* external "trigger" to begin each scan
1686 * scan_begin_arg==0 => use PPC0 input -> gate of CT0 -> gate
1687 * of CT2 (sample convert trigger is CT2) */
1688 if ((cmd->scan_begin_arg & ~CR_FLAGS_MASK) != 0) {
1689 cmd->scan_begin_arg = COMBINE(cmd->scan_begin_arg, 0,
1690 ~CR_FLAGS_MASK);
1691 err |= -EINVAL;
1692 }
1693 /* The only flag allowed is CR_EDGE, which is ignored. */
1694 if ((cmd->scan_begin_arg & CR_FLAGS_MASK & ~CR_EDGE) != 0) {
1695 cmd->scan_begin_arg = COMBINE(cmd->scan_begin_arg, 0,
1696 CR_FLAGS_MASK & ~CR_EDGE);
1697 err |= -EINVAL;
1698 }
1699 } else if (cmd->scan_begin_src == TRIG_TIMER) {
1700 /* N.B. cmd->convert_arg is also TRIG_TIMER */
1701 if (!pci230_ai_check_scan_period(cmd))
1702 err |= -EINVAL;
1703
1704 } else {
1705 err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, 0);
1706 }
1707
1708 if (err)
1709 return 3;
1710
1711 /* Step 4: fix up any arguments.
1712 * "argument conflict" returned by comedilib to user mode process
1713 * if this fails. */
1714
1715 if (cmd->convert_src == TRIG_TIMER) {
1716 tmp = cmd->convert_arg;
1717 pci230_ns_to_single_timer(&cmd->convert_arg,
1718 cmd->flags & TRIG_ROUND_MASK);
1719 if (tmp != cmd->convert_arg)
1720 err++;
1721 }
1722
1723 if (cmd->scan_begin_src == TRIG_TIMER) {
1724 /* N.B. cmd->convert_arg is also TRIG_TIMER */
1725 tmp = cmd->scan_begin_arg;
1726 pci230_ns_to_single_timer(&cmd->scan_begin_arg,
1727 cmd->flags & TRIG_ROUND_MASK);
1728 if (!pci230_ai_check_scan_period(cmd)) {
1729 /* Was below minimum required. Round up. */
1730 pci230_ns_to_single_timer(&cmd->scan_begin_arg,
1731 TRIG_ROUND_UP);
1732 pci230_ai_check_scan_period(cmd);
1733 }
1734 if (tmp != cmd->scan_begin_arg)
1735 err++;
1736 }
1737
1738 if (err)
1739 return 4;
1740
1741 /* Step 5: check channel list if it exists. */
1742
1743 if (cmd->chanlist && cmd->chanlist_len > 0) {
1744 enum {
1745 seq_err = 1 << 0,
1746 rangepair_err = 1 << 1,
1747 polarity_err = 1 << 2,
1748 aref_err = 1 << 3,
1749 diffchan_err = 1 << 4,
1750 buggy_chan0_err = 1 << 5
1751 };
1752 unsigned int errors;
1753 unsigned int chan, prev_chan;
1754 unsigned int range, prev_range;
1755 unsigned int polarity, prev_polarity;
1756 unsigned int aref, prev_aref;
1757 unsigned int subseq_len;
1758 unsigned int n;
1759
1760 subseq_len = 0;
1761 errors = 0;
1762 prev_chan = prev_aref = prev_range = prev_polarity = 0;
1763 for (n = 0; n < cmd->chanlist_len; n++) {
1764 chan = CR_CHAN(cmd->chanlist[n]);
1765 range = CR_RANGE(cmd->chanlist[n]);
1766 aref = CR_AREF(cmd->chanlist[n]);
1767 polarity = pci230_ai_bipolar[range];
1768 /* Only the first half of the channels are available if
1769 * differential. (These are remapped in software. In
1770 * hardware, only the even channels are available.) */
1771 if ((aref == AREF_DIFF)
1772 && (chan >= (s->n_chan / 2))) {
1773 errors |= diffchan_err;
1774 }
1775 if (n > 0) {
1776 /* Channel numbers must strictly increase or
1777 * subsequence must repeat exactly. */
1778 if ((chan <= prev_chan)
1779 && (subseq_len == 0)) {
1780 subseq_len = n;
1781 }
1782 if ((subseq_len > 0)
1783 && (cmd->chanlist[n] !=
1784 cmd->chanlist[n % subseq_len])) {
1785 errors |= seq_err;
1786 }
1787 /* Channels must have same AREF. */
1788 if (aref != prev_aref)
1789 errors |= aref_err;
1790
1791 /* Channel ranges must have same polarity. */
1792 if (polarity != prev_polarity)
1793 errors |= polarity_err;
1794
1795 /* Single-ended channel pairs must have same
1796 * range. */
1797 if ((aref != AREF_DIFF)
1798 && (((chan ^ prev_chan) & ~1) == 0)
1799 && (range != prev_range)) {
1800 errors |= rangepair_err;
1801 }
1802 }
1803 prev_chan = chan;
1804 prev_range = range;
1805 prev_aref = aref;
1806 prev_polarity = polarity;
1807 }
1808 if (subseq_len == 0) {
1809 /* Subsequence is whole sequence. */
1810 subseq_len = n;
1811 }
1812 /* If channel list is a repeating subsequence, need a whole
1813 * number of repeats. */
1814 if ((n % subseq_len) != 0)
1815 errors |= seq_err;
1816
1817 if ((devpriv->hwver > 0) && (devpriv->hwver < 4)) {
1818 /*
1819 * Buggy PCI230+ or PCI260+ requires channel 0 to be
1820 * (first) in the sequence if the sequence contains
1821 * more than one channel. Hardware versions 1 and 2
1822 * have the bug. There is no hardware version 3.
1823 *
1824 * Actually, there are two firmwares that report
1825 * themselves as hardware version 1 (the boards
1826 * have different ADC chips with slightly different
1827 * timing requirements, which was supposed to be
1828 * invisible to software). The first one doesn't
1829 * seem to have the bug, but the second one
1830 * does, and we can't tell them apart!
1831 */
1832 if ((subseq_len > 1)
1833 && (CR_CHAN(cmd->chanlist[0]) != 0)) {
1834 errors |= buggy_chan0_err;
1835 }
1836 }
1837 if (errors != 0) {
1838 err++;
1839 if ((errors & seq_err) != 0) {
1840 DPRINTK("comedi%d: amplc_pci230: ai_cmdtest: "
1841 "channel numbers must increase or "
1842 "sequence must repeat exactly\n",
1843 dev->minor);
1844 }
1845 if ((errors & rangepair_err) != 0) {
1846 DPRINTK("comedi%d: amplc_pci230: ai_cmdtest: "
1847 "single-ended channel pairs must "
1848 "have the same range\n", dev->minor);
1849 }
1850 if ((errors & polarity_err) != 0) {
1851 DPRINTK("comedi%d: amplc_pci230: ai_cmdtest: "
1852 "channel sequence ranges must be all "
1853 "bipolar or all unipolar\n",
1854 dev->minor);
1855 }
1856 if ((errors & aref_err) != 0) {
1857 DPRINTK("comedi%d: amplc_pci230: ai_cmdtest: "
1858 "channel sequence analogue references "
1859 "must be all the same (single-ended "
1860 "or differential)\n", dev->minor);
1861 }
1862 if ((errors & diffchan_err) != 0) {
1863 DPRINTK("comedi%d: amplc_pci230: ai_cmdtest: "
1864 "differential channel number out of "
1865 "range 0 to %u\n", dev->minor,
1866 (s->n_chan / 2) - 1);
1867 }
1868 if ((errors & buggy_chan0_err) != 0) {
1869 dev_info(dev->class_dev,
1870 "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",
1871 devpriv->hwver);
1872 }
1873 }
1874 }
1875
1876 if (err)
1877 return 5;
1878
1879 return 0;
1880 }
1881
1882 static void pci230_ai_update_fifo_trigger_level(struct comedi_device *dev,
1883 struct comedi_subdevice *s)
1884 {
1885 struct pci230_private *devpriv = dev->private;
1886 struct comedi_cmd *cmd = &s->async->cmd;
1887 unsigned int scanlen = cmd->scan_end_arg;
1888 unsigned int wake;
1889 unsigned short triglev;
1890 unsigned short adccon;
1891
1892 if ((cmd->flags & TRIG_WAKE_EOS) != 0) {
1893 /* Wake at end of scan. */
1894 wake = scanlen - devpriv->ai_scan_pos;
1895 } else {
1896 if (devpriv->ai_continuous
1897 || (devpriv->ai_scan_count >= PCI230_ADC_FIFOLEVEL_HALFFULL)
1898 || (scanlen >= PCI230_ADC_FIFOLEVEL_HALFFULL)) {
1899 wake = PCI230_ADC_FIFOLEVEL_HALFFULL;
1900 } else {
1901 wake = (devpriv->ai_scan_count * scanlen)
1902 - devpriv->ai_scan_pos;
1903 }
1904 }
1905 if (wake >= PCI230_ADC_FIFOLEVEL_HALFFULL) {
1906 triglev = PCI230_ADC_INT_FIFO_HALF;
1907 } else {
1908 if ((wake > 1) && (devpriv->hwver > 0)) {
1909 /* PCI230+/260+ programmable FIFO interrupt level. */
1910 if (devpriv->adcfifothresh != wake) {
1911 devpriv->adcfifothresh = wake;
1912 outw(wake, dev->iobase + PCI230P_ADCFFTH);
1913 }
1914 triglev = PCI230P_ADC_INT_FIFO_THRESH;
1915 } else {
1916 triglev = PCI230_ADC_INT_FIFO_NEMPTY;
1917 }
1918 }
1919 adccon = (devpriv->adccon & ~PCI230_ADC_INT_FIFO_MASK) | triglev;
1920 if (adccon != devpriv->adccon) {
1921 devpriv->adccon = adccon;
1922 outw(adccon, dev->iobase + PCI230_ADCCON);
1923 }
1924 }
1925
1926 static int pci230_ai_inttrig_convert(struct comedi_device *dev,
1927 struct comedi_subdevice *s,
1928 unsigned int trig_num)
1929 {
1930 struct pci230_private *devpriv = dev->private;
1931 unsigned long irqflags;
1932
1933 if (trig_num != 0)
1934 return -EINVAL;
1935
1936 spin_lock_irqsave(&devpriv->ai_stop_spinlock, irqflags);
1937 if (test_bit(AI_CMD_STARTED, &devpriv->state)) {
1938 unsigned int delayus;
1939
1940 /* Trigger conversion by toggling Z2-CT2 output. Finish
1941 * with output high. */
1942 i8254_set_mode(devpriv->iobase1 + PCI230_Z2_CT_BASE, 0, 2,
1943 I8254_MODE0);
1944 i8254_set_mode(devpriv->iobase1 + PCI230_Z2_CT_BASE, 0, 2,
1945 I8254_MODE1);
1946 /* Delay. Should driver be responsible for this? An
1947 * alternative would be to wait until conversion is complete,
1948 * but we can't tell when it's complete because the ADC busy
1949 * bit has a different meaning when FIFO enabled (and when
1950 * FIFO not enabled, it only works for software triggers). */
1951 if (((devpriv->adccon & PCI230_ADC_IM_MASK)
1952 == PCI230_ADC_IM_DIF)
1953 && (devpriv->hwver == 0)) {
1954 /* PCI230/260 in differential mode */
1955 delayus = 8;
1956 } else {
1957 /* single-ended or PCI230+/260+ */
1958 delayus = 4;
1959 }
1960 spin_unlock_irqrestore(&devpriv->ai_stop_spinlock, irqflags);
1961 udelay(delayus);
1962 } else {
1963 spin_unlock_irqrestore(&devpriv->ai_stop_spinlock, irqflags);
1964 }
1965
1966 return 1;
1967 }
1968
1969 static int pci230_ai_inttrig_scan_begin(struct comedi_device *dev,
1970 struct comedi_subdevice *s,
1971 unsigned int trig_num)
1972 {
1973 struct pci230_private *devpriv = dev->private;
1974 unsigned long irqflags;
1975 unsigned char zgat;
1976
1977 if (trig_num != 0)
1978 return -EINVAL;
1979
1980 spin_lock_irqsave(&devpriv->ai_stop_spinlock, irqflags);
1981 if (test_bit(AI_CMD_STARTED, &devpriv->state)) {
1982 /* Trigger scan by waggling CT0 gate source. */
1983 zgat = GAT_CONFIG(0, GAT_GND);
1984 outb(zgat, devpriv->iobase1 + PCI230_ZGAT_SCE);
1985 zgat = GAT_CONFIG(0, GAT_VCC);
1986 outb(zgat, devpriv->iobase1 + PCI230_ZGAT_SCE);
1987 }
1988 spin_unlock_irqrestore(&devpriv->ai_stop_spinlock, irqflags);
1989
1990 return 1;
1991 }
1992
1993 static void pci230_ai_stop(struct comedi_device *dev,
1994 struct comedi_subdevice *s)
1995 {
1996 struct pci230_private *devpriv = dev->private;
1997 unsigned long irqflags;
1998 struct comedi_cmd *cmd;
1999 int started;
2000
2001 spin_lock_irqsave(&devpriv->ai_stop_spinlock, irqflags);
2002 started = test_and_clear_bit(AI_CMD_STARTED, &devpriv->state);
2003 spin_unlock_irqrestore(&devpriv->ai_stop_spinlock, irqflags);
2004 if (!started)
2005 return;
2006 cmd = &s->async->cmd;
2007 if (cmd->convert_src == TRIG_TIMER) {
2008 /* Stop conversion rate generator. */
2009 pci230_cancel_ct(dev, 2);
2010 }
2011 if (cmd->scan_begin_src != TRIG_FOLLOW) {
2012 /* Stop scan period monostable. */
2013 pci230_cancel_ct(dev, 0);
2014 }
2015 spin_lock_irqsave(&devpriv->isr_spinlock, irqflags);
2016 /* Disable ADC interrupt and wait for interrupt routine to finish
2017 * running unless we are called from the interrupt routine. */
2018 devpriv->int_en &= ~PCI230_INT_ADC;
2019 while (devpriv->intr_running && devpriv->intr_cpuid != THISCPU) {
2020 spin_unlock_irqrestore(&devpriv->isr_spinlock, irqflags);
2021 spin_lock_irqsave(&devpriv->isr_spinlock, irqflags);
2022 }
2023 if (devpriv->ier != devpriv->int_en) {
2024 devpriv->ier = devpriv->int_en;
2025 outb(devpriv->ier, devpriv->iobase1 + PCI230_INT_SCE);
2026 }
2027 spin_unlock_irqrestore(&devpriv->isr_spinlock, irqflags);
2028 /* Reset FIFO, disable FIFO and set start conversion source to none.
2029 * Keep se/diff and bip/uni settings */
2030 devpriv->adccon = (devpriv->adccon & (PCI230_ADC_IR_MASK
2031 | PCI230_ADC_IM_MASK)) |
2032 PCI230_ADC_TRIG_NONE;
2033 outw(devpriv->adccon | PCI230_ADC_FIFO_RESET,
2034 dev->iobase + PCI230_ADCCON);
2035 /* Release resources. */
2036 put_all_resources(dev, OWNER_AICMD);
2037 }
2038
2039 static void pci230_ai_start(struct comedi_device *dev,
2040 struct comedi_subdevice *s)
2041 {
2042 struct pci230_private *devpriv = dev->private;
2043 unsigned long irqflags;
2044 unsigned short conv;
2045 struct comedi_async *async = s->async;
2046 struct comedi_cmd *cmd = &async->cmd;
2047
2048 set_bit(AI_CMD_STARTED, &devpriv->state);
2049 if (!devpriv->ai_continuous && (devpriv->ai_scan_count == 0)) {
2050 /* An empty acquisition! */
2051 async->events |= COMEDI_CB_EOA;
2052 pci230_ai_stop(dev, s);
2053 comedi_event(dev, s);
2054 } else {
2055 /* Enable ADC FIFO trigger level interrupt. */
2056 spin_lock_irqsave(&devpriv->isr_spinlock, irqflags);
2057 devpriv->int_en |= PCI230_INT_ADC;
2058 devpriv->ier |= PCI230_INT_ADC;
2059 outb(devpriv->ier, devpriv->iobase1 + PCI230_INT_SCE);
2060 spin_unlock_irqrestore(&devpriv->isr_spinlock, irqflags);
2061
2062 /* Update conversion trigger source which is currently set
2063 * to CT2 output, which is currently stuck high. */
2064 switch (cmd->convert_src) {
2065 default:
2066 conv = PCI230_ADC_TRIG_NONE;
2067 break;
2068 case TRIG_TIMER:
2069 /* Using CT2 output. */
2070 conv = PCI230_ADC_TRIG_Z2CT2;
2071 break;
2072 case TRIG_EXT:
2073 if ((cmd->convert_arg & CR_EDGE) != 0) {
2074 if ((cmd->convert_arg & CR_INVERT) == 0) {
2075 /* Trigger on +ve edge. */
2076 conv = PCI230_ADC_TRIG_EXTP;
2077 } else {
2078 /* Trigger on -ve edge. */
2079 conv = PCI230_ADC_TRIG_EXTN;
2080 }
2081 } else {
2082 /* Backwards compatibility. */
2083 if (cmd->convert_arg != 0) {
2084 /* Trigger on +ve edge. */
2085 conv = PCI230_ADC_TRIG_EXTP;
2086 } else {
2087 /* Trigger on -ve edge. */
2088 conv = PCI230_ADC_TRIG_EXTN;
2089 }
2090 }
2091 break;
2092 case TRIG_INT:
2093 /* Use CT2 output for software trigger due to problems
2094 * in differential mode on PCI230/260. */
2095 conv = PCI230_ADC_TRIG_Z2CT2;
2096 break;
2097 }
2098 devpriv->adccon = (devpriv->adccon & ~PCI230_ADC_TRIG_MASK)
2099 | conv;
2100 outw(devpriv->adccon, dev->iobase + PCI230_ADCCON);
2101 if (cmd->convert_src == TRIG_INT)
2102 async->inttrig = pci230_ai_inttrig_convert;
2103
2104 /* Update FIFO interrupt trigger level, which is currently
2105 * set to "full". */
2106 pci230_ai_update_fifo_trigger_level(dev, s);
2107 if (cmd->convert_src == TRIG_TIMER) {
2108 /* Update timer gates. */
2109 unsigned char zgat;
2110
2111 if (cmd->scan_begin_src != TRIG_FOLLOW) {
2112 /* Conversion timer CT2 needs to be gated by
2113 * inverted output of monostable CT2. */
2114 zgat = GAT_CONFIG(2, GAT_NOUTNM2);
2115 } else {
2116 /* Conversion timer CT2 needs to be gated on
2117 * continuously. */
2118 zgat = GAT_CONFIG(2, GAT_VCC);
2119 }
2120 outb(zgat, devpriv->iobase1 + PCI230_ZGAT_SCE);
2121 if (cmd->scan_begin_src != TRIG_FOLLOW) {
2122 /* Set monostable CT0 trigger source. */
2123 switch (cmd->scan_begin_src) {
2124 default:
2125 zgat = GAT_CONFIG(0, GAT_VCC);
2126 break;
2127 case TRIG_EXT:
2128 /*
2129 * For CT0 on PCI230, the external
2130 * trigger (gate) signal comes from
2131 * PPC0, which is channel 16 of the DIO
2132 * subdevice. The application needs to
2133 * configure this as an input in order
2134 * to use it as an external scan
2135 * trigger.
2136 */
2137 zgat = GAT_CONFIG(0, GAT_EXT);
2138 break;
2139 case TRIG_TIMER:
2140 /*
2141 * Monostable CT0 triggered by rising
2142 * edge on inverted output of CT1
2143 * (falling edge on CT1).
2144 */
2145 zgat = GAT_CONFIG(0, GAT_NOUTNM2);
2146 break;
2147 case TRIG_INT:
2148 /*
2149 * Monostable CT0 is triggered by
2150 * inttrig function waggling the CT0
2151 * gate source.
2152 */
2153 zgat = GAT_CONFIG(0, GAT_VCC);
2154 break;
2155 }
2156 outb(zgat, devpriv->iobase1 + PCI230_ZGAT_SCE);
2157 switch (cmd->scan_begin_src) {
2158 case TRIG_TIMER:
2159 /* Scan period timer CT1 needs to be
2160 * gated on to start counting. */
2161 zgat = GAT_CONFIG(1, GAT_VCC);
2162 outb(zgat, devpriv->iobase1
2163 + PCI230_ZGAT_SCE);
2164 break;
2165 case TRIG_INT:
2166 async->inttrig =
2167 pci230_ai_inttrig_scan_begin;
2168 break;
2169 }
2170 }
2171 } else if (cmd->convert_src != TRIG_INT) {
2172 /* No longer need Z2-CT2. */
2173 put_one_resource(dev, RES_Z2CT2, OWNER_AICMD);
2174 }
2175 }
2176 }
2177
2178 static int pci230_ai_inttrig_start(struct comedi_device *dev,
2179 struct comedi_subdevice *s,
2180 unsigned int trig_num)
2181 {
2182 if (trig_num != 0)
2183 return -EINVAL;
2184
2185 s->async->inttrig = NULL;
2186 pci230_ai_start(dev, s);
2187
2188 return 1;
2189 }
2190
2191 static void pci230_handle_ai(struct comedi_device *dev,
2192 struct comedi_subdevice *s)
2193 {
2194 struct pci230_private *devpriv = dev->private;
2195 unsigned int events = 0;
2196 unsigned int status_fifo;
2197 unsigned int i;
2198 unsigned int todo;
2199 unsigned int fifoamount;
2200 struct comedi_async *async = s->async;
2201 unsigned int scanlen = async->cmd.scan_end_arg;
2202
2203 /* Determine number of samples to read. */
2204 if (devpriv->ai_continuous) {
2205 todo = PCI230_ADC_FIFOLEVEL_HALFFULL;
2206 } else if (devpriv->ai_scan_count == 0) {
2207 todo = 0;
2208 } else if ((devpriv->ai_scan_count > PCI230_ADC_FIFOLEVEL_HALFFULL)
2209 || (scanlen > PCI230_ADC_FIFOLEVEL_HALFFULL)) {
2210 todo = PCI230_ADC_FIFOLEVEL_HALFFULL;
2211 } else {
2212 todo = (devpriv->ai_scan_count * scanlen)
2213 - devpriv->ai_scan_pos;
2214 if (todo > PCI230_ADC_FIFOLEVEL_HALFFULL)
2215 todo = PCI230_ADC_FIFOLEVEL_HALFFULL;
2216 }
2217 if (todo == 0)
2218 return;
2219 fifoamount = 0;
2220 for (i = 0; i < todo; i++) {
2221 if (fifoamount == 0) {
2222 /* Read FIFO state. */
2223 status_fifo = inw(dev->iobase + PCI230_ADCCON);
2224 if ((status_fifo & PCI230_ADC_FIFO_FULL_LATCHED) != 0) {
2225 /* Report error otherwise FIFO overruns will go
2226 * unnoticed by the caller. */
2227 comedi_error(dev, "AI FIFO overrun");
2228 events |= COMEDI_CB_OVERFLOW | COMEDI_CB_ERROR;
2229 break;
2230 } else if ((status_fifo & PCI230_ADC_FIFO_EMPTY) != 0) {
2231 /* FIFO empty. */
2232 break;
2233 } else if ((status_fifo & PCI230_ADC_FIFO_HALF) != 0) {
2234 /* FIFO half full. */
2235 fifoamount = PCI230_ADC_FIFOLEVEL_HALFFULL;
2236 } else {
2237 /* FIFO not empty. */
2238 if (devpriv->hwver > 0) {
2239 /* Read PCI230+/260+ ADC FIFO level. */
2240 fifoamount = inw(dev->iobase
2241 + PCI230P_ADCFFLEV);
2242 if (fifoamount == 0) {
2243 /* Shouldn't happen. */
2244 break;
2245 }
2246 } else {
2247 fifoamount = 1;
2248 }
2249 }
2250 }
2251 /* Read sample and store in Comedi's circular buffer. */
2252 if (comedi_buf_put(async, pci230_ai_read(dev)) == 0) {
2253 events |= COMEDI_CB_ERROR | COMEDI_CB_OVERFLOW;
2254 comedi_error(dev, "AI buffer overflow");
2255 break;
2256 }
2257 fifoamount--;
2258 devpriv->ai_scan_pos++;
2259 if (devpriv->ai_scan_pos == scanlen) {
2260 /* End of scan. */
2261 devpriv->ai_scan_pos = 0;
2262 devpriv->ai_scan_count--;
2263 async->events |= COMEDI_CB_EOS;
2264 }
2265 }
2266 if (!devpriv->ai_continuous && (devpriv->ai_scan_count == 0)) {
2267 /* End of acquisition. */
2268 events |= COMEDI_CB_EOA;
2269 } else {
2270 /* More samples required, tell Comedi to block. */
2271 events |= COMEDI_CB_BLOCK;
2272 }
2273 async->events |= events;
2274 if ((async->events & (COMEDI_CB_EOA | COMEDI_CB_ERROR |
2275 COMEDI_CB_OVERFLOW)) != 0) {
2276 /* disable hardware conversions */
2277 pci230_ai_stop(dev, s);
2278 } else {
2279 /* update FIFO interrupt trigger level */
2280 pci230_ai_update_fifo_trigger_level(dev, s);
2281 }
2282 }
2283
2284 static int pci230_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
2285 {
2286 struct pci230_private *devpriv = dev->private;
2287 unsigned int i, chan, range, diff;
2288 unsigned int res_mask;
2289 unsigned short adccon, adcen;
2290 unsigned char zgat;
2291
2292 /* Get the command. */
2293 struct comedi_async *async = s->async;
2294 struct comedi_cmd *cmd = &async->cmd;
2295
2296 /*
2297 * Determine which shared resources are needed.
2298 */
2299 res_mask = 0;
2300 /* Need Z2-CT2 to supply a conversion trigger source at a high
2301 * logic level, even if not doing timed conversions. */
2302 res_mask |= (1U << RES_Z2CT2);
2303 if (cmd->scan_begin_src != TRIG_FOLLOW) {
2304 /* Using Z2-CT0 monostable to gate Z2-CT2 conversion timer */
2305 res_mask |= (1U << RES_Z2CT0);
2306 if (cmd->scan_begin_src == TRIG_TIMER) {
2307 /* Using Z2-CT1 for scan frequency */
2308 res_mask |= (1U << RES_Z2CT1);
2309 }
2310 }
2311 /* Claim resources. */
2312 if (!get_resources(dev, res_mask, OWNER_AICMD))
2313 return -EBUSY;
2314
2315
2316 /* Get number of scans required. */
2317 if (cmd->stop_src == TRIG_COUNT) {
2318 devpriv->ai_scan_count = cmd->stop_arg;
2319 devpriv->ai_continuous = 0;
2320 } else {
2321 /* TRIG_NONE, user calls cancel. */
2322 devpriv->ai_scan_count = 0;
2323 devpriv->ai_continuous = 1;
2324 }
2325 devpriv->ai_scan_pos = 0; /* Position within scan. */
2326
2327 /* Steps;
2328 * - Set channel scan list.
2329 * - Set channel gains.
2330 * - Enable and reset FIFO, specify uni/bip, se/diff, and set
2331 * start conversion source to point to something at a high logic
2332 * level (we use the output of counter/timer 2 for this purpose.
2333 * - PAUSE to allow things to settle down.
2334 * - Reset the FIFO again because it needs resetting twice and there
2335 * may have been a false conversion trigger on some versions of
2336 * PCI230/260 due to the start conversion source being set to a
2337 * high logic level.
2338 * - Enable ADC FIFO level interrupt.
2339 * - Set actual conversion trigger source and FIFO interrupt trigger
2340 * level.
2341 * - If convert_src is TRIG_TIMER, set up the timers.
2342 */
2343
2344 adccon = PCI230_ADC_FIFO_EN;
2345 adcen = 0;
2346
2347 if (CR_AREF(cmd->chanlist[0]) == AREF_DIFF) {
2348 /* Differential - all channels must be differential. */
2349 diff = 1;
2350 adccon |= PCI230_ADC_IM_DIF;
2351 } else {
2352 /* Single ended - all channels must be single-ended. */
2353 diff = 0;
2354 adccon |= PCI230_ADC_IM_SE;
2355 }
2356
2357 range = CR_RANGE(cmd->chanlist[0]);
2358 devpriv->ai_bipolar = pci230_ai_bipolar[range];
2359 if (devpriv->ai_bipolar)
2360 adccon |= PCI230_ADC_IR_BIP;
2361 else
2362 adccon |= PCI230_ADC_IR_UNI;
2363
2364 for (i = 0; i < cmd->chanlist_len; i++) {
2365 unsigned int gainshift;
2366
2367 chan = CR_CHAN(cmd->chanlist[i]);
2368 range = CR_RANGE(cmd->chanlist[i]);
2369 if (diff) {
2370 gainshift = 2 * chan;
2371 if (devpriv->hwver == 0) {
2372 /* Original PCI230/260 expects both inputs of
2373 * the differential channel to be enabled. */
2374 adcen |= 3 << gainshift;
2375 } else {
2376 /* PCI230+/260+ expects only one input of the
2377 * differential channel to be enabled. */
2378 adcen |= 1 << gainshift;
2379 }
2380 } else {
2381 gainshift = (chan & ~1);
2382 adcen |= 1 << chan;
2383 }
2384 devpriv->adcg = (devpriv->adcg & ~(3 << gainshift))
2385 | (pci230_ai_gain[range] << gainshift);
2386 }
2387
2388 /* Set channel scan list. */
2389 outw(adcen, dev->iobase + PCI230_ADCEN);
2390
2391 /* Set channel gains. */
2392 outw(devpriv->adcg, dev->iobase + PCI230_ADCG);
2393
2394 /* Set counter/timer 2 output high for use as the initial start
2395 * conversion source. */
2396 i8254_set_mode(devpriv->iobase1 + PCI230_Z2_CT_BASE, 0, 2, I8254_MODE1);
2397
2398 /* Temporarily use CT2 output as conversion trigger source and
2399 * temporarily set FIFO interrupt trigger level to 'full'. */
2400 adccon |= PCI230_ADC_INT_FIFO_FULL | PCI230_ADC_TRIG_Z2CT2;
2401
2402 /* Enable and reset FIFO, specify FIFO trigger level full, specify
2403 * uni/bip, se/diff, and temporarily set the start conversion source
2404 * to CT2 output. Note that CT2 output is currently high, and this
2405 * will produce a false conversion trigger on some versions of the
2406 * PCI230/260, but that will be dealt with later. */
2407 devpriv->adccon = adccon;
2408 outw(adccon | PCI230_ADC_FIFO_RESET, dev->iobase + PCI230_ADCCON);
2409
2410 /* Delay */
2411 /* Failure to include this will result in the first few channels'-worth
2412 * of data being corrupt, normally manifesting itself by large negative
2413 * voltages. It seems the board needs time to settle between the first
2414 * FIFO reset (above) and the second FIFO reset (below). Setting the
2415 * channel gains and scan list _before_ the first FIFO reset also
2416 * helps, though only slightly. */
2417 udelay(25);
2418
2419 /* Reset FIFO again. */
2420 outw(adccon | PCI230_ADC_FIFO_RESET, dev->iobase + PCI230_ADCCON);
2421
2422 if (cmd->convert_src == TRIG_TIMER) {
2423 /* Set up CT2 as conversion timer, but gate it off for now.
2424 * Note, counter/timer output 2 can be monitored on the
2425 * connector: PCI230 pin 21, PCI260 pin 18. */
2426 zgat = GAT_CONFIG(2, GAT_GND);
2427 outb(zgat, devpriv->iobase1 + PCI230_ZGAT_SCE);
2428 /* Set counter/timer 2 to the specified conversion period. */
2429 pci230_ct_setup_ns_mode(dev, 2, I8254_MODE3, cmd->convert_arg,
2430 cmd->flags & TRIG_ROUND_MASK);
2431 if (cmd->scan_begin_src != TRIG_FOLLOW) {
2432 /*
2433 * Set up monostable on CT0 output for scan timing. A
2434 * rising edge on the trigger (gate) input of CT0 will
2435 * trigger the monostable, causing its output to go low
2436 * for the configured period. The period depends on
2437 * the conversion period and the number of conversions
2438 * in the scan.
2439 *
2440 * Set the trigger high before setting up the
2441 * monostable to stop it triggering. The trigger
2442 * source will be changed later.
2443 */
2444 zgat = GAT_CONFIG(0, GAT_VCC);
2445 outb(zgat, devpriv->iobase1 + PCI230_ZGAT_SCE);
2446 pci230_ct_setup_ns_mode(dev, 0, I8254_MODE1,
2447 ((uint64_t) cmd->convert_arg
2448 * cmd->scan_end_arg),
2449 TRIG_ROUND_UP);
2450 if (cmd->scan_begin_src == TRIG_TIMER) {
2451 /*
2452 * Monostable on CT0 will be triggered by
2453 * output of CT1 at configured scan frequency.
2454 *
2455 * Set up CT1 but gate it off for now.
2456 */
2457 zgat = GAT_CONFIG(1, GAT_GND);
2458 outb(zgat, devpriv->iobase1 + PCI230_ZGAT_SCE);
2459 pci230_ct_setup_ns_mode(dev, 1, I8254_MODE3,
2460 cmd->scan_begin_arg,
2461 cmd->
2462 flags &
2463 TRIG_ROUND_MASK);
2464 }
2465 }
2466 }
2467
2468 if (cmd->start_src == TRIG_INT) {
2469 s->async->inttrig = pci230_ai_inttrig_start;
2470 } else {
2471 /* TRIG_NOW */
2472 pci230_ai_start(dev, s);
2473 }
2474
2475 return 0;
2476 }
2477
2478 static int pci230_ai_cancel(struct comedi_device *dev,
2479 struct comedi_subdevice *s)
2480 {
2481 pci230_ai_stop(dev, s);
2482 return 0;
2483 }
2484
2485 /* Interrupt handler */
2486 static irqreturn_t pci230_interrupt(int irq, void *d)
2487 {
2488 unsigned char status_int, valid_status_int;
2489 struct comedi_device *dev = (struct comedi_device *)d;
2490 struct pci230_private *devpriv = dev->private;
2491 struct comedi_subdevice *s;
2492 unsigned long irqflags;
2493
2494 /* Read interrupt status/enable register. */
2495 status_int = inb(devpriv->iobase1 + PCI230_INT_STAT);
2496
2497 if (status_int == PCI230_INT_DISABLE)
2498 return IRQ_NONE;
2499
2500
2501 spin_lock_irqsave(&devpriv->isr_spinlock, irqflags);
2502 valid_status_int = devpriv->int_en & status_int;
2503 /* Disable triggered interrupts.
2504 * (Only those interrupts that need re-enabling, are, later in the
2505 * handler). */
2506 devpriv->ier = devpriv->int_en & ~status_int;
2507 outb(devpriv->ier, devpriv->iobase1 + PCI230_INT_SCE);
2508 devpriv->intr_running = 1;
2509 devpriv->intr_cpuid = THISCPU;
2510 spin_unlock_irqrestore(&devpriv->isr_spinlock, irqflags);
2511
2512 /*
2513 * Check the source of interrupt and handle it.
2514 * The PCI230 can cope with concurrent ADC, DAC, PPI C0 and C3
2515 * interrupts. However, at present (Comedi-0.7.60) does not allow
2516 * concurrent execution of commands, instructions or a mixture of the
2517 * two.
2518 */
2519
2520 if ((valid_status_int & PCI230_INT_ZCLK_CT1) != 0) {
2521 s = dev->write_subdev;
2522 pci230_handle_ao_nofifo(dev, s);
2523 comedi_event(dev, s);
2524 }
2525
2526 if ((valid_status_int & PCI230P2_INT_DAC) != 0) {
2527 s = dev->write_subdev;
2528 pci230_handle_ao_fifo(dev, s);
2529 comedi_event(dev, s);
2530 }
2531
2532 if ((valid_status_int & PCI230_INT_ADC) != 0) {
2533 s = dev->read_subdev;
2534 pci230_handle_ai(dev, s);
2535 comedi_event(dev, s);
2536 }
2537
2538 /* Reenable interrupts. */
2539 spin_lock_irqsave(&devpriv->isr_spinlock, irqflags);
2540 if (devpriv->ier != devpriv->int_en) {
2541 devpriv->ier = devpriv->int_en;
2542 outb(devpriv->ier, devpriv->iobase1 + PCI230_INT_SCE);
2543 }
2544 devpriv->intr_running = 0;
2545 spin_unlock_irqrestore(&devpriv->isr_spinlock, irqflags);
2546
2547 return IRQ_HANDLED;
2548 }
2549
2550 /* Check if PCI device matches a specific board. */
2551 static bool pci230_match_pci_board(const struct pci230_board *board,
2552 struct pci_dev *pci_dev)
2553 {
2554 /* assume pci_dev->device != PCI_DEVICE_ID_INVALID */
2555 if (board->id != pci_dev->device)
2556 return false;
2557 if (board->min_hwver == 0)
2558 return true;
2559 /* Looking for a '+' model. First check length of registers. */
2560 if (pci_resource_len(pci_dev, 3) < 32)
2561 return false; /* Not a '+' model. */
2562 /* TODO: temporarily enable PCI device and read the hardware version
2563 * register. For now, assume it's okay. */
2564 return true;
2565 }
2566
2567 /* Look for board matching PCI device. */
2568 static const struct pci230_board *pci230_find_pci_board(struct pci_dev *pci_dev)
2569 {
2570 unsigned int i;
2571
2572 for (i = 0; i < ARRAY_SIZE(pci230_boards); i++)
2573 if (pci230_match_pci_board(&pci230_boards[i], pci_dev))
2574 return &pci230_boards[i];
2575 return NULL;
2576 }
2577
2578 /* Look for PCI device matching requested board name, bus and slot. */
2579 static struct pci_dev *pci230_find_pci_dev(struct comedi_device *dev,
2580 struct comedi_devconfig *it)
2581 {
2582 const struct pci230_board *thisboard = comedi_board(dev);
2583 struct pci_dev *pci_dev = NULL;
2584 int bus = it->options[0];
2585 int slot = it->options[1];
2586
2587 for_each_pci_dev(pci_dev) {
2588 /* Check vendor ID (same for all supported PCI boards). */
2589 if (pci_dev->vendor != PCI_VENDOR_ID_AMPLICON)
2590 continue;
2591 /* If bus/slot specified, check them. */
2592 if ((bus || slot) &&
2593 (bus != pci_dev->bus->number ||
2594 slot != PCI_SLOT(pci_dev->devfn)))
2595 continue;
2596 if (thisboard->id == PCI_DEVICE_ID_INVALID) {
2597 /* Wildcard board matches any supported PCI board. */
2598 const struct pci230_board *foundboard;
2599
2600 foundboard = pci230_find_pci_board(pci_dev);
2601 if (foundboard == NULL)
2602 continue;
2603 /* Replace wildcard board_ptr. */
2604 dev->board_ptr = foundboard;
2605 } else {
2606 /* Need to match a specific board. */
2607 if (!pci230_match_pci_board(thisboard, pci_dev))
2608 continue;
2609 }
2610 return pci_dev;
2611 }
2612 dev_err(dev->class_dev,
2613 "No supported board found! (req. bus %d, slot %d)\n",
2614 bus, slot);
2615 return NULL;
2616 }
2617
2618 static int pci230_alloc_private(struct comedi_device *dev)
2619 {
2620 struct pci230_private *devpriv;
2621
2622 devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL);
2623 if (!devpriv)
2624 return -ENOMEM;
2625 dev->private = devpriv;
2626
2627 spin_lock_init(&devpriv->isr_spinlock);
2628 spin_lock_init(&devpriv->res_spinlock);
2629 spin_lock_init(&devpriv->ai_stop_spinlock);
2630 spin_lock_init(&devpriv->ao_stop_spinlock);
2631 return 0;
2632 }
2633
2634 /* Common part of attach and auto_attach. */
2635 static int pci230_attach_common(struct comedi_device *dev,
2636 struct pci_dev *pci_dev)
2637 {
2638 const struct pci230_board *thisboard = comedi_board(dev);
2639 struct pci230_private *devpriv = dev->private;
2640 struct comedi_subdevice *s;
2641 unsigned long iobase1, iobase2;
2642 /* PCI230's I/O spaces 1 and 2 respectively. */
2643 int irq_hdl, rc;
2644
2645 comedi_set_hw_dev(dev, &pci_dev->dev);
2646
2647 dev->board_name = thisboard->name;
2648
2649 rc = comedi_pci_enable(dev);
2650 if (rc)
2651 return rc;
2652
2653 /* Read base addresses of the PCI230's two I/O regions from PCI
2654 * configuration register. */
2655 iobase1 = pci_resource_start(pci_dev, 2);
2656 iobase2 = pci_resource_start(pci_dev, 3);
2657 dev_dbg(dev->class_dev,
2658 "%s I/O region 1 0x%04lx I/O region 2 0x%04lx\n",
2659 dev->board_name, iobase1, iobase2);
2660 devpriv->iobase1 = iobase1;
2661 dev->iobase = iobase2;
2662 /* Read bits of DACCON register - only the output range. */
2663 devpriv->daccon = inw(dev->iobase + PCI230_DACCON) & PCI230_DAC_OR_MASK;
2664 /* Read hardware version register and set extended function register
2665 * if they exist. */
2666 if (pci_resource_len(pci_dev, 3) >= 32) {
2667 unsigned short extfunc = 0;
2668
2669 devpriv->hwver = inw(dev->iobase + PCI230P_HWVER);
2670 if (devpriv->hwver < thisboard->min_hwver) {
2671 dev_err(dev->class_dev,
2672 "%s - bad hardware version - got %u, need %u\n",
2673 dev->board_name, devpriv->hwver,
2674 thisboard->min_hwver);
2675 return -EIO;
2676 }
2677 if (devpriv->hwver > 0) {
2678 if (!thisboard->have_dio) {
2679 /* No DIO ports. Route counters' external gates
2680 * to the EXTTRIG signal (PCI260+ pin 17).
2681 * (Otherwise, they would be routed to DIO
2682 * inputs PC0, PC1 and PC2 which don't exist
2683 * on PCI260[+].) */
2684 extfunc |= PCI230P_EXTFUNC_GAT_EXTTRIG;
2685 }
2686 if ((thisboard->ao_chans > 0)
2687 && (devpriv->hwver >= 2)) {
2688 /* Enable DAC FIFO functionality. */
2689 extfunc |= PCI230P2_EXTFUNC_DACFIFO;
2690 }
2691 }
2692 outw(extfunc, dev->iobase + PCI230P_EXTFUNC);
2693 if ((extfunc & PCI230P2_EXTFUNC_DACFIFO) != 0) {
2694 /* Temporarily enable DAC FIFO, reset it and disable
2695 * FIFO wraparound. */
2696 outw(devpriv->daccon | PCI230P2_DAC_FIFO_EN
2697 | PCI230P2_DAC_FIFO_RESET,
2698 dev->iobase + PCI230_DACCON);
2699 /* Clear DAC FIFO channel enable register. */
2700 outw(0, dev->iobase + PCI230P2_DACEN);
2701 /* Disable DAC FIFO. */
2702 outw(devpriv->daccon, dev->iobase + PCI230_DACCON);
2703 }
2704 }
2705 /* Disable board's interrupts. */
2706 outb(0, devpriv->iobase1 + PCI230_INT_SCE);
2707 /* Set ADC to a reasonable state. */
2708 devpriv->adcg = 0;
2709 devpriv->adccon = PCI230_ADC_TRIG_NONE | PCI230_ADC_IM_SE
2710 | PCI230_ADC_IR_BIP;
2711 outw(1 << 0, dev->iobase + PCI230_ADCEN);
2712 outw(devpriv->adcg, dev->iobase + PCI230_ADCG);
2713 outw(devpriv->adccon | PCI230_ADC_FIFO_RESET,
2714 dev->iobase + PCI230_ADCCON);
2715 /* Register the interrupt handler. */
2716 irq_hdl = request_irq(pci_dev->irq, pci230_interrupt,
2717 IRQF_SHARED, "amplc_pci230", dev);
2718 if (irq_hdl < 0) {
2719 dev_warn(dev->class_dev,
2720 "unable to register irq %u, commands will not be available\n",
2721 pci_dev->irq);
2722 } else {
2723 dev->irq = pci_dev->irq;
2724 dev_dbg(dev->class_dev, "registered irq %u\n", pci_dev->irq);
2725 }
2726
2727 rc = comedi_alloc_subdevices(dev, 3);
2728 if (rc)
2729 return rc;
2730
2731 s = &dev->subdevices[0];
2732 /* analog input subdevice */
2733 s->type = COMEDI_SUBD_AI;
2734 s->subdev_flags = SDF_READABLE | SDF_DIFF | SDF_GROUND;
2735 s->n_chan = thisboard->ai_chans;
2736 s->maxdata = (1 << thisboard->ai_bits) - 1;
2737 s->range_table = &pci230_ai_range;
2738 s->insn_read = &pci230_ai_rinsn;
2739 s->len_chanlist = 256; /* but there are restrictions. */
2740 /* Only register commands if the interrupt handler is installed. */
2741 if (irq_hdl == 0) {
2742 dev->read_subdev = s;
2743 s->subdev_flags |= SDF_CMD_READ;
2744 s->do_cmd = &pci230_ai_cmd;
2745 s->do_cmdtest = &pci230_ai_cmdtest;
2746 s->cancel = pci230_ai_cancel;
2747 }
2748 s = &dev->subdevices[1];
2749 /* analog output subdevice */
2750 if (thisboard->ao_chans > 0) {
2751 s->type = COMEDI_SUBD_AO;
2752 s->subdev_flags = SDF_WRITABLE | SDF_GROUND;
2753 s->n_chan = thisboard->ao_chans;
2754 s->maxdata = (1 << thisboard->ao_bits) - 1;
2755 s->range_table = &pci230_ao_range;
2756 s->insn_write = &pci230_ao_winsn;
2757 s->insn_read = &pci230_ao_rinsn;
2758 s->len_chanlist = thisboard->ao_chans;
2759 /* Only register commands if the interrupt handler is
2760 * installed. */
2761 if (irq_hdl == 0) {
2762 dev->write_subdev = s;
2763 s->subdev_flags |= SDF_CMD_WRITE;
2764 s->do_cmd = &pci230_ao_cmd;
2765 s->do_cmdtest = &pci230_ao_cmdtest;
2766 s->cancel = pci230_ao_cancel;
2767 }
2768 } else {
2769 s->type = COMEDI_SUBD_UNUSED;
2770 }
2771 s = &dev->subdevices[2];
2772 /* digital i/o subdevice */
2773 if (thisboard->have_dio) {
2774 rc = subdev_8255_init(dev, s, NULL,
2775 (devpriv->iobase1 + PCI230_PPI_X_BASE));
2776 if (rc < 0)
2777 return rc;
2778 } else {
2779 s->type = COMEDI_SUBD_UNUSED;
2780 }
2781 dev_info(dev->class_dev, "attached\n");
2782 return 1;
2783 }
2784
2785 static int pci230_attach(struct comedi_device *dev, struct comedi_devconfig *it)
2786 {
2787 const struct pci230_board *thisboard = comedi_board(dev);
2788 struct pci_dev *pci_dev;
2789 int rc;
2790
2791 dev_info(dev->class_dev, "amplc_pci230: attach %s %d,%d\n",
2792 thisboard->name, it->options[0], it->options[1]);
2793
2794 rc = pci230_alloc_private(dev);
2795 if (rc)
2796 return rc;
2797
2798 pci_dev = pci230_find_pci_dev(dev, it);
2799 if (!pci_dev)
2800 return -EIO;
2801 return pci230_attach_common(dev, pci_dev);
2802 }
2803
2804 static int pci230_auto_attach(struct comedi_device *dev,
2805 unsigned long context_unused)
2806 {
2807 struct pci_dev *pci_dev = comedi_to_pci_dev(dev);
2808 int rc;
2809
2810 dev_info(dev->class_dev, "amplc_pci230: attach pci %s\n",
2811 pci_name(pci_dev));
2812
2813 rc = pci230_alloc_private(dev);
2814 if (rc)
2815 return rc;
2816
2817 dev->board_ptr = pci230_find_pci_board(pci_dev);
2818 if (dev->board_ptr == NULL) {
2819 dev_err(dev->class_dev,
2820 "amplc_pci230: BUG! cannot determine board type!\n");
2821 return -EINVAL;
2822 }
2823 /*
2824 * Need to 'get' the PCI device to match the 'put' in pci230_detach().
2825 * TODO: Remove the pci_dev_get() and matching pci_dev_put() once
2826 * support for manual attachment of PCI devices via pci230_attach()
2827 * has been removed.
2828 */
2829 pci_dev_get(pci_dev);
2830 return pci230_attach_common(dev, pci_dev);
2831 }
2832
2833 static void pci230_detach(struct comedi_device *dev)
2834 {
2835 const struct pci230_board *thisboard = comedi_board(dev);
2836 struct pci_dev *pcidev = comedi_to_pci_dev(dev);
2837
2838 if (dev->subdevices && thisboard->have_dio)
2839 subdev_8255_cleanup(dev, &dev->subdevices[2]);
2840 if (dev->irq)
2841 free_irq(dev->irq, dev);
2842 comedi_pci_disable(dev);
2843 if (pcidev)
2844 pci_dev_put(pcidev);
2845 }
2846
2847 static struct comedi_driver amplc_pci230_driver = {
2848 .driver_name = "amplc_pci230",
2849 .module = THIS_MODULE,
2850 .attach = pci230_attach,
2851 .auto_attach = pci230_auto_attach,
2852 .detach = pci230_detach,
2853 .board_name = &pci230_boards[0].name,
2854 .offset = sizeof(pci230_boards[0]),
2855 .num_names = ARRAY_SIZE(pci230_boards),
2856 };
2857
2858 static int amplc_pci230_pci_probe(struct pci_dev *dev,
2859 const struct pci_device_id *id)
2860 {
2861 return comedi_pci_auto_config(dev, &amplc_pci230_driver,
2862 id->driver_data);
2863 }
2864
2865 static DEFINE_PCI_DEVICE_TABLE(amplc_pci230_pci_table) = {
2866 { PCI_DEVICE(PCI_VENDOR_ID_AMPLICON, PCI_DEVICE_ID_PCI230) },
2867 { PCI_DEVICE(PCI_VENDOR_ID_AMPLICON, PCI_DEVICE_ID_PCI260) },
2868 { 0 }
2869 };
2870 MODULE_DEVICE_TABLE(pci, amplc_pci230_pci_table);
2871
2872 static struct pci_driver amplc_pci230_pci_driver = {
2873 .name = "amplc_pci230",
2874 .id_table = amplc_pci230_pci_table,
2875 .probe = amplc_pci230_pci_probe,
2876 .remove = comedi_pci_auto_unconfig,
2877 };
2878 module_comedi_pci_driver(amplc_pci230_driver, amplc_pci230_pci_driver);
2879
2880 MODULE_AUTHOR("Comedi http://www.comedi.org");
2881 MODULE_DESCRIPTION("Comedi low-level driver");
2882 MODULE_LICENSE("GPL");
This page took 0.132377 seconds and 5 git commands to generate.