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