1 /*
2  * addi_apci_3120.c
3  * Copyright (C) 2004,2005  ADDI-DATA GmbH for the source code of this module.
4  *
5  *	ADDI-DATA GmbH
6  *	Dieselstrasse 3
7  *	D-77833 Ottersweier
8  *	Tel: +19(0)7223/9493-0
9  *	Fax: +49(0)7223/9493-92
10  *	http://www.addi-data.com
11  *	info@addi-data.com
12  *
13  * This program is free software; you can redistribute it and/or modify it
14  * under the terms of the GNU General Public License as published by the
15  * Free Software Foundation; either version 2 of the License, or (at your
16  * option) any later version.
17  *
18  * This program is distributed in the hope that it will be useful, but WITHOUT
19  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
20  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
21  * more details.
22  */
23 
24 #include <linux/module.h>
25 #include <linux/interrupt.h>
26 
27 #include "../comedi_pci.h"
28 #include "amcc_s5933.h"
29 
30 /*
31  * PCI BAR 0 register map (devpriv->amcc)
32  * see amcc_s5933.h for register and bit defines
33  */
34 #define APCI3120_FIFO_ADVANCE_ON_BYTE_2		(1 << 29)
35 
36 /*
37  * PCI BAR 1 register map (dev->iobase)
38  */
39 #define APCI3120_AI_FIFO_REG			0x00
40 #define APCI3120_CTRL_REG			0x00
41 #define APCI3120_CTRL_EXT_TRIG			(1 << 15)
42 #define APCI3120_CTRL_GATE(x)			(1 << (12 + (x)))
43 #define APCI3120_CTRL_PR(x)			(((x) & 0xf) << 8)
44 #define APCI3120_CTRL_PA(x)			(((x) & 0xf) << 0)
45 #define APCI3120_AI_SOFTTRIG_REG		0x02
46 #define APCI3120_STATUS_REG			0x02
47 #define APCI3120_STATUS_EOC_INT			(1 << 15)
48 #define APCI3120_STATUS_AMCC_INT		(1 << 14)
49 #define APCI3120_STATUS_EOS_INT			(1 << 13)
50 #define APCI3120_STATUS_TIMER2_INT		(1 << 12)
51 #define APCI3120_STATUS_INT_MASK		(0xf << 12)
52 #define APCI3120_STATUS_TO_DI_BITS(x)		(((x) >> 8) & 0xf)
53 #define APCI3120_STATUS_TO_VERSION(x)		(((x) >> 4) & 0xf)
54 #define APCI3120_STATUS_FIFO_FULL		(1 << 2)
55 #define APCI3120_STATUS_FIFO_EMPTY		(1 << 1)
56 #define APCI3120_STATUS_DA_READY		(1 << 0)
57 #define APCI3120_TIMER_REG			0x04
58 #define APCI3120_CHANLIST_REG			0x06
59 #define APCI3120_CHANLIST_INDEX(x)		(((x) & 0xf) << 8)
60 #define APCI3120_CHANLIST_UNIPOLAR		(1 << 7)
61 #define APCI3120_CHANLIST_GAIN(x)		(((x) & 0x3) << 4)
62 #define APCI3120_CHANLIST_MUX(x)		(((x) & 0xf) << 0)
63 #define APCI3120_AO_REG(x)			(0x08 + (((x) / 4) * 2))
64 #define APCI3120_AO_MUX(x)			(((x) & 0x3) << 14)
65 #define APCI3120_AO_DATA(x)			((x) << 0)
66 #define APCI3120_TIMER_MODE_REG			0x0c
67 #define APCI3120_TIMER_MODE(_t, _m)		((_m) << ((_t) * 2))
68 #define APCI3120_TIMER_MODE0			0  /* I8254_MODE0 */
69 #define APCI3120_TIMER_MODE2			1  /* I8254_MODE2 */
70 #define APCI3120_TIMER_MODE4			2  /* I8254_MODE4 */
71 #define APCI3120_TIMER_MODE5			3  /* I8254_MODE5 */
72 #define APCI3120_TIMER_MODE_MASK(_t)		(3 << ((_t) * 2))
73 #define APCI3120_CTR0_REG			0x0d
74 #define APCI3120_CTR0_DO_BITS(x)		((x) << 4)
75 #define APCI3120_CTR0_TIMER_SEL(x)		((x) << 0)
76 #define APCI3120_MODE_REG			0x0e
77 #define APCI3120_MODE_TIMER2_CLK_OSC		(0 << 6)
78 #define APCI3120_MODE_TIMER2_CLK_OUT1		(1 << 6)
79 #define APCI3120_MODE_TIMER2_CLK_EOC		(2 << 6)
80 #define APCI3120_MODE_TIMER2_CLK_EOS		(3 << 6)
81 #define APCI3120_MODE_TIMER2_CLK_MASK		(3 << 6)
82 #define APCI3120_MODE_TIMER2_AS_TIMER		(0 << 4)
83 #define APCI3120_MODE_TIMER2_AS_COUNTER		(1 << 4)
84 #define APCI3120_MODE_TIMER2_AS_WDOG		(2 << 4)
85 #define APCI3120_MODE_TIMER2_AS_MASK		(3 << 4)  /* sets AS_TIMER */
86 #define APCI3120_MODE_SCAN_ENA			(1 << 3)
87 #define APCI3120_MODE_TIMER2_IRQ_ENA		(1 << 2)
88 #define APCI3120_MODE_EOS_IRQ_ENA		(1 << 1)
89 #define APCI3120_MODE_EOC_IRQ_ENA		(1 << 0)
90 
91 /*
92  * PCI BAR 2 register map (devpriv->addon)
93  */
94 #define APCI3120_ADDON_ADDR_REG			0x00
95 #define APCI3120_ADDON_DATA_REG			0x02
96 #define APCI3120_ADDON_CTRL_REG			0x04
97 #define APCI3120_ADDON_CTRL_AMWEN_ENA		(1 << 1)
98 #define APCI3120_ADDON_CTRL_A2P_FIFO_ENA	(1 << 0)
99 
100 /*
101  * Board revisions
102  */
103 #define APCI3120_REVA				0xa
104 #define APCI3120_REVB				0xb
105 #define APCI3120_REVA_OSC_BASE			70	/* 70ns = 14.29MHz */
106 #define APCI3120_REVB_OSC_BASE			50	/* 50ns = 20MHz */
107 
108 static const struct comedi_lrange apci3120_ai_range = {
109 	8, {
110 		BIP_RANGE(10),
111 		BIP_RANGE(5),
112 		BIP_RANGE(2),
113 		BIP_RANGE(1),
114 		UNI_RANGE(10),
115 		UNI_RANGE(5),
116 		UNI_RANGE(2),
117 		UNI_RANGE(1)
118 	}
119 };
120 
121 enum apci3120_boardid {
122 	BOARD_APCI3120,
123 	BOARD_APCI3001,
124 };
125 
126 struct apci3120_board {
127 	const char *name;
128 	unsigned int ai_is_16bit:1;
129 	unsigned int has_ao:1;
130 };
131 
132 static const struct apci3120_board apci3120_boardtypes[] = {
133 	[BOARD_APCI3120] = {
134 		.name		= "apci3120",
135 		.ai_is_16bit	= 1,
136 		.has_ao		= 1,
137 	},
138 	[BOARD_APCI3001] = {
139 		.name		= "apci3001",
140 	},
141 };
142 
143 struct apci3120_dmabuf {
144 	unsigned short *virt;
145 	dma_addr_t hw;
146 	unsigned int size;
147 	unsigned int use_size;
148 };
149 
150 struct apci3120_private {
151 	unsigned long amcc;
152 	unsigned long addon;
153 	unsigned int osc_base;
154 	unsigned int use_dma:1;
155 	unsigned int use_double_buffer:1;
156 	unsigned int cur_dmabuf:1;
157 	struct apci3120_dmabuf dmabuf[2];
158 	unsigned char do_bits;
159 	unsigned char timer_mode;
160 	unsigned char mode;
161 	unsigned short ctrl;
162 };
163 
apci3120_addon_write(struct comedi_device * dev,unsigned int val,unsigned int reg)164 static void apci3120_addon_write(struct comedi_device *dev,
165 				 unsigned int val, unsigned int reg)
166 {
167 	struct apci3120_private *devpriv = dev->private;
168 
169 	/* 16-bit interface for AMCC add-on registers */
170 
171 	outw(reg, devpriv->addon + APCI3120_ADDON_ADDR_REG);
172 	outw(val & 0xffff, devpriv->addon + APCI3120_ADDON_DATA_REG);
173 
174 	outw(reg + 2, devpriv->addon + APCI3120_ADDON_ADDR_REG);
175 	outw((val >> 16) & 0xffff, devpriv->addon + APCI3120_ADDON_DATA_REG);
176 }
177 
apci3120_init_dma(struct comedi_device * dev,struct apci3120_dmabuf * dmabuf)178 static void apci3120_init_dma(struct comedi_device *dev,
179 			      struct apci3120_dmabuf *dmabuf)
180 {
181 	struct apci3120_private *devpriv = dev->private;
182 
183 	/* AMCC - enable transfer count and reset A2P FIFO */
184 	outl(AGCSTS_TC_ENABLE | AGCSTS_RESET_A2P_FIFO,
185 	     devpriv->amcc + AMCC_OP_REG_AGCSTS);
186 
187 	/* Add-On - enable transfer count and reset A2P FIFO */
188 	apci3120_addon_write(dev, AGCSTS_TC_ENABLE | AGCSTS_RESET_A2P_FIFO,
189 			     AMCC_OP_REG_AGCSTS);
190 
191 	/* AMCC - enable transfers and reset A2P flags */
192 	outl(RESET_A2P_FLAGS | EN_A2P_TRANSFERS,
193 	     devpriv->amcc + AMCC_OP_REG_MCSR);
194 
195 	/* Add-On - DMA start address */
196 	apci3120_addon_write(dev, dmabuf->hw, AMCC_OP_REG_AMWAR);
197 
198 	/* Add-On - Number of acquisitions */
199 	apci3120_addon_write(dev, dmabuf->use_size, AMCC_OP_REG_AMWTC);
200 
201 	/* AMCC - enable write complete (DMA) and set FIFO advance */
202 	outl(APCI3120_FIFO_ADVANCE_ON_BYTE_2 | AINT_WRITE_COMPL,
203 	     devpriv->amcc + AMCC_OP_REG_INTCSR);
204 
205 	/* Add-On - enable DMA */
206 	outw(APCI3120_ADDON_CTRL_AMWEN_ENA | APCI3120_ADDON_CTRL_A2P_FIFO_ENA,
207 	     devpriv->addon + APCI3120_ADDON_CTRL_REG);
208 }
209 
apci3120_setup_dma(struct comedi_device * dev,struct comedi_subdevice * s)210 static void apci3120_setup_dma(struct comedi_device *dev,
211 			       struct comedi_subdevice *s)
212 {
213 	struct apci3120_private *devpriv = dev->private;
214 	struct comedi_cmd *cmd = &s->async->cmd;
215 	struct apci3120_dmabuf *dmabuf0 = &devpriv->dmabuf[0];
216 	struct apci3120_dmabuf *dmabuf1 = &devpriv->dmabuf[1];
217 	unsigned int dmalen0 = dmabuf0->size;
218 	unsigned int dmalen1 = dmabuf1->size;
219 	unsigned int scan_bytes;
220 
221 	scan_bytes = comedi_samples_to_bytes(s, cmd->scan_end_arg);
222 
223 	if (cmd->stop_src == TRIG_COUNT) {
224 		/*
225 		 * Must we fill full first buffer? And must we fill
226 		 * full second buffer when first is once filled?
227 		 */
228 		if (dmalen0 > (cmd->stop_arg * scan_bytes))
229 			dmalen0 = cmd->stop_arg * scan_bytes;
230 		else if (dmalen1 > (cmd->stop_arg * scan_bytes - dmalen0))
231 			dmalen1 = cmd->stop_arg * scan_bytes - dmalen0;
232 	}
233 
234 	if (cmd->flags & CMDF_WAKE_EOS) {
235 		/* don't we want wake up every scan? */
236 		if (dmalen0 > scan_bytes) {
237 			dmalen0 = scan_bytes;
238 			if (cmd->scan_end_arg & 1)
239 				dmalen0 += 2;
240 		}
241 		if (dmalen1 > scan_bytes) {
242 			dmalen1 = scan_bytes;
243 			if (cmd->scan_end_arg & 1)
244 				dmalen1 -= 2;
245 			if (dmalen1 < 4)
246 				dmalen1 = 4;
247 		}
248 	} else {
249 		/* isn't output buff smaller that our DMA buff? */
250 		if (dmalen0 > s->async->prealloc_bufsz)
251 			dmalen0 = s->async->prealloc_bufsz;
252 		if (dmalen1 > s->async->prealloc_bufsz)
253 			dmalen1 = s->async->prealloc_bufsz;
254 	}
255 	dmabuf0->use_size = dmalen0;
256 	dmabuf1->use_size = dmalen1;
257 
258 	apci3120_init_dma(dev, dmabuf0);
259 }
260 
261 /*
262  * There are three timers on the board. They all use the same base
263  * clock with a fixed prescaler for each timer. The base clock used
264  * depends on the board version and type.
265  *
266  * APCI-3120 Rev A boards OSC = 14.29MHz base clock (~70ns)
267  * APCI-3120 Rev B boards OSC = 20MHz base clock (50ns)
268  * APCI-3001 boards OSC = 20MHz base clock (50ns)
269  *
270  * The prescalers for each timer are:
271  * Timer 0 CLK = OSC/10
272  * Timer 1 CLK = OSC/1000
273  * Timer 2 CLK = OSC/1000
274  */
apci3120_ns_to_timer(struct comedi_device * dev,unsigned int timer,unsigned int ns,unsigned int flags)275 static unsigned int apci3120_ns_to_timer(struct comedi_device *dev,
276 					 unsigned int timer,
277 					 unsigned int ns,
278 					 unsigned int flags)
279 {
280 	struct apci3120_private *devpriv = dev->private;
281 	unsigned int prescale = (timer == 0) ? 10 : 1000;
282 	unsigned int timer_base = devpriv->osc_base * prescale;
283 	unsigned int divisor;
284 
285 	switch (flags & CMDF_ROUND_MASK) {
286 	case CMDF_ROUND_UP:
287 		divisor = DIV_ROUND_UP(ns, timer_base);
288 		break;
289 	case CMDF_ROUND_DOWN:
290 		divisor = ns / timer_base;
291 		break;
292 	case CMDF_ROUND_NEAREST:
293 	default:
294 		divisor = DIV_ROUND_CLOSEST(ns, timer_base);
295 		break;
296 	}
297 
298 	if (timer == 2) {
299 		/* timer 2 is 24-bits */
300 		if (divisor > 0x00ffffff)
301 			divisor = 0x00ffffff;
302 	} else {
303 		/* timers 0 and 1 are 16-bits */
304 		if (divisor > 0xffff)
305 			divisor = 0xffff;
306 	}
307 	/* the timers require a minimum divisor of 2 */
308 	if (divisor < 2)
309 		divisor = 2;
310 
311 	return divisor;
312 }
313 
apci3120_clr_timer2_interrupt(struct comedi_device * dev)314 static void apci3120_clr_timer2_interrupt(struct comedi_device *dev)
315 {
316 	/* a dummy read of APCI3120_CTR0_REG clears the timer 2 interrupt */
317 	inb(dev->iobase + APCI3120_CTR0_REG);
318 }
319 
apci3120_timer_write(struct comedi_device * dev,unsigned int timer,unsigned int val)320 static void apci3120_timer_write(struct comedi_device *dev,
321 				 unsigned int timer, unsigned int val)
322 {
323 	struct apci3120_private *devpriv = dev->private;
324 
325 	/* write 16-bit value to timer (lower 16-bits of timer 2) */
326 	outb(APCI3120_CTR0_DO_BITS(devpriv->do_bits) |
327 	     APCI3120_CTR0_TIMER_SEL(timer),
328 	     dev->iobase + APCI3120_CTR0_REG);
329 	outw(val & 0xffff, dev->iobase + APCI3120_TIMER_REG);
330 
331 	if (timer == 2) {
332 		/* write upper 16-bits to timer 2 */
333 		outb(APCI3120_CTR0_DO_BITS(devpriv->do_bits) |
334 		     APCI3120_CTR0_TIMER_SEL(timer + 1),
335 		     dev->iobase + APCI3120_CTR0_REG);
336 		outw((val >> 16) & 0xffff, dev->iobase + APCI3120_TIMER_REG);
337 	}
338 }
339 
apci3120_timer_read(struct comedi_device * dev,unsigned int timer)340 static unsigned int apci3120_timer_read(struct comedi_device *dev,
341 					unsigned int timer)
342 {
343 	struct apci3120_private *devpriv = dev->private;
344 	unsigned int val;
345 
346 	/* read 16-bit value from timer (lower 16-bits of timer 2) */
347 	outb(APCI3120_CTR0_DO_BITS(devpriv->do_bits) |
348 	     APCI3120_CTR0_TIMER_SEL(timer),
349 	     dev->iobase + APCI3120_CTR0_REG);
350 	val = inw(dev->iobase + APCI3120_TIMER_REG);
351 
352 	if (timer == 2) {
353 		/* read upper 16-bits from timer 2 */
354 		outb(APCI3120_CTR0_DO_BITS(devpriv->do_bits) |
355 		     APCI3120_CTR0_TIMER_SEL(timer + 1),
356 		     dev->iobase + APCI3120_CTR0_REG);
357 		val |= (inw(dev->iobase + APCI3120_TIMER_REG) << 16);
358 	}
359 
360 	return val;
361 }
362 
apci3120_timer_set_mode(struct comedi_device * dev,unsigned int timer,unsigned int mode)363 static void apci3120_timer_set_mode(struct comedi_device *dev,
364 				    unsigned int timer, unsigned int mode)
365 {
366 	struct apci3120_private *devpriv = dev->private;
367 
368 	devpriv->timer_mode &= ~APCI3120_TIMER_MODE_MASK(timer);
369 	devpriv->timer_mode |= APCI3120_TIMER_MODE(timer, mode);
370 	outb(devpriv->timer_mode, dev->iobase + APCI3120_TIMER_MODE_REG);
371 }
372 
apci3120_timer_enable(struct comedi_device * dev,unsigned int timer,bool enable)373 static void apci3120_timer_enable(struct comedi_device *dev,
374 				  unsigned int timer, bool enable)
375 {
376 	struct apci3120_private *devpriv = dev->private;
377 
378 	if (enable)
379 		devpriv->ctrl |= APCI3120_CTRL_GATE(timer);
380 	else
381 		devpriv->ctrl &= ~APCI3120_CTRL_GATE(timer);
382 	outw(devpriv->ctrl, dev->iobase + APCI3120_CTRL_REG);
383 }
384 
apci3120_exttrig_enable(struct comedi_device * dev,bool enable)385 static void apci3120_exttrig_enable(struct comedi_device *dev, bool enable)
386 {
387 	struct apci3120_private *devpriv = dev->private;
388 
389 	if (enable)
390 		devpriv->ctrl |= APCI3120_CTRL_EXT_TRIG;
391 	else
392 		devpriv->ctrl &= ~APCI3120_CTRL_EXT_TRIG;
393 	outw(devpriv->ctrl, dev->iobase + APCI3120_CTRL_REG);
394 }
395 
apci3120_set_chanlist(struct comedi_device * dev,struct comedi_subdevice * s,int n_chan,unsigned int * chanlist)396 static void apci3120_set_chanlist(struct comedi_device *dev,
397 				  struct comedi_subdevice *s,
398 				  int n_chan, unsigned int *chanlist)
399 {
400 	struct apci3120_private *devpriv = dev->private;
401 	int i;
402 
403 	/* set chanlist for scan */
404 	for (i = 0; i < n_chan; i++) {
405 		unsigned int chan = CR_CHAN(chanlist[i]);
406 		unsigned int range = CR_RANGE(chanlist[i]);
407 		unsigned int val;
408 
409 		val = APCI3120_CHANLIST_MUX(chan) |
410 		      APCI3120_CHANLIST_GAIN(range) |
411 		      APCI3120_CHANLIST_INDEX(i);
412 
413 		if (comedi_range_is_unipolar(s, range))
414 			val |= APCI3120_CHANLIST_UNIPOLAR;
415 
416 		outw(val, dev->iobase + APCI3120_CHANLIST_REG);
417 	}
418 
419 	/* a dummy read of APCI3120_TIMER_MODE_REG resets the ai FIFO */
420 	inw(dev->iobase + APCI3120_TIMER_MODE_REG);
421 
422 	/* set scan length (PR) and scan start (PA) */
423 	devpriv->ctrl = APCI3120_CTRL_PR(n_chan - 1) | APCI3120_CTRL_PA(0);
424 	outw(devpriv->ctrl, dev->iobase + APCI3120_CTRL_REG);
425 
426 	/* enable chanlist scanning if necessary */
427 	if (n_chan > 1)
428 		devpriv->mode |= APCI3120_MODE_SCAN_ENA;
429 }
430 
apci3120_interrupt_dma(struct comedi_device * dev,struct comedi_subdevice * s)431 static void apci3120_interrupt_dma(struct comedi_device *dev,
432 				   struct comedi_subdevice *s)
433 {
434 	struct apci3120_private *devpriv = dev->private;
435 	struct comedi_async *async = s->async;
436 	struct comedi_cmd *cmd = &async->cmd;
437 	struct apci3120_dmabuf *dmabuf;
438 	unsigned int nbytes;
439 	unsigned int nsamples;
440 
441 	dmabuf = &devpriv->dmabuf[devpriv->cur_dmabuf];
442 
443 	nbytes = dmabuf->use_size - inl(devpriv->amcc + AMCC_OP_REG_MWTC);
444 
445 	if (nbytes < dmabuf->use_size)
446 		dev_err(dev->class_dev, "Interrupted DMA transfer!\n");
447 	if (nbytes & 1) {
448 		dev_err(dev->class_dev, "Odd count of bytes in DMA ring!\n");
449 		async->events |= COMEDI_CB_ERROR;
450 		return;
451 	}
452 
453 	nsamples = comedi_bytes_to_samples(s, nbytes);
454 	if (nsamples) {
455 		comedi_buf_write_samples(s, dmabuf->virt, nsamples);
456 
457 		if (!(cmd->flags & CMDF_WAKE_EOS))
458 			async->events |= COMEDI_CB_EOS;
459 	}
460 
461 	if ((async->events & COMEDI_CB_CANCEL_MASK) ||
462 	    (cmd->stop_src == TRIG_COUNT && async->scans_done >= cmd->stop_arg))
463 		return;
464 
465 	if (devpriv->use_double_buffer) {
466 		/* switch DMA buffers for next interrupt */
467 		devpriv->cur_dmabuf = !devpriv->cur_dmabuf;
468 		dmabuf = &devpriv->dmabuf[devpriv->cur_dmabuf];
469 		apci3120_init_dma(dev, dmabuf);
470 	} else {
471 		/* restart DMA if not using double buffering */
472 		apci3120_init_dma(dev, dmabuf);
473 	}
474 }
475 
apci3120_interrupt(int irq,void * d)476 static irqreturn_t apci3120_interrupt(int irq, void *d)
477 {
478 	struct comedi_device *dev = d;
479 	struct apci3120_private *devpriv = dev->private;
480 	struct comedi_subdevice *s = dev->read_subdev;
481 	struct comedi_async *async = s->async;
482 	struct comedi_cmd *cmd = &async->cmd;
483 	unsigned int status;
484 	unsigned int int_amcc;
485 
486 	status = inw(dev->iobase + APCI3120_STATUS_REG);
487 	int_amcc = inl(devpriv->amcc + AMCC_OP_REG_INTCSR);
488 
489 	if (!(status & APCI3120_STATUS_INT_MASK) &&
490 	    !(int_amcc & ANY_S593X_INT)) {
491 		dev_err(dev->class_dev, "IRQ from unknown source\n");
492 		return IRQ_NONE;
493 	}
494 
495 	outl(int_amcc | AINT_INT_MASK, devpriv->amcc + AMCC_OP_REG_INTCSR);
496 
497 	if (devpriv->ctrl & APCI3120_CTRL_EXT_TRIG)
498 		apci3120_exttrig_enable(dev, false);
499 
500 	if (int_amcc & MASTER_ABORT_INT)
501 		dev_err(dev->class_dev, "AMCC IRQ - MASTER DMA ABORT!\n");
502 	if (int_amcc & TARGET_ABORT_INT)
503 		dev_err(dev->class_dev, "AMCC IRQ - TARGET DMA ABORT!\n");
504 
505 	if ((status & APCI3120_STATUS_EOC_INT) == 0 &&
506 	    (devpriv->mode & APCI3120_MODE_EOC_IRQ_ENA)) {
507 		/* nothing to do... EOC mode is not currently used */
508 	}
509 
510 	if ((status & APCI3120_STATUS_EOS_INT) &&
511 	    (devpriv->mode & APCI3120_MODE_EOS_IRQ_ENA)) {
512 		unsigned short val;
513 		int i;
514 
515 		for (i = 0; i < cmd->chanlist_len; i++) {
516 			val = inw(dev->iobase + APCI3120_AI_FIFO_REG);
517 			comedi_buf_write_samples(s, &val, 1);
518 		}
519 
520 		devpriv->mode |= APCI3120_MODE_EOS_IRQ_ENA;
521 		outb(devpriv->mode, dev->iobase + APCI3120_MODE_REG);
522 	}
523 
524 	if (status & APCI3120_STATUS_TIMER2_INT) {
525 		/*
526 		 * for safety...
527 		 * timer2 interrupts are not enabled in the driver
528 		 */
529 		apci3120_clr_timer2_interrupt(dev);
530 	}
531 
532 	if (status & APCI3120_STATUS_AMCC_INT) {
533 		/* AMCC- Clear write complete interrupt (DMA) */
534 		outl(AINT_WT_COMPLETE, devpriv->amcc + AMCC_OP_REG_INTCSR);
535 
536 		/* do some data transfer */
537 		apci3120_interrupt_dma(dev, s);
538 	}
539 
540 	if (cmd->stop_src == TRIG_COUNT && async->scans_done >= cmd->stop_arg)
541 		async->events |= COMEDI_CB_EOA;
542 
543 	comedi_handle_events(dev, s);
544 
545 	return IRQ_HANDLED;
546 }
547 
apci3120_ai_cmd(struct comedi_device * dev,struct comedi_subdevice * s)548 static int apci3120_ai_cmd(struct comedi_device *dev,
549 			   struct comedi_subdevice *s)
550 {
551 	struct apci3120_private *devpriv = dev->private;
552 	struct comedi_cmd *cmd = &s->async->cmd;
553 	unsigned int divisor;
554 
555 	/* set default mode bits */
556 	devpriv->mode = APCI3120_MODE_TIMER2_CLK_OSC |
557 			APCI3120_MODE_TIMER2_AS_TIMER;
558 
559 	/* AMCC- Clear write complete interrupt (DMA) */
560 	outl(AINT_WT_COMPLETE, devpriv->amcc + AMCC_OP_REG_INTCSR);
561 
562 	devpriv->cur_dmabuf = 0;
563 
564 	/* load chanlist for command scan */
565 	apci3120_set_chanlist(dev, s, cmd->chanlist_len, cmd->chanlist);
566 
567 	if (cmd->start_src == TRIG_EXT)
568 		apci3120_exttrig_enable(dev, true);
569 
570 	if (cmd->scan_begin_src == TRIG_TIMER) {
571 		/*
572 		 * Timer 1 is used in MODE2 (rate generator) to set the
573 		 * start time for each scan.
574 		 */
575 		divisor = apci3120_ns_to_timer(dev, 1, cmd->scan_begin_arg,
576 					       cmd->flags);
577 		apci3120_timer_set_mode(dev, 1, APCI3120_TIMER_MODE2);
578 		apci3120_timer_write(dev, 1, divisor);
579 	}
580 
581 	/*
582 	 * Timer 0 is used in MODE2 (rate generator) to set the conversion
583 	 * time for each acquisition.
584 	 */
585 	divisor = apci3120_ns_to_timer(dev, 0, cmd->convert_arg, cmd->flags);
586 	apci3120_timer_set_mode(dev, 0, APCI3120_TIMER_MODE2);
587 	apci3120_timer_write(dev, 0, divisor);
588 
589 	if (devpriv->use_dma)
590 		apci3120_setup_dma(dev, s);
591 	else
592 		devpriv->mode |= APCI3120_MODE_EOS_IRQ_ENA;
593 
594 	/* set mode to enable acquisition */
595 	outb(devpriv->mode, dev->iobase + APCI3120_MODE_REG);
596 
597 	if (cmd->scan_begin_src == TRIG_TIMER)
598 		apci3120_timer_enable(dev, 1, true);
599 	apci3120_timer_enable(dev, 0, true);
600 
601 	return 0;
602 }
603 
apci3120_ai_cmdtest(struct comedi_device * dev,struct comedi_subdevice * s,struct comedi_cmd * cmd)604 static int apci3120_ai_cmdtest(struct comedi_device *dev,
605 			       struct comedi_subdevice *s,
606 			       struct comedi_cmd *cmd)
607 {
608 	unsigned int arg;
609 	int err = 0;
610 
611 	/* Step 1 : check if triggers are trivially valid */
612 
613 	err |= comedi_check_trigger_src(&cmd->start_src, TRIG_NOW | TRIG_EXT);
614 	err |= comedi_check_trigger_src(&cmd->scan_begin_src,
615 					TRIG_TIMER | TRIG_FOLLOW);
616 	err |= comedi_check_trigger_src(&cmd->convert_src, TRIG_TIMER);
617 	err |= comedi_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
618 	err |= comedi_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE);
619 
620 	if (err)
621 		return 1;
622 
623 	/* Step 2a : make sure trigger sources are unique */
624 
625 	err |= comedi_check_trigger_is_unique(cmd->start_src);
626 	err |= comedi_check_trigger_is_unique(cmd->scan_begin_src);
627 	err |= comedi_check_trigger_is_unique(cmd->stop_src);
628 
629 	/* Step 2b : and mutually compatible */
630 
631 	if (err)
632 		return 2;
633 
634 	/* Step 3: check if arguments are trivially valid */
635 
636 	err |= comedi_check_trigger_arg_is(&cmd->start_arg, 0);
637 
638 	if (cmd->scan_begin_src == TRIG_TIMER) {	/* Test Delay timing */
639 		err |= comedi_check_trigger_arg_min(&cmd->scan_begin_arg,
640 						    100000);
641 	}
642 
643 	/* minimum conversion time per sample is 10us */
644 	err |= comedi_check_trigger_arg_min(&cmd->convert_arg, 10000);
645 
646 	err |= comedi_check_trigger_arg_min(&cmd->chanlist_len, 1);
647 	err |= comedi_check_trigger_arg_is(&cmd->scan_end_arg,
648 					   cmd->chanlist_len);
649 
650 	if (cmd->stop_src == TRIG_COUNT)
651 		err |= comedi_check_trigger_arg_min(&cmd->stop_arg, 1);
652 	else	/*  TRIG_NONE */
653 		err |= comedi_check_trigger_arg_is(&cmd->stop_arg, 0);
654 
655 	if (err)
656 		return 3;
657 
658 	/* Step 4: fix up any arguments */
659 
660 	if (cmd->scan_begin_src == TRIG_TIMER) {
661 		/* scan begin must be larger than the scan time */
662 		arg = cmd->convert_arg * cmd->scan_end_arg;
663 		err |= comedi_check_trigger_arg_min(&cmd->scan_begin_arg, arg);
664 	}
665 
666 	if (err)
667 		return 4;
668 
669 	/* Step 5: check channel list if it exists */
670 
671 	return 0;
672 }
673 
apci3120_cancel(struct comedi_device * dev,struct comedi_subdevice * s)674 static int apci3120_cancel(struct comedi_device *dev,
675 			   struct comedi_subdevice *s)
676 {
677 	struct apci3120_private *devpriv = dev->private;
678 
679 	/* Add-On - disable DMA */
680 	outw(0, devpriv->addon + 4);
681 
682 	/* Add-On - disable bus master */
683 	apci3120_addon_write(dev, 0, AMCC_OP_REG_AGCSTS);
684 
685 	/* AMCC - disable bus master */
686 	outl(0, devpriv->amcc + AMCC_OP_REG_MCSR);
687 
688 	/* disable all counters, ext trigger, and reset scan */
689 	devpriv->ctrl = 0;
690 	outw(devpriv->ctrl, dev->iobase + APCI3120_CTRL_REG);
691 
692 	/* DISABLE_ALL_INTERRUPT */
693 	devpriv->mode = 0;
694 	outb(devpriv->mode, dev->iobase + APCI3120_MODE_REG);
695 
696 	inw(dev->iobase + APCI3120_STATUS_REG);
697 	devpriv->cur_dmabuf = 0;
698 
699 	return 0;
700 }
701 
apci3120_ai_eoc(struct comedi_device * dev,struct comedi_subdevice * s,struct comedi_insn * insn,unsigned long context)702 static int apci3120_ai_eoc(struct comedi_device *dev,
703 			   struct comedi_subdevice *s,
704 			   struct comedi_insn *insn,
705 			   unsigned long context)
706 {
707 	unsigned int status;
708 
709 	status = inw(dev->iobase + APCI3120_STATUS_REG);
710 	if ((status & APCI3120_STATUS_EOC_INT) == 0)
711 		return 0;
712 	return -EBUSY;
713 }
714 
apci3120_ai_insn_read(struct comedi_device * dev,struct comedi_subdevice * s,struct comedi_insn * insn,unsigned int * data)715 static int apci3120_ai_insn_read(struct comedi_device *dev,
716 				 struct comedi_subdevice *s,
717 				 struct comedi_insn *insn,
718 				 unsigned int *data)
719 {
720 	struct apci3120_private *devpriv = dev->private;
721 	unsigned int divisor;
722 	int ret;
723 	int i;
724 
725 	/* set mode for A/D conversions by software trigger with timer 0 */
726 	devpriv->mode = APCI3120_MODE_TIMER2_CLK_OSC |
727 			APCI3120_MODE_TIMER2_AS_TIMER;
728 	outb(devpriv->mode, dev->iobase + APCI3120_MODE_REG);
729 
730 	/* load chanlist for single channel scan */
731 	apci3120_set_chanlist(dev, s, 1, &insn->chanspec);
732 
733 	/*
734 	 * Timer 0 is used in MODE4 (software triggered strobe) to set the
735 	 * conversion time for each acquisition. Each conversion is triggered
736 	 * when the divisor is written to the timer, The conversion is done
737 	 * when the EOC bit in the status register is '0'.
738 	 */
739 	apci3120_timer_set_mode(dev, 0, APCI3120_TIMER_MODE4);
740 	apci3120_timer_enable(dev, 0, true);
741 
742 	/* fixed conversion time of 10 us */
743 	divisor = apci3120_ns_to_timer(dev, 0, 10000, CMDF_ROUND_NEAREST);
744 
745 	for (i = 0; i < insn->n; i++) {
746 		/* trigger conversion */
747 		apci3120_timer_write(dev, 0, divisor);
748 
749 		ret = comedi_timeout(dev, s, insn, apci3120_ai_eoc, 0);
750 		if (ret)
751 			return ret;
752 
753 		data[i] = inw(dev->iobase + APCI3120_AI_FIFO_REG);
754 	}
755 
756 	return insn->n;
757 }
758 
apci3120_ao_ready(struct comedi_device * dev,struct comedi_subdevice * s,struct comedi_insn * insn,unsigned long context)759 static int apci3120_ao_ready(struct comedi_device *dev,
760 			     struct comedi_subdevice *s,
761 			     struct comedi_insn *insn,
762 			     unsigned long context)
763 {
764 	unsigned int status;
765 
766 	status = inw(dev->iobase + APCI3120_STATUS_REG);
767 	if (status & APCI3120_STATUS_DA_READY)
768 		return 0;
769 	return -EBUSY;
770 }
771 
apci3120_ao_insn_write(struct comedi_device * dev,struct comedi_subdevice * s,struct comedi_insn * insn,unsigned int * data)772 static int apci3120_ao_insn_write(struct comedi_device *dev,
773 				  struct comedi_subdevice *s,
774 				  struct comedi_insn *insn,
775 				  unsigned int *data)
776 {
777 	unsigned int chan = CR_CHAN(insn->chanspec);
778 	int i;
779 
780 	for (i = 0; i < insn->n; i++) {
781 		unsigned int val = data[i];
782 		int ret;
783 
784 		ret = comedi_timeout(dev, s, insn, apci3120_ao_ready, 0);
785 		if (ret)
786 			return ret;
787 
788 		outw(APCI3120_AO_MUX(chan) | APCI3120_AO_DATA(val),
789 		     dev->iobase + APCI3120_AO_REG(chan));
790 
791 		s->readback[chan] = val;
792 	}
793 
794 	return insn->n;
795 }
796 
apci3120_di_insn_bits(struct comedi_device * dev,struct comedi_subdevice * s,struct comedi_insn * insn,unsigned int * data)797 static int apci3120_di_insn_bits(struct comedi_device *dev,
798 				 struct comedi_subdevice *s,
799 				 struct comedi_insn *insn,
800 				 unsigned int *data)
801 {
802 	unsigned int status;
803 
804 	status = inw(dev->iobase + APCI3120_STATUS_REG);
805 	data[1] = APCI3120_STATUS_TO_DI_BITS(status);
806 
807 	return insn->n;
808 }
809 
apci3120_do_insn_bits(struct comedi_device * dev,struct comedi_subdevice * s,struct comedi_insn * insn,unsigned int * data)810 static int apci3120_do_insn_bits(struct comedi_device *dev,
811 				 struct comedi_subdevice *s,
812 				 struct comedi_insn *insn,
813 				 unsigned int *data)
814 {
815 	struct apci3120_private *devpriv = dev->private;
816 
817 	if (comedi_dio_update_state(s, data)) {
818 		devpriv->do_bits = s->state;
819 		outb(APCI3120_CTR0_DO_BITS(devpriv->do_bits),
820 		     dev->iobase + APCI3120_CTR0_REG);
821 	}
822 
823 	data[1] = s->state;
824 
825 	return insn->n;
826 }
827 
apci3120_timer_insn_config(struct comedi_device * dev,struct comedi_subdevice * s,struct comedi_insn * insn,unsigned int * data)828 static int apci3120_timer_insn_config(struct comedi_device *dev,
829 				      struct comedi_subdevice *s,
830 				      struct comedi_insn *insn,
831 				      unsigned int *data)
832 {
833 	struct apci3120_private *devpriv = dev->private;
834 	unsigned int divisor;
835 	unsigned int status;
836 	unsigned int mode;
837 	unsigned int timer_mode;
838 
839 	switch (data[0]) {
840 	case INSN_CONFIG_ARM:
841 		apci3120_clr_timer2_interrupt(dev);
842 		divisor = apci3120_ns_to_timer(dev, 2, data[1],
843 					       CMDF_ROUND_DOWN);
844 		apci3120_timer_write(dev, 2, divisor);
845 		apci3120_timer_enable(dev, 2, true);
846 		break;
847 
848 	case INSN_CONFIG_DISARM:
849 		apci3120_timer_enable(dev, 2, false);
850 		apci3120_clr_timer2_interrupt(dev);
851 		break;
852 
853 	case INSN_CONFIG_GET_COUNTER_STATUS:
854 		data[1] = 0;
855 		data[2] = COMEDI_COUNTER_ARMED | COMEDI_COUNTER_COUNTING |
856 			  COMEDI_COUNTER_TERMINAL_COUNT;
857 
858 		if (devpriv->ctrl & APCI3120_CTRL_GATE(2)) {
859 			data[1] |= COMEDI_COUNTER_ARMED;
860 			data[1] |= COMEDI_COUNTER_COUNTING;
861 		}
862 		status = inw(dev->iobase + APCI3120_STATUS_REG);
863 		if (status & APCI3120_STATUS_TIMER2_INT) {
864 			data[1] &= ~COMEDI_COUNTER_COUNTING;
865 			data[1] |= COMEDI_COUNTER_TERMINAL_COUNT;
866 		}
867 		break;
868 
869 	case INSN_CONFIG_SET_COUNTER_MODE:
870 		switch (data[1]) {
871 		case I8254_MODE0:
872 			mode = APCI3120_MODE_TIMER2_AS_COUNTER;
873 			timer_mode = APCI3120_TIMER_MODE0;
874 			break;
875 		case I8254_MODE2:
876 			mode = APCI3120_MODE_TIMER2_AS_TIMER;
877 			timer_mode = APCI3120_TIMER_MODE2;
878 			break;
879 		case I8254_MODE4:
880 			mode = APCI3120_MODE_TIMER2_AS_TIMER;
881 			timer_mode = APCI3120_TIMER_MODE4;
882 			break;
883 		case I8254_MODE5:
884 			mode = APCI3120_MODE_TIMER2_AS_WDOG;
885 			timer_mode = APCI3120_TIMER_MODE5;
886 			break;
887 		default:
888 			return -EINVAL;
889 		}
890 		apci3120_timer_enable(dev, 2, false);
891 		apci3120_clr_timer2_interrupt(dev);
892 		apci3120_timer_set_mode(dev, 2, timer_mode);
893 		devpriv->mode &= ~APCI3120_MODE_TIMER2_AS_MASK;
894 		devpriv->mode |= mode;
895 		outb(devpriv->mode, dev->iobase + APCI3120_MODE_REG);
896 		break;
897 
898 	default:
899 		return -EINVAL;
900 	}
901 
902 	return insn->n;
903 }
904 
apci3120_timer_insn_read(struct comedi_device * dev,struct comedi_subdevice * s,struct comedi_insn * insn,unsigned int * data)905 static int apci3120_timer_insn_read(struct comedi_device *dev,
906 				    struct comedi_subdevice *s,
907 				    struct comedi_insn *insn,
908 				    unsigned int *data)
909 {
910 	int i;
911 
912 	for (i = 0; i < insn->n; i++)
913 		data[i] = apci3120_timer_read(dev, 2);
914 
915 	return insn->n;
916 }
917 
apci3120_dma_alloc(struct comedi_device * dev)918 static void apci3120_dma_alloc(struct comedi_device *dev)
919 {
920 	struct apci3120_private *devpriv = dev->private;
921 	struct apci3120_dmabuf *dmabuf;
922 	int order;
923 	int i;
924 
925 	for (i = 0; i < 2; i++) {
926 		dmabuf = &devpriv->dmabuf[i];
927 		for (order = 2; order >= 0; order--) {
928 			dmabuf->virt = dma_alloc_coherent(dev->hw_dev,
929 							  PAGE_SIZE << order,
930 							  &dmabuf->hw,
931 							  GFP_KERNEL);
932 			if (dmabuf->virt)
933 				break;
934 		}
935 		if (!dmabuf->virt)
936 			break;
937 		dmabuf->size = PAGE_SIZE << order;
938 
939 		if (i == 0)
940 			devpriv->use_dma = 1;
941 		if (i == 1)
942 			devpriv->use_double_buffer = 1;
943 	}
944 }
945 
apci3120_dma_free(struct comedi_device * dev)946 static void apci3120_dma_free(struct comedi_device *dev)
947 {
948 	struct apci3120_private *devpriv = dev->private;
949 	struct apci3120_dmabuf *dmabuf;
950 	int i;
951 
952 	if (!devpriv)
953 		return;
954 
955 	for (i = 0; i < 2; i++) {
956 		dmabuf = &devpriv->dmabuf[i];
957 		if (dmabuf->virt) {
958 			dma_free_coherent(dev->hw_dev, dmabuf->size,
959 					  dmabuf->virt, dmabuf->hw);
960 		}
961 	}
962 }
963 
apci3120_reset(struct comedi_device * dev)964 static void apci3120_reset(struct comedi_device *dev)
965 {
966 	/* disable all interrupt sources */
967 	outb(0, dev->iobase + APCI3120_MODE_REG);
968 
969 	/* disable all counters, ext trigger, and reset scan */
970 	outw(0, dev->iobase + APCI3120_CTRL_REG);
971 
972 	/* clear interrupt status */
973 	inw(dev->iobase + APCI3120_STATUS_REG);
974 }
975 
apci3120_auto_attach(struct comedi_device * dev,unsigned long context)976 static int apci3120_auto_attach(struct comedi_device *dev,
977 				unsigned long context)
978 {
979 	struct pci_dev *pcidev = comedi_to_pci_dev(dev);
980 	const struct apci3120_board *this_board = NULL;
981 	struct apci3120_private *devpriv;
982 	struct comedi_subdevice *s;
983 	unsigned int status;
984 	int ret;
985 
986 	if (context < ARRAY_SIZE(apci3120_boardtypes))
987 		this_board = &apci3120_boardtypes[context];
988 	if (!this_board)
989 		return -ENODEV;
990 	dev->board_ptr = this_board;
991 	dev->board_name = this_board->name;
992 
993 	devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
994 	if (!devpriv)
995 		return -ENOMEM;
996 
997 	ret = comedi_pci_enable(dev);
998 	if (ret)
999 		return ret;
1000 	pci_set_master(pcidev);
1001 
1002 	dev->iobase = pci_resource_start(pcidev, 1);
1003 	devpriv->amcc = pci_resource_start(pcidev, 0);
1004 	devpriv->addon = pci_resource_start(pcidev, 2);
1005 
1006 	apci3120_reset(dev);
1007 
1008 	if (pcidev->irq > 0) {
1009 		ret = request_irq(pcidev->irq, apci3120_interrupt, IRQF_SHARED,
1010 				  dev->board_name, dev);
1011 		if (ret == 0) {
1012 			dev->irq = pcidev->irq;
1013 
1014 			apci3120_dma_alloc(dev);
1015 		}
1016 	}
1017 
1018 	status = inw(dev->iobase + APCI3120_STATUS_REG);
1019 	if (APCI3120_STATUS_TO_VERSION(status) == APCI3120_REVB ||
1020 	    context == BOARD_APCI3001)
1021 		devpriv->osc_base = APCI3120_REVB_OSC_BASE;
1022 	else
1023 		devpriv->osc_base = APCI3120_REVA_OSC_BASE;
1024 
1025 	ret = comedi_alloc_subdevices(dev, 5);
1026 	if (ret)
1027 		return ret;
1028 
1029 	/* Analog Input subdevice */
1030 	s = &dev->subdevices[0];
1031 	s->type		= COMEDI_SUBD_AI;
1032 	s->subdev_flags	= SDF_READABLE | SDF_COMMON | SDF_GROUND | SDF_DIFF;
1033 	s->n_chan	= 16;
1034 	s->maxdata	= this_board->ai_is_16bit ? 0xffff : 0x0fff;
1035 	s->range_table	= &apci3120_ai_range;
1036 	s->insn_read	= apci3120_ai_insn_read;
1037 	if (dev->irq) {
1038 		dev->read_subdev = s;
1039 		s->subdev_flags	|= SDF_CMD_READ;
1040 		s->len_chanlist	= s->n_chan;
1041 		s->do_cmdtest	= apci3120_ai_cmdtest;
1042 		s->do_cmd	= apci3120_ai_cmd;
1043 		s->cancel	= apci3120_cancel;
1044 	}
1045 
1046 	/* Analog Output subdevice */
1047 	s = &dev->subdevices[1];
1048 	if (this_board->has_ao) {
1049 		s->type		= COMEDI_SUBD_AO;
1050 		s->subdev_flags	= SDF_WRITABLE | SDF_GROUND | SDF_COMMON;
1051 		s->n_chan	= 8;
1052 		s->maxdata	= 0x3fff;
1053 		s->range_table	= &range_bipolar10;
1054 		s->insn_write	= apci3120_ao_insn_write;
1055 
1056 		ret = comedi_alloc_subdev_readback(s);
1057 		if (ret)
1058 			return ret;
1059 	} else {
1060 		s->type		= COMEDI_SUBD_UNUSED;
1061 	}
1062 
1063 	/* Digital Input subdevice */
1064 	s = &dev->subdevices[2];
1065 	s->type		= COMEDI_SUBD_DI;
1066 	s->subdev_flags	= SDF_READABLE;
1067 	s->n_chan	= 4;
1068 	s->maxdata	= 1;
1069 	s->range_table	= &range_digital;
1070 	s->insn_bits	= apci3120_di_insn_bits;
1071 
1072 	/* Digital Output subdevice */
1073 	s = &dev->subdevices[3];
1074 	s->type		= COMEDI_SUBD_DO;
1075 	s->subdev_flags	= SDF_WRITABLE;
1076 	s->n_chan	= 4;
1077 	s->maxdata	= 1;
1078 	s->range_table	= &range_digital;
1079 	s->insn_bits	= apci3120_do_insn_bits;
1080 
1081 	/* Timer subdevice */
1082 	s = &dev->subdevices[4];
1083 	s->type		= COMEDI_SUBD_TIMER;
1084 	s->subdev_flags	= SDF_READABLE;
1085 	s->n_chan	= 1;
1086 	s->maxdata	= 0x00ffffff;
1087 	s->insn_config	= apci3120_timer_insn_config;
1088 	s->insn_read	= apci3120_timer_insn_read;
1089 
1090 	return 0;
1091 }
1092 
apci3120_detach(struct comedi_device * dev)1093 static void apci3120_detach(struct comedi_device *dev)
1094 {
1095 	comedi_pci_detach(dev);
1096 	apci3120_dma_free(dev);
1097 }
1098 
1099 static struct comedi_driver apci3120_driver = {
1100 	.driver_name	= "addi_apci_3120",
1101 	.module		= THIS_MODULE,
1102 	.auto_attach	= apci3120_auto_attach,
1103 	.detach		= apci3120_detach,
1104 };
1105 
apci3120_pci_probe(struct pci_dev * dev,const struct pci_device_id * id)1106 static int apci3120_pci_probe(struct pci_dev *dev,
1107 			      const struct pci_device_id *id)
1108 {
1109 	return comedi_pci_auto_config(dev, &apci3120_driver, id->driver_data);
1110 }
1111 
1112 static const struct pci_device_id apci3120_pci_table[] = {
1113 	{ PCI_VDEVICE(AMCC, 0x818d), BOARD_APCI3120 },
1114 	{ PCI_VDEVICE(AMCC, 0x828d), BOARD_APCI3001 },
1115 	{ 0 }
1116 };
1117 MODULE_DEVICE_TABLE(pci, apci3120_pci_table);
1118 
1119 static struct pci_driver apci3120_pci_driver = {
1120 	.name		= "addi_apci_3120",
1121 	.id_table	= apci3120_pci_table,
1122 	.probe		= apci3120_pci_probe,
1123 	.remove		= comedi_pci_auto_unconfig,
1124 };
1125 module_comedi_pci_driver(apci3120_driver, apci3120_pci_driver);
1126 
1127 MODULE_AUTHOR("Comedi http://www.comedi.org");
1128 MODULE_DESCRIPTION("ADDI-DATA APCI-3120, Analog input board");
1129 MODULE_LICENSE("GPL");
1130