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>
6 COMEDI - Linux Control and Measurement Device Interface
7 Copyright (C) 2000 David A. Schleef <ds@schleef.org>
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.
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.
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.
23 ************************************************************************
27 Description: National Instruments AT-A2150
28 Author: Frank Mori Hess
30 Devices: [National Instruments] AT-A2150C (at_a2150c), AT-2150S (at_a2150s)
32 If you want to ac couple the board's inputs, use AREF_OTHER.
34 Configuration options:
35 [0] - I/O port base address
36 [1] - IRQ (optional, required for timed conversions)
37 [2] - DMA (optional, required for timed conversions)
41 Yet another driver for obsolete hardware brought to you by Frank Hess.
42 Testing and debugging help provided by Dave Andruczyk.
44 This driver supports the boards:
49 The only difference is their master clock frequencies.
56 References (from ftp://ftp.natinst.com/support/manuals):
58 320360.pdf AT-A2150 User Manual
62 analog level triggering
67 #include "../comedidev.h"
69 #include <linux/ioport.h>
73 #include "comedi_fc.h"
76 #define A2150_DMA_BUFFER_SIZE 0xff00 /* size in bytes of dma buffer */
78 /* #define A2150_DEBUG enable debugging code */
79 #undef A2150_DEBUG /* disable debugging code */
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 */
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 */
129 /* analog input range */
130 static const struct comedi_lrange range_a2150 = {
133 RANGE(-2.828, 2.828),
137 /* enum must match board indices */
138 enum { a2150_c, a2150_s };
139 static const struct a2150_board a2150_boards[] = {
142 clock: {31250, 22676, 20833, 19531},
148 clock: {62500, 50000, 41667, 0},
155 * Useful for shorthand access to the particular board structure
157 #define thisboard ((const struct a2150_board *)dev->board_ptr)
159 struct a2150_private {
161 volatile unsigned int count; /* number of data points left to be taken */
162 unsigned int dma; /* dma channel */
163 s16 *dma_buffer; /* dma buffer */
164 unsigned int dma_transfer_size; /* size in bytes of dma transfers */
165 int irq_dma_bits; /* irq/dma register bits */
166 int config_bits; /* config register bits */
170 #define devpriv ((struct a2150_private *)dev->private)
172 static int a2150_attach(struct comedi_device *dev, struct comedi_devconfig *it);
173 static int a2150_detach(struct comedi_device *dev);
174 static int a2150_cancel(struct comedi_device *dev, struct comedi_subdevice *s);
176 static struct comedi_driver driver_a2150 = {
177 driver_name:"ni_at_a2150",
183 static irqreturn_t a2150_interrupt(int irq, void *d);
184 static int a2150_ai_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s,
185 struct comedi_cmd * cmd);
186 static int a2150_ai_cmd(struct comedi_device * dev, struct comedi_subdevice * s);
187 static int a2150_ai_rinsn(struct comedi_device * dev, struct comedi_subdevice * s,
188 struct comedi_insn * insn, unsigned int * data);
189 static int a2150_get_timing(struct comedi_device * dev, unsigned int *period,
191 static int a2150_probe(struct comedi_device * dev);
192 static int a2150_set_chanlist(struct comedi_device * dev, unsigned int start_channel,
193 unsigned int num_channels);
195 * A convenient macro that defines init_module() and cleanup_module(),
198 COMEDI_INITCLEANUP(driver_a2150);
202 static void ni_dump_regs(struct comedi_device *dev)
204 rt_printk("config bits 0x%x\n", devpriv->config_bits);
205 rt_printk("irq dma bits 0x%x\n", devpriv->irq_dma_bits);
206 rt_printk("status bits 0x%x\n", inw(dev->iobase + STATUS_REG));
211 /* interrupt service routine */
212 static irqreturn_t a2150_interrupt(int irq, void *d)
217 struct comedi_device *dev = d;
218 struct comedi_subdevice *s = dev->read_subdev;
219 struct comedi_async *async;
220 struct comedi_cmd *cmd;
221 unsigned int max_points, num_points, residue, leftover;
223 static const int sample_size = sizeof(devpriv->dma_buffer[0]);
225 if (dev->attached == 0) {
226 comedi_error(dev, "premature interrupt");
229 /* initialize async here to make sure s is not NULL */
234 status = inw(dev->iobase + STATUS_REG);
236 if ((status & INTR_BIT) == 0) {
237 comedi_error(dev, "spurious interrupt");
241 if (status & OVFL_BIT) {
242 comedi_error(dev, "fifo overflow");
243 a2150_cancel(dev, s);
244 async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
247 if ((status & DMA_TC_BIT) == 0) {
248 comedi_error(dev, "caught non-dma interrupt? Aborting.");
249 a2150_cancel(dev, s);
250 async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
251 comedi_event(dev, s);
255 flags = claim_dma_lock();
256 disable_dma(devpriv->dma);
257 /* clear flip-flop to make sure 2-byte registers for
258 * count and address get set correctly */
259 clear_dma_ff(devpriv->dma);
261 /* figure out how many points to read */
262 max_points = devpriv->dma_transfer_size / sample_size;
263 /* residue is the number of points left to be done on the dma
264 * transfer. It should always be zero at this point unless
265 * the stop_src is set to external triggering.
267 residue = get_dma_residue(devpriv->dma) / sample_size;
268 num_points = max_points - residue;
269 if (devpriv->count < num_points && cmd->stop_src == TRIG_COUNT)
270 num_points = devpriv->count;
272 /* figure out how many points will be stored next time */
274 if (cmd->stop_src == TRIG_NONE) {
275 leftover = devpriv->dma_transfer_size / sample_size;
276 } else if (devpriv->count > max_points) {
277 leftover = devpriv->count - max_points;
278 if (leftover > max_points)
279 leftover = max_points;
281 /* there should only be a residue if collection was stopped by having
282 * the stop_src set to an external trigger, in which case there
283 * will be no more data
288 for (i = 0; i < num_points; i++) {
289 /* write data point to comedi buffer */
290 dpnt = devpriv->dma_buffer[i];
291 /* convert from 2's complement to unsigned coding */
293 cfc_write_to_buffer(s, dpnt);
294 if (cmd->stop_src == TRIG_COUNT) {
295 if (--devpriv->count == 0) { /* end of acquisition */
296 a2150_cancel(dev, s);
297 async->events |= COMEDI_CB_EOA;
304 set_dma_addr(devpriv->dma, virt_to_bus(devpriv->dma_buffer));
305 set_dma_count(devpriv->dma, leftover * sample_size);
306 enable_dma(devpriv->dma);
308 release_dma_lock(flags);
310 async->events |= COMEDI_CB_BLOCK;
312 comedi_event(dev, s);
314 /* clear interrupt */
315 outw(0x00, dev->iobase + DMA_TC_CLEAR_REG);
320 /* probes board type, returns offset */
321 static int a2150_probe(struct comedi_device *dev)
323 int status = inw(dev->iobase + STATUS_REG);
324 return ID_BITS(status);
327 static int a2150_attach(struct comedi_device *dev, struct comedi_devconfig *it)
329 struct comedi_subdevice *s;
330 unsigned long iobase = it->options[0];
331 unsigned int irq = it->options[1];
332 unsigned int dma = it->options[2];
333 static const int timeout = 2000;
336 printk("comedi%d: %s: io 0x%lx", dev->minor, driver_a2150.driver_name,
339 printk(", irq %u", irq);
344 printk(", dma %u", dma);
350 /* allocate and initialize dev->private */
351 if (alloc_private(dev, sizeof(struct a2150_private)) < 0)
355 printk(" io base address required\n");
359 /* check if io addresses are available */
360 if (!request_region(iobase, A2150_SIZE, driver_a2150.driver_name)) {
361 printk(" I/O port conflict\n");
364 dev->iobase = iobase;
368 /* check that irq is supported */
369 if (irq < 3 || irq == 8 || irq == 13 || irq > 15) {
370 printk(" invalid irq line %u\n", irq);
373 if (comedi_request_irq(irq, a2150_interrupt, 0,
374 driver_a2150.driver_name, dev)) {
375 printk("unable to allocate irq %u\n", irq);
378 devpriv->irq_dma_bits |= IRQ_LVL_BITS(irq);
383 if (dma == 4 || dma > 7) {
384 printk(" invalid dma channel %u\n", dma);
387 if (request_dma(dma, driver_a2150.driver_name)) {
388 printk(" failed to allocate dma channel %u\n", dma);
392 devpriv->dma_buffer =
393 kmalloc(A2150_DMA_BUFFER_SIZE, GFP_KERNEL | GFP_DMA);
394 if (devpriv->dma_buffer == NULL)
398 set_dma_mode(dma, DMA_MODE_READ);
400 devpriv->irq_dma_bits |= DMA_CHAN_BITS(dma);
403 dev->board_ptr = a2150_boards + a2150_probe(dev);
404 dev->board_name = thisboard->name;
406 if (alloc_subdevices(dev, 1) < 0)
409 /* analog input subdevice */
410 s = dev->subdevices + 0;
411 dev->read_subdev = s;
412 s->type = COMEDI_SUBD_AI;
413 s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_OTHER | SDF_CMD_READ;
417 s->range_table = &range_a2150;
418 s->do_cmd = a2150_ai_cmd;
419 s->do_cmdtest = a2150_ai_cmdtest;
420 s->insn_read = a2150_ai_rinsn;
421 s->cancel = a2150_cancel;
423 /* need to do this for software counting of completed conversions, to
424 * prevent hardware count from stopping aquisition */
425 outw(HW_COUNT_DISABLE, dev->iobase + I8253_MODE_REG);
427 /* set card's irq and dma levels */
428 outw(devpriv->irq_dma_bits, dev->iobase + IRQ_DMA_CNTRL_REG);
430 /* reset and sync adc clock circuitry */
431 outw_p(DPD_BIT | APD_BIT, dev->iobase + CONFIG_REG);
432 outw_p(DPD_BIT, dev->iobase + CONFIG_REG);
433 /* initialize configuration register */
434 devpriv->config_bits = 0;
435 outw(devpriv->config_bits, dev->iobase + CONFIG_REG);
436 /* wait until offset calibration is done, then enable analog inputs */
437 for (i = 0; i < timeout; i++) {
438 if ((DCAL_BIT & inw(dev->iobase + STATUS_REG)) == 0)
443 printk(" timed out waiting for offset calibration to complete\n");
446 devpriv->config_bits |= ENABLE0_BIT | ENABLE1_BIT;
447 outw(devpriv->config_bits, dev->iobase + CONFIG_REG);
452 static int a2150_detach(struct comedi_device *dev)
454 printk("comedi%d: %s: remove\n", dev->minor, driver_a2150.driver_name);
456 /* only free stuff if it has been allocated by _attach */
458 /* put board in power-down mode */
459 outw(APD_BIT | DPD_BIT, dev->iobase + CONFIG_REG);
460 release_region(dev->iobase, A2150_SIZE);
464 comedi_free_irq(dev->irq, dev);
467 free_dma(devpriv->dma);
468 if (devpriv->dma_buffer)
469 kfree(devpriv->dma_buffer);
475 static int a2150_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
477 /* disable dma on card */
478 devpriv->irq_dma_bits &= ~DMA_INTR_EN_BIT & ~DMA_EN_BIT;
479 outw(devpriv->irq_dma_bits, dev->iobase + IRQ_DMA_CNTRL_REG);
481 /* disable computer's dma */
482 disable_dma(devpriv->dma);
484 /* clear fifo and reset triggering circuitry */
485 outw(0, dev->iobase + FIFO_RESET_REG);
490 static int a2150_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
491 struct comedi_cmd *cmd)
498 /* step 1: make sure trigger sources are trivially valid */
500 tmp = cmd->start_src;
501 cmd->start_src &= TRIG_NOW | TRIG_EXT;
502 if (!cmd->start_src || tmp != cmd->start_src)
505 tmp = cmd->scan_begin_src;
506 cmd->scan_begin_src &= TRIG_TIMER;
507 if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
510 tmp = cmd->convert_src;
511 cmd->convert_src &= TRIG_NOW;
512 if (!cmd->convert_src || tmp != cmd->convert_src)
515 tmp = cmd->scan_end_src;
516 cmd->scan_end_src &= TRIG_COUNT;
517 if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
521 cmd->stop_src &= TRIG_COUNT | TRIG_NONE;
522 if (!cmd->stop_src || tmp != cmd->stop_src)
528 /* step 2: make sure trigger sources are unique and mutually compatible */
530 if (cmd->start_src != TRIG_NOW && cmd->start_src != TRIG_EXT)
532 if (cmd->stop_src != TRIG_COUNT && cmd->stop_src != TRIG_NONE)
538 /* step 3: make sure arguments are trivially compatible */
540 if (cmd->start_arg != 0) {
544 if (cmd->convert_src == TRIG_TIMER) {
545 if (cmd->convert_arg < thisboard->ai_speed) {
546 cmd->convert_arg = thisboard->ai_speed;
550 if (!cmd->chanlist_len) {
551 cmd->chanlist_len = 1;
554 if (cmd->scan_end_arg != cmd->chanlist_len) {
555 cmd->scan_end_arg = cmd->chanlist_len;
558 if (cmd->stop_src == TRIG_COUNT) {
559 if (!cmd->stop_arg) {
563 } else { /* TRIG_NONE */
564 if (cmd->stop_arg != 0) {
573 /* step 4: fix up any arguments */
575 if (cmd->scan_begin_src == TRIG_TIMER) {
576 tmp = cmd->scan_begin_arg;
577 a2150_get_timing(dev, &cmd->scan_begin_arg, cmd->flags);
578 if (tmp != cmd->scan_begin_arg)
585 /* check channel/gain list against card's limitations */
587 startChan = CR_CHAN(cmd->chanlist[0]);
588 for (i = 1; i < cmd->chanlist_len; i++) {
589 if (CR_CHAN(cmd->chanlist[i]) != (startChan + i)) {
591 "entries in chanlist must be consecutive channels, counting upwards\n");
595 if (cmd->chanlist_len == 2 && CR_CHAN(cmd->chanlist[0]) == 1) {
597 "length 2 chanlist must be channels 0,1 or channels 2,3");
600 if (cmd->chanlist_len == 3) {
602 "chanlist must have 1,2 or 4 channels");
605 if (CR_AREF(cmd->chanlist[0]) != CR_AREF(cmd->chanlist[1]) ||
606 CR_AREF(cmd->chanlist[2]) != CR_AREF(cmd->chanlist[3]))
609 "channels 0/1 and 2/3 must have the same analog reference");
620 static int a2150_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
622 struct comedi_async *async = s->async;
623 struct comedi_cmd *cmd = &async->cmd;
624 unsigned long lock_flags;
625 unsigned int old_config_bits = devpriv->config_bits;
626 unsigned int trigger_bits;
628 if (!dev->irq || !devpriv->dma) {
630 " irq and dma required, cannot do hardware conversions");
633 if (cmd->flags & TRIG_RT) {
635 " dma incompatible with hard real-time interrupt (TRIG_RT), aborting");
638 /* clear fifo and reset triggering circuitry */
639 outw(0, dev->iobase + FIFO_RESET_REG);
642 if (a2150_set_chanlist(dev, CR_CHAN(cmd->chanlist[0]),
643 cmd->chanlist_len) < 0)
646 /* setup ac/dc coupling */
647 if (CR_AREF(cmd->chanlist[0]) == AREF_OTHER)
648 devpriv->config_bits |= AC0_BIT;
650 devpriv->config_bits &= ~AC0_BIT;
651 if (CR_AREF(cmd->chanlist[2]) == AREF_OTHER)
652 devpriv->config_bits |= AC1_BIT;
654 devpriv->config_bits &= ~AC1_BIT;
657 a2150_get_timing(dev, &cmd->scan_begin_arg, cmd->flags);
659 /* send timing, channel, config bits */
660 outw(devpriv->config_bits, dev->iobase + CONFIG_REG);
662 /* initialize number of samples remaining */
663 devpriv->count = cmd->stop_arg * cmd->chanlist_len;
665 /* enable computer's dma */
666 lock_flags = claim_dma_lock();
667 disable_dma(devpriv->dma);
668 /* clear flip-flop to make sure 2-byte registers for
669 * count and address get set correctly */
670 clear_dma_ff(devpriv->dma);
671 set_dma_addr(devpriv->dma, virt_to_bus(devpriv->dma_buffer));
672 /* set size of transfer to fill in 1/3 second */
673 #define ONE_THIRD_SECOND 333333333
674 devpriv->dma_transfer_size =
675 sizeof(devpriv->dma_buffer[0]) * cmd->chanlist_len *
676 ONE_THIRD_SECOND / cmd->scan_begin_arg;
677 if (devpriv->dma_transfer_size > A2150_DMA_BUFFER_SIZE)
678 devpriv->dma_transfer_size = A2150_DMA_BUFFER_SIZE;
679 if (devpriv->dma_transfer_size < sizeof(devpriv->dma_buffer[0]))
680 devpriv->dma_transfer_size = sizeof(devpriv->dma_buffer[0]);
681 devpriv->dma_transfer_size -=
682 devpriv->dma_transfer_size % sizeof(devpriv->dma_buffer[0]);
683 set_dma_count(devpriv->dma, devpriv->dma_transfer_size);
684 enable_dma(devpriv->dma);
685 release_dma_lock(lock_flags);
687 /* clear dma interrupt before enabling it, to try and get rid of that
688 * one spurious interrupt that has been happening */
689 outw(0x00, dev->iobase + DMA_TC_CLEAR_REG);
691 /* enable dma on card */
692 devpriv->irq_dma_bits |= DMA_INTR_EN_BIT | DMA_EN_BIT;
693 outw(devpriv->irq_dma_bits, dev->iobase + IRQ_DMA_CNTRL_REG);
695 /* may need to wait 72 sampling periods if timing was changed */
696 i8254_load(dev->iobase + I8253_BASE_REG, 0, 2, 72, 0);
698 /* setup start triggering */
700 /* decide if we need to wait 72 periods for valid data */
701 if (cmd->start_src == TRIG_NOW &&
702 (old_config_bits & CLOCK_MASK) !=
703 (devpriv->config_bits & CLOCK_MASK)) {
704 /* set trigger source to delay trigger */
705 trigger_bits |= DELAY_TRIGGER_BITS;
707 /* otherwise no delay */
708 trigger_bits |= POST_TRIGGER_BITS;
710 /* enable external hardware trigger */
711 if (cmd->start_src == TRIG_EXT) {
712 trigger_bits |= HW_TRIG_EN;
713 } else if (cmd->start_src == TRIG_OTHER) {
714 /* XXX add support for level/slope start trigger using TRIG_OTHER */
715 comedi_error(dev, "you shouldn't see this?");
717 /* send trigger config bits */
718 outw(trigger_bits, dev->iobase + TRIGGER_REG);
720 /* start aquisition for soft trigger */
721 if (cmd->start_src == TRIG_NOW) {
722 outw(0, dev->iobase + FIFO_START_REG);
731 static int a2150_ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
732 struct comedi_insn *insn, unsigned int *data)
735 static const int timeout = 100000;
736 static const int filter_delay = 36;
738 /* clear fifo and reset triggering circuitry */
739 outw(0, dev->iobase + FIFO_RESET_REG);
742 if (a2150_set_chanlist(dev, CR_CHAN(insn->chanspec), 1) < 0)
745 /* set dc coupling */
746 devpriv->config_bits &= ~AC0_BIT;
747 devpriv->config_bits &= ~AC1_BIT;
749 /* send timing, channel, config bits */
750 outw(devpriv->config_bits, dev->iobase + CONFIG_REG);
752 /* disable dma on card */
753 devpriv->irq_dma_bits &= ~DMA_INTR_EN_BIT & ~DMA_EN_BIT;
754 outw(devpriv->irq_dma_bits, dev->iobase + IRQ_DMA_CNTRL_REG);
756 /* setup start triggering */
757 outw(0, dev->iobase + TRIGGER_REG);
759 /* start aquisition for soft trigger */
760 outw(0, dev->iobase + FIFO_START_REG);
762 /* there is a 35.6 sample delay for data to get through the antialias filter */
763 for (n = 0; n < filter_delay; n++) {
764 for (i = 0; i < timeout; i++) {
765 if (inw(dev->iobase + STATUS_REG) & FNE_BIT)
770 comedi_error(dev, "timeout");
773 inw(dev->iobase + FIFO_DATA_REG);
777 for (n = 0; n < insn->n; n++) {
778 for (i = 0; i < timeout; i++) {
779 if (inw(dev->iobase + STATUS_REG) & FNE_BIT)
784 comedi_error(dev, "timeout");
790 data[n] = inw(dev->iobase + FIFO_DATA_REG);
792 rt_printk(" data is %i\n", data[n]);
797 /* clear fifo and reset triggering circuitry */
798 outw(0, dev->iobase + FIFO_RESET_REG);
803 /* sets bits in devpriv->clock_bits to nearest approximation of requested period,
804 * adjusts requested period to actual timing. */
805 static int a2150_get_timing(struct comedi_device *dev, unsigned int *period,
809 int lub_divisor_shift, lub_index, glb_divisor_shift, glb_index;
812 /* initialize greatest lower and least upper bounds */
813 lub_divisor_shift = 3;
815 lub = thisboard->clock[lub_index] * (1 << lub_divisor_shift);
816 glb_divisor_shift = 0;
817 glb_index = thisboard->num_clocks - 1;
818 glb = thisboard->clock[glb_index] * (1 << glb_divisor_shift);
820 /* make sure period is in available range */
826 /* we can multiply period by 1, 2, 4, or 8, using (1 << i) */
827 for (i = 0; i < 4; i++) {
828 /* there are a maximum of 4 master clocks */
829 for (j = 0; j < thisboard->num_clocks; j++) {
830 /* temp is the period in nanosec we are evaluating */
831 temp = thisboard->clock[j] * (1 << i);
832 /* if it is the best match yet */
833 if (temp < lub && temp >= *period) {
834 lub_divisor_shift = i;
838 if (temp > glb && temp <= *period) {
839 glb_divisor_shift = i;
845 flags &= TRIG_ROUND_MASK;
847 case TRIG_ROUND_NEAREST:
849 /* if least upper bound is better approximation */
850 if (lub - *period < *period - glb) {
859 case TRIG_ROUND_DOWN:
864 /* set clock bits for config register appropriately */
865 devpriv->config_bits &= ~CLOCK_MASK;
866 if (*period == lub) {
867 devpriv->config_bits |=
868 CLOCK_SELECT_BITS(lub_index) |
869 CLOCK_DIVISOR_BITS(lub_divisor_shift);
871 devpriv->config_bits |=
872 CLOCK_SELECT_BITS(glb_index) |
873 CLOCK_DIVISOR_BITS(glb_divisor_shift);
879 static int a2150_set_chanlist(struct comedi_device *dev, unsigned int start_channel,
880 unsigned int num_channels)
882 if (start_channel + num_channels > 4)
885 devpriv->config_bits &= ~CHANNEL_MASK;
887 switch (num_channels) {
889 devpriv->config_bits |= CHANNEL_BITS(0x4 | start_channel);
892 if (start_channel == 0) {
893 devpriv->config_bits |= CHANNEL_BITS(0x2);
894 } else if (start_channel == 2) {
895 devpriv->config_bits |= CHANNEL_BITS(0x3);
901 devpriv->config_bits |= CHANNEL_BITS(0x1);