ni_at_a2150.c revision 90035c0886b256d75bced13b3b3cea5234aff136
1/*
2    comedi/drivers/ni_at_a2150.c
3    Driver for National Instruments AT-A2150 boards
4    Copyright (C) 2001, 2002 Frank Mori Hess <fmhess@users.sourceforge.net>
5
6    COMEDI - Linux Control and Measurement Device Interface
7    Copyright (C) 2000 David A. Schleef <ds@schleef.org>
8
9    This program is free software; you can redistribute it and/or modify
10    it under the terms of the GNU General Public License as published by
11    the Free Software Foundation; either version 2 of the License, or
12    (at your option) any later version.
13
14    This program is distributed in the hope that it will be useful,
15    but WITHOUT ANY WARRANTY; without even the implied warranty of
16    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17    GNU General Public License for more details.
18
19    You should have received a copy of the GNU General Public License
20    along with this program; if not, write to the Free Software
21    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22
23************************************************************************
24*/
25/*
26Driver: ni_at_a2150
27Description: National Instruments AT-A2150
28Author: Frank Mori Hess
29Status: works
30Devices: [National Instruments] AT-A2150C (at_a2150c), AT-2150S (at_a2150s)
31
32If you want to ac couple the board's inputs, use AREF_OTHER.
33
34Configuration options:
35  [0] - I/O port base address
36  [1] - IRQ (optional, required for timed conversions)
37  [2] - DMA (optional, required for timed conversions)
38
39*/
40/*
41Yet another driver for obsolete hardware brought to you by Frank Hess.
42Testing and debugging help provided by Dave Andruczyk.
43
44This driver supports the boards:
45
46AT-A2150C
47AT-A2150S
48
49The only difference is their master clock frequencies.
50
51Options:
52	[0] - base io address
53	[1] - irq
54	[2] - dma channel
55
56References (from ftp://ftp.natinst.com/support/manuals):
57
58	   320360.pdf  AT-A2150 User Manual
59
60TODO:
61
62analog level triggering
63TRIG_WAKE_EOS
64
65*/
66
67#include "../comedidev.h"
68
69#include <linux/ioport.h>
70#include <asm/dma.h>
71
72#include "8253.h"
73#include "comedi_fc.h"
74
75#define A2150_SIZE           28
76#define A2150_DMA_BUFFER_SIZE	0xff00	// size in bytes of dma buffer
77
78//#define A2150_DEBUG   // enable debugging code
79#undef A2150_DEBUG		// disable debugging code
80
81/* Registers and bits */
82#define CONFIG_REG		0x0
83#define   CHANNEL_BITS(x)		((x) & 0x7)
84#define   CHANNEL_MASK		0x7
85#define   CLOCK_SELECT_BITS(x)		(((x) & 0x3) << 3)
86#define   CLOCK_DIVISOR_BITS(x)		(((x) & 0x3) << 5)
87#define   CLOCK_MASK		(0xf << 3)
88#define   ENABLE0_BIT		0x80	// enable (don't internally ground) channels 0 and 1
89#define   ENABLE1_BIT		0x100	// enable (don't internally ground) channels 2 and 3
90#define   AC0_BIT		0x200	// ac couple channels 0,1
91#define   AC1_BIT		0x400	// ac couple channels 2,3
92#define   APD_BIT		0x800	// analog power down
93#define   DPD_BIT		0x1000	// digital power down
94#define TRIGGER_REG		0x2	// trigger config register
95#define   POST_TRIGGER_BITS		0x2
96#define   DELAY_TRIGGER_BITS		0x3
97#define   HW_TRIG_EN		0x10	// enable hardware trigger
98#define FIFO_START_REG		0x6	// software start aquistion trigger
99#define FIFO_RESET_REG		0x8	// clears fifo + fifo flags
100#define FIFO_DATA_REG		0xa	// read data
101#define DMA_TC_CLEAR_REG		0xe	// clear dma terminal count interrupt
102#define STATUS_REG		0x12	// read only
103#define   FNE_BIT		0x1	// fifo not empty
104#define   OVFL_BIT		0x8	// fifo overflow
105#define   EDAQ_BIT		0x10	// end of aquisition interrupt
106#define   DCAL_BIT		0x20	// offset calibration in progress
107#define   INTR_BIT		0x40	// interrupt has occured
108#define   DMA_TC_BIT		0x80	// dma terminal count interrupt has occured
109#define   ID_BITS(x)	(((x) >> 8) & 0x3)
110#define IRQ_DMA_CNTRL_REG		0x12	// write only
111#define   DMA_CHAN_BITS(x)		((x) & 0x7)	// sets dma channel
112#define   DMA_EN_BIT		0x8	// enables dma
113#define   IRQ_LVL_BITS(x)		(((x) & 0xf) << 4)	// sets irq level
114#define   FIFO_INTR_EN_BIT		0x100	// enable fifo interrupts
115#define   FIFO_INTR_FHF_BIT		0x200	// interrupt fifo half full
116#define   DMA_INTR_EN_BIT 		0x800	// enable interrupt on dma terminal count
117#define   DMA_DEM_EN_BIT	0x1000	// enables demand mode dma
118#define I8253_BASE_REG		0x14
119#define I8253_MODE_REG		0x17
120#define   HW_COUNT_DISABLE		0x30	// disable hardware counting of conversions
121
122typedef struct a2150_board_struct {
123	const char *name;
124	int clock[4];		// master clock periods, in nanoseconds
125	int num_clocks;		// number of available master clock speeds
126	int ai_speed;		// maximum conversion rate in nanoseconds
127} a2150_board;
128
129//analog input range
130static const struct comedi_lrange range_a2150 = {
131	1,
132	{
133			RANGE(-2.828, 2.828),
134		}
135};
136
137// enum must match board indices
138enum { a2150_c, a2150_s };
139static const a2150_board a2150_boards[] = {
140	{
141	      name:	"at-a2150c",
142	      clock:	{31250, 22676, 20833, 19531},
143	      num_clocks:4,
144	      ai_speed:19531,
145		},
146	{
147	      name:	"at-a2150s",
148	      clock:	{62500, 50000, 41667, 0},
149	      num_clocks:3,
150	      ai_speed:41667,
151		},
152};
153
154/*
155 * Useful for shorthand access to the particular board structure
156 */
157#define thisboard ((const a2150_board *)dev->board_ptr)
158
159typedef struct {
160	volatile unsigned int count;	/* number of data points left to be taken */
161	unsigned int dma;	// dma channel
162	s16 *dma_buffer;	// dma buffer
163	unsigned int dma_transfer_size;	// size in bytes of dma transfers
164	int irq_dma_bits;	// irq/dma register bits
165	int config_bits;	// config register bits
166} a2150_private;
167
168#define devpriv ((a2150_private *)dev->private)
169
170static int a2150_attach(struct comedi_device * dev, comedi_devconfig * it);
171static int a2150_detach(struct comedi_device * dev);
172static int a2150_cancel(struct comedi_device * dev, struct comedi_subdevice * s);
173
174static struct comedi_driver driver_a2150 = {
175      driver_name:"ni_at_a2150",
176      module:THIS_MODULE,
177      attach:a2150_attach,
178      detach:a2150_detach,
179};
180
181static irqreturn_t a2150_interrupt(int irq, void *d PT_REGS_ARG);
182static int a2150_ai_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s,
183	struct comedi_cmd * cmd);
184static int a2150_ai_cmd(struct comedi_device * dev, struct comedi_subdevice * s);
185static int a2150_ai_rinsn(struct comedi_device * dev, struct comedi_subdevice * s,
186	struct comedi_insn * insn, unsigned int * data);
187static int a2150_get_timing(struct comedi_device * dev, unsigned int *period,
188	int flags);
189static int a2150_probe(struct comedi_device * dev);
190static int a2150_set_chanlist(struct comedi_device * dev, unsigned int start_channel,
191	unsigned int num_channels);
192/*
193 * A convenient macro that defines init_module() and cleanup_module(),
194 * as necessary.
195 */
196COMEDI_INITCLEANUP(driver_a2150);
197
198#ifdef A2150_DEBUG
199
200static void ni_dump_regs(struct comedi_device * dev)
201{
202	rt_printk("config bits 0x%x\n", devpriv->config_bits);
203	rt_printk("irq dma bits 0x%x\n", devpriv->irq_dma_bits);
204	rt_printk("status bits 0x%x\n", inw(dev->iobase + STATUS_REG));
205}
206
207#endif
208
209/* interrupt service routine */
210static irqreturn_t a2150_interrupt(int irq, void *d PT_REGS_ARG)
211{
212	int i;
213	int status;
214	unsigned long flags;
215	struct comedi_device *dev = d;
216	struct comedi_subdevice *s = dev->read_subdev;
217	struct comedi_async *async;
218	struct comedi_cmd *cmd;
219	unsigned int max_points, num_points, residue, leftover;
220	short dpnt;
221	static const int sample_size = sizeof(devpriv->dma_buffer[0]);
222
223	if (dev->attached == 0) {
224		comedi_error(dev, "premature interrupt");
225		return IRQ_HANDLED;
226	}
227	// initialize async here to make sure s is not NULL
228	async = s->async;
229	async->events = 0;
230	cmd = &async->cmd;
231
232	status = inw(dev->iobase + STATUS_REG);
233
234	if ((status & INTR_BIT) == 0) {
235		comedi_error(dev, "spurious interrupt");
236		return IRQ_NONE;
237	}
238
239	if (status & OVFL_BIT) {
240		comedi_error(dev, "fifo overflow");
241		a2150_cancel(dev, s);
242		async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
243	}
244
245	if ((status & DMA_TC_BIT) == 0) {
246		comedi_error(dev, "caught non-dma interrupt?  Aborting.");
247		a2150_cancel(dev, s);
248		async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
249		comedi_event(dev, s);
250		return IRQ_HANDLED;
251	}
252
253	flags = claim_dma_lock();
254	disable_dma(devpriv->dma);
255	/* clear flip-flop to make sure 2-byte registers for
256	 * count and address get set correctly */
257	clear_dma_ff(devpriv->dma);
258
259	// figure out how many points to read
260	max_points = devpriv->dma_transfer_size / sample_size;
261	/* residue is the number of points left to be done on the dma
262	 * transfer.  It should always be zero at this point unless
263	 * the stop_src is set to external triggering.
264	 */
265	residue = get_dma_residue(devpriv->dma) / sample_size;
266	num_points = max_points - residue;
267	if (devpriv->count < num_points && cmd->stop_src == TRIG_COUNT)
268		num_points = devpriv->count;
269
270	// figure out how many points will be stored next time
271	leftover = 0;
272	if (cmd->stop_src == TRIG_NONE) {
273		leftover = devpriv->dma_transfer_size / sample_size;
274	} else if (devpriv->count > max_points) {
275		leftover = devpriv->count - max_points;
276		if (leftover > max_points)
277			leftover = max_points;
278	}
279	/* there should only be a residue if collection was stopped by having
280	 * the stop_src set to an external trigger, in which case there
281	 * will be no more data
282	 */
283	if (residue)
284		leftover = 0;
285
286	for (i = 0; i < num_points; i++) {
287		/* write data point to comedi buffer */
288		dpnt = devpriv->dma_buffer[i];
289		// convert from 2's complement to unsigned coding
290		dpnt ^= 0x8000;
291		cfc_write_to_buffer(s, dpnt);
292		if (cmd->stop_src == TRIG_COUNT) {
293			if (--devpriv->count == 0) {	/* end of acquisition */
294				a2150_cancel(dev, s);
295				async->events |= COMEDI_CB_EOA;
296				break;
297			}
298		}
299	}
300	// re-enable  dma
301	if (leftover) {
302		set_dma_addr(devpriv->dma, virt_to_bus(devpriv->dma_buffer));
303		set_dma_count(devpriv->dma, leftover * sample_size);
304		enable_dma(devpriv->dma);
305	}
306	release_dma_lock(flags);
307
308	async->events |= COMEDI_CB_BLOCK;
309
310	comedi_event(dev, s);
311
312	/* clear interrupt */
313	outw(0x00, dev->iobase + DMA_TC_CLEAR_REG);
314
315	return IRQ_HANDLED;
316}
317
318// probes board type, returns offset
319static int a2150_probe(struct comedi_device * dev)
320{
321	int status = inw(dev->iobase + STATUS_REG);
322	return ID_BITS(status);
323}
324
325static int a2150_attach(struct comedi_device * dev, comedi_devconfig * it)
326{
327	struct comedi_subdevice *s;
328	unsigned long iobase = it->options[0];
329	unsigned int irq = it->options[1];
330	unsigned int dma = it->options[2];
331	static const int timeout = 2000;
332	int i;
333
334	printk("comedi%d: %s: io 0x%lx", dev->minor, driver_a2150.driver_name,
335		iobase);
336	if (irq) {
337		printk(", irq %u", irq);
338	} else {
339		printk(", no irq");
340	}
341	if (dma) {
342		printk(", dma %u", dma);
343	} else {
344		printk(", no dma");
345	}
346	printk("\n");
347
348	/* allocate and initialize dev->private */
349	if (alloc_private(dev, sizeof(a2150_private)) < 0)
350		return -ENOMEM;
351
352	if (iobase == 0) {
353		printk(" io base address required\n");
354		return -EINVAL;
355	}
356
357	/* check if io addresses are available */
358	if (!request_region(iobase, A2150_SIZE, driver_a2150.driver_name)) {
359		printk(" I/O port conflict\n");
360		return -EIO;
361	}
362	dev->iobase = iobase;
363
364	/* grab our IRQ */
365	if (irq) {
366		// check that irq is supported
367		if (irq < 3 || irq == 8 || irq == 13 || irq > 15) {
368			printk(" invalid irq line %u\n", irq);
369			return -EINVAL;
370		}
371		if (comedi_request_irq(irq, a2150_interrupt, 0,
372				driver_a2150.driver_name, dev)) {
373			printk("unable to allocate irq %u\n", irq);
374			return -EINVAL;
375		}
376		devpriv->irq_dma_bits |= IRQ_LVL_BITS(irq);
377		dev->irq = irq;
378	}
379	// initialize dma
380	if (dma) {
381		if (dma == 4 || dma > 7) {
382			printk(" invalid dma channel %u\n", dma);
383			return -EINVAL;
384		}
385		if (request_dma(dma, driver_a2150.driver_name)) {
386			printk(" failed to allocate dma channel %u\n", dma);
387			return -EINVAL;
388		}
389		devpriv->dma = dma;
390		devpriv->dma_buffer =
391			kmalloc(A2150_DMA_BUFFER_SIZE, GFP_KERNEL | GFP_DMA);
392		if (devpriv->dma_buffer == NULL)
393			return -ENOMEM;
394
395		disable_dma(dma);
396		set_dma_mode(dma, DMA_MODE_READ);
397
398		devpriv->irq_dma_bits |= DMA_CHAN_BITS(dma);
399	}
400
401	dev->board_ptr = a2150_boards + a2150_probe(dev);
402	dev->board_name = thisboard->name;
403
404	if (alloc_subdevices(dev, 1) < 0)
405		return -ENOMEM;
406
407	/* analog input subdevice */
408	s = dev->subdevices + 0;
409	dev->read_subdev = s;
410	s->type = COMEDI_SUBD_AI;
411	s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_OTHER | SDF_CMD_READ;
412	s->n_chan = 4;
413	s->len_chanlist = 4;
414	s->maxdata = 0xffff;
415	s->range_table = &range_a2150;
416	s->do_cmd = a2150_ai_cmd;
417	s->do_cmdtest = a2150_ai_cmdtest;
418	s->insn_read = a2150_ai_rinsn;
419	s->cancel = a2150_cancel;
420
421	/* need to do this for software counting of completed conversions, to
422	 * prevent hardware count from stopping aquisition */
423	outw(HW_COUNT_DISABLE, dev->iobase + I8253_MODE_REG);
424
425	// set card's irq and dma levels
426	outw(devpriv->irq_dma_bits, dev->iobase + IRQ_DMA_CNTRL_REG);
427
428	// reset and sync adc clock circuitry
429	outw_p(DPD_BIT | APD_BIT, dev->iobase + CONFIG_REG);
430	outw_p(DPD_BIT, dev->iobase + CONFIG_REG);
431	// initialize configuration register
432	devpriv->config_bits = 0;
433	outw(devpriv->config_bits, dev->iobase + CONFIG_REG);
434	// wait until offset calibration is done, then enable analog inputs
435	for (i = 0; i < timeout; i++) {
436		if ((DCAL_BIT & inw(dev->iobase + STATUS_REG)) == 0)
437			break;
438		comedi_udelay(1000);
439	}
440	if (i == timeout) {
441		printk(" timed out waiting for offset calibration to complete\n");
442		return -ETIME;
443	}
444	devpriv->config_bits |= ENABLE0_BIT | ENABLE1_BIT;
445	outw(devpriv->config_bits, dev->iobase + CONFIG_REG);
446
447	return 0;
448};
449
450static int a2150_detach(struct comedi_device * dev)
451{
452	printk("comedi%d: %s: remove\n", dev->minor, driver_a2150.driver_name);
453
454	/* only free stuff if it has been allocated by _attach */
455	if (dev->iobase) {
456		// put board in power-down mode
457		outw(APD_BIT | DPD_BIT, dev->iobase + CONFIG_REG);
458		release_region(dev->iobase, A2150_SIZE);
459	}
460
461	if (dev->irq)
462		comedi_free_irq(dev->irq, dev);
463	if (devpriv) {
464		if (devpriv->dma)
465			free_dma(devpriv->dma);
466		if (devpriv->dma_buffer)
467			kfree(devpriv->dma_buffer);
468	}
469
470	return 0;
471};
472
473static int a2150_cancel(struct comedi_device * dev, struct comedi_subdevice * s)
474{
475	// disable dma on card
476	devpriv->irq_dma_bits &= ~DMA_INTR_EN_BIT & ~DMA_EN_BIT;
477	outw(devpriv->irq_dma_bits, dev->iobase + IRQ_DMA_CNTRL_REG);
478
479	// disable computer's dma
480	disable_dma(devpriv->dma);
481
482	// clear fifo and reset triggering circuitry
483	outw(0, dev->iobase + FIFO_RESET_REG);
484
485	return 0;
486}
487
488static int a2150_ai_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s,
489	struct comedi_cmd * cmd)
490{
491	int err = 0;
492	int tmp;
493	int startChan;
494	int i;
495
496	/* step 1: make sure trigger sources are trivially valid */
497
498	tmp = cmd->start_src;
499	cmd->start_src &= TRIG_NOW | TRIG_EXT;
500	if (!cmd->start_src || tmp != cmd->start_src)
501		err++;
502
503	tmp = cmd->scan_begin_src;
504	cmd->scan_begin_src &= TRIG_TIMER;
505	if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
506		err++;
507
508	tmp = cmd->convert_src;
509	cmd->convert_src &= TRIG_NOW;
510	if (!cmd->convert_src || tmp != cmd->convert_src)
511		err++;
512
513	tmp = cmd->scan_end_src;
514	cmd->scan_end_src &= TRIG_COUNT;
515	if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
516		err++;
517
518	tmp = cmd->stop_src;
519	cmd->stop_src &= TRIG_COUNT | TRIG_NONE;
520	if (!cmd->stop_src || tmp != cmd->stop_src)
521		err++;
522
523	if (err)
524		return 1;
525
526	/* step 2: make sure trigger sources are unique and mutually compatible */
527
528	if (cmd->start_src != TRIG_NOW && cmd->start_src != TRIG_EXT)
529		err++;
530	if (cmd->stop_src != TRIG_COUNT && cmd->stop_src != TRIG_NONE)
531		err++;
532
533	if (err)
534		return 2;
535
536	/* step 3: make sure arguments are trivially compatible */
537
538	if (cmd->start_arg != 0) {
539		cmd->start_arg = 0;
540		err++;
541	}
542	if (cmd->convert_src == TRIG_TIMER) {
543		if (cmd->convert_arg < thisboard->ai_speed) {
544			cmd->convert_arg = thisboard->ai_speed;
545			err++;
546		}
547	}
548	if (!cmd->chanlist_len) {
549		cmd->chanlist_len = 1;
550		err++;
551	}
552	if (cmd->scan_end_arg != cmd->chanlist_len) {
553		cmd->scan_end_arg = cmd->chanlist_len;
554		err++;
555	}
556	if (cmd->stop_src == TRIG_COUNT) {
557		if (!cmd->stop_arg) {
558			cmd->stop_arg = 1;
559			err++;
560		}
561	} else {		/* TRIG_NONE */
562		if (cmd->stop_arg != 0) {
563			cmd->stop_arg = 0;
564			err++;
565		}
566	}
567
568	if (err)
569		return 3;
570
571	/* step 4: fix up any arguments */
572
573	if (cmd->scan_begin_src == TRIG_TIMER) {
574		tmp = cmd->scan_begin_arg;
575		a2150_get_timing(dev, &cmd->scan_begin_arg, cmd->flags);
576		if (tmp != cmd->scan_begin_arg)
577			err++;
578	}
579
580	if (err)
581		return 4;
582
583	// check channel/gain list against card's limitations
584	if (cmd->chanlist) {
585		startChan = CR_CHAN(cmd->chanlist[0]);
586		for (i = 1; i < cmd->chanlist_len; i++) {
587			if (CR_CHAN(cmd->chanlist[i]) != (startChan + i)) {
588				comedi_error(dev,
589					"entries in chanlist must be consecutive channels, counting upwards\n");
590				err++;
591			}
592		}
593		if (cmd->chanlist_len == 2 && CR_CHAN(cmd->chanlist[0]) == 1) {
594			comedi_error(dev,
595				"length 2 chanlist must be channels 0,1 or channels 2,3");
596			err++;
597		}
598		if (cmd->chanlist_len == 3) {
599			comedi_error(dev,
600				"chanlist must have 1,2 or 4 channels");
601			err++;
602		}
603		if (CR_AREF(cmd->chanlist[0]) != CR_AREF(cmd->chanlist[1]) ||
604			CR_AREF(cmd->chanlist[2]) != CR_AREF(cmd->chanlist[3]))
605		{
606			comedi_error(dev,
607				"channels 0/1 and 2/3 must have the same analog reference");
608			err++;
609		}
610	}
611
612	if (err)
613		return 5;
614
615	return 0;
616}
617
618static int a2150_ai_cmd(struct comedi_device * dev, struct comedi_subdevice * s)
619{
620	struct comedi_async *async = s->async;
621	struct comedi_cmd *cmd = &async->cmd;
622	unsigned long lock_flags;
623	unsigned int old_config_bits = devpriv->config_bits;
624	unsigned int trigger_bits;
625
626	if (!dev->irq || !devpriv->dma) {
627		comedi_error(dev,
628			" irq and dma required, cannot do hardware conversions");
629		return -1;
630	}
631	if (cmd->flags & TRIG_RT) {
632		comedi_error(dev,
633			" dma incompatible with hard real-time interrupt (TRIG_RT), aborting");
634		return -1;
635	}
636	// clear fifo and reset triggering circuitry
637	outw(0, dev->iobase + FIFO_RESET_REG);
638
639	/* setup chanlist */
640	if (a2150_set_chanlist(dev, CR_CHAN(cmd->chanlist[0]),
641			cmd->chanlist_len) < 0)
642		return -1;
643
644	// setup ac/dc coupling
645	if (CR_AREF(cmd->chanlist[0]) == AREF_OTHER)
646		devpriv->config_bits |= AC0_BIT;
647	else
648		devpriv->config_bits &= ~AC0_BIT;
649	if (CR_AREF(cmd->chanlist[2]) == AREF_OTHER)
650		devpriv->config_bits |= AC1_BIT;
651	else
652		devpriv->config_bits &= ~AC1_BIT;
653
654	// setup timing
655	a2150_get_timing(dev, &cmd->scan_begin_arg, cmd->flags);
656
657	// send timing, channel, config bits
658	outw(devpriv->config_bits, dev->iobase + CONFIG_REG);
659
660	// initialize number of samples remaining
661	devpriv->count = cmd->stop_arg * cmd->chanlist_len;
662
663	// enable computer's dma
664	lock_flags = claim_dma_lock();
665	disable_dma(devpriv->dma);
666	/* clear flip-flop to make sure 2-byte registers for
667	 * count and address get set correctly */
668	clear_dma_ff(devpriv->dma);
669	set_dma_addr(devpriv->dma, virt_to_bus(devpriv->dma_buffer));
670	// set size of transfer to fill in 1/3 second
671#define ONE_THIRD_SECOND 333333333
672	devpriv->dma_transfer_size =
673		sizeof(devpriv->dma_buffer[0]) * cmd->chanlist_len *
674		ONE_THIRD_SECOND / cmd->scan_begin_arg;
675	if (devpriv->dma_transfer_size > A2150_DMA_BUFFER_SIZE)
676		devpriv->dma_transfer_size = A2150_DMA_BUFFER_SIZE;
677	if (devpriv->dma_transfer_size < sizeof(devpriv->dma_buffer[0]))
678		devpriv->dma_transfer_size = sizeof(devpriv->dma_buffer[0]);
679	devpriv->dma_transfer_size -=
680		devpriv->dma_transfer_size % sizeof(devpriv->dma_buffer[0]);
681	set_dma_count(devpriv->dma, devpriv->dma_transfer_size);
682	enable_dma(devpriv->dma);
683	release_dma_lock(lock_flags);
684
685	/* clear dma interrupt before enabling it, to try and get rid of that
686	 * one spurious interrupt that has been happening */
687	outw(0x00, dev->iobase + DMA_TC_CLEAR_REG);
688
689	// enable dma on card
690	devpriv->irq_dma_bits |= DMA_INTR_EN_BIT | DMA_EN_BIT;
691	outw(devpriv->irq_dma_bits, dev->iobase + IRQ_DMA_CNTRL_REG);
692
693	// may need to wait 72 sampling periods if timing was changed
694	i8254_load(dev->iobase + I8253_BASE_REG, 0, 2, 72, 0);
695
696	// setup start triggering
697	trigger_bits = 0;
698	// decide if we need to wait 72 periods for valid data
699	if (cmd->start_src == TRIG_NOW &&
700		(old_config_bits & CLOCK_MASK) !=
701		(devpriv->config_bits & CLOCK_MASK)) {
702		// set trigger source to delay trigger
703		trigger_bits |= DELAY_TRIGGER_BITS;
704	} else {
705		// otherwise no delay
706		trigger_bits |= POST_TRIGGER_BITS;
707	}
708	// enable external hardware trigger
709	if (cmd->start_src == TRIG_EXT) {
710		trigger_bits |= HW_TRIG_EN;
711	} else if (cmd->start_src == TRIG_OTHER) {
712		// XXX add support for level/slope start trigger using TRIG_OTHER
713		comedi_error(dev, "you shouldn't see this?");
714	}
715	// send trigger config bits
716	outw(trigger_bits, dev->iobase + TRIGGER_REG);
717
718	// start aquisition for soft trigger
719	if (cmd->start_src == TRIG_NOW) {
720		outw(0, dev->iobase + FIFO_START_REG);
721	}
722#ifdef A2150_DEBUG
723	ni_dump_regs(dev);
724#endif
725
726	return 0;
727}
728
729static int a2150_ai_rinsn(struct comedi_device * dev, struct comedi_subdevice * s,
730	struct comedi_insn * insn, unsigned int * data)
731{
732	unsigned int i, n;
733	static const int timeout = 100000;
734	static const int filter_delay = 36;
735
736	// clear fifo and reset triggering circuitry
737	outw(0, dev->iobase + FIFO_RESET_REG);
738
739	/* setup chanlist */
740	if (a2150_set_chanlist(dev, CR_CHAN(insn->chanspec), 1) < 0)
741		return -1;
742
743	// set dc coupling
744	devpriv->config_bits &= ~AC0_BIT;
745	devpriv->config_bits &= ~AC1_BIT;
746
747	// send timing, channel, config bits
748	outw(devpriv->config_bits, dev->iobase + CONFIG_REG);
749
750	// disable dma on card
751	devpriv->irq_dma_bits &= ~DMA_INTR_EN_BIT & ~DMA_EN_BIT;
752	outw(devpriv->irq_dma_bits, dev->iobase + IRQ_DMA_CNTRL_REG);
753
754	// setup start triggering
755	outw(0, dev->iobase + TRIGGER_REG);
756
757	// start aquisition for soft trigger
758	outw(0, dev->iobase + FIFO_START_REG);
759
760	/* there is a 35.6 sample delay for data to get through the antialias filter */
761	for (n = 0; n < filter_delay; n++) {
762		for (i = 0; i < timeout; i++) {
763			if (inw(dev->iobase + STATUS_REG) & FNE_BIT)
764				break;
765			comedi_udelay(1);
766		}
767		if (i == timeout) {
768			comedi_error(dev, "timeout");
769			return -ETIME;
770		}
771		inw(dev->iobase + FIFO_DATA_REG);
772	}
773
774	// read data
775	for (n = 0; n < insn->n; n++) {
776		for (i = 0; i < timeout; i++) {
777			if (inw(dev->iobase + STATUS_REG) & FNE_BIT)
778				break;
779			comedi_udelay(1);
780		}
781		if (i == timeout) {
782			comedi_error(dev, "timeout");
783			return -ETIME;
784		}
785#ifdef A2150_DEBUG
786		ni_dump_regs(dev);
787#endif
788		data[n] = inw(dev->iobase + FIFO_DATA_REG);
789#ifdef A2150_DEBUG
790		rt_printk(" data is %i\n", data[n]);
791#endif
792		data[n] ^= 0x8000;
793	}
794
795	// clear fifo and reset triggering circuitry
796	outw(0, dev->iobase + FIFO_RESET_REG);
797
798	return n;
799}
800
801/* sets bits in devpriv->clock_bits to nearest approximation of requested period,
802 * adjusts requested period to actual timing. */
803static int a2150_get_timing(struct comedi_device * dev, unsigned int *period,
804	int flags)
805{
806	int lub, glb, temp;
807	int lub_divisor_shift, lub_index, glb_divisor_shift, glb_index;
808	int i, j;
809
810	// initialize greatest lower and least upper bounds
811	lub_divisor_shift = 3;
812	lub_index = 0;
813	lub = thisboard->clock[lub_index] * (1 << lub_divisor_shift);
814	glb_divisor_shift = 0;
815	glb_index = thisboard->num_clocks - 1;
816	glb = thisboard->clock[glb_index] * (1 << glb_divisor_shift);
817
818	// make sure period is in available range
819	if (*period < glb)
820		*period = glb;
821	if (*period > lub)
822		*period = lub;
823
824	// we can multiply period by 1, 2, 4, or 8, using (1 << i)
825	for (i = 0; i < 4; i++) {
826		// there are a maximum of 4 master clocks
827		for (j = 0; j < thisboard->num_clocks; j++) {
828			// temp is the period in nanosec we are evaluating
829			temp = thisboard->clock[j] * (1 << i);
830			// if it is the best match yet
831			if (temp < lub && temp >= *period) {
832				lub_divisor_shift = i;
833				lub_index = j;
834				lub = temp;
835			}
836			if (temp > glb && temp <= *period) {
837				glb_divisor_shift = i;
838				glb_index = j;
839				glb = temp;
840			}
841		}
842	}
843	flags &= TRIG_ROUND_MASK;
844	switch (flags) {
845	case TRIG_ROUND_NEAREST:
846	default:
847		// if least upper bound is better approximation
848		if (lub - *period < *period - glb) {
849			*period = lub;
850		} else {
851			*period = glb;
852		}
853		break;
854	case TRIG_ROUND_UP:
855		*period = lub;
856		break;
857	case TRIG_ROUND_DOWN:
858		*period = glb;
859		break;
860	}
861
862	// set clock bits for config register appropriately
863	devpriv->config_bits &= ~CLOCK_MASK;
864	if (*period == lub) {
865		devpriv->config_bits |=
866			CLOCK_SELECT_BITS(lub_index) |
867			CLOCK_DIVISOR_BITS(lub_divisor_shift);
868	} else {
869		devpriv->config_bits |=
870			CLOCK_SELECT_BITS(glb_index) |
871			CLOCK_DIVISOR_BITS(glb_divisor_shift);
872	}
873
874	return 0;
875}
876
877static int a2150_set_chanlist(struct comedi_device * dev, unsigned int start_channel,
878	unsigned int num_channels)
879{
880	if (start_channel + num_channels > 4)
881		return -1;
882
883	devpriv->config_bits &= ~CHANNEL_MASK;
884
885	switch (num_channels) {
886	case 1:
887		devpriv->config_bits |= CHANNEL_BITS(0x4 | start_channel);
888		break;
889	case 2:
890		if (start_channel == 0) {
891			devpriv->config_bits |= CHANNEL_BITS(0x2);
892		} else if (start_channel == 2) {
893			devpriv->config_bits |= CHANNEL_BITS(0x3);
894		} else {
895			return -1;
896		}
897		break;
898	case 4:
899		devpriv->config_bits |= CHANNEL_BITS(0x1);
900		break;
901	default:
902		return -1;
903		break;
904	}
905
906	return 0;
907}
908