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 
pci230_ai_read(struct comedi_device * dev)529 static unsigned short pci230_ai_read(struct comedi_device *dev)
530 {
531 	const struct pci230_board *thisboard = 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 - thisboard->ai_bits);
547 	return data;
548 }
549 
pci230_ao_mangle_datum(struct comedi_device * dev,unsigned short datum)550 static unsigned short pci230_ao_mangle_datum(struct comedi_device *dev,
551 					     unsigned short datum)
552 {
553 	const struct pci230_board *thisboard = 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 - thisboard->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 
pci230_ao_write_nofifo(struct comedi_device * dev,unsigned short datum,unsigned int chan)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 
pci230_ao_write_fifo(struct comedi_device * dev,unsigned short datum,unsigned int chan)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 
pci230_claim_shared(struct comedi_device * dev,unsigned char res_mask,unsigned int owner)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 
pci230_release_shared(struct comedi_device * dev,unsigned char res_mask,unsigned int owner)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 
pci230_release_all_resources(struct comedi_device * dev,unsigned int owner)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 
pci230_divide_ns(uint64_t ns,unsigned int timebase,unsigned int flags)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  */
pci230_choose_clk_count(uint64_t ns,unsigned int * count,unsigned int flags)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 
pci230_ns_to_single_timer(unsigned int * ns,unsigned int flags)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 
pci230_ct_setup_ns_mode(struct comedi_device * dev,unsigned int ct,unsigned int mode,uint64_t ns,unsigned int flags)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 
pci230_cancel_ct(struct comedi_device * dev,unsigned int ct)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 
pci230_ai_eoc(struct comedi_device * dev,struct comedi_subdevice * s,struct comedi_insn * insn,unsigned long context)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 
pci230_ai_insn_read(struct comedi_device * dev,struct comedi_subdevice * s,struct comedi_insn * insn,unsigned int * data)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 
pci230_ao_insn_write(struct comedi_device * dev,struct comedi_subdevice * s,struct comedi_insn * insn,unsigned int * data)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 
pci230_ao_check_chanlist(struct comedi_device * dev,struct comedi_subdevice * s,struct comedi_cmd * cmd)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 
pci230_ao_cmdtest(struct comedi_device * dev,struct comedi_subdevice * s,struct comedi_cmd * cmd)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 *thisboard = 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 (thisboard->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 thisboard->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 
pci230_ao_stop(struct comedi_device * dev,struct comedi_subdevice * s)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 
pci230_handle_ao_nofifo(struct comedi_device * dev,struct comedi_subdevice * s)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  */
pci230_handle_ao_fifo(struct comedi_device * dev,struct comedi_subdevice * s)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 
pci230_ao_inttrig_scan_begin(struct comedi_device * dev,struct comedi_subdevice * s,unsigned int trig_num)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 
pci230_ao_start(struct comedi_device * dev,struct comedi_subdevice * s)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 
pci230_ao_inttrig_start(struct comedi_device * dev,struct comedi_subdevice * s,unsigned int trig_num)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 
pci230_ao_cmd(struct comedi_device * dev,struct comedi_subdevice * s)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 
pci230_ao_cancel(struct comedi_device * dev,struct comedi_subdevice * s)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 
pci230_ai_check_scan_period(struct comedi_cmd * cmd)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 
pci230_ai_check_chanlist(struct comedi_device * dev,struct comedi_subdevice * s,struct comedi_cmd * cmd)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 
pci230_ai_cmdtest(struct comedi_device * dev,struct comedi_subdevice * s,struct comedi_cmd * cmd)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 *thisboard = 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 (thisboard->have_dio || thisboard->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 
pci230_ai_update_fifo_trigger_level(struct comedi_device * dev,struct comedi_subdevice * s)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 
pci230_ai_inttrig_convert(struct comedi_device * dev,struct comedi_subdevice * s,unsigned int trig_num)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 
pci230_ai_inttrig_scan_begin(struct comedi_device * dev,struct comedi_subdevice * s,unsigned int trig_num)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 
pci230_ai_stop(struct comedi_device * dev,struct comedi_subdevice * s)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 
pci230_ai_start(struct comedi_device * dev,struct comedi_subdevice * s)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 
pci230_ai_inttrig_start(struct comedi_device * dev,struct comedi_subdevice * s,unsigned int trig_num)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 
pci230_handle_ai(struct comedi_device * dev,struct comedi_subdevice * s)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 todo;
2015 	unsigned int fifoamount;
2016 	unsigned short val;
2017 
2018 	/* Determine number of samples to read. */
2019 	todo = comedi_nsamples_left(s, PCI230_ADC_FIFOLEVEL_HALFFULL);
2020 	if (todo == 0)
2021 		return;
2022 
2023 	fifoamount = 0;
2024 	for (i = 0; i < todo; 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 
pci230_ai_cmd(struct comedi_device * dev,struct comedi_subdevice * s)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 
pci230_ai_cancel(struct comedi_device * dev,struct comedi_subdevice * s)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 */
pci230_interrupt(int irq,void * d)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 = (struct comedi_device *)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. */
pci230_match_pci_board(const struct pci230_board * board,struct pci_dev * pci_dev)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. */
pci230_find_pci_board(struct pci_dev * pci_dev)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 
pci230_auto_attach(struct comedi_device * dev,unsigned long context_unused)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 *thisboard;
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 	dev->board_ptr = pci230_find_pci_board(pci_dev);
2385 	if (!dev->board_ptr) {
2386 		dev_err(dev->class_dev,
2387 			"amplc_pci230: BUG! cannot determine board type!\n");
2388 		return -EINVAL;
2389 	}
2390 	thisboard = dev->board_ptr;
2391 	dev->board_name = thisboard->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 < thisboard->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 				thisboard->min_hwver);
2422 			return -EIO;
2423 		}
2424 		if (devpriv->hwver > 0) {
2425 			if (!thisboard->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 (thisboard->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 << thisboard->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 (thisboard->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 << thisboard->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 (thisboard->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 
amplc_pci230_pci_probe(struct pci_dev * dev,const struct pci_device_id * id)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");
2569