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