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