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 <linux/interrupt.h>
68 #include <linux/slab.h>
69 #include "../comedidev.h"
71 #include <linux/ioport.h>
76 #include "comedi_fc.h"
79 #define A2150_DMA_BUFFER_SIZE 0xff00 /* size in bytes of dma buffer */
81 /* #define A2150_DEBUG enable debugging code */
82 #undef A2150_DEBUG /* disable debugging code */
84 /* Registers and bits */
85 #define CONFIG_REG 0x0
86 #define CHANNEL_BITS(x) ((x) & 0x7)
87 #define CHANNEL_MASK 0x7
88 #define CLOCK_SELECT_BITS(x) (((x) & 0x3) << 3)
89 #define CLOCK_DIVISOR_BITS(x) (((x) & 0x3) << 5)
90 #define CLOCK_MASK (0xf << 3)
91 #define ENABLE0_BIT 0x80 /* enable (don't internally ground) channels 0 and 1 */
92 #define ENABLE1_BIT 0x100 /* enable (don't internally ground) channels 2 and 3 */
93 #define AC0_BIT 0x200 /* ac couple channels 0,1 */
94 #define AC1_BIT 0x400 /* ac couple channels 2,3 */
95 #define APD_BIT 0x800 /* analog power down */
96 #define DPD_BIT 0x1000 /* digital power down */
97 #define TRIGGER_REG 0x2 /* trigger config register */
98 #define POST_TRIGGER_BITS 0x2
99 #define DELAY_TRIGGER_BITS 0x3
100 #define HW_TRIG_EN 0x10 /* enable hardware trigger */
101 #define FIFO_START_REG 0x6 /* software start aquistion trigger */
102 #define FIFO_RESET_REG 0x8 /* clears fifo + fifo flags */
103 #define FIFO_DATA_REG 0xa /* read data */
104 #define DMA_TC_CLEAR_REG 0xe /* clear dma terminal count interrupt */
105 #define STATUS_REG 0x12 /* read only */
106 #define FNE_BIT 0x1 /* fifo not empty */
107 #define OVFL_BIT 0x8 /* fifo overflow */
108 #define EDAQ_BIT 0x10 /* end of acquisition interrupt */
109 #define DCAL_BIT 0x20 /* offset calibration in progress */
110 #define INTR_BIT 0x40 /* interrupt has occurred */
111 #define DMA_TC_BIT 0x80 /* dma terminal count interrupt has occurred */
112 #define ID_BITS(x) (((x) >> 8) & 0x3)
113 #define IRQ_DMA_CNTRL_REG 0x12 /* write only */
114 #define DMA_CHAN_BITS(x) ((x) & 0x7) /* sets dma channel */
115 #define DMA_EN_BIT 0x8 /* enables dma */
116 #define IRQ_LVL_BITS(x) (((x) & 0xf) << 4) /* sets irq level */
117 #define FIFO_INTR_EN_BIT 0x100 /* enable fifo interrupts */
118 #define FIFO_INTR_FHF_BIT 0x200 /* interrupt fifo half full */
119 #define DMA_INTR_EN_BIT 0x800 /* enable interrupt on dma terminal count */
120 #define DMA_DEM_EN_BIT 0x1000 /* enables demand mode dma */
121 #define I8253_BASE_REG 0x14
122 #define I8253_MODE_REG 0x17
123 #define HW_COUNT_DISABLE 0x30 /* disable hardware counting of conversions */
127 int clock[4]; /* master clock periods, in nanoseconds */
128 int num_clocks; /* number of available master clock speeds */
129 int ai_speed; /* maximum conversion rate in nanoseconds */
132 /* analog input range */
133 static const struct comedi_lrange range_a2150 = {
136 RANGE(-2.828, 2.828),
140 /* enum must match board indices */
141 enum { a2150_c, a2150_s };
142 static const struct a2150_board a2150_boards[] = {
145 .clock = {31250, 22676, 20833, 19531},
151 .clock = {62500, 50000, 41667, 0},
158 * Useful for shorthand access to the particular board structure
160 #define thisboard ((const struct a2150_board *)dev->board_ptr)
162 struct a2150_private {
164 volatile unsigned int count; /* number of data points left to be taken */
165 unsigned int dma; /* dma channel */
166 s16 *dma_buffer; /* dma buffer */
167 unsigned int dma_transfer_size; /* size in bytes of dma transfers */
168 int irq_dma_bits; /* irq/dma register bits */
169 int config_bits; /* config register bits */
172 #define devpriv ((struct a2150_private *)dev->private)
174 static int a2150_cancel(struct comedi_device *dev, struct comedi_subdevice *s);
176 static int a2150_get_timing(struct comedi_device *dev, unsigned int *period,
178 static int a2150_set_chanlist(struct comedi_device *dev,
179 unsigned int start_channel,
180 unsigned int num_channels);
183 static void ni_dump_regs(struct comedi_device *dev)
185 printk("config bits 0x%x\n", devpriv->config_bits);
186 printk("irq dma bits 0x%x\n", devpriv->irq_dma_bits);
187 printk("status bits 0x%x\n", inw(dev->iobase + STATUS_REG));
192 /* interrupt service routine */
193 static irqreturn_t a2150_interrupt(int irq, void *d)
198 struct comedi_device *dev = d;
199 struct comedi_subdevice *s = dev->read_subdev;
200 struct comedi_async *async;
201 struct comedi_cmd *cmd;
202 unsigned int max_points, num_points, residue, leftover;
204 static const int sample_size = sizeof(devpriv->dma_buffer[0]);
206 if (dev->attached == 0) {
207 comedi_error(dev, "premature interrupt");
210 /* initialize async here to make sure s is not NULL */
215 status = inw(dev->iobase + STATUS_REG);
217 if ((status & INTR_BIT) == 0) {
218 comedi_error(dev, "spurious interrupt");
222 if (status & OVFL_BIT) {
223 comedi_error(dev, "fifo overflow");
224 a2150_cancel(dev, s);
225 async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
228 if ((status & DMA_TC_BIT) == 0) {
229 comedi_error(dev, "caught non-dma interrupt? Aborting.");
230 a2150_cancel(dev, s);
231 async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
232 comedi_event(dev, s);
236 flags = claim_dma_lock();
237 disable_dma(devpriv->dma);
238 /* clear flip-flop to make sure 2-byte registers for
239 * count and address get set correctly */
240 clear_dma_ff(devpriv->dma);
242 /* figure out how many points to read */
243 max_points = devpriv->dma_transfer_size / sample_size;
244 /* residue is the number of points left to be done on the dma
245 * transfer. It should always be zero at this point unless
246 * the stop_src is set to external triggering.
248 residue = get_dma_residue(devpriv->dma) / sample_size;
249 num_points = max_points - residue;
250 if (devpriv->count < num_points && cmd->stop_src == TRIG_COUNT)
251 num_points = devpriv->count;
253 /* figure out how many points will be stored next time */
255 if (cmd->stop_src == TRIG_NONE) {
256 leftover = devpriv->dma_transfer_size / sample_size;
257 } else if (devpriv->count > max_points) {
258 leftover = devpriv->count - max_points;
259 if (leftover > max_points)
260 leftover = max_points;
262 /* there should only be a residue if collection was stopped by having
263 * the stop_src set to an external trigger, in which case there
264 * will be no more data
269 for (i = 0; i < num_points; i++) {
270 /* write data point to comedi buffer */
271 dpnt = devpriv->dma_buffer[i];
272 /* convert from 2's complement to unsigned coding */
274 cfc_write_to_buffer(s, dpnt);
275 if (cmd->stop_src == TRIG_COUNT) {
276 if (--devpriv->count == 0) { /* end of acquisition */
277 a2150_cancel(dev, s);
278 async->events |= COMEDI_CB_EOA;
285 set_dma_addr(devpriv->dma, virt_to_bus(devpriv->dma_buffer));
286 set_dma_count(devpriv->dma, leftover * sample_size);
287 enable_dma(devpriv->dma);
289 release_dma_lock(flags);
291 async->events |= COMEDI_CB_BLOCK;
293 comedi_event(dev, s);
295 /* clear interrupt */
296 outw(0x00, dev->iobase + DMA_TC_CLEAR_REG);
301 static int a2150_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
303 /* disable dma on card */
304 devpriv->irq_dma_bits &= ~DMA_INTR_EN_BIT & ~DMA_EN_BIT;
305 outw(devpriv->irq_dma_bits, dev->iobase + IRQ_DMA_CNTRL_REG);
307 /* disable computer's dma */
308 disable_dma(devpriv->dma);
310 /* clear fifo and reset triggering circuitry */
311 outw(0, dev->iobase + FIFO_RESET_REG);
316 static int a2150_ai_cmdtest(struct comedi_device *dev,
317 struct comedi_subdevice *s, struct comedi_cmd *cmd)
324 /* step 1: make sure trigger sources are trivially valid */
326 tmp = cmd->start_src;
327 cmd->start_src &= TRIG_NOW | TRIG_EXT;
328 if (!cmd->start_src || tmp != cmd->start_src)
331 tmp = cmd->scan_begin_src;
332 cmd->scan_begin_src &= TRIG_TIMER;
333 if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
336 tmp = cmd->convert_src;
337 cmd->convert_src &= TRIG_NOW;
338 if (!cmd->convert_src || tmp != cmd->convert_src)
341 tmp = cmd->scan_end_src;
342 cmd->scan_end_src &= TRIG_COUNT;
343 if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
347 cmd->stop_src &= TRIG_COUNT | TRIG_NONE;
348 if (!cmd->stop_src || tmp != cmd->stop_src)
355 * step 2: make sure trigger sources are unique and mutually
359 if (cmd->start_src != TRIG_NOW && cmd->start_src != TRIG_EXT)
361 if (cmd->stop_src != TRIG_COUNT && cmd->stop_src != TRIG_NONE)
367 /* step 3: make sure arguments are trivially compatible */
369 if (cmd->start_arg != 0) {
373 if (cmd->convert_src == TRIG_TIMER) {
374 if (cmd->convert_arg < thisboard->ai_speed) {
375 cmd->convert_arg = thisboard->ai_speed;
379 if (!cmd->chanlist_len) {
380 cmd->chanlist_len = 1;
383 if (cmd->scan_end_arg != cmd->chanlist_len) {
384 cmd->scan_end_arg = cmd->chanlist_len;
387 if (cmd->stop_src == TRIG_COUNT) {
388 if (!cmd->stop_arg) {
392 } else { /* TRIG_NONE */
393 if (cmd->stop_arg != 0) {
402 /* step 4: fix up any arguments */
404 if (cmd->scan_begin_src == TRIG_TIMER) {
405 tmp = cmd->scan_begin_arg;
406 a2150_get_timing(dev, &cmd->scan_begin_arg, cmd->flags);
407 if (tmp != cmd->scan_begin_arg)
414 /* check channel/gain list against card's limitations */
416 startChan = CR_CHAN(cmd->chanlist[0]);
417 for (i = 1; i < cmd->chanlist_len; i++) {
418 if (CR_CHAN(cmd->chanlist[i]) != (startChan + i)) {
420 "entries in chanlist must be consecutive channels, counting upwards\n");
424 if (cmd->chanlist_len == 2 && CR_CHAN(cmd->chanlist[0]) == 1) {
426 "length 2 chanlist must be channels 0,1 or channels 2,3");
429 if (cmd->chanlist_len == 3) {
431 "chanlist must have 1,2 or 4 channels");
434 if (CR_AREF(cmd->chanlist[0]) != CR_AREF(cmd->chanlist[1]) ||
435 CR_AREF(cmd->chanlist[2]) != CR_AREF(cmd->chanlist[3])) {
437 "channels 0/1 and 2/3 must have the same analog reference");
448 static int a2150_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
450 struct comedi_async *async = s->async;
451 struct comedi_cmd *cmd = &async->cmd;
452 unsigned long lock_flags;
453 unsigned int old_config_bits = devpriv->config_bits;
454 unsigned int trigger_bits;
456 if (!dev->irq || !devpriv->dma) {
458 " irq and dma required, cannot do hardware conversions");
461 if (cmd->flags & TRIG_RT) {
463 " dma incompatible with hard real-time interrupt (TRIG_RT), aborting");
466 /* clear fifo and reset triggering circuitry */
467 outw(0, dev->iobase + FIFO_RESET_REG);
470 if (a2150_set_chanlist(dev, CR_CHAN(cmd->chanlist[0]),
471 cmd->chanlist_len) < 0)
474 /* setup ac/dc coupling */
475 if (CR_AREF(cmd->chanlist[0]) == AREF_OTHER)
476 devpriv->config_bits |= AC0_BIT;
478 devpriv->config_bits &= ~AC0_BIT;
479 if (CR_AREF(cmd->chanlist[2]) == AREF_OTHER)
480 devpriv->config_bits |= AC1_BIT;
482 devpriv->config_bits &= ~AC1_BIT;
485 a2150_get_timing(dev, &cmd->scan_begin_arg, cmd->flags);
487 /* send timing, channel, config bits */
488 outw(devpriv->config_bits, dev->iobase + CONFIG_REG);
490 /* initialize number of samples remaining */
491 devpriv->count = cmd->stop_arg * cmd->chanlist_len;
493 /* enable computer's dma */
494 lock_flags = claim_dma_lock();
495 disable_dma(devpriv->dma);
496 /* clear flip-flop to make sure 2-byte registers for
497 * count and address get set correctly */
498 clear_dma_ff(devpriv->dma);
499 set_dma_addr(devpriv->dma, virt_to_bus(devpriv->dma_buffer));
500 /* set size of transfer to fill in 1/3 second */
501 #define ONE_THIRD_SECOND 333333333
502 devpriv->dma_transfer_size =
503 sizeof(devpriv->dma_buffer[0]) * cmd->chanlist_len *
504 ONE_THIRD_SECOND / cmd->scan_begin_arg;
505 if (devpriv->dma_transfer_size > A2150_DMA_BUFFER_SIZE)
506 devpriv->dma_transfer_size = A2150_DMA_BUFFER_SIZE;
507 if (devpriv->dma_transfer_size < sizeof(devpriv->dma_buffer[0]))
508 devpriv->dma_transfer_size = sizeof(devpriv->dma_buffer[0]);
509 devpriv->dma_transfer_size -=
510 devpriv->dma_transfer_size % sizeof(devpriv->dma_buffer[0]);
511 set_dma_count(devpriv->dma, devpriv->dma_transfer_size);
512 enable_dma(devpriv->dma);
513 release_dma_lock(lock_flags);
515 /* clear dma interrupt before enabling it, to try and get rid of that
516 * one spurious interrupt that has been happening */
517 outw(0x00, dev->iobase + DMA_TC_CLEAR_REG);
519 /* enable dma on card */
520 devpriv->irq_dma_bits |= DMA_INTR_EN_BIT | DMA_EN_BIT;
521 outw(devpriv->irq_dma_bits, dev->iobase + IRQ_DMA_CNTRL_REG);
523 /* may need to wait 72 sampling periods if timing was changed */
524 i8254_load(dev->iobase + I8253_BASE_REG, 0, 2, 72, 0);
526 /* setup start triggering */
528 /* decide if we need to wait 72 periods for valid data */
529 if (cmd->start_src == TRIG_NOW &&
530 (old_config_bits & CLOCK_MASK) !=
531 (devpriv->config_bits & CLOCK_MASK)) {
532 /* set trigger source to delay trigger */
533 trigger_bits |= DELAY_TRIGGER_BITS;
535 /* otherwise no delay */
536 trigger_bits |= POST_TRIGGER_BITS;
538 /* enable external hardware trigger */
539 if (cmd->start_src == TRIG_EXT) {
540 trigger_bits |= HW_TRIG_EN;
541 } else if (cmd->start_src == TRIG_OTHER) {
542 /* XXX add support for level/slope start trigger using TRIG_OTHER */
543 comedi_error(dev, "you shouldn't see this?");
545 /* send trigger config bits */
546 outw(trigger_bits, dev->iobase + TRIGGER_REG);
548 /* start acquisition for soft trigger */
549 if (cmd->start_src == TRIG_NOW)
550 outw(0, dev->iobase + FIFO_START_REG);
558 static int a2150_ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
559 struct comedi_insn *insn, unsigned int *data)
562 static const int timeout = 100000;
563 static const int filter_delay = 36;
565 /* clear fifo and reset triggering circuitry */
566 outw(0, dev->iobase + FIFO_RESET_REG);
569 if (a2150_set_chanlist(dev, CR_CHAN(insn->chanspec), 1) < 0)
572 /* set dc coupling */
573 devpriv->config_bits &= ~AC0_BIT;
574 devpriv->config_bits &= ~AC1_BIT;
576 /* send timing, channel, config bits */
577 outw(devpriv->config_bits, dev->iobase + CONFIG_REG);
579 /* disable dma on card */
580 devpriv->irq_dma_bits &= ~DMA_INTR_EN_BIT & ~DMA_EN_BIT;
581 outw(devpriv->irq_dma_bits, dev->iobase + IRQ_DMA_CNTRL_REG);
583 /* setup start triggering */
584 outw(0, dev->iobase + TRIGGER_REG);
586 /* start acquisition for soft trigger */
587 outw(0, dev->iobase + FIFO_START_REG);
590 * there is a 35.6 sample delay for data to get through the
593 for (n = 0; n < filter_delay; n++) {
594 for (i = 0; i < timeout; i++) {
595 if (inw(dev->iobase + STATUS_REG) & FNE_BIT)
600 comedi_error(dev, "timeout");
603 inw(dev->iobase + FIFO_DATA_REG);
607 for (n = 0; n < insn->n; n++) {
608 for (i = 0; i < timeout; i++) {
609 if (inw(dev->iobase + STATUS_REG) & FNE_BIT)
614 comedi_error(dev, "timeout");
620 data[n] = inw(dev->iobase + FIFO_DATA_REG);
622 printk(" data is %i\n", data[n]);
627 /* clear fifo and reset triggering circuitry */
628 outw(0, dev->iobase + FIFO_RESET_REG);
634 * sets bits in devpriv->clock_bits to nearest approximation of requested
635 * period, adjusts requested period to actual timing.
637 static int a2150_get_timing(struct comedi_device *dev, unsigned int *period,
641 int lub_divisor_shift, lub_index, glb_divisor_shift, glb_index;
644 /* initialize greatest lower and least upper bounds */
645 lub_divisor_shift = 3;
647 lub = thisboard->clock[lub_index] * (1 << lub_divisor_shift);
648 glb_divisor_shift = 0;
649 glb_index = thisboard->num_clocks - 1;
650 glb = thisboard->clock[glb_index] * (1 << glb_divisor_shift);
652 /* make sure period is in available range */
658 /* we can multiply period by 1, 2, 4, or 8, using (1 << i) */
659 for (i = 0; i < 4; i++) {
660 /* there are a maximum of 4 master clocks */
661 for (j = 0; j < thisboard->num_clocks; j++) {
662 /* temp is the period in nanosec we are evaluating */
663 temp = thisboard->clock[j] * (1 << i);
664 /* if it is the best match yet */
665 if (temp < lub && temp >= *period) {
666 lub_divisor_shift = i;
670 if (temp > glb && temp <= *period) {
671 glb_divisor_shift = i;
677 flags &= TRIG_ROUND_MASK;
679 case TRIG_ROUND_NEAREST:
681 /* if least upper bound is better approximation */
682 if (lub - *period < *period - glb)
690 case TRIG_ROUND_DOWN:
695 /* set clock bits for config register appropriately */
696 devpriv->config_bits &= ~CLOCK_MASK;
697 if (*period == lub) {
698 devpriv->config_bits |=
699 CLOCK_SELECT_BITS(lub_index) |
700 CLOCK_DIVISOR_BITS(lub_divisor_shift);
702 devpriv->config_bits |=
703 CLOCK_SELECT_BITS(glb_index) |
704 CLOCK_DIVISOR_BITS(glb_divisor_shift);
710 static int a2150_set_chanlist(struct comedi_device *dev,
711 unsigned int start_channel,
712 unsigned int num_channels)
714 if (start_channel + num_channels > 4)
717 devpriv->config_bits &= ~CHANNEL_MASK;
719 switch (num_channels) {
721 devpriv->config_bits |= CHANNEL_BITS(0x4 | start_channel);
724 if (start_channel == 0) {
725 devpriv->config_bits |= CHANNEL_BITS(0x2);
726 } else if (start_channel == 2) {
727 devpriv->config_bits |= CHANNEL_BITS(0x3);
733 devpriv->config_bits |= CHANNEL_BITS(0x1);
743 /* probes board type, returns offset */
744 static int a2150_probe(struct comedi_device *dev)
746 int status = inw(dev->iobase + STATUS_REG);
747 return ID_BITS(status);
750 static int a2150_attach(struct comedi_device *dev, struct comedi_devconfig *it)
752 struct comedi_subdevice *s;
753 unsigned long iobase = it->options[0];
754 unsigned int irq = it->options[1];
755 unsigned int dma = it->options[2];
756 static const int timeout = 2000;
760 printk("comedi%d: %s: io 0x%lx", dev->minor, dev->driver->driver_name,
763 printk(", irq %u", irq);
768 printk(", dma %u", dma);
774 /* allocate and initialize dev->private */
775 if (alloc_private(dev, sizeof(struct a2150_private)) < 0)
779 printk(" io base address required\n");
783 /* check if io addresses are available */
784 if (!request_region(iobase, A2150_SIZE, dev->driver->driver_name)) {
785 printk(" I/O port conflict\n");
788 dev->iobase = iobase;
792 /* check that irq is supported */
793 if (irq < 3 || irq == 8 || irq == 13 || irq > 15) {
794 printk(" invalid irq line %u\n", irq);
797 if (request_irq(irq, a2150_interrupt, 0,
798 dev->driver->driver_name, dev)) {
799 printk("unable to allocate irq %u\n", irq);
802 devpriv->irq_dma_bits |= IRQ_LVL_BITS(irq);
807 if (dma == 4 || dma > 7) {
808 printk(" invalid dma channel %u\n", dma);
811 if (request_dma(dma, dev->driver->driver_name)) {
812 printk(" failed to allocate dma channel %u\n", dma);
816 devpriv->dma_buffer =
817 kmalloc(A2150_DMA_BUFFER_SIZE, GFP_KERNEL | GFP_DMA);
818 if (devpriv->dma_buffer == NULL)
822 set_dma_mode(dma, DMA_MODE_READ);
824 devpriv->irq_dma_bits |= DMA_CHAN_BITS(dma);
827 dev->board_ptr = a2150_boards + a2150_probe(dev);
828 dev->board_name = thisboard->name;
830 ret = comedi_alloc_subdevices(dev, 1);
834 /* analog input subdevice */
835 s = dev->subdevices + 0;
836 dev->read_subdev = s;
837 s->type = COMEDI_SUBD_AI;
838 s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_OTHER | SDF_CMD_READ;
842 s->range_table = &range_a2150;
843 s->do_cmd = a2150_ai_cmd;
844 s->do_cmdtest = a2150_ai_cmdtest;
845 s->insn_read = a2150_ai_rinsn;
846 s->cancel = a2150_cancel;
848 /* need to do this for software counting of completed conversions, to
849 * prevent hardware count from stopping acquisition */
850 outw(HW_COUNT_DISABLE, dev->iobase + I8253_MODE_REG);
852 /* set card's irq and dma levels */
853 outw(devpriv->irq_dma_bits, dev->iobase + IRQ_DMA_CNTRL_REG);
855 /* reset and sync adc clock circuitry */
856 outw_p(DPD_BIT | APD_BIT, dev->iobase + CONFIG_REG);
857 outw_p(DPD_BIT, dev->iobase + CONFIG_REG);
858 /* initialize configuration register */
859 devpriv->config_bits = 0;
860 outw(devpriv->config_bits, dev->iobase + CONFIG_REG);
861 /* wait until offset calibration is done, then enable analog inputs */
862 for (i = 0; i < timeout; i++) {
863 if ((DCAL_BIT & inw(dev->iobase + STATUS_REG)) == 0)
869 (" timed out waiting for offset calibration to complete\n");
872 devpriv->config_bits |= ENABLE0_BIT | ENABLE1_BIT;
873 outw(devpriv->config_bits, dev->iobase + CONFIG_REG);
878 static void a2150_detach(struct comedi_device *dev)
881 outw(APD_BIT | DPD_BIT, dev->iobase + CONFIG_REG);
882 release_region(dev->iobase, A2150_SIZE);
885 free_irq(dev->irq, dev);
888 free_dma(devpriv->dma);
889 kfree(devpriv->dma_buffer);
893 static struct comedi_driver ni_at_a2150_driver = {
894 .driver_name = "ni_at_a2150",
895 .module = THIS_MODULE,
896 .attach = a2150_attach,
897 .detach = a2150_detach,
899 module_comedi_driver(ni_at_a2150_driver);
901 MODULE_AUTHOR("Comedi http://www.comedi.org");
902 MODULE_DESCRIPTION("Comedi low-level driver");
903 MODULE_LICENSE("GPL");