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 static int a2150_cancel(struct comedi_device *dev, struct comedi_subdevice *s);
174 static int a2150_get_timing(struct comedi_device *dev, unsigned int *period,
176 static int a2150_set_chanlist(struct comedi_device *dev,
177 unsigned int start_channel,
178 unsigned int num_channels);
181 static void ni_dump_regs(struct comedi_device *dev)
183 struct a2150_private *devpriv = dev->private;
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 a2150_private *devpriv = dev->private;
200 struct comedi_subdevice *s = dev->read_subdev;
201 struct comedi_async *async;
202 struct comedi_cmd *cmd;
203 unsigned int max_points, num_points, residue, leftover;
205 static const int sample_size = sizeof(devpriv->dma_buffer[0]);
207 if (dev->attached == 0) {
208 comedi_error(dev, "premature interrupt");
211 /* initialize async here to make sure s is not NULL */
216 status = inw(dev->iobase + STATUS_REG);
218 if ((status & INTR_BIT) == 0) {
219 comedi_error(dev, "spurious interrupt");
223 if (status & OVFL_BIT) {
224 comedi_error(dev, "fifo overflow");
225 a2150_cancel(dev, s);
226 async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
229 if ((status & DMA_TC_BIT) == 0) {
230 comedi_error(dev, "caught non-dma interrupt? Aborting.");
231 a2150_cancel(dev, s);
232 async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
233 comedi_event(dev, s);
237 flags = claim_dma_lock();
238 disable_dma(devpriv->dma);
239 /* clear flip-flop to make sure 2-byte registers for
240 * count and address get set correctly */
241 clear_dma_ff(devpriv->dma);
243 /* figure out how many points to read */
244 max_points = devpriv->dma_transfer_size / sample_size;
245 /* residue is the number of points left to be done on the dma
246 * transfer. It should always be zero at this point unless
247 * the stop_src is set to external triggering.
249 residue = get_dma_residue(devpriv->dma) / sample_size;
250 num_points = max_points - residue;
251 if (devpriv->count < num_points && cmd->stop_src == TRIG_COUNT)
252 num_points = devpriv->count;
254 /* figure out how many points will be stored next time */
256 if (cmd->stop_src == TRIG_NONE) {
257 leftover = devpriv->dma_transfer_size / sample_size;
258 } else if (devpriv->count > max_points) {
259 leftover = devpriv->count - max_points;
260 if (leftover > max_points)
261 leftover = max_points;
263 /* there should only be a residue if collection was stopped by having
264 * the stop_src set to an external trigger, in which case there
265 * will be no more data
270 for (i = 0; i < num_points; i++) {
271 /* write data point to comedi buffer */
272 dpnt = devpriv->dma_buffer[i];
273 /* convert from 2's complement to unsigned coding */
275 cfc_write_to_buffer(s, dpnt);
276 if (cmd->stop_src == TRIG_COUNT) {
277 if (--devpriv->count == 0) { /* end of acquisition */
278 a2150_cancel(dev, s);
279 async->events |= COMEDI_CB_EOA;
286 set_dma_addr(devpriv->dma, virt_to_bus(devpriv->dma_buffer));
287 set_dma_count(devpriv->dma, leftover * sample_size);
288 enable_dma(devpriv->dma);
290 release_dma_lock(flags);
292 async->events |= COMEDI_CB_BLOCK;
294 comedi_event(dev, s);
296 /* clear interrupt */
297 outw(0x00, dev->iobase + DMA_TC_CLEAR_REG);
302 static int a2150_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
304 struct a2150_private *devpriv = dev->private;
306 /* disable dma on card */
307 devpriv->irq_dma_bits &= ~DMA_INTR_EN_BIT & ~DMA_EN_BIT;
308 outw(devpriv->irq_dma_bits, dev->iobase + IRQ_DMA_CNTRL_REG);
310 /* disable computer's dma */
311 disable_dma(devpriv->dma);
313 /* clear fifo and reset triggering circuitry */
314 outw(0, dev->iobase + FIFO_RESET_REG);
319 static int a2150_ai_cmdtest(struct comedi_device *dev,
320 struct comedi_subdevice *s, struct comedi_cmd *cmd)
327 /* Step 1 : check if triggers are trivially valid */
329 err |= cfc_check_trigger_src(&cmd->start_src, TRIG_NOW | TRIG_EXT);
330 err |= cfc_check_trigger_src(&cmd->scan_begin_src, TRIG_TIMER);
331 err |= cfc_check_trigger_src(&cmd->convert_src, TRIG_NOW);
332 err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
333 err |= cfc_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE);
338 /* Step 2a : make sure trigger sources are unique */
340 err |= cfc_check_trigger_is_unique(cmd->start_src);
341 err |= cfc_check_trigger_is_unique(cmd->stop_src);
343 /* Step 2b : and mutually compatible */
348 /* Step 3: check if arguments are trivially valid */
350 err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0);
352 if (cmd->convert_src == TRIG_TIMER)
353 err |= cfc_check_trigger_arg_min(&cmd->convert_arg,
354 thisboard->ai_speed);
356 err |= cfc_check_trigger_arg_min(&cmd->chanlist_len, 1);
357 err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len);
359 if (cmd->stop_src == TRIG_COUNT)
360 err |= cfc_check_trigger_arg_min(&cmd->stop_arg, 1);
362 err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0);
367 /* step 4: fix up any arguments */
369 if (cmd->scan_begin_src == TRIG_TIMER) {
370 tmp = cmd->scan_begin_arg;
371 a2150_get_timing(dev, &cmd->scan_begin_arg, cmd->flags);
372 if (tmp != cmd->scan_begin_arg)
379 /* check channel/gain list against card's limitations */
381 startChan = CR_CHAN(cmd->chanlist[0]);
382 for (i = 1; i < cmd->chanlist_len; i++) {
383 if (CR_CHAN(cmd->chanlist[i]) != (startChan + i)) {
385 "entries in chanlist must be consecutive channels, counting upwards\n");
389 if (cmd->chanlist_len == 2 && CR_CHAN(cmd->chanlist[0]) == 1) {
391 "length 2 chanlist must be channels 0,1 or channels 2,3");
394 if (cmd->chanlist_len == 3) {
396 "chanlist must have 1,2 or 4 channels");
399 if (CR_AREF(cmd->chanlist[0]) != CR_AREF(cmd->chanlist[1]) ||
400 CR_AREF(cmd->chanlist[2]) != CR_AREF(cmd->chanlist[3])) {
402 "channels 0/1 and 2/3 must have the same analog reference");
413 static int a2150_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
415 struct a2150_private *devpriv = dev->private;
416 struct comedi_async *async = s->async;
417 struct comedi_cmd *cmd = &async->cmd;
418 unsigned long lock_flags;
419 unsigned int old_config_bits = devpriv->config_bits;
420 unsigned int trigger_bits;
422 if (!dev->irq || !devpriv->dma) {
424 " irq and dma required, cannot do hardware conversions");
427 if (cmd->flags & TRIG_RT) {
429 " dma incompatible with hard real-time interrupt (TRIG_RT), aborting");
432 /* clear fifo and reset triggering circuitry */
433 outw(0, dev->iobase + FIFO_RESET_REG);
436 if (a2150_set_chanlist(dev, CR_CHAN(cmd->chanlist[0]),
437 cmd->chanlist_len) < 0)
440 /* setup ac/dc coupling */
441 if (CR_AREF(cmd->chanlist[0]) == AREF_OTHER)
442 devpriv->config_bits |= AC0_BIT;
444 devpriv->config_bits &= ~AC0_BIT;
445 if (CR_AREF(cmd->chanlist[2]) == AREF_OTHER)
446 devpriv->config_bits |= AC1_BIT;
448 devpriv->config_bits &= ~AC1_BIT;
451 a2150_get_timing(dev, &cmd->scan_begin_arg, cmd->flags);
453 /* send timing, channel, config bits */
454 outw(devpriv->config_bits, dev->iobase + CONFIG_REG);
456 /* initialize number of samples remaining */
457 devpriv->count = cmd->stop_arg * cmd->chanlist_len;
459 /* enable computer's dma */
460 lock_flags = claim_dma_lock();
461 disable_dma(devpriv->dma);
462 /* clear flip-flop to make sure 2-byte registers for
463 * count and address get set correctly */
464 clear_dma_ff(devpriv->dma);
465 set_dma_addr(devpriv->dma, virt_to_bus(devpriv->dma_buffer));
466 /* set size of transfer to fill in 1/3 second */
467 #define ONE_THIRD_SECOND 333333333
468 devpriv->dma_transfer_size =
469 sizeof(devpriv->dma_buffer[0]) * cmd->chanlist_len *
470 ONE_THIRD_SECOND / cmd->scan_begin_arg;
471 if (devpriv->dma_transfer_size > A2150_DMA_BUFFER_SIZE)
472 devpriv->dma_transfer_size = A2150_DMA_BUFFER_SIZE;
473 if (devpriv->dma_transfer_size < sizeof(devpriv->dma_buffer[0]))
474 devpriv->dma_transfer_size = sizeof(devpriv->dma_buffer[0]);
475 devpriv->dma_transfer_size -=
476 devpriv->dma_transfer_size % sizeof(devpriv->dma_buffer[0]);
477 set_dma_count(devpriv->dma, devpriv->dma_transfer_size);
478 enable_dma(devpriv->dma);
479 release_dma_lock(lock_flags);
481 /* clear dma interrupt before enabling it, to try and get rid of that
482 * one spurious interrupt that has been happening */
483 outw(0x00, dev->iobase + DMA_TC_CLEAR_REG);
485 /* enable dma on card */
486 devpriv->irq_dma_bits |= DMA_INTR_EN_BIT | DMA_EN_BIT;
487 outw(devpriv->irq_dma_bits, dev->iobase + IRQ_DMA_CNTRL_REG);
489 /* may need to wait 72 sampling periods if timing was changed */
490 i8254_load(dev->iobase + I8253_BASE_REG, 0, 2, 72, 0);
492 /* setup start triggering */
494 /* decide if we need to wait 72 periods for valid data */
495 if (cmd->start_src == TRIG_NOW &&
496 (old_config_bits & CLOCK_MASK) !=
497 (devpriv->config_bits & CLOCK_MASK)) {
498 /* set trigger source to delay trigger */
499 trigger_bits |= DELAY_TRIGGER_BITS;
501 /* otherwise no delay */
502 trigger_bits |= POST_TRIGGER_BITS;
504 /* enable external hardware trigger */
505 if (cmd->start_src == TRIG_EXT) {
506 trigger_bits |= HW_TRIG_EN;
507 } else if (cmd->start_src == TRIG_OTHER) {
508 /* XXX add support for level/slope start trigger using TRIG_OTHER */
509 comedi_error(dev, "you shouldn't see this?");
511 /* send trigger config bits */
512 outw(trigger_bits, dev->iobase + TRIGGER_REG);
514 /* start acquisition for soft trigger */
515 if (cmd->start_src == TRIG_NOW)
516 outw(0, dev->iobase + FIFO_START_REG);
524 static int a2150_ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
525 struct comedi_insn *insn, unsigned int *data)
527 struct a2150_private *devpriv = dev->private;
529 static const int timeout = 100000;
530 static const int filter_delay = 36;
532 /* clear fifo and reset triggering circuitry */
533 outw(0, dev->iobase + FIFO_RESET_REG);
536 if (a2150_set_chanlist(dev, CR_CHAN(insn->chanspec), 1) < 0)
539 /* set dc coupling */
540 devpriv->config_bits &= ~AC0_BIT;
541 devpriv->config_bits &= ~AC1_BIT;
543 /* send timing, channel, config bits */
544 outw(devpriv->config_bits, dev->iobase + CONFIG_REG);
546 /* disable dma on card */
547 devpriv->irq_dma_bits &= ~DMA_INTR_EN_BIT & ~DMA_EN_BIT;
548 outw(devpriv->irq_dma_bits, dev->iobase + IRQ_DMA_CNTRL_REG);
550 /* setup start triggering */
551 outw(0, dev->iobase + TRIGGER_REG);
553 /* start acquisition for soft trigger */
554 outw(0, dev->iobase + FIFO_START_REG);
557 * there is a 35.6 sample delay for data to get through the
560 for (n = 0; n < filter_delay; n++) {
561 for (i = 0; i < timeout; i++) {
562 if (inw(dev->iobase + STATUS_REG) & FNE_BIT)
567 comedi_error(dev, "timeout");
570 inw(dev->iobase + FIFO_DATA_REG);
574 for (n = 0; n < insn->n; n++) {
575 for (i = 0; i < timeout; i++) {
576 if (inw(dev->iobase + STATUS_REG) & FNE_BIT)
581 comedi_error(dev, "timeout");
587 data[n] = inw(dev->iobase + FIFO_DATA_REG);
589 printk(" data is %i\n", data[n]);
594 /* clear fifo and reset triggering circuitry */
595 outw(0, dev->iobase + FIFO_RESET_REG);
601 * sets bits in devpriv->clock_bits to nearest approximation of requested
602 * period, adjusts requested period to actual timing.
604 static int a2150_get_timing(struct comedi_device *dev, unsigned int *period,
607 struct a2150_private *devpriv = dev->private;
609 int lub_divisor_shift, lub_index, glb_divisor_shift, glb_index;
612 /* initialize greatest lower and least upper bounds */
613 lub_divisor_shift = 3;
615 lub = thisboard->clock[lub_index] * (1 << lub_divisor_shift);
616 glb_divisor_shift = 0;
617 glb_index = thisboard->num_clocks - 1;
618 glb = thisboard->clock[glb_index] * (1 << glb_divisor_shift);
620 /* make sure period is in available range */
626 /* we can multiply period by 1, 2, 4, or 8, using (1 << i) */
627 for (i = 0; i < 4; i++) {
628 /* there are a maximum of 4 master clocks */
629 for (j = 0; j < thisboard->num_clocks; j++) {
630 /* temp is the period in nanosec we are evaluating */
631 temp = thisboard->clock[j] * (1 << i);
632 /* if it is the best match yet */
633 if (temp < lub && temp >= *period) {
634 lub_divisor_shift = i;
638 if (temp > glb && temp <= *period) {
639 glb_divisor_shift = i;
645 flags &= TRIG_ROUND_MASK;
647 case TRIG_ROUND_NEAREST:
649 /* if least upper bound is better approximation */
650 if (lub - *period < *period - glb)
658 case TRIG_ROUND_DOWN:
663 /* set clock bits for config register appropriately */
664 devpriv->config_bits &= ~CLOCK_MASK;
665 if (*period == lub) {
666 devpriv->config_bits |=
667 CLOCK_SELECT_BITS(lub_index) |
668 CLOCK_DIVISOR_BITS(lub_divisor_shift);
670 devpriv->config_bits |=
671 CLOCK_SELECT_BITS(glb_index) |
672 CLOCK_DIVISOR_BITS(glb_divisor_shift);
678 static int a2150_set_chanlist(struct comedi_device *dev,
679 unsigned int start_channel,
680 unsigned int num_channels)
682 struct a2150_private *devpriv = dev->private;
684 if (start_channel + num_channels > 4)
687 devpriv->config_bits &= ~CHANNEL_MASK;
689 switch (num_channels) {
691 devpriv->config_bits |= CHANNEL_BITS(0x4 | start_channel);
694 if (start_channel == 0) {
695 devpriv->config_bits |= CHANNEL_BITS(0x2);
696 } else if (start_channel == 2) {
697 devpriv->config_bits |= CHANNEL_BITS(0x3);
703 devpriv->config_bits |= CHANNEL_BITS(0x1);
713 /* probes board type, returns offset */
714 static int a2150_probe(struct comedi_device *dev)
716 int status = inw(dev->iobase + STATUS_REG);
717 return ID_BITS(status);
720 static int a2150_attach(struct comedi_device *dev, struct comedi_devconfig *it)
722 struct a2150_private *devpriv;
723 struct comedi_subdevice *s;
724 unsigned long iobase = it->options[0];
725 unsigned int irq = it->options[1];
726 unsigned int dma = it->options[2];
727 static const int timeout = 2000;
731 printk("comedi%d: %s: io 0x%lx", dev->minor, dev->driver->driver_name,
734 printk(", irq %u", irq);
739 printk(", dma %u", dma);
745 devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL);
748 dev->private = devpriv;
751 printk(" io base address required\n");
755 /* check if io addresses are available */
756 if (!request_region(iobase, A2150_SIZE, dev->driver->driver_name)) {
757 printk(" I/O port conflict\n");
760 dev->iobase = iobase;
764 /* check that irq is supported */
765 if (irq < 3 || irq == 8 || irq == 13 || irq > 15) {
766 printk(" invalid irq line %u\n", irq);
769 if (request_irq(irq, a2150_interrupt, 0,
770 dev->driver->driver_name, dev)) {
771 printk("unable to allocate irq %u\n", irq);
774 devpriv->irq_dma_bits |= IRQ_LVL_BITS(irq);
779 if (dma == 4 || dma > 7) {
780 printk(" invalid dma channel %u\n", dma);
783 if (request_dma(dma, dev->driver->driver_name)) {
784 printk(" failed to allocate dma channel %u\n", dma);
788 devpriv->dma_buffer =
789 kmalloc(A2150_DMA_BUFFER_SIZE, GFP_KERNEL | GFP_DMA);
790 if (devpriv->dma_buffer == NULL)
794 set_dma_mode(dma, DMA_MODE_READ);
796 devpriv->irq_dma_bits |= DMA_CHAN_BITS(dma);
799 dev->board_ptr = a2150_boards + a2150_probe(dev);
800 dev->board_name = thisboard->name;
802 ret = comedi_alloc_subdevices(dev, 1);
806 /* analog input subdevice */
807 s = &dev->subdevices[0];
808 dev->read_subdev = s;
809 s->type = COMEDI_SUBD_AI;
810 s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_OTHER | SDF_CMD_READ;
814 s->range_table = &range_a2150;
815 s->do_cmd = a2150_ai_cmd;
816 s->do_cmdtest = a2150_ai_cmdtest;
817 s->insn_read = a2150_ai_rinsn;
818 s->cancel = a2150_cancel;
820 /* need to do this for software counting of completed conversions, to
821 * prevent hardware count from stopping acquisition */
822 outw(HW_COUNT_DISABLE, dev->iobase + I8253_MODE_REG);
824 /* set card's irq and dma levels */
825 outw(devpriv->irq_dma_bits, dev->iobase + IRQ_DMA_CNTRL_REG);
827 /* reset and sync adc clock circuitry */
828 outw_p(DPD_BIT | APD_BIT, dev->iobase + CONFIG_REG);
829 outw_p(DPD_BIT, dev->iobase + CONFIG_REG);
830 /* initialize configuration register */
831 devpriv->config_bits = 0;
832 outw(devpriv->config_bits, dev->iobase + CONFIG_REG);
833 /* wait until offset calibration is done, then enable analog inputs */
834 for (i = 0; i < timeout; i++) {
835 if ((DCAL_BIT & inw(dev->iobase + STATUS_REG)) == 0)
841 (" timed out waiting for offset calibration to complete\n");
844 devpriv->config_bits |= ENABLE0_BIT | ENABLE1_BIT;
845 outw(devpriv->config_bits, dev->iobase + CONFIG_REG);
850 static void a2150_detach(struct comedi_device *dev)
852 struct a2150_private *devpriv = dev->private;
855 outw(APD_BIT | DPD_BIT, dev->iobase + CONFIG_REG);
856 release_region(dev->iobase, A2150_SIZE);
859 free_irq(dev->irq, dev);
862 free_dma(devpriv->dma);
863 kfree(devpriv->dma_buffer);
867 static struct comedi_driver ni_at_a2150_driver = {
868 .driver_name = "ni_at_a2150",
869 .module = THIS_MODULE,
870 .attach = a2150_attach,
871 .detach = a2150_detach,
873 module_comedi_driver(ni_at_a2150_driver);
875 MODULE_AUTHOR("Comedi http://www.comedi.org");
876 MODULE_DESCRIPTION("Comedi low-level driver");
877 MODULE_LICENSE("GPL");