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/interrupt.h>
62 #include <linux/slab.h>
63 #include "../comedidev.h"
65 #include <linux/ioport.h>
70 #include "comedi_fc.h"
73 #define A2150_DMA_BUFFER_SIZE 0xff00 /* size in bytes of dma buffer */
75 /* #define A2150_DEBUG enable debugging code */
76 #undef A2150_DEBUG /* disable debugging code */
78 /* Registers and bits */
79 #define CONFIG_REG 0x0
80 #define CHANNEL_BITS(x) ((x) & 0x7)
81 #define CHANNEL_MASK 0x7
82 #define CLOCK_SELECT_BITS(x) (((x) & 0x3) << 3)
83 #define CLOCK_DIVISOR_BITS(x) (((x) & 0x3) << 5)
84 #define CLOCK_MASK (0xf << 3)
85 #define ENABLE0_BIT 0x80 /* enable (don't internally ground) channels 0 and 1 */
86 #define ENABLE1_BIT 0x100 /* enable (don't internally ground) channels 2 and 3 */
87 #define AC0_BIT 0x200 /* ac couple channels 0,1 */
88 #define AC1_BIT 0x400 /* ac couple channels 2,3 */
89 #define APD_BIT 0x800 /* analog power down */
90 #define DPD_BIT 0x1000 /* digital power down */
91 #define TRIGGER_REG 0x2 /* trigger config register */
92 #define POST_TRIGGER_BITS 0x2
93 #define DELAY_TRIGGER_BITS 0x3
94 #define HW_TRIG_EN 0x10 /* enable hardware trigger */
95 #define FIFO_START_REG 0x6 /* software start aquistion trigger */
96 #define FIFO_RESET_REG 0x8 /* clears fifo + fifo flags */
97 #define FIFO_DATA_REG 0xa /* read data */
98 #define DMA_TC_CLEAR_REG 0xe /* clear dma terminal count interrupt */
99 #define STATUS_REG 0x12 /* read only */
100 #define FNE_BIT 0x1 /* fifo not empty */
101 #define OVFL_BIT 0x8 /* fifo overflow */
102 #define EDAQ_BIT 0x10 /* end of acquisition interrupt */
103 #define DCAL_BIT 0x20 /* offset calibration in progress */
104 #define INTR_BIT 0x40 /* interrupt has occurred */
105 #define DMA_TC_BIT 0x80 /* dma terminal count interrupt has occurred */
106 #define ID_BITS(x) (((x) >> 8) & 0x3)
107 #define IRQ_DMA_CNTRL_REG 0x12 /* write only */
108 #define DMA_CHAN_BITS(x) ((x) & 0x7) /* sets dma channel */
109 #define DMA_EN_BIT 0x8 /* enables dma */
110 #define IRQ_LVL_BITS(x) (((x) & 0xf) << 4) /* sets irq level */
111 #define FIFO_INTR_EN_BIT 0x100 /* enable fifo interrupts */
112 #define FIFO_INTR_FHF_BIT 0x200 /* interrupt fifo half full */
113 #define DMA_INTR_EN_BIT 0x800 /* enable interrupt on dma terminal count */
114 #define DMA_DEM_EN_BIT 0x1000 /* enables demand mode dma */
115 #define I8253_BASE_REG 0x14
116 #define I8253_MODE_REG 0x17
117 #define HW_COUNT_DISABLE 0x30 /* disable hardware counting of conversions */
121 int clock[4]; /* master clock periods, in nanoseconds */
122 int num_clocks; /* number of available master clock speeds */
123 int ai_speed; /* maximum conversion rate in nanoseconds */
126 /* analog input range */
127 static const struct comedi_lrange range_a2150 = {
130 RANGE(-2.828, 2.828),
134 /* enum must match board indices */
135 enum { a2150_c, a2150_s };
136 static const struct a2150_board a2150_boards[] = {
139 .clock = {31250, 22676, 20833, 19531},
145 .clock = {62500, 50000, 41667, 0},
151 struct a2150_private {
153 volatile unsigned int count; /* number of data points left to be taken */
154 unsigned int dma; /* dma channel */
155 s16 *dma_buffer; /* dma buffer */
156 unsigned int dma_transfer_size; /* size in bytes of dma transfers */
157 int irq_dma_bits; /* irq/dma register bits */
158 int config_bits; /* config register bits */
161 static int a2150_cancel(struct comedi_device *dev, struct comedi_subdevice *s);
163 static int a2150_get_timing(struct comedi_device *dev, unsigned int *period,
165 static int a2150_set_chanlist(struct comedi_device *dev,
166 unsigned int start_channel,
167 unsigned int num_channels);
170 static void ni_dump_regs(struct comedi_device *dev)
172 struct a2150_private *devpriv = dev->private;
174 printk("config bits 0x%x\n", devpriv->config_bits);
175 printk("irq dma bits 0x%x\n", devpriv->irq_dma_bits);
176 printk("status bits 0x%x\n", inw(dev->iobase + STATUS_REG));
181 /* interrupt service routine */
182 static irqreturn_t a2150_interrupt(int irq, void *d)
187 struct comedi_device *dev = d;
188 struct a2150_private *devpriv = dev->private;
189 struct comedi_subdevice *s = dev->read_subdev;
190 struct comedi_async *async;
191 struct comedi_cmd *cmd;
192 unsigned int max_points, num_points, residue, leftover;
194 static const int sample_size = sizeof(devpriv->dma_buffer[0]);
196 if (!dev->attached) {
197 comedi_error(dev, "premature interrupt");
200 /* initialize async here to make sure s is not NULL */
205 status = inw(dev->iobase + STATUS_REG);
207 if ((status & INTR_BIT) == 0) {
208 comedi_error(dev, "spurious interrupt");
212 if (status & OVFL_BIT) {
213 comedi_error(dev, "fifo overflow");
214 a2150_cancel(dev, s);
215 async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
218 if ((status & DMA_TC_BIT) == 0) {
219 comedi_error(dev, "caught non-dma interrupt? Aborting.");
220 a2150_cancel(dev, s);
221 async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
222 comedi_event(dev, s);
226 flags = claim_dma_lock();
227 disable_dma(devpriv->dma);
228 /* clear flip-flop to make sure 2-byte registers for
229 * count and address get set correctly */
230 clear_dma_ff(devpriv->dma);
232 /* figure out how many points to read */
233 max_points = devpriv->dma_transfer_size / sample_size;
234 /* residue is the number of points left to be done on the dma
235 * transfer. It should always be zero at this point unless
236 * the stop_src is set to external triggering.
238 residue = get_dma_residue(devpriv->dma) / sample_size;
239 num_points = max_points - residue;
240 if (devpriv->count < num_points && cmd->stop_src == TRIG_COUNT)
241 num_points = devpriv->count;
243 /* figure out how many points will be stored next time */
245 if (cmd->stop_src == TRIG_NONE) {
246 leftover = devpriv->dma_transfer_size / sample_size;
247 } else if (devpriv->count > max_points) {
248 leftover = devpriv->count - max_points;
249 if (leftover > max_points)
250 leftover = max_points;
252 /* there should only be a residue if collection was stopped by having
253 * the stop_src set to an external trigger, in which case there
254 * will be no more data
259 for (i = 0; i < num_points; i++) {
260 /* write data point to comedi buffer */
261 dpnt = devpriv->dma_buffer[i];
262 /* convert from 2's complement to unsigned coding */
264 cfc_write_to_buffer(s, dpnt);
265 if (cmd->stop_src == TRIG_COUNT) {
266 if (--devpriv->count == 0) { /* end of acquisition */
267 a2150_cancel(dev, s);
268 async->events |= COMEDI_CB_EOA;
275 set_dma_addr(devpriv->dma, virt_to_bus(devpriv->dma_buffer));
276 set_dma_count(devpriv->dma, leftover * sample_size);
277 enable_dma(devpriv->dma);
279 release_dma_lock(flags);
281 async->events |= COMEDI_CB_BLOCK;
283 comedi_event(dev, s);
285 /* clear interrupt */
286 outw(0x00, dev->iobase + DMA_TC_CLEAR_REG);
291 static int a2150_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
293 struct a2150_private *devpriv = dev->private;
295 /* disable dma on card */
296 devpriv->irq_dma_bits &= ~DMA_INTR_EN_BIT & ~DMA_EN_BIT;
297 outw(devpriv->irq_dma_bits, dev->iobase + IRQ_DMA_CNTRL_REG);
299 /* disable computer's dma */
300 disable_dma(devpriv->dma);
302 /* clear fifo and reset triggering circuitry */
303 outw(0, dev->iobase + FIFO_RESET_REG);
308 static int a2150_ai_cmdtest(struct comedi_device *dev,
309 struct comedi_subdevice *s, struct comedi_cmd *cmd)
311 const struct a2150_board *thisboard = comedi_board(dev);
317 /* Step 1 : check if triggers are trivially valid */
319 err |= cfc_check_trigger_src(&cmd->start_src, TRIG_NOW | TRIG_EXT);
320 err |= cfc_check_trigger_src(&cmd->scan_begin_src, TRIG_TIMER);
321 err |= cfc_check_trigger_src(&cmd->convert_src, TRIG_NOW);
322 err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
323 err |= cfc_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE);
328 /* Step 2a : make sure trigger sources are unique */
330 err |= cfc_check_trigger_is_unique(cmd->start_src);
331 err |= cfc_check_trigger_is_unique(cmd->stop_src);
333 /* Step 2b : and mutually compatible */
338 /* Step 3: check if arguments are trivially valid */
340 err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0);
342 if (cmd->convert_src == TRIG_TIMER)
343 err |= cfc_check_trigger_arg_min(&cmd->convert_arg,
344 thisboard->ai_speed);
346 err |= cfc_check_trigger_arg_min(&cmd->chanlist_len, 1);
347 err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len);
349 if (cmd->stop_src == TRIG_COUNT)
350 err |= cfc_check_trigger_arg_min(&cmd->stop_arg, 1);
352 err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0);
357 /* step 4: fix up any arguments */
359 if (cmd->scan_begin_src == TRIG_TIMER) {
360 tmp = cmd->scan_begin_arg;
361 a2150_get_timing(dev, &cmd->scan_begin_arg, cmd->flags);
362 if (tmp != cmd->scan_begin_arg)
369 /* check channel/gain list against card's limitations */
371 startChan = CR_CHAN(cmd->chanlist[0]);
372 for (i = 1; i < cmd->chanlist_len; i++) {
373 if (CR_CHAN(cmd->chanlist[i]) != (startChan + i)) {
375 "entries in chanlist must be consecutive channels, counting upwards\n");
379 if (cmd->chanlist_len == 2 && CR_CHAN(cmd->chanlist[0]) == 1) {
381 "length 2 chanlist must be channels 0,1 or channels 2,3");
384 if (cmd->chanlist_len == 3) {
386 "chanlist must have 1,2 or 4 channels");
389 if (CR_AREF(cmd->chanlist[0]) != CR_AREF(cmd->chanlist[1]) ||
390 CR_AREF(cmd->chanlist[2]) != CR_AREF(cmd->chanlist[3])) {
392 "channels 0/1 and 2/3 must have the same analog reference");
403 static int a2150_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
405 struct a2150_private *devpriv = dev->private;
406 struct comedi_async *async = s->async;
407 struct comedi_cmd *cmd = &async->cmd;
408 unsigned long lock_flags;
409 unsigned int old_config_bits = devpriv->config_bits;
410 unsigned int trigger_bits;
412 if (!dev->irq || !devpriv->dma) {
414 " irq and dma required, cannot do hardware conversions");
417 if (cmd->flags & TRIG_RT) {
419 " dma incompatible with hard real-time interrupt (TRIG_RT), aborting");
422 /* clear fifo and reset triggering circuitry */
423 outw(0, dev->iobase + FIFO_RESET_REG);
426 if (a2150_set_chanlist(dev, CR_CHAN(cmd->chanlist[0]),
427 cmd->chanlist_len) < 0)
430 /* setup ac/dc coupling */
431 if (CR_AREF(cmd->chanlist[0]) == AREF_OTHER)
432 devpriv->config_bits |= AC0_BIT;
434 devpriv->config_bits &= ~AC0_BIT;
435 if (CR_AREF(cmd->chanlist[2]) == AREF_OTHER)
436 devpriv->config_bits |= AC1_BIT;
438 devpriv->config_bits &= ~AC1_BIT;
441 a2150_get_timing(dev, &cmd->scan_begin_arg, cmd->flags);
443 /* send timing, channel, config bits */
444 outw(devpriv->config_bits, dev->iobase + CONFIG_REG);
446 /* initialize number of samples remaining */
447 devpriv->count = cmd->stop_arg * cmd->chanlist_len;
449 /* enable computer's dma */
450 lock_flags = claim_dma_lock();
451 disable_dma(devpriv->dma);
452 /* clear flip-flop to make sure 2-byte registers for
453 * count and address get set correctly */
454 clear_dma_ff(devpriv->dma);
455 set_dma_addr(devpriv->dma, virt_to_bus(devpriv->dma_buffer));
456 /* set size of transfer to fill in 1/3 second */
457 #define ONE_THIRD_SECOND 333333333
458 devpriv->dma_transfer_size =
459 sizeof(devpriv->dma_buffer[0]) * cmd->chanlist_len *
460 ONE_THIRD_SECOND / cmd->scan_begin_arg;
461 if (devpriv->dma_transfer_size > A2150_DMA_BUFFER_SIZE)
462 devpriv->dma_transfer_size = A2150_DMA_BUFFER_SIZE;
463 if (devpriv->dma_transfer_size < sizeof(devpriv->dma_buffer[0]))
464 devpriv->dma_transfer_size = sizeof(devpriv->dma_buffer[0]);
465 devpriv->dma_transfer_size -=
466 devpriv->dma_transfer_size % sizeof(devpriv->dma_buffer[0]);
467 set_dma_count(devpriv->dma, devpriv->dma_transfer_size);
468 enable_dma(devpriv->dma);
469 release_dma_lock(lock_flags);
471 /* clear dma interrupt before enabling it, to try and get rid of that
472 * one spurious interrupt that has been happening */
473 outw(0x00, dev->iobase + DMA_TC_CLEAR_REG);
475 /* enable 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);
479 /* may need to wait 72 sampling periods if timing was changed */
480 i8254_load(dev->iobase + I8253_BASE_REG, 0, 2, 72, 0);
482 /* setup start triggering */
484 /* decide if we need to wait 72 periods for valid data */
485 if (cmd->start_src == TRIG_NOW &&
486 (old_config_bits & CLOCK_MASK) !=
487 (devpriv->config_bits & CLOCK_MASK)) {
488 /* set trigger source to delay trigger */
489 trigger_bits |= DELAY_TRIGGER_BITS;
491 /* otherwise no delay */
492 trigger_bits |= POST_TRIGGER_BITS;
494 /* enable external hardware trigger */
495 if (cmd->start_src == TRIG_EXT) {
496 trigger_bits |= HW_TRIG_EN;
497 } else if (cmd->start_src == TRIG_OTHER) {
498 /* XXX add support for level/slope start trigger using TRIG_OTHER */
499 comedi_error(dev, "you shouldn't see this?");
501 /* send trigger config bits */
502 outw(trigger_bits, dev->iobase + TRIGGER_REG);
504 /* start acquisition for soft trigger */
505 if (cmd->start_src == TRIG_NOW)
506 outw(0, dev->iobase + FIFO_START_REG);
514 static int a2150_ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
515 struct comedi_insn *insn, unsigned int *data)
517 struct a2150_private *devpriv = dev->private;
519 static const int timeout = 100000;
520 static const int filter_delay = 36;
522 /* clear fifo and reset triggering circuitry */
523 outw(0, dev->iobase + FIFO_RESET_REG);
526 if (a2150_set_chanlist(dev, CR_CHAN(insn->chanspec), 1) < 0)
529 /* set dc coupling */
530 devpriv->config_bits &= ~AC0_BIT;
531 devpriv->config_bits &= ~AC1_BIT;
533 /* send timing, channel, config bits */
534 outw(devpriv->config_bits, dev->iobase + CONFIG_REG);
536 /* disable dma on card */
537 devpriv->irq_dma_bits &= ~DMA_INTR_EN_BIT & ~DMA_EN_BIT;
538 outw(devpriv->irq_dma_bits, dev->iobase + IRQ_DMA_CNTRL_REG);
540 /* setup start triggering */
541 outw(0, dev->iobase + TRIGGER_REG);
543 /* start acquisition for soft trigger */
544 outw(0, dev->iobase + FIFO_START_REG);
547 * there is a 35.6 sample delay for data to get through the
550 for (n = 0; n < filter_delay; n++) {
551 for (i = 0; i < timeout; i++) {
552 if (inw(dev->iobase + STATUS_REG) & FNE_BIT)
557 comedi_error(dev, "timeout");
560 inw(dev->iobase + FIFO_DATA_REG);
564 for (n = 0; n < insn->n; n++) {
565 for (i = 0; i < timeout; i++) {
566 if (inw(dev->iobase + STATUS_REG) & FNE_BIT)
571 comedi_error(dev, "timeout");
577 data[n] = inw(dev->iobase + FIFO_DATA_REG);
579 printk(" data is %i\n", data[n]);
584 /* clear fifo and reset triggering circuitry */
585 outw(0, dev->iobase + FIFO_RESET_REG);
591 * sets bits in devpriv->clock_bits to nearest approximation of requested
592 * period, adjusts requested period to actual timing.
594 static int a2150_get_timing(struct comedi_device *dev, unsigned int *period,
597 const struct a2150_board *thisboard = comedi_board(dev);
598 struct a2150_private *devpriv = dev->private;
600 int lub_divisor_shift, lub_index, glb_divisor_shift, glb_index;
603 /* initialize greatest lower and least upper bounds */
604 lub_divisor_shift = 3;
606 lub = thisboard->clock[lub_index] * (1 << lub_divisor_shift);
607 glb_divisor_shift = 0;
608 glb_index = thisboard->num_clocks - 1;
609 glb = thisboard->clock[glb_index] * (1 << glb_divisor_shift);
611 /* make sure period is in available range */
617 /* we can multiply period by 1, 2, 4, or 8, using (1 << i) */
618 for (i = 0; i < 4; i++) {
619 /* there are a maximum of 4 master clocks */
620 for (j = 0; j < thisboard->num_clocks; j++) {
621 /* temp is the period in nanosec we are evaluating */
622 temp = thisboard->clock[j] * (1 << i);
623 /* if it is the best match yet */
624 if (temp < lub && temp >= *period) {
625 lub_divisor_shift = i;
629 if (temp > glb && temp <= *period) {
630 glb_divisor_shift = i;
636 flags &= TRIG_ROUND_MASK;
638 case TRIG_ROUND_NEAREST:
640 /* if least upper bound is better approximation */
641 if (lub - *period < *period - glb)
649 case TRIG_ROUND_DOWN:
654 /* set clock bits for config register appropriately */
655 devpriv->config_bits &= ~CLOCK_MASK;
656 if (*period == lub) {
657 devpriv->config_bits |=
658 CLOCK_SELECT_BITS(lub_index) |
659 CLOCK_DIVISOR_BITS(lub_divisor_shift);
661 devpriv->config_bits |=
662 CLOCK_SELECT_BITS(glb_index) |
663 CLOCK_DIVISOR_BITS(glb_divisor_shift);
669 static int a2150_set_chanlist(struct comedi_device *dev,
670 unsigned int start_channel,
671 unsigned int num_channels)
673 struct a2150_private *devpriv = dev->private;
675 if (start_channel + num_channels > 4)
678 devpriv->config_bits &= ~CHANNEL_MASK;
680 switch (num_channels) {
682 devpriv->config_bits |= CHANNEL_BITS(0x4 | start_channel);
685 if (start_channel == 0) {
686 devpriv->config_bits |= CHANNEL_BITS(0x2);
687 } else if (start_channel == 2) {
688 devpriv->config_bits |= CHANNEL_BITS(0x3);
694 devpriv->config_bits |= CHANNEL_BITS(0x1);
704 /* probes board type, returns offset */
705 static int a2150_probe(struct comedi_device *dev)
707 int status = inw(dev->iobase + STATUS_REG);
708 return ID_BITS(status);
711 static int a2150_attach(struct comedi_device *dev, struct comedi_devconfig *it)
713 const struct a2150_board *thisboard = comedi_board(dev);
714 struct a2150_private *devpriv;
715 struct comedi_subdevice *s;
716 unsigned int irq = it->options[1];
717 unsigned int dma = it->options[2];
718 static const int timeout = 2000;
722 devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL);
725 dev->private = devpriv;
727 ret = comedi_request_region(dev, it->options[0], A2150_SIZE);
733 /* check that irq is supported */
734 if (irq < 3 || irq == 8 || irq == 13 || irq > 15) {
735 printk(" invalid irq line %u\n", irq);
738 if (request_irq(irq, a2150_interrupt, 0,
739 dev->driver->driver_name, dev)) {
740 printk("unable to allocate irq %u\n", irq);
743 devpriv->irq_dma_bits |= IRQ_LVL_BITS(irq);
748 if (dma == 4 || dma > 7) {
749 printk(" invalid dma channel %u\n", dma);
752 if (request_dma(dma, dev->driver->driver_name)) {
753 printk(" failed to allocate dma channel %u\n", dma);
757 devpriv->dma_buffer =
758 kmalloc(A2150_DMA_BUFFER_SIZE, GFP_KERNEL | GFP_DMA);
759 if (devpriv->dma_buffer == NULL)
763 set_dma_mode(dma, DMA_MODE_READ);
765 devpriv->irq_dma_bits |= DMA_CHAN_BITS(dma);
768 dev->board_ptr = a2150_boards + a2150_probe(dev);
769 thisboard = comedi_board(dev);
770 dev->board_name = thisboard->name;
772 ret = comedi_alloc_subdevices(dev, 1);
776 /* analog input subdevice */
777 s = &dev->subdevices[0];
778 dev->read_subdev = s;
779 s->type = COMEDI_SUBD_AI;
780 s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_OTHER | SDF_CMD_READ;
784 s->range_table = &range_a2150;
785 s->do_cmd = a2150_ai_cmd;
786 s->do_cmdtest = a2150_ai_cmdtest;
787 s->insn_read = a2150_ai_rinsn;
788 s->cancel = a2150_cancel;
790 /* need to do this for software counting of completed conversions, to
791 * prevent hardware count from stopping acquisition */
792 outw(HW_COUNT_DISABLE, dev->iobase + I8253_MODE_REG);
794 /* set card's irq and dma levels */
795 outw(devpriv->irq_dma_bits, dev->iobase + IRQ_DMA_CNTRL_REG);
797 /* reset and sync adc clock circuitry */
798 outw_p(DPD_BIT | APD_BIT, dev->iobase + CONFIG_REG);
799 outw_p(DPD_BIT, dev->iobase + CONFIG_REG);
800 /* initialize configuration register */
801 devpriv->config_bits = 0;
802 outw(devpriv->config_bits, dev->iobase + CONFIG_REG);
803 /* wait until offset calibration is done, then enable analog inputs */
804 for (i = 0; i < timeout; i++) {
805 if ((DCAL_BIT & inw(dev->iobase + STATUS_REG)) == 0)
811 (" timed out waiting for offset calibration to complete\n");
814 devpriv->config_bits |= ENABLE0_BIT | ENABLE1_BIT;
815 outw(devpriv->config_bits, dev->iobase + CONFIG_REG);
820 static void a2150_detach(struct comedi_device *dev)
822 struct a2150_private *devpriv = dev->private;
825 outw(APD_BIT | DPD_BIT, dev->iobase + CONFIG_REG);
828 free_dma(devpriv->dma);
829 kfree(devpriv->dma_buffer);
831 comedi_legacy_detach(dev);
834 static struct comedi_driver ni_at_a2150_driver = {
835 .driver_name = "ni_at_a2150",
836 .module = THIS_MODULE,
837 .attach = a2150_attach,
838 .detach = a2150_detach,
840 module_comedi_driver(ni_at_a2150_driver);
842 MODULE_AUTHOR("Comedi http://www.comedi.org");
843 MODULE_DESCRIPTION("Comedi low-level driver");
844 MODULE_LICENSE("GPL");