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.
21 Description: National Instruments AT-A2150
22 Author: Frank Mori Hess
24 Devices: [National Instruments] AT-A2150C (at_a2150c), AT-2150S (at_a2150s)
26 If you want to ac couple the board's inputs, use AREF_OTHER.
28 Configuration options:
29 [0] - I/O port base address
30 [1] - IRQ (optional, required for timed conversions)
31 [2] - DMA (optional, required for timed conversions)
35 Yet another driver for obsolete hardware brought to you by Frank Hess.
36 Testing and debugging help provided by Dave Andruczyk.
38 This driver supports the boards:
43 The only difference is their master clock frequencies.
50 References (from ftp://ftp.natinst.com/support/manuals):
52 320360.pdf AT-A2150 User Manual
56 analog level triggering
61 #include <linux/module.h>
62 #include <linux/delay.h>
63 #include <linux/interrupt.h>
64 #include <linux/slab.h>
65 #include "../comedidev.h"
72 #include "comedi_fc.h"
75 #define A2150_DMA_BUFFER_SIZE 0xff00 /* size in bytes of dma buffer */
77 /* #define A2150_DEBUG enable debugging code */
78 #undef A2150_DEBUG /* disable debugging code */
80 /* Registers and bits */
81 #define CONFIG_REG 0x0
82 #define CHANNEL_BITS(x) ((x) & 0x7)
83 #define CHANNEL_MASK 0x7
84 #define CLOCK_SELECT_BITS(x) (((x) & 0x3) << 3)
85 #define CLOCK_DIVISOR_BITS(x) (((x) & 0x3) << 5)
86 #define CLOCK_MASK (0xf << 3)
87 #define ENABLE0_BIT 0x80 /* enable (don't internally ground) channels 0 and 1 */
88 #define ENABLE1_BIT 0x100 /* enable (don't internally ground) channels 2 and 3 */
89 #define AC0_BIT 0x200 /* ac couple channels 0,1 */
90 #define AC1_BIT 0x400 /* ac couple channels 2,3 */
91 #define APD_BIT 0x800 /* analog power down */
92 #define DPD_BIT 0x1000 /* digital power down */
93 #define TRIGGER_REG 0x2 /* trigger config register */
94 #define POST_TRIGGER_BITS 0x2
95 #define DELAY_TRIGGER_BITS 0x3
96 #define HW_TRIG_EN 0x10 /* enable hardware trigger */
97 #define FIFO_START_REG 0x6 /* software start aquistion trigger */
98 #define FIFO_RESET_REG 0x8 /* clears fifo + fifo flags */
99 #define FIFO_DATA_REG 0xa /* read data */
100 #define DMA_TC_CLEAR_REG 0xe /* clear dma terminal count interrupt */
101 #define STATUS_REG 0x12 /* read only */
102 #define FNE_BIT 0x1 /* fifo not empty */
103 #define OVFL_BIT 0x8 /* fifo overflow */
104 #define EDAQ_BIT 0x10 /* end of acquisition interrupt */
105 #define DCAL_BIT 0x20 /* offset calibration in progress */
106 #define INTR_BIT 0x40 /* interrupt has occurred */
107 #define DMA_TC_BIT 0x80 /* dma terminal count interrupt has occurred */
108 #define ID_BITS(x) (((x) >> 8) & 0x3)
109 #define IRQ_DMA_CNTRL_REG 0x12 /* write only */
110 #define DMA_CHAN_BITS(x) ((x) & 0x7) /* sets dma channel */
111 #define DMA_EN_BIT 0x8 /* enables dma */
112 #define IRQ_LVL_BITS(x) (((x) & 0xf) << 4) /* sets irq level */
113 #define FIFO_INTR_EN_BIT 0x100 /* enable fifo interrupts */
114 #define FIFO_INTR_FHF_BIT 0x200 /* interrupt fifo half full */
115 #define DMA_INTR_EN_BIT 0x800 /* enable interrupt on dma terminal count */
116 #define DMA_DEM_EN_BIT 0x1000 /* enables demand mode dma */
117 #define I8253_BASE_REG 0x14
118 #define I8253_MODE_REG 0x17
119 #define HW_COUNT_DISABLE 0x30 /* disable hardware counting of conversions */
123 int clock[4]; /* master clock periods, in nanoseconds */
124 int num_clocks; /* number of available master clock speeds */
125 int ai_speed; /* maximum conversion rate in nanoseconds */
128 /* analog input range */
129 static const struct comedi_lrange range_a2150 = {
132 RANGE(-2.828, 2.828),
136 /* enum must match board indices */
137 enum { a2150_c, a2150_s };
138 static const struct a2150_board a2150_boards[] = {
141 .clock = {31250, 22676, 20833, 19531},
147 .clock = {62500, 50000, 41667, 0},
153 struct a2150_private {
155 volatile unsigned int count; /* number of data points left to be taken */
156 unsigned int dma; /* dma channel */
157 s16 *dma_buffer; /* dma buffer */
158 unsigned int dma_transfer_size; /* size in bytes of dma transfers */
159 int irq_dma_bits; /* irq/dma register bits */
160 int config_bits; /* config register bits */
163 static int a2150_cancel(struct comedi_device *dev, struct comedi_subdevice *s);
165 static int a2150_get_timing(struct comedi_device *dev, unsigned int *period,
167 static int a2150_set_chanlist(struct comedi_device *dev,
168 unsigned int start_channel,
169 unsigned int num_channels);
172 static void ni_dump_regs(struct comedi_device *dev)
174 struct a2150_private *devpriv = dev->private;
176 printk("config bits 0x%x\n", devpriv->config_bits);
177 printk("irq dma bits 0x%x\n", devpriv->irq_dma_bits);
178 printk("status bits 0x%x\n", inw(dev->iobase + STATUS_REG));
183 /* interrupt service routine */
184 static irqreturn_t a2150_interrupt(int irq, void *d)
189 struct comedi_device *dev = d;
190 struct a2150_private *devpriv = dev->private;
191 struct comedi_subdevice *s = dev->read_subdev;
192 struct comedi_async *async;
193 struct comedi_cmd *cmd;
194 unsigned int max_points, num_points, residue, leftover;
196 static const int sample_size = sizeof(devpriv->dma_buffer[0]);
198 if (!dev->attached) {
199 comedi_error(dev, "premature interrupt");
202 /* initialize async here to make sure s is not NULL */
207 status = inw(dev->iobase + STATUS_REG);
209 if ((status & INTR_BIT) == 0) {
210 comedi_error(dev, "spurious interrupt");
214 if (status & OVFL_BIT) {
215 comedi_error(dev, "fifo overflow");
216 a2150_cancel(dev, s);
217 async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
220 if ((status & DMA_TC_BIT) == 0) {
221 comedi_error(dev, "caught non-dma interrupt? Aborting.");
222 a2150_cancel(dev, s);
223 async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
224 comedi_event(dev, s);
228 flags = claim_dma_lock();
229 disable_dma(devpriv->dma);
230 /* clear flip-flop to make sure 2-byte registers for
231 * count and address get set correctly */
232 clear_dma_ff(devpriv->dma);
234 /* figure out how many points to read */
235 max_points = devpriv->dma_transfer_size / sample_size;
236 /* residue is the number of points left to be done on the dma
237 * transfer. It should always be zero at this point unless
238 * the stop_src is set to external triggering.
240 residue = get_dma_residue(devpriv->dma) / sample_size;
241 num_points = max_points - residue;
242 if (devpriv->count < num_points && cmd->stop_src == TRIG_COUNT)
243 num_points = devpriv->count;
245 /* figure out how many points will be stored next time */
247 if (cmd->stop_src == TRIG_NONE) {
248 leftover = devpriv->dma_transfer_size / sample_size;
249 } else if (devpriv->count > max_points) {
250 leftover = devpriv->count - max_points;
251 if (leftover > max_points)
252 leftover = max_points;
254 /* there should only be a residue if collection was stopped by having
255 * the stop_src set to an external trigger, in which case there
256 * will be no more data
261 for (i = 0; i < num_points; i++) {
262 /* write data point to comedi buffer */
263 dpnt = devpriv->dma_buffer[i];
264 /* convert from 2's complement to unsigned coding */
266 cfc_write_to_buffer(s, dpnt);
267 if (cmd->stop_src == TRIG_COUNT) {
268 if (--devpriv->count == 0) { /* end of acquisition */
269 a2150_cancel(dev, s);
270 async->events |= COMEDI_CB_EOA;
277 set_dma_addr(devpriv->dma, virt_to_bus(devpriv->dma_buffer));
278 set_dma_count(devpriv->dma, leftover * sample_size);
279 enable_dma(devpriv->dma);
281 release_dma_lock(flags);
283 async->events |= COMEDI_CB_BLOCK;
285 comedi_event(dev, s);
287 /* clear interrupt */
288 outw(0x00, dev->iobase + DMA_TC_CLEAR_REG);
293 static int a2150_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
295 struct a2150_private *devpriv = dev->private;
297 /* disable dma on card */
298 devpriv->irq_dma_bits &= ~DMA_INTR_EN_BIT & ~DMA_EN_BIT;
299 outw(devpriv->irq_dma_bits, dev->iobase + IRQ_DMA_CNTRL_REG);
301 /* disable computer's dma */
302 disable_dma(devpriv->dma);
304 /* clear fifo and reset triggering circuitry */
305 outw(0, dev->iobase + FIFO_RESET_REG);
310 static int a2150_ai_cmdtest(struct comedi_device *dev,
311 struct comedi_subdevice *s, struct comedi_cmd *cmd)
313 const struct a2150_board *thisboard = comedi_board(dev);
319 /* Step 1 : check if triggers are trivially valid */
321 err |= cfc_check_trigger_src(&cmd->start_src, TRIG_NOW | TRIG_EXT);
322 err |= cfc_check_trigger_src(&cmd->scan_begin_src, TRIG_TIMER);
323 err |= cfc_check_trigger_src(&cmd->convert_src, TRIG_NOW);
324 err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
325 err |= cfc_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE);
330 /* Step 2a : make sure trigger sources are unique */
332 err |= cfc_check_trigger_is_unique(cmd->start_src);
333 err |= cfc_check_trigger_is_unique(cmd->stop_src);
335 /* Step 2b : and mutually compatible */
340 /* Step 3: check if arguments are trivially valid */
342 err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0);
344 if (cmd->convert_src == TRIG_TIMER)
345 err |= cfc_check_trigger_arg_min(&cmd->convert_arg,
346 thisboard->ai_speed);
348 err |= cfc_check_trigger_arg_min(&cmd->chanlist_len, 1);
349 err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len);
351 if (cmd->stop_src == TRIG_COUNT)
352 err |= cfc_check_trigger_arg_min(&cmd->stop_arg, 1);
354 err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0);
359 /* step 4: fix up any arguments */
361 if (cmd->scan_begin_src == TRIG_TIMER) {
362 tmp = cmd->scan_begin_arg;
363 a2150_get_timing(dev, &cmd->scan_begin_arg, cmd->flags);
364 if (tmp != cmd->scan_begin_arg)
371 /* check channel/gain list against card's limitations */
373 startChan = CR_CHAN(cmd->chanlist[0]);
374 for (i = 1; i < cmd->chanlist_len; i++) {
375 if (CR_CHAN(cmd->chanlist[i]) != (startChan + i)) {
377 "entries in chanlist must be consecutive channels, counting upwards\n");
381 if (cmd->chanlist_len == 2 && CR_CHAN(cmd->chanlist[0]) == 1) {
383 "length 2 chanlist must be channels 0,1 or channels 2,3");
386 if (cmd->chanlist_len == 3) {
388 "chanlist must have 1,2 or 4 channels");
391 if (CR_AREF(cmd->chanlist[0]) != CR_AREF(cmd->chanlist[1]) ||
392 CR_AREF(cmd->chanlist[2]) != CR_AREF(cmd->chanlist[3])) {
394 "channels 0/1 and 2/3 must have the same analog reference");
405 static int a2150_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
407 struct a2150_private *devpriv = dev->private;
408 struct comedi_async *async = s->async;
409 struct comedi_cmd *cmd = &async->cmd;
410 unsigned long lock_flags;
411 unsigned int old_config_bits = devpriv->config_bits;
412 unsigned int trigger_bits;
414 if (!dev->irq || !devpriv->dma) {
416 " irq and dma required, cannot do hardware conversions");
419 if (cmd->flags & TRIG_RT) {
421 " dma incompatible with hard real-time interrupt (TRIG_RT), aborting");
424 /* clear fifo and reset triggering circuitry */
425 outw(0, dev->iobase + FIFO_RESET_REG);
428 if (a2150_set_chanlist(dev, CR_CHAN(cmd->chanlist[0]),
429 cmd->chanlist_len) < 0)
432 /* setup ac/dc coupling */
433 if (CR_AREF(cmd->chanlist[0]) == AREF_OTHER)
434 devpriv->config_bits |= AC0_BIT;
436 devpriv->config_bits &= ~AC0_BIT;
437 if (CR_AREF(cmd->chanlist[2]) == AREF_OTHER)
438 devpriv->config_bits |= AC1_BIT;
440 devpriv->config_bits &= ~AC1_BIT;
443 a2150_get_timing(dev, &cmd->scan_begin_arg, cmd->flags);
445 /* send timing, channel, config bits */
446 outw(devpriv->config_bits, dev->iobase + CONFIG_REG);
448 /* initialize number of samples remaining */
449 devpriv->count = cmd->stop_arg * cmd->chanlist_len;
451 /* enable computer's dma */
452 lock_flags = claim_dma_lock();
453 disable_dma(devpriv->dma);
454 /* clear flip-flop to make sure 2-byte registers for
455 * count and address get set correctly */
456 clear_dma_ff(devpriv->dma);
457 set_dma_addr(devpriv->dma, virt_to_bus(devpriv->dma_buffer));
458 /* set size of transfer to fill in 1/3 second */
459 #define ONE_THIRD_SECOND 333333333
460 devpriv->dma_transfer_size =
461 sizeof(devpriv->dma_buffer[0]) * cmd->chanlist_len *
462 ONE_THIRD_SECOND / cmd->scan_begin_arg;
463 if (devpriv->dma_transfer_size > A2150_DMA_BUFFER_SIZE)
464 devpriv->dma_transfer_size = A2150_DMA_BUFFER_SIZE;
465 if (devpriv->dma_transfer_size < sizeof(devpriv->dma_buffer[0]))
466 devpriv->dma_transfer_size = sizeof(devpriv->dma_buffer[0]);
467 devpriv->dma_transfer_size -=
468 devpriv->dma_transfer_size % sizeof(devpriv->dma_buffer[0]);
469 set_dma_count(devpriv->dma, devpriv->dma_transfer_size);
470 enable_dma(devpriv->dma);
471 release_dma_lock(lock_flags);
473 /* clear dma interrupt before enabling it, to try and get rid of that
474 * one spurious interrupt that has been happening */
475 outw(0x00, dev->iobase + DMA_TC_CLEAR_REG);
477 /* enable 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 /* may need to wait 72 sampling periods if timing was changed */
482 i8254_load(dev->iobase + I8253_BASE_REG, 0, 2, 72, 0);
484 /* setup start triggering */
486 /* decide if we need to wait 72 periods for valid data */
487 if (cmd->start_src == TRIG_NOW &&
488 (old_config_bits & CLOCK_MASK) !=
489 (devpriv->config_bits & CLOCK_MASK)) {
490 /* set trigger source to delay trigger */
491 trigger_bits |= DELAY_TRIGGER_BITS;
493 /* otherwise no delay */
494 trigger_bits |= POST_TRIGGER_BITS;
496 /* enable external hardware trigger */
497 if (cmd->start_src == TRIG_EXT) {
498 trigger_bits |= HW_TRIG_EN;
499 } else if (cmd->start_src == TRIG_OTHER) {
500 /* XXX add support for level/slope start trigger using TRIG_OTHER */
501 comedi_error(dev, "you shouldn't see this?");
503 /* send trigger config bits */
504 outw(trigger_bits, dev->iobase + TRIGGER_REG);
506 /* start acquisition for soft trigger */
507 if (cmd->start_src == TRIG_NOW)
508 outw(0, dev->iobase + FIFO_START_REG);
516 static int a2150_ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
517 struct comedi_insn *insn, unsigned int *data)
519 struct a2150_private *devpriv = dev->private;
521 static const int timeout = 100000;
522 static const int filter_delay = 36;
524 /* clear fifo and reset triggering circuitry */
525 outw(0, dev->iobase + FIFO_RESET_REG);
528 if (a2150_set_chanlist(dev, CR_CHAN(insn->chanspec), 1) < 0)
531 /* set dc coupling */
532 devpriv->config_bits &= ~AC0_BIT;
533 devpriv->config_bits &= ~AC1_BIT;
535 /* send timing, channel, config bits */
536 outw(devpriv->config_bits, dev->iobase + CONFIG_REG);
538 /* disable dma on card */
539 devpriv->irq_dma_bits &= ~DMA_INTR_EN_BIT & ~DMA_EN_BIT;
540 outw(devpriv->irq_dma_bits, dev->iobase + IRQ_DMA_CNTRL_REG);
542 /* setup start triggering */
543 outw(0, dev->iobase + TRIGGER_REG);
545 /* start acquisition for soft trigger */
546 outw(0, dev->iobase + FIFO_START_REG);
549 * there is a 35.6 sample delay for data to get through the
552 for (n = 0; n < filter_delay; n++) {
553 for (i = 0; i < timeout; i++) {
554 if (inw(dev->iobase + STATUS_REG) & FNE_BIT)
559 comedi_error(dev, "timeout");
562 inw(dev->iobase + FIFO_DATA_REG);
566 for (n = 0; n < insn->n; n++) {
567 for (i = 0; i < timeout; i++) {
568 if (inw(dev->iobase + STATUS_REG) & FNE_BIT)
573 comedi_error(dev, "timeout");
579 data[n] = inw(dev->iobase + FIFO_DATA_REG);
581 printk(" data is %i\n", data[n]);
586 /* clear fifo and reset triggering circuitry */
587 outw(0, dev->iobase + FIFO_RESET_REG);
593 * sets bits in devpriv->clock_bits to nearest approximation of requested
594 * period, adjusts requested period to actual timing.
596 static int a2150_get_timing(struct comedi_device *dev, unsigned int *period,
599 const struct a2150_board *thisboard = comedi_board(dev);
600 struct a2150_private *devpriv = dev->private;
602 int lub_divisor_shift, lub_index, glb_divisor_shift, glb_index;
605 /* initialize greatest lower and least upper bounds */
606 lub_divisor_shift = 3;
608 lub = thisboard->clock[lub_index] * (1 << lub_divisor_shift);
609 glb_divisor_shift = 0;
610 glb_index = thisboard->num_clocks - 1;
611 glb = thisboard->clock[glb_index] * (1 << glb_divisor_shift);
613 /* make sure period is in available range */
619 /* we can multiply period by 1, 2, 4, or 8, using (1 << i) */
620 for (i = 0; i < 4; i++) {
621 /* there are a maximum of 4 master clocks */
622 for (j = 0; j < thisboard->num_clocks; j++) {
623 /* temp is the period in nanosec we are evaluating */
624 temp = thisboard->clock[j] * (1 << i);
625 /* if it is the best match yet */
626 if (temp < lub && temp >= *period) {
627 lub_divisor_shift = i;
631 if (temp > glb && temp <= *period) {
632 glb_divisor_shift = i;
638 flags &= TRIG_ROUND_MASK;
640 case TRIG_ROUND_NEAREST:
642 /* if least upper bound is better approximation */
643 if (lub - *period < *period - glb)
651 case TRIG_ROUND_DOWN:
656 /* set clock bits for config register appropriately */
657 devpriv->config_bits &= ~CLOCK_MASK;
658 if (*period == lub) {
659 devpriv->config_bits |=
660 CLOCK_SELECT_BITS(lub_index) |
661 CLOCK_DIVISOR_BITS(lub_divisor_shift);
663 devpriv->config_bits |=
664 CLOCK_SELECT_BITS(glb_index) |
665 CLOCK_DIVISOR_BITS(glb_divisor_shift);
671 static int a2150_set_chanlist(struct comedi_device *dev,
672 unsigned int start_channel,
673 unsigned int num_channels)
675 struct a2150_private *devpriv = dev->private;
677 if (start_channel + num_channels > 4)
680 devpriv->config_bits &= ~CHANNEL_MASK;
682 switch (num_channels) {
684 devpriv->config_bits |= CHANNEL_BITS(0x4 | start_channel);
687 if (start_channel == 0) {
688 devpriv->config_bits |= CHANNEL_BITS(0x2);
689 } else if (start_channel == 2) {
690 devpriv->config_bits |= CHANNEL_BITS(0x3);
696 devpriv->config_bits |= CHANNEL_BITS(0x1);
706 /* probes board type, returns offset */
707 static int a2150_probe(struct comedi_device *dev)
709 int status = inw(dev->iobase + STATUS_REG);
710 return ID_BITS(status);
713 static int a2150_attach(struct comedi_device *dev, struct comedi_devconfig *it)
715 const struct a2150_board *thisboard = comedi_board(dev);
716 struct a2150_private *devpriv;
717 struct comedi_subdevice *s;
718 unsigned int irq = it->options[1];
719 unsigned int dma = it->options[2];
720 static const int timeout = 2000;
724 devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
728 ret = comedi_request_region(dev, it->options[0], A2150_SIZE);
734 /* check that irq is supported */
735 if (irq < 3 || irq == 8 || irq == 13 || irq > 15) {
736 printk(" invalid irq line %u\n", irq);
739 if (request_irq(irq, a2150_interrupt, 0,
740 dev->driver->driver_name, dev)) {
741 printk("unable to allocate irq %u\n", irq);
744 devpriv->irq_dma_bits |= IRQ_LVL_BITS(irq);
749 if (dma == 4 || dma > 7) {
750 printk(" invalid dma channel %u\n", dma);
753 if (request_dma(dma, dev->driver->driver_name)) {
754 printk(" failed to allocate dma channel %u\n", dma);
758 devpriv->dma_buffer =
759 kmalloc(A2150_DMA_BUFFER_SIZE, GFP_KERNEL | GFP_DMA);
760 if (devpriv->dma_buffer == NULL)
764 set_dma_mode(dma, DMA_MODE_READ);
766 devpriv->irq_dma_bits |= DMA_CHAN_BITS(dma);
769 dev->board_ptr = a2150_boards + a2150_probe(dev);
770 thisboard = comedi_board(dev);
771 dev->board_name = thisboard->name;
773 ret = comedi_alloc_subdevices(dev, 1);
777 /* analog input subdevice */
778 s = &dev->subdevices[0];
779 dev->read_subdev = s;
780 s->type = COMEDI_SUBD_AI;
781 s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_OTHER | SDF_CMD_READ;
785 s->range_table = &range_a2150;
786 s->do_cmd = a2150_ai_cmd;
787 s->do_cmdtest = a2150_ai_cmdtest;
788 s->insn_read = a2150_ai_rinsn;
789 s->cancel = a2150_cancel;
791 /* need to do this for software counting of completed conversions, to
792 * prevent hardware count from stopping acquisition */
793 outw(HW_COUNT_DISABLE, dev->iobase + I8253_MODE_REG);
795 /* set card's irq and dma levels */
796 outw(devpriv->irq_dma_bits, dev->iobase + IRQ_DMA_CNTRL_REG);
798 /* reset and sync adc clock circuitry */
799 outw_p(DPD_BIT | APD_BIT, dev->iobase + CONFIG_REG);
800 outw_p(DPD_BIT, dev->iobase + CONFIG_REG);
801 /* initialize configuration register */
802 devpriv->config_bits = 0;
803 outw(devpriv->config_bits, dev->iobase + CONFIG_REG);
804 /* wait until offset calibration is done, then enable analog inputs */
805 for (i = 0; i < timeout; i++) {
806 if ((DCAL_BIT & inw(dev->iobase + STATUS_REG)) == 0)
812 (" timed out waiting for offset calibration to complete\n");
815 devpriv->config_bits |= ENABLE0_BIT | ENABLE1_BIT;
816 outw(devpriv->config_bits, dev->iobase + CONFIG_REG);
821 static void a2150_detach(struct comedi_device *dev)
823 struct a2150_private *devpriv = dev->private;
826 outw(APD_BIT | DPD_BIT, dev->iobase + CONFIG_REG);
829 free_dma(devpriv->dma);
830 kfree(devpriv->dma_buffer);
832 comedi_legacy_detach(dev);
835 static struct comedi_driver ni_at_a2150_driver = {
836 .driver_name = "ni_at_a2150",
837 .module = THIS_MODULE,
838 .attach = a2150_attach,
839 .detach = a2150_detach,
841 module_comedi_driver(ni_at_a2150_driver);
843 MODULE_AUTHOR("Comedi http://www.comedi.org");
844 MODULE_DESCRIPTION("Comedi low-level driver");
845 MODULE_LICENSE("GPL");