1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * comedi/drivers/amplc_pci224.c
4  * Driver for Amplicon PCI224 and PCI234 AO boards.
5  *
6  * Copyright (C) 2005 MEV Ltd. <https://www.mev.co.uk/>
7  *
8  * COMEDI - Linux Control and Measurement Device Interface
9  * Copyright (C) 1998,2000 David A. Schleef <ds@schleef.org>
10  */
11 
12 /*
13  * Driver: amplc_pci224
14  * Description: Amplicon PCI224, PCI234
15  * Author: Ian Abbott <abbotti@mev.co.uk>
16  * Devices: [Amplicon] PCI224 (amplc_pci224), PCI234
17  * Updated: Thu, 31 Jul 2014 11:08:03 +0000
18  * Status: works, but see caveats
19  *
20  * Supports:
21  *
22  *   - ao_insn read/write
23  *   - ao_do_cmd mode with the following sources:
24  *
25  *     - start_src         TRIG_INT        TRIG_EXT
26  *     - scan_begin_src    TRIG_TIMER      TRIG_EXT
27  *     - convert_src       TRIG_NOW
28  *     - scan_end_src      TRIG_COUNT
29  *     - stop_src          TRIG_COUNT      TRIG_EXT        TRIG_NONE
30  *
31  *     The channel list must contain at least one channel with no repeated
32  *     channels.  The scan end count must equal the number of channels in
33  *     the channel list.
34  *
35  *     There is only one external trigger source so only one of start_src,
36  *     scan_begin_src or stop_src may use TRIG_EXT.
37  *
38  * Configuration options:
39  *   none
40  *
41  * Manual configuration of PCI cards is not supported; they are configured
42  * automatically.
43  *
44  * Output range selection - PCI224:
45  *
46  *   Output ranges on PCI224 are partly software-selectable and partly
47  *   hardware-selectable according to jumper LK1.  All channels are set
48  *   to the same range:
49  *
50  *   - LK1 position 1-2 (factory default) corresponds to the following
51  *     comedi ranges:
52  *
53  *       0: [-10V,+10V]; 1: [-5V,+5V]; 2: [-2.5V,+2.5V], 3: [-1.25V,+1.25V],
54  *       4: [0,+10V],    5: [0,+5V],   6: [0,+2.5V],     7: [0,+1.25V]
55  *
56  *   - LK1 position 2-3 corresponds to the following Comedi ranges, using
57  *     an external voltage reference:
58  *
59  *       0: [-Vext,+Vext],
60  *       1: [0,+Vext]
61  *
62  * Output range selection - PCI234:
63  *
64  *   Output ranges on PCI234 are hardware-selectable according to jumper
65  *   LK1 which affects all channels, and jumpers LK2, LK3, LK4 and LK5
66  *   which affect channels 0, 1, 2 and 3 individually.  LK1 chooses between
67  *   an internal 5V reference and an external voltage reference (Vext).
68  *   LK2/3/4/5 choose (per channel) to double the reference or not according
69  *   to the following table:
70  *
71  *     LK1 position   LK2/3/4/5 pos  Comedi range
72  *     -------------  -------------  --------------
73  *     2-3 (factory)  1-2 (factory)  0: [-10V,+10V]
74  *     2-3 (factory)  2-3            1: [-5V,+5V]
75  *     1-2            1-2 (factory)  2: [-2*Vext,+2*Vext]
76  *     1-2            2-3            3: [-Vext,+Vext]
77  *
78  * Caveats:
79  *
80  *   1) All channels on the PCI224 share the same range.  Any change to the
81  *      range as a result of insn_write or a streaming command will affect
82  *      the output voltages of all channels, including those not specified
83  *      by the instruction or command.
84  *
85  *   2) For the analog output command,  the first scan may be triggered
86  *      falsely at the start of acquisition.  This occurs when the DAC scan
87  *      trigger source is switched from 'none' to 'timer' (scan_begin_src =
88  *      TRIG_TIMER) or 'external' (scan_begin_src == TRIG_EXT) at the start
89  *      of acquisition and the trigger source is at logic level 1 at the
90  *      time of the switch.  This is very likely for TRIG_TIMER.  For
91  *      TRIG_EXT, it depends on the state of the external line and whether
92  *      the CR_INVERT flag has been set.  The remaining scans are triggered
93  *      correctly.
94  */
95 
96 #include <linux/module.h>
97 #include <linux/interrupt.h>
98 #include <linux/slab.h>
99 
100 #include "../comedi_pci.h"
101 
102 #include "comedi_8254.h"
103 
104 /*
105  * PCI224/234 i/o space 1 (PCIBAR2) registers.
106  */
107 #define PCI224_Z2_BASE	0x14	/* 82C54 counter/timer */
108 #define PCI224_ZCLK_SCE	0x1A	/* Group Z Clock Configuration Register */
109 #define PCI224_ZGAT_SCE	0x1D	/* Group Z Gate Configuration Register */
110 #define PCI224_INT_SCE	0x1E	/* ISR Interrupt source mask register */
111 				/* /Interrupt status */
112 
113 /*
114  * PCI224/234 i/o space 2 (PCIBAR3) 16-bit registers.
115  */
116 #define PCI224_DACDATA	0x00	/* (w-o) DAC FIFO data. */
117 #define PCI224_SOFTTRIG	0x00	/* (r-o) DAC software scan trigger. */
118 #define PCI224_DACCON	0x02	/* (r/w) DAC status/configuration. */
119 #define PCI224_FIFOSIZ	0x04	/* (w-o) FIFO size for wraparound mode. */
120 #define PCI224_DACCEN	0x06	/* (w-o) DAC channel enable register. */
121 
122 /*
123  * DACCON values.
124  */
125 /* (r/w) Scan trigger. */
126 #define PCI224_DACCON_TRIG(x)		(((x) & 0x7) << 0)
127 #define PCI224_DACCON_TRIG_MASK		PCI224_DACCON_TRIG(7)
128 #define PCI224_DACCON_TRIG_NONE		PCI224_DACCON_TRIG(0)	/* none */
129 #define PCI224_DACCON_TRIG_SW		PCI224_DACCON_TRIG(1)	/* soft trig */
130 #define PCI224_DACCON_TRIG_EXTP		PCI224_DACCON_TRIG(2)	/* ext + edge */
131 #define PCI224_DACCON_TRIG_EXTN		PCI224_DACCON_TRIG(3)	/* ext - edge */
132 #define PCI224_DACCON_TRIG_Z2CT0	PCI224_DACCON_TRIG(4)	/* Z2 CT0 out */
133 #define PCI224_DACCON_TRIG_Z2CT1	PCI224_DACCON_TRIG(5)	/* Z2 CT1 out */
134 #define PCI224_DACCON_TRIG_Z2CT2	PCI224_DACCON_TRIG(6)	/* Z2 CT2 out */
135 /* (r/w) Polarity (PCI224 only, PCI234 always bipolar!). */
136 #define PCI224_DACCON_POLAR(x)		(((x) & 0x1) << 3)
137 #define PCI224_DACCON_POLAR_MASK	PCI224_DACCON_POLAR(1)
138 #define PCI224_DACCON_POLAR_UNI		PCI224_DACCON_POLAR(0)	/* [0,+V] */
139 #define PCI224_DACCON_POLAR_BI		PCI224_DACCON_POLAR(1)	/* [-V,+V] */
140 /* (r/w) Internal Vref (PCI224 only, when LK1 in position 1-2). */
141 #define PCI224_DACCON_VREF(x)		(((x) & 0x3) << 4)
142 #define PCI224_DACCON_VREF_MASK		PCI224_DACCON_VREF(3)
143 #define PCI224_DACCON_VREF_1_25		PCI224_DACCON_VREF(0)	/* 1.25V */
144 #define PCI224_DACCON_VREF_2_5		PCI224_DACCON_VREF(1)	/* 2.5V */
145 #define PCI224_DACCON_VREF_5		PCI224_DACCON_VREF(2)	/* 5V */
146 #define PCI224_DACCON_VREF_10		PCI224_DACCON_VREF(3)	/* 10V */
147 /* (r/w) Wraparound mode enable (to play back stored waveform). */
148 #define PCI224_DACCON_FIFOWRAP		BIT(7)
149 /* (r/w) FIFO enable.  It MUST be set! */
150 #define PCI224_DACCON_FIFOENAB		BIT(8)
151 /* (r/w) FIFO interrupt trigger level (most values are not very useful). */
152 #define PCI224_DACCON_FIFOINTR(x)	(((x) & 0x7) << 9)
153 #define PCI224_DACCON_FIFOINTR_MASK	PCI224_DACCON_FIFOINTR(7)
154 #define PCI224_DACCON_FIFOINTR_EMPTY	PCI224_DACCON_FIFOINTR(0) /* empty */
155 #define PCI224_DACCON_FIFOINTR_NEMPTY	PCI224_DACCON_FIFOINTR(1) /* !empty */
156 #define PCI224_DACCON_FIFOINTR_NHALF	PCI224_DACCON_FIFOINTR(2) /* !half */
157 #define PCI224_DACCON_FIFOINTR_HALF	PCI224_DACCON_FIFOINTR(3) /* half */
158 #define PCI224_DACCON_FIFOINTR_NFULL	PCI224_DACCON_FIFOINTR(4) /* !full */
159 #define PCI224_DACCON_FIFOINTR_FULL	PCI224_DACCON_FIFOINTR(5) /* full */
160 /* (r-o) FIFO fill level. */
161 #define PCI224_DACCON_FIFOFL(x)		(((x) & 0x7) << 12)
162 #define PCI224_DACCON_FIFOFL_MASK	PCI224_DACCON_FIFOFL(7)
163 #define PCI224_DACCON_FIFOFL_EMPTY	PCI224_DACCON_FIFOFL(1)	/* 0 */
164 #define PCI224_DACCON_FIFOFL_ONETOHALF	PCI224_DACCON_FIFOFL(0)	/* 1-2048 */
165 #define PCI224_DACCON_FIFOFL_HALFTOFULL	PCI224_DACCON_FIFOFL(4)	/* 2049-4095 */
166 #define PCI224_DACCON_FIFOFL_FULL	PCI224_DACCON_FIFOFL(6)	/* 4096 */
167 /* (r-o) DAC busy flag. */
168 #define PCI224_DACCON_BUSY		BIT(15)
169 /* (w-o) FIFO reset. */
170 #define PCI224_DACCON_FIFORESET		BIT(12)
171 /* (w-o) Global reset (not sure what it does). */
172 #define PCI224_DACCON_GLOBALRESET	BIT(13)
173 
174 /*
175  * DAC FIFO size.
176  */
177 #define PCI224_FIFO_SIZE	4096
178 
179 /*
180  * DAC FIFO guaranteed minimum room available, depending on reported fill level.
181  * The maximum room available depends on the reported fill level and how much
182  * has been written!
183  */
184 #define PCI224_FIFO_ROOM_EMPTY		PCI224_FIFO_SIZE
185 #define PCI224_FIFO_ROOM_ONETOHALF	(PCI224_FIFO_SIZE / 2)
186 #define PCI224_FIFO_ROOM_HALFTOFULL	1
187 #define PCI224_FIFO_ROOM_FULL		0
188 
189 /*
190  * Counter/timer clock input configuration sources.
191  */
192 #define CLK_CLK		0	/* reserved (channel-specific clock) */
193 #define CLK_10MHZ	1	/* internal 10 MHz clock */
194 #define CLK_1MHZ	2	/* internal 1 MHz clock */
195 #define CLK_100KHZ	3	/* internal 100 kHz clock */
196 #define CLK_10KHZ	4	/* internal 10 kHz clock */
197 #define CLK_1KHZ	5	/* internal 1 kHz clock */
198 #define CLK_OUTNM1	6	/* output of channel-1 modulo total */
199 #define CLK_EXT		7	/* external clock */
200 
pci224_clk_config(unsigned int chan,unsigned int src)201 static unsigned int pci224_clk_config(unsigned int chan, unsigned int src)
202 {
203 	return ((chan & 3) << 3) | (src & 7);
204 }
205 
206 /*
207  * Counter/timer gate input configuration sources.
208  */
209 #define GAT_VCC		0	/* VCC (i.e. enabled) */
210 #define GAT_GND		1	/* GND (i.e. disabled) */
211 #define GAT_EXT		2	/* reserved (external gate input) */
212 #define GAT_NOUTNM2	3	/* inverted output of channel-2 modulo total */
213 
pci224_gat_config(unsigned int chan,unsigned int src)214 static unsigned int pci224_gat_config(unsigned int chan, unsigned int src)
215 {
216 	return ((chan & 3) << 3) | (src & 7);
217 }
218 
219 /*
220  * Summary of CLK_OUTNM1 and GAT_NOUTNM2 connections for PCI224 and PCI234:
221  *
222  *              Channel's       Channel's
223  *              clock input     gate input
224  * Channel      CLK_OUTNM1      GAT_NOUTNM2
225  * -------      ----------      -----------
226  * Z2-CT0       Z2-CT2-OUT      /Z2-CT1-OUT
227  * Z2-CT1       Z2-CT0-OUT      /Z2-CT2-OUT
228  * Z2-CT2       Z2-CT1-OUT      /Z2-CT0-OUT
229  */
230 
231 /*
232  * Interrupt enable/status bits
233  */
234 #define PCI224_INTR_EXT		0x01	/* rising edge on external input */
235 #define PCI224_INTR_DAC		0x04	/* DAC (FIFO) interrupt */
236 #define PCI224_INTR_Z2CT1	0x20	/* rising edge on Z2-CT1 output */
237 
238 #define PCI224_INTR_EDGE_BITS	(PCI224_INTR_EXT | PCI224_INTR_Z2CT1)
239 #define PCI224_INTR_LEVEL_BITS	PCI224_INTR_DACFIFO
240 
241 /*
242  * Handy macros.
243  */
244 
245 /* Combine old and new bits. */
246 #define COMBINE(old, new, mask)	(((old) & ~(mask)) | ((new) & (mask)))
247 
248 /* Current CPU.  XXX should this be hard_smp_processor_id()? */
249 #define THISCPU		smp_processor_id()
250 
251 /* State bits for use with atomic bit operations. */
252 #define AO_CMD_STARTED	0
253 
254 /*
255  * Range tables.
256  */
257 
258 /*
259  * The ranges for PCI224.
260  *
261  * These are partly hardware-selectable by jumper LK1 and partly
262  * software-selectable.
263  *
264  * All channels share the same hardware range.
265  */
266 static const struct comedi_lrange range_pci224 = {
267 	10, {
268 		/* jumper LK1 in position 1-2 (factory default) */
269 		BIP_RANGE(10),
270 		BIP_RANGE(5),
271 		BIP_RANGE(2.5),
272 		BIP_RANGE(1.25),
273 		UNI_RANGE(10),
274 		UNI_RANGE(5),
275 		UNI_RANGE(2.5),
276 		UNI_RANGE(1.25),
277 		/* jumper LK1 in position 2-3 */
278 		RANGE_ext(-1, 1),	/* bipolar [-Vext,+Vext] */
279 		RANGE_ext(0, 1),	/* unipolar [0,+Vext] */
280 	}
281 };
282 
283 static const unsigned short hwrange_pci224[10] = {
284 	/* jumper LK1 in position 1-2 (factory default) */
285 	PCI224_DACCON_POLAR_BI | PCI224_DACCON_VREF_10,
286 	PCI224_DACCON_POLAR_BI | PCI224_DACCON_VREF_5,
287 	PCI224_DACCON_POLAR_BI | PCI224_DACCON_VREF_2_5,
288 	PCI224_DACCON_POLAR_BI | PCI224_DACCON_VREF_1_25,
289 	PCI224_DACCON_POLAR_UNI | PCI224_DACCON_VREF_10,
290 	PCI224_DACCON_POLAR_UNI | PCI224_DACCON_VREF_5,
291 	PCI224_DACCON_POLAR_UNI | PCI224_DACCON_VREF_2_5,
292 	PCI224_DACCON_POLAR_UNI | PCI224_DACCON_VREF_1_25,
293 	/* jumper LK1 in position 2-3 */
294 	PCI224_DACCON_POLAR_BI,
295 	PCI224_DACCON_POLAR_UNI,
296 };
297 
298 /* Used to check all channels set to the same range on PCI224. */
299 static const unsigned char range_check_pci224[10] = {
300 	0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
301 };
302 
303 /*
304  * The ranges for PCI234.
305  *
306  * These are all hardware-selectable by jumper LK1 affecting all channels,
307  * and jumpers LK2, LK3, LK4 and LK5 affecting channels 0, 1, 2 and 3
308  * individually.
309  */
310 static const struct comedi_lrange range_pci234 = {
311 	4, {
312 		/* LK1: 1-2 (fact def), LK2/3/4/5: 2-3 (fac def) */
313 		BIP_RANGE(10),
314 		/* LK1: 1-2 (fact def), LK2/3/4/5: 1-2 */
315 		BIP_RANGE(5),
316 		/* LK1: 2-3, LK2/3/4/5: 2-3 (fac def) */
317 		RANGE_ext(-2, 2),	/* bipolar [-2*Vext,+2*Vext] */
318 		/* LK1: 2-3, LK2/3/4/5: 1-2 */
319 		RANGE_ext(-1, 1),	/* bipolar [-Vext,+Vext] */
320 	}
321 };
322 
323 /* N.B. PCI234 ignores the polarity bit, but software uses it. */
324 static const unsigned short hwrange_pci234[4] = {
325 	PCI224_DACCON_POLAR_BI,
326 	PCI224_DACCON_POLAR_BI,
327 	PCI224_DACCON_POLAR_BI,
328 	PCI224_DACCON_POLAR_BI,
329 };
330 
331 /* Used to check all channels use same LK1 setting on PCI234. */
332 static const unsigned char range_check_pci234[4] = {
333 	0, 0, 1, 1,
334 };
335 
336 /*
337  * Board descriptions.
338  */
339 
340 enum pci224_model { pci224_model, pci234_model };
341 
342 struct pci224_board {
343 	const char *name;
344 	unsigned int ao_chans;
345 	unsigned int ao_bits;
346 	const struct comedi_lrange *ao_range;
347 	const unsigned short *ao_hwrange;
348 	const unsigned char *ao_range_check;
349 };
350 
351 static const struct pci224_board pci224_boards[] = {
352 	[pci224_model] = {
353 		.name		= "pci224",
354 		.ao_chans	= 16,
355 		.ao_bits	= 12,
356 		.ao_range	= &range_pci224,
357 		.ao_hwrange	= &hwrange_pci224[0],
358 		.ao_range_check	= &range_check_pci224[0],
359 	},
360 	[pci234_model] = {
361 		.name		= "pci234",
362 		.ao_chans	= 4,
363 		.ao_bits	= 16,
364 		.ao_range	= &range_pci234,
365 		.ao_hwrange	= &hwrange_pci234[0],
366 		.ao_range_check	= &range_check_pci234[0],
367 	},
368 };
369 
370 struct pci224_private {
371 	unsigned long iobase1;
372 	unsigned long state;
373 	spinlock_t ao_spinlock;	/* spinlock for AO command handling */
374 	unsigned short *ao_scan_vals;
375 	unsigned char *ao_scan_order;
376 	int intr_cpuid;
377 	short intr_running;
378 	unsigned short daccon;
379 	unsigned short ao_enab;	/* max 16 channels so 'short' will do */
380 	unsigned char intsce;
381 };
382 
383 /*
384  * Called from the 'insn_write' function to perform a single write.
385  */
386 static void
pci224_ao_set_data(struct comedi_device * dev,int chan,int range,unsigned int data)387 pci224_ao_set_data(struct comedi_device *dev, int chan, int range,
388 		   unsigned int data)
389 {
390 	const struct pci224_board *board = dev->board_ptr;
391 	struct pci224_private *devpriv = dev->private;
392 	unsigned short mangled;
393 
394 	/* Enable the channel. */
395 	outw(1 << chan, dev->iobase + PCI224_DACCEN);
396 	/* Set range and reset FIFO. */
397 	devpriv->daccon = COMBINE(devpriv->daccon, board->ao_hwrange[range],
398 				  PCI224_DACCON_POLAR_MASK |
399 				  PCI224_DACCON_VREF_MASK);
400 	outw(devpriv->daccon | PCI224_DACCON_FIFORESET,
401 	     dev->iobase + PCI224_DACCON);
402 	/*
403 	 * Mangle the data.  The hardware expects:
404 	 * - bipolar: 16-bit 2's complement
405 	 * - unipolar: 16-bit unsigned
406 	 */
407 	mangled = (unsigned short)data << (16 - board->ao_bits);
408 	if ((devpriv->daccon & PCI224_DACCON_POLAR_MASK) ==
409 	    PCI224_DACCON_POLAR_BI) {
410 		mangled ^= 0x8000;
411 	}
412 	/* Write mangled data to the FIFO. */
413 	outw(mangled, dev->iobase + PCI224_DACDATA);
414 	/* Trigger the conversion. */
415 	inw(dev->iobase + PCI224_SOFTTRIG);
416 }
417 
pci224_ao_insn_write(struct comedi_device * dev,struct comedi_subdevice * s,struct comedi_insn * insn,unsigned int * data)418 static int pci224_ao_insn_write(struct comedi_device *dev,
419 				struct comedi_subdevice *s,
420 				struct comedi_insn *insn,
421 				unsigned int *data)
422 {
423 	unsigned int chan = CR_CHAN(insn->chanspec);
424 	unsigned int range = CR_RANGE(insn->chanspec);
425 	unsigned int val = s->readback[chan];
426 	int i;
427 
428 	for (i = 0; i < insn->n; i++) {
429 		val = data[i];
430 		pci224_ao_set_data(dev, chan, range, val);
431 	}
432 	s->readback[chan] = val;
433 
434 	return insn->n;
435 }
436 
437 /*
438  * Kills a command running on the AO subdevice.
439  */
pci224_ao_stop(struct comedi_device * dev,struct comedi_subdevice * s)440 static void pci224_ao_stop(struct comedi_device *dev,
441 			   struct comedi_subdevice *s)
442 {
443 	struct pci224_private *devpriv = dev->private;
444 	unsigned long flags;
445 
446 	if (!test_and_clear_bit(AO_CMD_STARTED, &devpriv->state))
447 		return;
448 
449 	spin_lock_irqsave(&devpriv->ao_spinlock, flags);
450 	/* Kill the interrupts. */
451 	devpriv->intsce = 0;
452 	outb(0, devpriv->iobase1 + PCI224_INT_SCE);
453 	/*
454 	 * Interrupt routine may or may not be running.  We may or may not
455 	 * have been called from the interrupt routine (directly or
456 	 * indirectly via a comedi_events() callback routine).  It's highly
457 	 * unlikely that we've been called from some other interrupt routine
458 	 * but who knows what strange things coders get up to!
459 	 *
460 	 * If the interrupt routine is currently running, wait for it to
461 	 * finish, unless we appear to have been called via the interrupt
462 	 * routine.
463 	 */
464 	while (devpriv->intr_running && devpriv->intr_cpuid != THISCPU) {
465 		spin_unlock_irqrestore(&devpriv->ao_spinlock, flags);
466 		spin_lock_irqsave(&devpriv->ao_spinlock, flags);
467 	}
468 	spin_unlock_irqrestore(&devpriv->ao_spinlock, flags);
469 	/* Reconfigure DAC for insn_write usage. */
470 	outw(0, dev->iobase + PCI224_DACCEN);	/* Disable channels. */
471 	devpriv->daccon =
472 	     COMBINE(devpriv->daccon,
473 		     PCI224_DACCON_TRIG_SW | PCI224_DACCON_FIFOINTR_EMPTY,
474 		     PCI224_DACCON_TRIG_MASK | PCI224_DACCON_FIFOINTR_MASK);
475 	outw(devpriv->daccon | PCI224_DACCON_FIFORESET,
476 	     dev->iobase + PCI224_DACCON);
477 }
478 
479 /*
480  * Handles start of acquisition for the AO subdevice.
481  */
pci224_ao_start(struct comedi_device * dev,struct comedi_subdevice * s)482 static void pci224_ao_start(struct comedi_device *dev,
483 			    struct comedi_subdevice *s)
484 {
485 	struct pci224_private *devpriv = dev->private;
486 	struct comedi_cmd *cmd = &s->async->cmd;
487 	unsigned long flags;
488 
489 	set_bit(AO_CMD_STARTED, &devpriv->state);
490 
491 	/* Enable interrupts. */
492 	spin_lock_irqsave(&devpriv->ao_spinlock, flags);
493 	if (cmd->stop_src == TRIG_EXT)
494 		devpriv->intsce = PCI224_INTR_EXT | PCI224_INTR_DAC;
495 	else
496 		devpriv->intsce = PCI224_INTR_DAC;
497 
498 	outb(devpriv->intsce, devpriv->iobase1 + PCI224_INT_SCE);
499 	spin_unlock_irqrestore(&devpriv->ao_spinlock, flags);
500 }
501 
502 /*
503  * Handles interrupts from the DAC FIFO.
504  */
pci224_ao_handle_fifo(struct comedi_device * dev,struct comedi_subdevice * s)505 static void pci224_ao_handle_fifo(struct comedi_device *dev,
506 				  struct comedi_subdevice *s)
507 {
508 	struct pci224_private *devpriv = dev->private;
509 	struct comedi_cmd *cmd = &s->async->cmd;
510 	unsigned int num_scans = comedi_nscans_left(s, 0);
511 	unsigned int room;
512 	unsigned short dacstat;
513 	unsigned int i, n;
514 
515 	/* Determine how much room is in the FIFO (in samples). */
516 	dacstat = inw(dev->iobase + PCI224_DACCON);
517 	switch (dacstat & PCI224_DACCON_FIFOFL_MASK) {
518 	case PCI224_DACCON_FIFOFL_EMPTY:
519 		room = PCI224_FIFO_ROOM_EMPTY;
520 		if (cmd->stop_src == TRIG_COUNT &&
521 		    s->async->scans_done >= cmd->stop_arg) {
522 			/* FIFO empty at end of counted acquisition. */
523 			s->async->events |= COMEDI_CB_EOA;
524 			comedi_handle_events(dev, s);
525 			return;
526 		}
527 		break;
528 	case PCI224_DACCON_FIFOFL_ONETOHALF:
529 		room = PCI224_FIFO_ROOM_ONETOHALF;
530 		break;
531 	case PCI224_DACCON_FIFOFL_HALFTOFULL:
532 		room = PCI224_FIFO_ROOM_HALFTOFULL;
533 		break;
534 	default:
535 		room = PCI224_FIFO_ROOM_FULL;
536 		break;
537 	}
538 	if (room >= PCI224_FIFO_ROOM_ONETOHALF) {
539 		/* FIFO is less than half-full. */
540 		if (num_scans == 0) {
541 			/* Nothing left to put in the FIFO. */
542 			dev_err(dev->class_dev, "AO buffer underrun\n");
543 			s->async->events |= COMEDI_CB_OVERFLOW;
544 		}
545 	}
546 	/* Determine how many new scans can be put in the FIFO. */
547 	room /= cmd->chanlist_len;
548 
549 	/* Determine how many scans to process. */
550 	if (num_scans > room)
551 		num_scans = room;
552 
553 	/* Process scans. */
554 	for (n = 0; n < num_scans; n++) {
555 		comedi_buf_read_samples(s, &devpriv->ao_scan_vals[0],
556 					cmd->chanlist_len);
557 		for (i = 0; i < cmd->chanlist_len; i++) {
558 			outw(devpriv->ao_scan_vals[devpriv->ao_scan_order[i]],
559 			     dev->iobase + PCI224_DACDATA);
560 		}
561 	}
562 	if (cmd->stop_src == TRIG_COUNT &&
563 	    s->async->scans_done >= cmd->stop_arg) {
564 		/*
565 		 * Change FIFO interrupt trigger level to wait
566 		 * until FIFO is empty.
567 		 */
568 		devpriv->daccon = COMBINE(devpriv->daccon,
569 					  PCI224_DACCON_FIFOINTR_EMPTY,
570 					  PCI224_DACCON_FIFOINTR_MASK);
571 		outw(devpriv->daccon, dev->iobase + PCI224_DACCON);
572 	}
573 	if ((devpriv->daccon & PCI224_DACCON_TRIG_MASK) ==
574 	    PCI224_DACCON_TRIG_NONE) {
575 		unsigned short trig;
576 
577 		/*
578 		 * This is the initial DAC FIFO interrupt at the
579 		 * start of the acquisition.  The DAC's scan trigger
580 		 * has been set to 'none' up until now.
581 		 *
582 		 * Now that data has been written to the FIFO, the
583 		 * DAC's scan trigger source can be set to the
584 		 * correct value.
585 		 *
586 		 * BUG: The first scan will be triggered immediately
587 		 * if the scan trigger source is at logic level 1.
588 		 */
589 		if (cmd->scan_begin_src == TRIG_TIMER) {
590 			trig = PCI224_DACCON_TRIG_Z2CT0;
591 		} else {
592 			/* cmd->scan_begin_src == TRIG_EXT */
593 			if (cmd->scan_begin_arg & CR_INVERT)
594 				trig = PCI224_DACCON_TRIG_EXTN;
595 			else
596 				trig = PCI224_DACCON_TRIG_EXTP;
597 		}
598 		devpriv->daccon =
599 		    COMBINE(devpriv->daccon, trig, PCI224_DACCON_TRIG_MASK);
600 		outw(devpriv->daccon, dev->iobase + PCI224_DACCON);
601 	}
602 
603 	comedi_handle_events(dev, s);
604 }
605 
pci224_ao_inttrig_start(struct comedi_device * dev,struct comedi_subdevice * s,unsigned int trig_num)606 static int pci224_ao_inttrig_start(struct comedi_device *dev,
607 				   struct comedi_subdevice *s,
608 				   unsigned int trig_num)
609 {
610 	struct comedi_cmd *cmd = &s->async->cmd;
611 
612 	if (trig_num != cmd->start_arg)
613 		return -EINVAL;
614 
615 	s->async->inttrig = NULL;
616 	pci224_ao_start(dev, s);
617 
618 	return 1;
619 }
620 
pci224_ao_check_chanlist(struct comedi_device * dev,struct comedi_subdevice * s,struct comedi_cmd * cmd)621 static int pci224_ao_check_chanlist(struct comedi_device *dev,
622 				    struct comedi_subdevice *s,
623 				    struct comedi_cmd *cmd)
624 {
625 	const struct pci224_board *board = dev->board_ptr;
626 	unsigned int range_check_0;
627 	unsigned int chan_mask = 0;
628 	int i;
629 
630 	range_check_0 = board->ao_range_check[CR_RANGE(cmd->chanlist[0])];
631 	for (i = 0; i < cmd->chanlist_len; i++) {
632 		unsigned int chan = CR_CHAN(cmd->chanlist[i]);
633 
634 		if (chan_mask & (1 << chan)) {
635 			dev_dbg(dev->class_dev,
636 				"%s: entries in chanlist must contain no duplicate channels\n",
637 				__func__);
638 			return -EINVAL;
639 		}
640 		chan_mask |= 1 << chan;
641 
642 		if (board->ao_range_check[CR_RANGE(cmd->chanlist[i])] !=
643 		    range_check_0) {
644 			dev_dbg(dev->class_dev,
645 				"%s: entries in chanlist have incompatible ranges\n",
646 				__func__);
647 			return -EINVAL;
648 		}
649 	}
650 
651 	return 0;
652 }
653 
654 #define MAX_SCAN_PERIOD		0xFFFFFFFFU
655 #define MIN_SCAN_PERIOD		2500
656 #define CONVERT_PERIOD		625
657 
658 /*
659  * 'do_cmdtest' function for AO subdevice.
660  */
661 static int
pci224_ao_cmdtest(struct comedi_device * dev,struct comedi_subdevice * s,struct comedi_cmd * cmd)662 pci224_ao_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
663 		  struct comedi_cmd *cmd)
664 {
665 	int err = 0;
666 	unsigned int arg;
667 
668 	/* Step 1 : check if triggers are trivially valid */
669 
670 	err |= comedi_check_trigger_src(&cmd->start_src, TRIG_INT | TRIG_EXT);
671 	err |= comedi_check_trigger_src(&cmd->scan_begin_src,
672 					TRIG_EXT | TRIG_TIMER);
673 	err |= comedi_check_trigger_src(&cmd->convert_src, TRIG_NOW);
674 	err |= comedi_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
675 	err |= comedi_check_trigger_src(&cmd->stop_src,
676 					TRIG_COUNT | TRIG_EXT | TRIG_NONE);
677 
678 	if (err)
679 		return 1;
680 
681 	/* Step 2a : make sure trigger sources are unique */
682 
683 	err |= comedi_check_trigger_is_unique(cmd->start_src);
684 	err |= comedi_check_trigger_is_unique(cmd->scan_begin_src);
685 	err |= comedi_check_trigger_is_unique(cmd->stop_src);
686 
687 	/* Step 2b : and mutually compatible */
688 
689 	/*
690 	 * There's only one external trigger signal (which makes these
691 	 * tests easier).  Only one thing can use it.
692 	 */
693 	arg = 0;
694 	if (cmd->start_src & TRIG_EXT)
695 		arg++;
696 	if (cmd->scan_begin_src & TRIG_EXT)
697 		arg++;
698 	if (cmd->stop_src & TRIG_EXT)
699 		arg++;
700 	if (arg > 1)
701 		err |= -EINVAL;
702 
703 	if (err)
704 		return 2;
705 
706 	/* Step 3: check if arguments are trivially valid */
707 
708 	switch (cmd->start_src) {
709 	case TRIG_INT:
710 		err |= comedi_check_trigger_arg_is(&cmd->start_arg, 0);
711 		break;
712 	case TRIG_EXT:
713 		/* Force to external trigger 0. */
714 		if (cmd->start_arg & ~CR_FLAGS_MASK) {
715 			cmd->start_arg =
716 			    COMBINE(cmd->start_arg, 0, ~CR_FLAGS_MASK);
717 			err |= -EINVAL;
718 		}
719 		/* The only flag allowed is CR_EDGE, which is ignored. */
720 		if (cmd->start_arg & CR_FLAGS_MASK & ~CR_EDGE) {
721 			cmd->start_arg = COMBINE(cmd->start_arg, 0,
722 						 CR_FLAGS_MASK & ~CR_EDGE);
723 			err |= -EINVAL;
724 		}
725 		break;
726 	}
727 
728 	switch (cmd->scan_begin_src) {
729 	case TRIG_TIMER:
730 		err |= comedi_check_trigger_arg_max(&cmd->scan_begin_arg,
731 						    MAX_SCAN_PERIOD);
732 
733 		arg = cmd->chanlist_len * CONVERT_PERIOD;
734 		if (arg < MIN_SCAN_PERIOD)
735 			arg = MIN_SCAN_PERIOD;
736 		err |= comedi_check_trigger_arg_min(&cmd->scan_begin_arg, arg);
737 		break;
738 	case TRIG_EXT:
739 		/* Force to external trigger 0. */
740 		if (cmd->scan_begin_arg & ~CR_FLAGS_MASK) {
741 			cmd->scan_begin_arg =
742 			    COMBINE(cmd->scan_begin_arg, 0, ~CR_FLAGS_MASK);
743 			err |= -EINVAL;
744 		}
745 		/* Only allow flags CR_EDGE and CR_INVERT.  Ignore CR_EDGE. */
746 		if (cmd->scan_begin_arg & CR_FLAGS_MASK &
747 		    ~(CR_EDGE | CR_INVERT)) {
748 			cmd->scan_begin_arg =
749 			    COMBINE(cmd->scan_begin_arg, 0,
750 				    CR_FLAGS_MASK & ~(CR_EDGE | CR_INVERT));
751 			err |= -EINVAL;
752 		}
753 		break;
754 	}
755 
756 	err |= comedi_check_trigger_arg_is(&cmd->convert_arg, 0);
757 	err |= comedi_check_trigger_arg_is(&cmd->scan_end_arg,
758 					   cmd->chanlist_len);
759 
760 	switch (cmd->stop_src) {
761 	case TRIG_COUNT:
762 		err |= comedi_check_trigger_arg_min(&cmd->stop_arg, 1);
763 		break;
764 	case TRIG_EXT:
765 		/* Force to external trigger 0. */
766 		if (cmd->stop_arg & ~CR_FLAGS_MASK) {
767 			cmd->stop_arg =
768 			    COMBINE(cmd->stop_arg, 0, ~CR_FLAGS_MASK);
769 			err |= -EINVAL;
770 		}
771 		/* The only flag allowed is CR_EDGE, which is ignored. */
772 		if (cmd->stop_arg & CR_FLAGS_MASK & ~CR_EDGE) {
773 			cmd->stop_arg =
774 			    COMBINE(cmd->stop_arg, 0, CR_FLAGS_MASK & ~CR_EDGE);
775 		}
776 		break;
777 	case TRIG_NONE:
778 		err |= comedi_check_trigger_arg_is(&cmd->stop_arg, 0);
779 		break;
780 	}
781 
782 	if (err)
783 		return 3;
784 
785 	/* Step 4: fix up any arguments. */
786 
787 	if (cmd->scan_begin_src == TRIG_TIMER) {
788 		arg = cmd->scan_begin_arg;
789 		/* Use two timers. */
790 		comedi_8254_cascade_ns_to_timer(dev->pacer, &arg, cmd->flags);
791 		err |= comedi_check_trigger_arg_is(&cmd->scan_begin_arg, arg);
792 	}
793 
794 	if (err)
795 		return 4;
796 
797 	/* Step 5: check channel list if it exists */
798 	if (cmd->chanlist && cmd->chanlist_len > 0)
799 		err |= pci224_ao_check_chanlist(dev, s, cmd);
800 
801 	if (err)
802 		return 5;
803 
804 	return 0;
805 }
806 
pci224_ao_start_pacer(struct comedi_device * dev,struct comedi_subdevice * s)807 static void pci224_ao_start_pacer(struct comedi_device *dev,
808 				  struct comedi_subdevice *s)
809 {
810 	struct pci224_private *devpriv = dev->private;
811 
812 	/*
813 	 * The output of timer Z2-0 will be used as the scan trigger
814 	 * source.
815 	 */
816 	/* Make sure Z2-0 is gated on.  */
817 	outb(pci224_gat_config(0, GAT_VCC), devpriv->iobase1 + PCI224_ZGAT_SCE);
818 	/* Cascading with Z2-2. */
819 	/* Make sure Z2-2 is gated on.  */
820 	outb(pci224_gat_config(2, GAT_VCC), devpriv->iobase1 + PCI224_ZGAT_SCE);
821 	/* Z2-2 needs 10 MHz clock. */
822 	outb(pci224_clk_config(2, CLK_10MHZ),
823 	     devpriv->iobase1 + PCI224_ZCLK_SCE);
824 	/* Z2-0 is clocked from Z2-2's output. */
825 	outb(pci224_clk_config(0, CLK_OUTNM1),
826 	     devpriv->iobase1 + PCI224_ZCLK_SCE);
827 
828 	comedi_8254_pacer_enable(dev->pacer, 2, 0, false);
829 }
830 
pci224_ao_cmd(struct comedi_device * dev,struct comedi_subdevice * s)831 static int pci224_ao_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
832 {
833 	const struct pci224_board *board = dev->board_ptr;
834 	struct pci224_private *devpriv = dev->private;
835 	struct comedi_cmd *cmd = &s->async->cmd;
836 	int range;
837 	unsigned int i, j;
838 	unsigned int ch;
839 	unsigned int rank;
840 	unsigned long flags;
841 
842 	/* Cannot handle null/empty chanlist. */
843 	if (!cmd->chanlist || cmd->chanlist_len == 0)
844 		return -EINVAL;
845 
846 	/* Determine which channels are enabled and their load order.  */
847 	devpriv->ao_enab = 0;
848 
849 	for (i = 0; i < cmd->chanlist_len; i++) {
850 		ch = CR_CHAN(cmd->chanlist[i]);
851 		devpriv->ao_enab |= 1U << ch;
852 		rank = 0;
853 		for (j = 0; j < cmd->chanlist_len; j++) {
854 			if (CR_CHAN(cmd->chanlist[j]) < ch)
855 				rank++;
856 		}
857 		devpriv->ao_scan_order[rank] = i;
858 	}
859 
860 	/* Set enabled channels. */
861 	outw(devpriv->ao_enab, dev->iobase + PCI224_DACCEN);
862 
863 	/* Determine range and polarity.  All channels the same.  */
864 	range = CR_RANGE(cmd->chanlist[0]);
865 
866 	/*
867 	 * Set DAC range and polarity.
868 	 * Set DAC scan trigger source to 'none'.
869 	 * Set DAC FIFO interrupt trigger level to 'not half full'.
870 	 * Reset DAC FIFO.
871 	 *
872 	 * N.B. DAC FIFO interrupts are currently disabled.
873 	 */
874 	devpriv->daccon =
875 	    COMBINE(devpriv->daccon,
876 		    board->ao_hwrange[range] | PCI224_DACCON_TRIG_NONE |
877 		    PCI224_DACCON_FIFOINTR_NHALF,
878 		    PCI224_DACCON_POLAR_MASK | PCI224_DACCON_VREF_MASK |
879 		    PCI224_DACCON_TRIG_MASK | PCI224_DACCON_FIFOINTR_MASK);
880 	outw(devpriv->daccon | PCI224_DACCON_FIFORESET,
881 	     dev->iobase + PCI224_DACCON);
882 
883 	if (cmd->scan_begin_src == TRIG_TIMER) {
884 		comedi_8254_update_divisors(dev->pacer);
885 		pci224_ao_start_pacer(dev, s);
886 	}
887 
888 	spin_lock_irqsave(&devpriv->ao_spinlock, flags);
889 	if (cmd->start_src == TRIG_INT) {
890 		s->async->inttrig = pci224_ao_inttrig_start;
891 	} else {	/* TRIG_EXT */
892 		/* Enable external interrupt trigger to start acquisition. */
893 		devpriv->intsce |= PCI224_INTR_EXT;
894 		outb(devpriv->intsce, devpriv->iobase1 + PCI224_INT_SCE);
895 	}
896 	spin_unlock_irqrestore(&devpriv->ao_spinlock, flags);
897 
898 	return 0;
899 }
900 
901 /*
902  * 'cancel' function for AO subdevice.
903  */
pci224_ao_cancel(struct comedi_device * dev,struct comedi_subdevice * s)904 static int pci224_ao_cancel(struct comedi_device *dev,
905 			    struct comedi_subdevice *s)
906 {
907 	pci224_ao_stop(dev, s);
908 	return 0;
909 }
910 
911 /*
912  * 'munge' data for AO command.
913  */
914 static void
pci224_ao_munge(struct comedi_device * dev,struct comedi_subdevice * s,void * data,unsigned int num_bytes,unsigned int chan_index)915 pci224_ao_munge(struct comedi_device *dev, struct comedi_subdevice *s,
916 		void *data, unsigned int num_bytes, unsigned int chan_index)
917 {
918 	const struct pci224_board *board = dev->board_ptr;
919 	struct comedi_cmd *cmd = &s->async->cmd;
920 	unsigned short *array = data;
921 	unsigned int length = num_bytes / sizeof(*array);
922 	unsigned int offset;
923 	unsigned int shift;
924 	unsigned int i;
925 
926 	/* The hardware expects 16-bit numbers. */
927 	shift = 16 - board->ao_bits;
928 	/* Channels will be all bipolar or all unipolar. */
929 	if ((board->ao_hwrange[CR_RANGE(cmd->chanlist[0])] &
930 	     PCI224_DACCON_POLAR_MASK) == PCI224_DACCON_POLAR_UNI) {
931 		/* Unipolar */
932 		offset = 0;
933 	} else {
934 		/* Bipolar */
935 		offset = 32768;
936 	}
937 	/* Munge the data. */
938 	for (i = 0; i < length; i++)
939 		array[i] = (array[i] << shift) - offset;
940 }
941 
942 /*
943  * Interrupt handler.
944  */
pci224_interrupt(int irq,void * d)945 static irqreturn_t pci224_interrupt(int irq, void *d)
946 {
947 	struct comedi_device *dev = d;
948 	struct pci224_private *devpriv = dev->private;
949 	struct comedi_subdevice *s = dev->write_subdev;
950 	struct comedi_cmd *cmd;
951 	unsigned char intstat, valid_intstat;
952 	unsigned char curenab;
953 	int retval = 0;
954 	unsigned long flags;
955 
956 	intstat = inb(devpriv->iobase1 + PCI224_INT_SCE) & 0x3F;
957 	if (intstat) {
958 		retval = 1;
959 		spin_lock_irqsave(&devpriv->ao_spinlock, flags);
960 		valid_intstat = devpriv->intsce & intstat;
961 		/* Temporarily disable interrupt sources. */
962 		curenab = devpriv->intsce & ~intstat;
963 		outb(curenab, devpriv->iobase1 + PCI224_INT_SCE);
964 		devpriv->intr_running = 1;
965 		devpriv->intr_cpuid = THISCPU;
966 		spin_unlock_irqrestore(&devpriv->ao_spinlock, flags);
967 		if (valid_intstat) {
968 			cmd = &s->async->cmd;
969 			if (valid_intstat & PCI224_INTR_EXT) {
970 				devpriv->intsce &= ~PCI224_INTR_EXT;
971 				if (cmd->start_src == TRIG_EXT)
972 					pci224_ao_start(dev, s);
973 				else if (cmd->stop_src == TRIG_EXT)
974 					pci224_ao_stop(dev, s);
975 			}
976 			if (valid_intstat & PCI224_INTR_DAC)
977 				pci224_ao_handle_fifo(dev, s);
978 		}
979 		/* Reenable interrupt sources. */
980 		spin_lock_irqsave(&devpriv->ao_spinlock, flags);
981 		if (curenab != devpriv->intsce) {
982 			outb(devpriv->intsce,
983 			     devpriv->iobase1 + PCI224_INT_SCE);
984 		}
985 		devpriv->intr_running = 0;
986 		spin_unlock_irqrestore(&devpriv->ao_spinlock, flags);
987 	}
988 	return IRQ_RETVAL(retval);
989 }
990 
991 static int
pci224_auto_attach(struct comedi_device * dev,unsigned long context_model)992 pci224_auto_attach(struct comedi_device *dev, unsigned long context_model)
993 {
994 	struct pci_dev *pci_dev = comedi_to_pci_dev(dev);
995 	const struct pci224_board *board = NULL;
996 	struct pci224_private *devpriv;
997 	struct comedi_subdevice *s;
998 	unsigned int irq;
999 	int ret;
1000 
1001 	if (context_model < ARRAY_SIZE(pci224_boards))
1002 		board = &pci224_boards[context_model];
1003 	if (!board || !board->name) {
1004 		dev_err(dev->class_dev,
1005 			"amplc_pci224: BUG! cannot determine board type!\n");
1006 		return -EINVAL;
1007 	}
1008 	dev->board_ptr = board;
1009 	dev->board_name = board->name;
1010 
1011 	dev_info(dev->class_dev, "amplc_pci224: attach pci %s - %s\n",
1012 		 pci_name(pci_dev), dev->board_name);
1013 
1014 	devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
1015 	if (!devpriv)
1016 		return -ENOMEM;
1017 
1018 	ret = comedi_pci_enable(dev);
1019 	if (ret)
1020 		return ret;
1021 
1022 	spin_lock_init(&devpriv->ao_spinlock);
1023 
1024 	devpriv->iobase1 = pci_resource_start(pci_dev, 2);
1025 	dev->iobase = pci_resource_start(pci_dev, 3);
1026 	irq = pci_dev->irq;
1027 
1028 	/* Allocate buffer to hold values for AO channel scan. */
1029 	devpriv->ao_scan_vals = kmalloc_array(board->ao_chans,
1030 					      sizeof(devpriv->ao_scan_vals[0]),
1031 					      GFP_KERNEL);
1032 	if (!devpriv->ao_scan_vals)
1033 		return -ENOMEM;
1034 
1035 	/* Allocate buffer to hold AO channel scan order. */
1036 	devpriv->ao_scan_order =
1037 				kmalloc_array(board->ao_chans,
1038 					      sizeof(devpriv->ao_scan_order[0]),
1039 					      GFP_KERNEL);
1040 	if (!devpriv->ao_scan_order)
1041 		return -ENOMEM;
1042 
1043 	/* Disable interrupt sources. */
1044 	devpriv->intsce = 0;
1045 	outb(0, devpriv->iobase1 + PCI224_INT_SCE);
1046 
1047 	/* Initialize the DAC hardware. */
1048 	outw(PCI224_DACCON_GLOBALRESET, dev->iobase + PCI224_DACCON);
1049 	outw(0, dev->iobase + PCI224_DACCEN);
1050 	outw(0, dev->iobase + PCI224_FIFOSIZ);
1051 	devpriv->daccon = PCI224_DACCON_TRIG_SW | PCI224_DACCON_POLAR_BI |
1052 			  PCI224_DACCON_FIFOENAB | PCI224_DACCON_FIFOINTR_EMPTY;
1053 	outw(devpriv->daccon | PCI224_DACCON_FIFORESET,
1054 	     dev->iobase + PCI224_DACCON);
1055 
1056 	dev->pacer = comedi_8254_init(devpriv->iobase1 + PCI224_Z2_BASE,
1057 				      I8254_OSC_BASE_10MHZ, I8254_IO8, 0);
1058 	if (!dev->pacer)
1059 		return -ENOMEM;
1060 
1061 	ret = comedi_alloc_subdevices(dev, 1);
1062 	if (ret)
1063 		return ret;
1064 
1065 	s = &dev->subdevices[0];
1066 	/* Analog output subdevice. */
1067 	s->type = COMEDI_SUBD_AO;
1068 	s->subdev_flags = SDF_WRITABLE | SDF_GROUND | SDF_CMD_WRITE;
1069 	s->n_chan = board->ao_chans;
1070 	s->maxdata = (1 << board->ao_bits) - 1;
1071 	s->range_table = board->ao_range;
1072 	s->insn_write = pci224_ao_insn_write;
1073 	s->len_chanlist = s->n_chan;
1074 	dev->write_subdev = s;
1075 	s->do_cmd = pci224_ao_cmd;
1076 	s->do_cmdtest = pci224_ao_cmdtest;
1077 	s->cancel = pci224_ao_cancel;
1078 	s->munge = pci224_ao_munge;
1079 
1080 	ret = comedi_alloc_subdev_readback(s);
1081 	if (ret)
1082 		return ret;
1083 
1084 	if (irq) {
1085 		ret = request_irq(irq, pci224_interrupt, IRQF_SHARED,
1086 				  dev->board_name, dev);
1087 		if (ret < 0) {
1088 			dev_err(dev->class_dev,
1089 				"error! unable to allocate irq %u\n", irq);
1090 			return ret;
1091 		}
1092 		dev->irq = irq;
1093 	}
1094 
1095 	return 0;
1096 }
1097 
pci224_detach(struct comedi_device * dev)1098 static void pci224_detach(struct comedi_device *dev)
1099 {
1100 	struct pci224_private *devpriv = dev->private;
1101 
1102 	comedi_pci_detach(dev);
1103 	if (devpriv) {
1104 		kfree(devpriv->ao_scan_vals);
1105 		kfree(devpriv->ao_scan_order);
1106 	}
1107 }
1108 
1109 static struct comedi_driver amplc_pci224_driver = {
1110 	.driver_name	= "amplc_pci224",
1111 	.module		= THIS_MODULE,
1112 	.detach		= pci224_detach,
1113 	.auto_attach	= pci224_auto_attach,
1114 	.board_name	= &pci224_boards[0].name,
1115 	.offset		= sizeof(struct pci224_board),
1116 	.num_names	= ARRAY_SIZE(pci224_boards),
1117 };
1118 
amplc_pci224_pci_probe(struct pci_dev * dev,const struct pci_device_id * id)1119 static int amplc_pci224_pci_probe(struct pci_dev *dev,
1120 				  const struct pci_device_id *id)
1121 {
1122 	return comedi_pci_auto_config(dev, &amplc_pci224_driver,
1123 				      id->driver_data);
1124 }
1125 
1126 static const struct pci_device_id amplc_pci224_pci_table[] = {
1127 	{ PCI_VDEVICE(AMPLICON, 0x0007), pci224_model },
1128 	{ PCI_VDEVICE(AMPLICON, 0x0008), pci234_model },
1129 	{ 0 }
1130 };
1131 MODULE_DEVICE_TABLE(pci, amplc_pci224_pci_table);
1132 
1133 static struct pci_driver amplc_pci224_pci_driver = {
1134 	.name		= "amplc_pci224",
1135 	.id_table	= amplc_pci224_pci_table,
1136 	.probe		= amplc_pci224_pci_probe,
1137 	.remove		= comedi_pci_auto_unconfig,
1138 };
1139 module_comedi_pci_driver(amplc_pci224_driver, amplc_pci224_pci_driver);
1140 
1141 MODULE_AUTHOR("Comedi https://www.comedi.org");
1142 MODULE_DESCRIPTION("Comedi driver for Amplicon PCI224 and PCI234 AO boards");
1143 MODULE_LICENSE("GPL");
1144