5 COMEDI - Linux Control and Measurement Device Interface
6 Copyright (C) 2000 David A. Schleef <ds@schleef.org>
7 Copyright (C) 2000 Chris R. Baugher <baugher@enteract.com>
8 Copyright (C) 2001,2002 Frank Mori Hess <fmhess@users.sourceforge.net>
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 2 of the License, or
13 (at your option) any later version.
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 ************************************************************************
28 Description: DAS16 compatible boards
29 Author: Sam Moore, Warren Jasper, ds, Chris Baugher, Frank Hess, Roman Fietze
30 Devices: [Keithley Metrabyte] DAS-16 (das-16), DAS-16G (das-16g),
31 DAS-16F (das-16f), DAS-1201 (das-1201), DAS-1202 (das-1202),
32 DAS-1401 (das-1401), DAS-1402 (das-1402), DAS-1601 (das-1601),
34 [ComputerBoards] PC104-DAS16/JR (pc104-das16jr),
35 PC104-DAS16JR/16 (pc104-das16jr/16),
36 CIO-DAS16JR/16 (cio-das16jr/16),
37 CIO-DAS16/JR (cio-das16/jr), CIO-DAS1401/12 (cio-das1401/12),
38 CIO-DAS1402/12 (cio-das1402/12), CIO-DAS1402/16 (cio-das1402/16),
39 CIO-DAS1601/12 (cio-das1601/12), CIO-DAS1602/12 (cio-das1602/12),
40 CIO-DAS1602/16 (cio-das1602/16), CIO-DAS16/330 (cio-das16/330)
44 A rewrite of the das16 and das1600 drivers.
47 [1] - irq (does nothing, irq is not used anymore)
48 [2] - dma (optional, required for comedi_command support)
49 [3] - master clock speed in MHz (optional, 1 or 10, ignored if
50 board can probe clock, defaults to 1)
51 [4] - analog input range lowest voltage in microvolts (optional,
52 only useful if your board does not have software
54 [5] - analog input range highest voltage in microvolts (optional,
55 only useful if board does not have software programmable
57 [6] - analog output range lowest voltage in microvolts (optional)
58 [7] - analog output range highest voltage in microvolts (optional)
59 [8] - use timer mode for DMA. Timer mode is needed e.g. for
60 buggy DMA controllers in NS CS5530A (Geode Companion), and for
61 'jr' cards that lack a hardware fifo. This option is no
62 longer needed, since timer mode is _always_ used.
64 Passing a zero for an option is the same as leaving it unspecified.
69 Testing and debugging help provided by Daniel Koch.
73 4919.PDF (das1400, 1600)
75 4923.PDF (das1200, 1400, 1600)
77 Computer boards manuals also available from their website
78 www.measurementcomputing.com
82 #include <linux/pci.h>
83 #include <linux/slab.h>
84 #include <linux/interrupt.h>
88 #include "../comedidev.h"
92 #include "comedi_fc.h"
98 #define DEBUG_PRINT(format, args...) \
99 printk(KERN_DEBUG "das16: " format, ## args)
101 #define DEBUG_PRINT(format, args...)
104 #define DAS16_SIZE 20 /* number of ioports */
105 #define DAS16_DMA_SIZE 0xff00 /* size in bytes of allocated dma buffer */
113 0 a/d bits 0-3 start 12 bit
114 1 a/d bits 4-11 unused
121 8 status eoc uni/bip interrupt reset
122 9 dma, int, trig ctrl set dma, int
123 a pacer control unused
135 0 a/d bits 0-3 start 12 bit
136 1 a/d bits 4-11 unused
140 8 status eoc uni/bip interrupt reset
141 9 dma, int, trig ctrl set dma, int
142 a pacer control unused
143 b gain status gain control
153 0 a/d bits 0-7 start 16 bit
154 1 a/d bits 8-15 unused
158 8 status eoc uni/bip interrupt reset
159 9 dma, int, trig ctrl set dma, int
160 a pacer control unused
161 b gain status gain control
172 0 a/d bits 0-3 start 12 bit
173 1 a/d bits 4-11 unused
180 8 status eoc uni/bip interrupt reset
181 9 dma, int, trig ctrl set dma, int
182 a pacer control unused
183 b gain status gain control
186 404 unused conversion enable
187 405 unused burst enable
188 406 unused das1600 enable
193 /* size in bytes of a sample from board */
194 static const int sample_size = 2;
197 #define DAS16_AI_LSB 0
198 #define DAS16_AI_MSB 1
201 #define DAS16_AO_LSB(x) ((x) ? 6 : 4)
202 #define DAS16_AO_MSB(x) ((x) ? 7 : 5)
203 #define DAS16_STATUS 8
205 #define UNIPOLAR (1<<6)
206 #define DAS16_MUXBIT (1<<5)
207 #define DAS16_INT (1<<4)
208 #define DAS16_CONTROL 9
209 #define DAS16_INTE (1<<7)
210 #define DAS16_IRQ(x) (((x) & 0x7) << 4)
211 #define DMA_ENABLE (1<<2)
212 #define PACING_MASK 0x3
213 #define INT_PACER 0x03
214 #define EXT_PACER 0x02
215 #define DAS16_SOFT 0x00
216 #define DAS16_PACER 0x0A
217 #define DAS16_CTR0 (1<<1)
218 #define DAS16_TRIG0 (1<<0)
219 #define BURST_LEN_BITS(x) (((x) & 0xf) << 4)
220 #define DAS16_GAIN 0x0B
221 #define DAS16_CNTR0_DATA 0x0C
222 #define DAS16_CNTR1_DATA 0x0D
223 #define DAS16_CNTR2_DATA 0x0E
224 #define DAS16_CNTR_CONTROL 0x0F
225 #define DAS16_TERM_CNT 0x00
226 #define DAS16_ONE_SHOT 0x02
227 #define DAS16_RATE_GEN 0x04
228 #define DAS16_CNTR_LSB_MSB 0x30
229 #define DAS16_CNTR0 0x00
230 #define DAS16_CNTR1 0x40
231 #define DAS16_CNTR2 0x80
233 #define DAS1600_CONV 0x404
234 #define DAS1600_CONV_DISABLE 0x40
235 #define DAS1600_BURST 0x405
236 #define DAS1600_BURST_VAL 0x40
237 #define DAS1600_ENABLE 0x406
238 #define DAS1600_ENABLE_VAL 0x40
239 #define DAS1600_STATUS_B 0x407
240 #define DAS1600_BME 0x40
241 #define DAS1600_ME 0x20
242 #define DAS1600_CD 0x10
243 #define DAS1600_WS 0x02
244 #define DAS1600_CLK_10MHZ 0x01
246 static const struct comedi_lrange range_das1x01_bip = { 4, {
254 static const struct comedi_lrange range_das1x01_unip = { 4, {
262 static const struct comedi_lrange range_das1x02_bip = { 4, {
270 static const struct comedi_lrange range_das1x02_unip = { 4, {
278 static const struct comedi_lrange range_das16jr = { 9, {
279 /* also used by 16/330 */
292 static const struct comedi_lrange range_das16jr_16 = { 8, {
304 static const int das16jr_gainlist[] = { 8, 0, 1, 2, 3, 4, 5, 6, 7 };
305 static const int das16jr_16_gainlist[] = { 0, 1, 2, 3, 4, 5, 6, 7 };
306 static const int das1600_gainlist[] = { 0, 1, 2, 3 };
315 static const int *const das16_gainlists[] = {
323 static const struct comedi_lrange *const das16_ai_uni_lranges[] = {
331 static const struct comedi_lrange *const das16_ai_bip_lranges[] = {
341 unsigned have_byte:1;
347 unsigned int ai_nbits;
348 unsigned int ai_speed; /* max conversion speed in nanosec */
351 unsigned int ao_nbits;
355 unsigned int i8255_offset;
356 unsigned int i8254_offset;
362 #define DAS16_TIMEOUT 1000
364 /* Period for timer interrupt in jiffies. It's a function
365 * to deal with possibility of dynamic HZ patches */
366 static inline int timer_period(void)
371 struct das16_private_struct {
372 unsigned int ai_unipolar; /* unipolar flag */
373 unsigned int ai_singleended; /* single ended flag */
374 unsigned int clockbase; /* master clock speed in ns */
375 volatile unsigned int control_state; /* dma, interrupt and trigger control bits */
376 volatile unsigned long adc_byte_count; /* number of bytes remaining */
377 /* divisor dividing master clock to get conversion frequency */
378 unsigned int divisor1;
379 /* divisor dividing master clock to get conversion frequency */
380 unsigned int divisor2;
381 unsigned int dma_chan; /* dma channel */
382 uint16_t *dma_buffer[2];
383 dma_addr_t dma_buffer_addr[2];
384 unsigned int current_buffer;
385 volatile unsigned int dma_transfer_size; /* target number of bytes to transfer per dma shot */
387 * user-defined analog input and output ranges
388 * defined from config options
390 struct comedi_lrange *user_ai_range_table;
391 struct comedi_lrange *user_ao_range_table;
393 struct timer_list timer; /* for timed interrupt */
394 volatile short timer_running;
395 volatile short timer_mode; /* true if using timer mode */
397 unsigned long extra_iobase;
400 static int das16_cmd_test(struct comedi_device *dev, struct comedi_subdevice *s,
401 struct comedi_cmd *cmd)
403 const struct das16_board *board = comedi_board(dev);
404 struct das16_private_struct *devpriv = dev->private;
406 int gain, start_chan, i;
409 /* Step 1 : check if triggers are trivially valid */
411 err |= cfc_check_trigger_src(&cmd->start_src, TRIG_NOW);
414 /* if board supports burst mode */
415 if (board->size > 0x400)
416 mask |= TRIG_TIMER | TRIG_EXT;
417 err |= cfc_check_trigger_src(&cmd->scan_begin_src, mask);
419 tmp = cmd->convert_src;
420 mask = TRIG_TIMER | TRIG_EXT;
421 /* if board supports burst mode */
422 if (board->size > 0x400)
424 err |= cfc_check_trigger_src(&cmd->convert_src, mask);
426 err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
427 err |= cfc_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE);
432 /* Step 2a : make sure trigger sources are unique */
434 err |= cfc_check_trigger_is_unique(cmd->scan_begin_src);
435 err |= cfc_check_trigger_is_unique(cmd->convert_src);
436 err |= cfc_check_trigger_is_unique(cmd->stop_src);
438 /* Step 2b : and mutually compatible */
440 /* make sure scan_begin_src and convert_src dont conflict */
441 if (cmd->scan_begin_src == TRIG_FOLLOW && cmd->convert_src == TRIG_NOW)
443 if (cmd->scan_begin_src != TRIG_FOLLOW && cmd->convert_src != TRIG_NOW)
449 /* Step 3: check if arguments are trivially valid */
451 err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0);
453 if (cmd->scan_begin_src == TRIG_FOLLOW) /* internal trigger */
454 err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, 0);
456 err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len);
458 /* check against maximum frequency */
459 if (cmd->scan_begin_src == TRIG_TIMER)
460 err |= cfc_check_trigger_arg_min(&cmd->scan_begin_arg,
461 board->ai_speed * cmd->chanlist_len);
463 if (cmd->convert_src == TRIG_TIMER)
464 err |= cfc_check_trigger_arg_min(&cmd->convert_arg,
467 if (cmd->stop_src == TRIG_NONE)
468 err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0);
473 /* step 4: fix up arguments */
474 if (cmd->scan_begin_src == TRIG_TIMER) {
475 unsigned int tmp = cmd->scan_begin_arg;
476 /* set divisors, correct timing arguments */
477 i8253_cascade_ns_to_timer_2div(devpriv->clockbase,
478 &(devpriv->divisor1),
479 &(devpriv->divisor2),
480 &(cmd->scan_begin_arg),
481 cmd->flags & TRIG_ROUND_MASK);
482 err += (tmp != cmd->scan_begin_arg);
484 if (cmd->convert_src == TRIG_TIMER) {
485 unsigned int tmp = cmd->convert_arg;
486 /* set divisors, correct timing arguments */
487 i8253_cascade_ns_to_timer_2div(devpriv->clockbase,
488 &(devpriv->divisor1),
489 &(devpriv->divisor2),
491 cmd->flags & TRIG_ROUND_MASK);
492 err += (tmp != cmd->convert_arg);
497 /* check channel/gain list against card's limitations */
499 gain = CR_RANGE(cmd->chanlist[0]);
500 start_chan = CR_CHAN(cmd->chanlist[0]);
501 for (i = 1; i < cmd->chanlist_len; i++) {
502 if (CR_CHAN(cmd->chanlist[i]) !=
503 (start_chan + i) % s->n_chan) {
505 "entries in chanlist must be "
506 "consecutive channels, "
507 "counting upwards\n");
510 if (CR_RANGE(cmd->chanlist[i]) != gain) {
512 "entries in chanlist must all "
513 "have the same gain\n");
524 /* utility function that suggests a dma transfer size in bytes */
525 static unsigned int das16_suggest_transfer_size(struct comedi_device *dev,
526 const struct comedi_cmd *cmd)
528 struct das16_private_struct *devpriv = dev->private;
532 /* if we are using timer interrupt, we don't care how long it
533 * will take to complete transfer since it will be interrupted
534 * by timer interrupt */
535 if (devpriv->timer_mode)
536 return DAS16_DMA_SIZE;
538 /* otherwise, we are relying on dma terminal count interrupt,
539 * so pick a reasonable size */
540 if (cmd->convert_src == TRIG_TIMER)
541 freq = 1000000000 / cmd->convert_arg;
542 else if (cmd->scan_begin_src == TRIG_TIMER)
543 freq = (1000000000 / cmd->scan_begin_arg) * cmd->chanlist_len;
544 /* return some default value */
548 if (cmd->flags & TRIG_WAKE_EOS) {
549 size = sample_size * cmd->chanlist_len;
551 /* make buffer fill in no more than 1/3 second */
552 size = (freq / 3) * sample_size;
555 /* set a minimum and maximum size allowed */
556 if (size > DAS16_DMA_SIZE)
557 size = DAS16_DMA_SIZE - DAS16_DMA_SIZE % sample_size;
558 else if (size < sample_size)
561 if (cmd->stop_src == TRIG_COUNT && size > devpriv->adc_byte_count)
562 size = devpriv->adc_byte_count;
567 static unsigned int das16_set_pacer(struct comedi_device *dev, unsigned int ns,
570 struct das16_private_struct *devpriv = dev->private;
572 i8253_cascade_ns_to_timer_2div(devpriv->clockbase, &(devpriv->divisor1),
573 &(devpriv->divisor2), &ns,
574 rounding_flags & TRIG_ROUND_MASK);
576 /* Write the values of ctr1 and ctr2 into counters 1 and 2 */
577 i8254_load(dev->iobase + DAS16_CNTR0_DATA, 0, 1, devpriv->divisor1, 2);
578 i8254_load(dev->iobase + DAS16_CNTR0_DATA, 0, 2, devpriv->divisor2, 2);
583 static int das16_cmd_exec(struct comedi_device *dev, struct comedi_subdevice *s)
585 const struct das16_board *board = comedi_board(dev);
586 struct das16_private_struct *devpriv = dev->private;
587 struct comedi_async *async = s->async;
588 struct comedi_cmd *cmd = &async->cmd;
593 if (devpriv->dma_chan == 0 || (dev->irq == 0
594 && devpriv->timer_mode == 0)) {
596 "irq (or use of 'timer mode') dma required to "
597 "execute comedi_cmd");
600 if (cmd->flags & TRIG_RT) {
601 comedi_error(dev, "isa dma transfers cannot be performed with "
602 "TRIG_RT, aborting");
606 devpriv->adc_byte_count =
607 cmd->stop_arg * cmd->chanlist_len * sizeof(uint16_t);
609 /* disable conversions for das1600 mode */
610 if (board->size > 0x400)
611 outb(DAS1600_CONV_DISABLE, dev->iobase + DAS1600_CONV);
613 /* set scan limits */
614 byte = CR_CHAN(cmd->chanlist[0]);
615 byte |= CR_CHAN(cmd->chanlist[cmd->chanlist_len - 1]) << 4;
616 outb(byte, dev->iobase + DAS16_MUX);
618 /* set gain (this is also burst rate register but according to
619 * computer boards manual, burst rate does nothing, even on
621 if (board->ai_pg != das16_pg_none) {
622 range = CR_RANGE(cmd->chanlist[0]);
623 outb((das16_gainlists[board->ai_pg])[range],
624 dev->iobase + DAS16_GAIN);
627 /* set counter mode and counts */
629 das16_set_pacer(dev, cmd->convert_arg,
630 cmd->flags & TRIG_ROUND_MASK);
631 DEBUG_PRINT("pacer period: %d ns\n", cmd->convert_arg);
633 /* enable counters */
635 /* Enable burst mode if appropriate. */
636 if (board->size > 0x400) {
637 if (cmd->convert_src == TRIG_NOW) {
638 outb(DAS1600_BURST_VAL, dev->iobase + DAS1600_BURST);
639 /* set burst length */
640 byte |= BURST_LEN_BITS(cmd->chanlist_len - 1);
642 outb(0, dev->iobase + DAS1600_BURST);
645 outb(byte, dev->iobase + DAS16_PACER);
647 /* set up dma transfer */
648 flags = claim_dma_lock();
649 disable_dma(devpriv->dma_chan);
650 /* clear flip-flop to make sure 2-byte registers for
651 * count and address get set correctly */
652 clear_dma_ff(devpriv->dma_chan);
653 devpriv->current_buffer = 0;
654 set_dma_addr(devpriv->dma_chan,
655 devpriv->dma_buffer_addr[devpriv->current_buffer]);
656 /* set appropriate size of transfer */
657 devpriv->dma_transfer_size = das16_suggest_transfer_size(dev, cmd);
658 set_dma_count(devpriv->dma_chan, devpriv->dma_transfer_size);
659 enable_dma(devpriv->dma_chan);
660 release_dma_lock(flags);
662 /* set up interrupt */
663 if (devpriv->timer_mode) {
664 devpriv->timer_running = 1;
665 devpriv->timer.expires = jiffies + timer_period();
666 add_timer(&devpriv->timer);
667 devpriv->control_state &= ~DAS16_INTE;
669 /* clear interrupt bit */
670 outb(0x00, dev->iobase + DAS16_STATUS);
671 /* enable interrupts */
672 devpriv->control_state |= DAS16_INTE;
674 devpriv->control_state |= DMA_ENABLE;
675 devpriv->control_state &= ~PACING_MASK;
676 if (cmd->convert_src == TRIG_EXT)
677 devpriv->control_state |= EXT_PACER;
679 devpriv->control_state |= INT_PACER;
680 outb(devpriv->control_state, dev->iobase + DAS16_CONTROL);
682 /* Enable conversions if using das1600 mode */
683 if (board->size > 0x400)
684 outb(0, dev->iobase + DAS1600_CONV);
690 static int das16_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
692 const struct das16_board *board = comedi_board(dev);
693 struct das16_private_struct *devpriv = dev->private;
696 spin_lock_irqsave(&dev->spinlock, flags);
697 /* disable interrupts, dma and pacer clocked conversions */
698 devpriv->control_state &= ~DAS16_INTE & ~PACING_MASK & ~DMA_ENABLE;
699 outb(devpriv->control_state, dev->iobase + DAS16_CONTROL);
700 if (devpriv->dma_chan)
701 disable_dma(devpriv->dma_chan);
703 /* disable SW timer */
704 if (devpriv->timer_mode && devpriv->timer_running) {
705 devpriv->timer_running = 0;
706 del_timer(&devpriv->timer);
709 /* disable burst mode */
710 if (board->size > 0x400)
711 outb(0, dev->iobase + DAS1600_BURST);
714 spin_unlock_irqrestore(&dev->spinlock, flags);
719 static void das16_reset(struct comedi_device *dev)
721 outb(0, dev->iobase + DAS16_STATUS);
722 outb(0, dev->iobase + DAS16_CONTROL);
723 outb(0, dev->iobase + DAS16_PACER);
724 outb(0, dev->iobase + DAS16_CNTR_CONTROL);
727 static int das16_ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
728 struct comedi_insn *insn, unsigned int *data)
730 const struct das16_board *board = comedi_board(dev);
731 struct das16_private_struct *devpriv = dev->private;
737 /* disable interrupts and pacing */
738 devpriv->control_state &= ~DAS16_INTE & ~DMA_ENABLE & ~PACING_MASK;
739 outb(devpriv->control_state, dev->iobase + DAS16_CONTROL);
741 /* set multiplexer */
742 chan = CR_CHAN(insn->chanspec);
743 chan |= CR_CHAN(insn->chanspec) << 4;
744 outb(chan, dev->iobase + DAS16_MUX);
747 if (board->ai_pg != das16_pg_none) {
748 range = CR_RANGE(insn->chanspec);
749 outb((das16_gainlists[board->ai_pg])[range],
750 dev->iobase + DAS16_GAIN);
753 for (n = 0; n < insn->n; n++) {
754 /* trigger conversion */
755 outb_p(0, dev->iobase + DAS16_TRIG);
757 for (i = 0; i < DAS16_TIMEOUT; i++) {
758 if (!(inb(dev->iobase + DAS16_STATUS) & BUSY))
761 if (i == DAS16_TIMEOUT) {
762 printk("das16: timeout\n");
765 msb = inb(dev->iobase + DAS16_AI_MSB);
766 lsb = inb(dev->iobase + DAS16_AI_LSB);
767 if (board->ai_nbits == 12)
768 data[n] = ((lsb >> 4) & 0xf) | (msb << 4);
770 data[n] = lsb | (msb << 8);
777 static int das16_di_rbits(struct comedi_device *dev, struct comedi_subdevice *s,
778 struct comedi_insn *insn, unsigned int *data)
782 bits = inb(dev->iobase + DAS16_DIO) & 0xf;
789 static int das16_do_wbits(struct comedi_device *dev, struct comedi_subdevice *s,
790 struct comedi_insn *insn, unsigned int *data)
794 /* only set bits that have been masked */
797 /* zero bits that have been masked */
799 /* set masked bits */
800 wbits |= data[0] & data[1];
804 outb(s->state, dev->iobase + DAS16_DIO);
809 static int das16_ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s,
810 struct comedi_insn *insn, unsigned int *data)
812 const struct das16_board *board = comedi_board(dev);
817 chan = CR_CHAN(insn->chanspec);
819 for (i = 0; i < insn->n; i++) {
820 if (board->ao_nbits == 12) {
821 lsb = (data[i] << 4) & 0xff;
822 msb = (data[i] >> 4) & 0xff;
824 lsb = data[i] & 0xff;
825 msb = (data[i] >> 8) & 0xff;
827 outb(lsb, dev->iobase + DAS16_AO_LSB(chan));
828 outb(msb, dev->iobase + DAS16_AO_MSB(chan));
834 /* the pc104-das16jr (at least) has problems if the dma
835 transfer is interrupted in the middle of transferring
836 a 16 bit sample, so this function takes care to get
837 an even transfer count after disabling dma
840 static int disable_dma_on_even(struct comedi_device *dev)
842 struct das16_private_struct *devpriv = dev->private;
845 static const int disable_limit = 100;
846 static const int enable_timeout = 100;
848 disable_dma(devpriv->dma_chan);
849 residue = get_dma_residue(devpriv->dma_chan);
850 for (i = 0; i < disable_limit && (residue % 2); ++i) {
852 enable_dma(devpriv->dma_chan);
853 for (j = 0; j < enable_timeout; ++j) {
856 new_residue = get_dma_residue(devpriv->dma_chan);
857 if (new_residue != residue)
860 disable_dma(devpriv->dma_chan);
861 residue = get_dma_residue(devpriv->dma_chan);
863 if (i == disable_limit) {
864 comedi_error(dev, "failed to get an even dma transfer, "
865 "could be trouble.");
870 static void das16_interrupt(struct comedi_device *dev)
872 const struct das16_board *board = comedi_board(dev);
873 struct das16_private_struct *devpriv = dev->private;
874 unsigned long dma_flags, spin_flags;
875 struct comedi_subdevice *s = dev->read_subdev;
876 struct comedi_async *async;
877 struct comedi_cmd *cmd;
878 int num_bytes, residue;
881 if (!dev->attached) {
882 comedi_error(dev, "premature interrupt");
885 /* initialize async here to make sure it is not NULL */
889 if (devpriv->dma_chan == 0) {
890 comedi_error(dev, "interrupt with no dma channel?");
894 spin_lock_irqsave(&dev->spinlock, spin_flags);
895 if ((devpriv->control_state & DMA_ENABLE) == 0) {
896 spin_unlock_irqrestore(&dev->spinlock, spin_flags);
897 DEBUG_PRINT("interrupt while dma disabled?\n");
901 dma_flags = claim_dma_lock();
902 clear_dma_ff(devpriv->dma_chan);
903 residue = disable_dma_on_even(dev);
905 /* figure out how many points to read */
906 if (residue > devpriv->dma_transfer_size) {
907 comedi_error(dev, "residue > transfer size!\n");
908 async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
911 num_bytes = devpriv->dma_transfer_size - residue;
913 if (cmd->stop_src == TRIG_COUNT &&
914 num_bytes >= devpriv->adc_byte_count) {
915 num_bytes = devpriv->adc_byte_count;
916 async->events |= COMEDI_CB_EOA;
919 buffer_index = devpriv->current_buffer;
920 devpriv->current_buffer = (devpriv->current_buffer + 1) % 2;
921 devpriv->adc_byte_count -= num_bytes;
923 /* figure out how many bytes for next transfer */
924 if (cmd->stop_src == TRIG_COUNT && devpriv->timer_mode == 0 &&
925 devpriv->dma_transfer_size > devpriv->adc_byte_count)
926 devpriv->dma_transfer_size = devpriv->adc_byte_count;
929 if ((async->events & COMEDI_CB_EOA) == 0) {
930 set_dma_addr(devpriv->dma_chan,
931 devpriv->dma_buffer_addr[devpriv->current_buffer]);
932 set_dma_count(devpriv->dma_chan, devpriv->dma_transfer_size);
933 enable_dma(devpriv->dma_chan);
934 /* reenable conversions for das1600 mode, (stupid hardware) */
935 if (board->size > 0x400 && devpriv->timer_mode == 0)
936 outb(0x00, dev->iobase + DAS1600_CONV);
939 release_dma_lock(dma_flags);
941 spin_unlock_irqrestore(&dev->spinlock, spin_flags);
943 cfc_write_array_to_buffer(s,
944 devpriv->dma_buffer[buffer_index], num_bytes);
946 cfc_handle_events(dev, s);
949 static irqreturn_t das16_dma_interrupt(int irq, void *d)
952 struct comedi_device *dev = d;
954 status = inb(dev->iobase + DAS16_STATUS);
956 if ((status & DAS16_INT) == 0) {
957 DEBUG_PRINT("spurious interrupt\n");
961 /* clear interrupt */
962 outb(0x00, dev->iobase + DAS16_STATUS);
963 das16_interrupt(dev);
967 static void das16_timer_interrupt(unsigned long arg)
969 struct comedi_device *dev = (struct comedi_device *)arg;
970 struct das16_private_struct *devpriv = dev->private;
972 das16_interrupt(dev);
974 if (devpriv->timer_running)
975 mod_timer(&devpriv->timer, jiffies + timer_period());
978 static void reg_dump(struct comedi_device *dev)
980 DEBUG_PRINT("********DAS1600 REGISTER DUMP********\n");
981 DEBUG_PRINT("DAS16_MUX: %x\n", inb(dev->iobase + DAS16_MUX));
982 DEBUG_PRINT("DAS16_DIO: %x\n", inb(dev->iobase + DAS16_DIO));
983 DEBUG_PRINT("DAS16_STATUS: %x\n", inb(dev->iobase + DAS16_STATUS));
984 DEBUG_PRINT("DAS16_CONTROL: %x\n", inb(dev->iobase + DAS16_CONTROL));
985 DEBUG_PRINT("DAS16_PACER: %x\n", inb(dev->iobase + DAS16_PACER));
986 DEBUG_PRINT("DAS16_GAIN: %x\n", inb(dev->iobase + DAS16_GAIN));
987 DEBUG_PRINT("DAS16_CNTR_CONTROL: %x\n",
988 inb(dev->iobase + DAS16_CNTR_CONTROL));
989 DEBUG_PRINT("DAS1600_CONV: %x\n", inb(dev->iobase + DAS1600_CONV));
990 DEBUG_PRINT("DAS1600_BURST: %x\n", inb(dev->iobase + DAS1600_BURST));
991 DEBUG_PRINT("DAS1600_ENABLE: %x\n", inb(dev->iobase + DAS1600_ENABLE));
992 DEBUG_PRINT("DAS1600_STATUS_B: %x\n",
993 inb(dev->iobase + DAS1600_STATUS_B));
996 static int das16_probe(struct comedi_device *dev, struct comedi_devconfig *it)
998 const struct das16_board *board = comedi_board(dev);
999 struct das16_private_struct *devpriv = dev->private;
1003 /* status is available on all boards */
1005 status = inb(dev->iobase + DAS16_STATUS);
1007 if ((status & UNIPOLAR))
1008 devpriv->ai_unipolar = 1;
1010 devpriv->ai_unipolar = 0;
1013 if ((status & DAS16_MUXBIT))
1014 devpriv->ai_singleended = 1;
1016 devpriv->ai_singleended = 0;
1019 /* diobits indicates boards */
1021 diobits = inb(dev->iobase + DAS16_DIO) & 0xf0;
1023 printk(KERN_INFO " id bits are 0x%02x\n", diobits);
1024 if (board->id != diobits) {
1025 printk(KERN_INFO " requested board's id bits are 0x%x (ignore)\n",
1032 static int das1600_mode_detect(struct comedi_device *dev)
1034 struct das16_private_struct *devpriv = dev->private;
1037 status = inb(dev->iobase + DAS1600_STATUS_B);
1039 if (status & DAS1600_CLK_10MHZ) {
1040 devpriv->clockbase = 100;
1041 printk(KERN_INFO " 10MHz pacer clock\n");
1043 devpriv->clockbase = 1000;
1044 printk(KERN_INFO " 1MHz pacer clock\n");
1052 static void das16_ai_munge(struct comedi_device *dev,
1053 struct comedi_subdevice *s, void *array,
1054 unsigned int num_bytes,
1055 unsigned int start_chan_index)
1057 const struct das16_board *board = comedi_board(dev);
1058 unsigned int i, num_samples = num_bytes / sizeof(short);
1059 short *data = array;
1061 for (i = 0; i < num_samples; i++) {
1062 data[i] = le16_to_cpu(data[i]);
1063 if (board->ai_nbits == 12)
1064 data[i] = (data[i] >> 4) & 0xfff;
1075 * 3 Clock speed (in MHz)
1077 static int das16_attach(struct comedi_device *dev, struct comedi_devconfig *it)
1079 const struct das16_board *board = comedi_board(dev);
1080 struct das16_private_struct *devpriv;
1081 struct comedi_subdevice *s;
1084 unsigned int dma_chan;
1086 unsigned long flags;
1087 struct comedi_krange *user_ai_range, *user_ao_range;
1090 irq = it->options[1];
1091 timer_mode = it->options[8];
1093 /* always use time_mode since using irq can drop samples while
1094 * waiting for dma done interrupt (due to hardware limitations) */
1100 /* check that clock setting is valid */
1101 if (it->options[3]) {
1102 if (it->options[3] != 0 &&
1103 it->options[3] != 1 && it->options[3] != 10) {
1105 ("\n Invalid option. Master clock must be set "
1106 "to 1 or 10 (MHz)\n");
1111 devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL);
1114 dev->private = devpriv;
1116 if (board->size < 0x400) {
1117 ret = comedi_request_region(dev, it->options[0], board->size);
1121 ret = comedi_request_region(dev, it->options[0], 0x10);
1124 /* Request an additional region for the 8255 */
1125 ret = __comedi_request_region(dev, dev->iobase + 0x400,
1126 board->size & 0x3ff);
1129 devpriv->extra_iobase = dev->iobase + 0x400;
1132 /* probe id bits to make sure they are consistent */
1133 if (das16_probe(dev, it)) {
1134 printk(KERN_ERR " id bits do not match selected board, aborting\n");
1138 /* get master clock speed */
1139 if (board->size < 0x400) {
1141 devpriv->clockbase = 1000 / it->options[3];
1143 devpriv->clockbase = 1000; /* 1 MHz default */
1145 das1600_mode_detect(dev);
1148 /* now for the irq */
1149 if (irq > 1 && irq < 8) {
1150 ret = request_irq(irq, das16_dma_interrupt, 0,
1151 dev->board_name, dev);
1156 printk(KERN_INFO " ( irq = %u )", irq);
1157 } else if (irq == 0) {
1158 printk(" ( no irq )");
1160 printk(" invalid irq\n");
1164 /* initialize dma */
1165 dma_chan = it->options[2];
1166 if (dma_chan == 1 || dma_chan == 3) {
1167 /* allocate dma buffers */
1169 for (i = 0; i < 2; i++) {
1170 devpriv->dma_buffer[i] = pci_alloc_consistent(
1171 NULL, DAS16_DMA_SIZE,
1172 &devpriv->dma_buffer_addr[i]);
1174 if (devpriv->dma_buffer[i] == NULL)
1177 if (request_dma(dma_chan, dev->board_name)) {
1178 printk(KERN_ERR " failed to allocate dma channel %i\n",
1182 devpriv->dma_chan = dma_chan;
1183 flags = claim_dma_lock();
1184 disable_dma(devpriv->dma_chan);
1185 set_dma_mode(devpriv->dma_chan, DMA_MODE_READ);
1186 release_dma_lock(flags);
1187 printk(KERN_INFO " ( dma = %u)\n", dma_chan);
1188 } else if (dma_chan == 0) {
1189 printk(KERN_INFO " ( no dma )\n");
1191 printk(KERN_ERR " invalid dma channel\n");
1195 /* get any user-defined input range */
1196 if (board->ai_pg == das16_pg_none &&
1197 (it->options[4] || it->options[5])) {
1198 /* allocate single-range range table */
1199 devpriv->user_ai_range_table =
1200 kmalloc(sizeof(struct comedi_lrange) +
1201 sizeof(struct comedi_krange), GFP_KERNEL);
1202 /* initialize ai range */
1203 devpriv->user_ai_range_table->length = 1;
1204 user_ai_range = devpriv->user_ai_range_table->range;
1205 user_ai_range->min = it->options[4];
1206 user_ai_range->max = it->options[5];
1207 user_ai_range->flags = UNIT_volt;
1209 /* get any user-defined output range */
1210 if (it->options[6] || it->options[7]) {
1211 /* allocate single-range range table */
1212 devpriv->user_ao_range_table =
1213 kmalloc(sizeof(struct comedi_lrange) +
1214 sizeof(struct comedi_krange), GFP_KERNEL);
1215 /* initialize ao range */
1216 devpriv->user_ao_range_table->length = 1;
1217 user_ao_range = devpriv->user_ao_range_table->range;
1218 user_ao_range->min = it->options[6];
1219 user_ao_range->max = it->options[7];
1220 user_ao_range->flags = UNIT_volt;
1224 init_timer(&(devpriv->timer));
1225 devpriv->timer.function = das16_timer_interrupt;
1226 devpriv->timer.data = (unsigned long)dev;
1228 devpriv->timer_mode = timer_mode ? 1 : 0;
1230 ret = comedi_alloc_subdevices(dev, 5);
1234 s = &dev->subdevices[0];
1235 dev->read_subdev = s;
1238 s->type = COMEDI_SUBD_AI;
1239 s->subdev_flags = SDF_READABLE | SDF_CMD_READ;
1240 if (devpriv->ai_singleended) {
1242 s->len_chanlist = 16;
1243 s->subdev_flags |= SDF_GROUND;
1246 s->len_chanlist = 8;
1247 s->subdev_flags |= SDF_DIFF;
1249 s->maxdata = (1 << board->ai_nbits) - 1;
1250 if (devpriv->user_ai_range_table) { /* user defined ai range */
1251 s->range_table = devpriv->user_ai_range_table;
1252 } else if (devpriv->ai_unipolar) {
1253 s->range_table = das16_ai_uni_lranges[board->ai_pg];
1255 s->range_table = das16_ai_bip_lranges[board->ai_pg];
1257 s->insn_read = board->ai;
1258 s->do_cmdtest = das16_cmd_test;
1259 s->do_cmd = das16_cmd_exec;
1260 s->cancel = das16_cancel;
1261 s->munge = das16_ai_munge;
1263 s->type = COMEDI_SUBD_UNUSED;
1266 s = &dev->subdevices[1];
1269 s->type = COMEDI_SUBD_AO;
1270 s->subdev_flags = SDF_WRITABLE;
1272 s->maxdata = (1 << board->ao_nbits) - 1;
1273 /* user defined ao range */
1274 if (devpriv->user_ao_range_table)
1275 s->range_table = devpriv->user_ao_range_table;
1277 s->range_table = &range_unknown;
1279 s->insn_write = board->ao;
1281 s->type = COMEDI_SUBD_UNUSED;
1284 s = &dev->subdevices[2];
1287 s->type = COMEDI_SUBD_DI;
1288 s->subdev_flags = SDF_READABLE;
1291 s->range_table = &range_digital;
1292 s->insn_bits = board->di;
1294 s->type = COMEDI_SUBD_UNUSED;
1297 s = &dev->subdevices[3];
1300 s->type = COMEDI_SUBD_DO;
1301 s->subdev_flags = SDF_WRITABLE | SDF_READABLE;
1304 s->range_table = &range_digital;
1305 s->insn_bits = board->do_;
1306 /* initialize digital output lines */
1307 outb(s->state, dev->iobase + DAS16_DIO);
1309 s->type = COMEDI_SUBD_UNUSED;
1312 s = &dev->subdevices[4];
1314 if (board->i8255_offset != 0) {
1315 subdev_8255_init(dev, s, NULL, (dev->iobase +
1316 board->i8255_offset));
1318 s->type = COMEDI_SUBD_UNUSED;
1322 /* set the interrupt level */
1323 devpriv->control_state = DAS16_IRQ(dev->irq);
1324 outb(devpriv->control_state, dev->iobase + DAS16_CONTROL);
1326 /* turn on das1600 mode if available */
1327 if (board->size > 0x400) {
1328 outb(DAS1600_ENABLE_VAL, dev->iobase + DAS1600_ENABLE);
1329 outb(0, dev->iobase + DAS1600_CONV);
1330 outb(0, dev->iobase + DAS1600_BURST);
1336 static void das16_detach(struct comedi_device *dev)
1338 const struct das16_board *board = comedi_board(dev);
1339 struct das16_private_struct *devpriv = dev->private;
1342 comedi_spriv_free(dev, 4);
1345 for (i = 0; i < 2; i++) {
1346 if (devpriv->dma_buffer[i])
1347 pci_free_consistent(NULL, DAS16_DMA_SIZE,
1348 devpriv->dma_buffer[i],
1350 dma_buffer_addr[i]);
1352 if (devpriv->dma_chan)
1353 free_dma(devpriv->dma_chan);
1354 kfree(devpriv->user_ai_range_table);
1355 kfree(devpriv->user_ao_range_table);
1357 if (devpriv->extra_iobase)
1358 release_region(devpriv->extra_iobase, board->size & 0x3ff);
1359 comedi_legacy_detach(dev);
1362 static const struct das16_board das16_boards[] = {
1365 .ai = das16_ai_rinsn,
1368 .ai_pg = das16_pg_none,
1369 .ao = das16_ao_winsn,
1371 .di = das16_di_rbits,
1372 .do_ = das16_do_wbits,
1373 .i8255_offset = 0x10,
1374 .i8254_offset = 0x0c,
1379 .ai = das16_ai_rinsn,
1382 .ai_pg = das16_pg_none,
1383 .ao = das16_ao_winsn,
1385 .di = das16_di_rbits,
1386 .do_ = das16_do_wbits,
1387 .i8255_offset = 0x10,
1388 .i8254_offset = 0x0c,
1393 .ai = das16_ai_rinsn,
1396 .ai_pg = das16_pg_none,
1397 .ao = das16_ao_winsn,
1399 .di = das16_di_rbits,
1400 .do_ = das16_do_wbits,
1401 .i8255_offset = 0x10,
1402 .i8254_offset = 0x0c,
1406 .name = "cio-das16",
1407 .ai = das16_ai_rinsn,
1410 .ai_pg = das16_pg_none,
1411 .ao = das16_ao_winsn,
1413 .di = das16_di_rbits,
1414 .do_ = das16_do_wbits,
1415 .i8255_offset = 0x10,
1416 .i8254_offset = 0x0c,
1420 .name = "cio-das16/f",
1421 .ai = das16_ai_rinsn,
1424 .ai_pg = das16_pg_none,
1425 .ao = das16_ao_winsn,
1427 .di = das16_di_rbits,
1428 .do_ = das16_do_wbits,
1429 .i8255_offset = 0x10,
1430 .i8254_offset = 0x0c,
1434 .name = "cio-das16/jr",
1435 .ai = das16_ai_rinsn,
1438 .ai_pg = das16_pg_16jr,
1440 .di = das16_di_rbits,
1441 .do_ = das16_do_wbits,
1443 .i8254_offset = 0x0c,
1447 .name = "pc104-das16jr",
1448 .ai = das16_ai_rinsn,
1451 .ai_pg = das16_pg_16jr,
1453 .di = das16_di_rbits,
1454 .do_ = das16_do_wbits,
1456 .i8254_offset = 0x0c,
1460 .name = "cio-das16jr/16",
1461 .ai = das16_ai_rinsn,
1464 .ai_pg = das16_pg_16jr_16,
1466 .di = das16_di_rbits,
1467 .do_ = das16_do_wbits,
1469 .i8254_offset = 0x0c,
1473 .name = "pc104-das16jr/16",
1474 .ai = das16_ai_rinsn,
1477 .ai_pg = das16_pg_16jr_16,
1479 .di = das16_di_rbits,
1480 .do_ = das16_do_wbits,
1482 .i8254_offset = 0x0c,
1487 .ai = das16_ai_rinsn,
1490 .ai_pg = das16_pg_none,
1492 .di = das16_di_rbits,
1493 .do_ = das16_do_wbits,
1494 .i8255_offset = 0x400,
1495 .i8254_offset = 0x0c,
1500 .ai = das16_ai_rinsn,
1503 .ai_pg = das16_pg_none,
1505 .di = das16_di_rbits,
1506 .do_ = das16_do_wbits,
1507 .i8255_offset = 0x400,
1508 .i8254_offset = 0x0c,
1513 .ai = das16_ai_rinsn,
1516 .ai_pg = das16_pg_1601,
1518 .di = das16_di_rbits,
1519 .do_ = das16_do_wbits,
1520 .i8255_offset = 0x0,
1521 .i8254_offset = 0x0c,
1526 .ai = das16_ai_rinsn,
1529 .ai_pg = das16_pg_1602,
1531 .di = das16_di_rbits,
1532 .do_ = das16_do_wbits,
1533 .i8255_offset = 0x0,
1534 .i8254_offset = 0x0c,
1539 .ai = das16_ai_rinsn,
1542 .ai_pg = das16_pg_1601,
1543 .ao = das16_ao_winsn,
1545 .di = das16_di_rbits,
1546 .do_ = das16_do_wbits,
1547 .i8255_offset = 0x400,
1548 .i8254_offset = 0x0c,
1553 .ai = das16_ai_rinsn,
1556 .ai_pg = das16_pg_1602,
1557 .ao = das16_ao_winsn,
1559 .di = das16_di_rbits,
1560 .do_ = das16_do_wbits,
1561 .i8255_offset = 0x400,
1562 .i8254_offset = 0x0c,
1566 .name = "cio-das1401/12",
1567 .ai = das16_ai_rinsn,
1570 .ai_pg = das16_pg_1601,
1572 .di = das16_di_rbits,
1573 .do_ = das16_do_wbits,
1575 .i8254_offset = 0x0c,
1579 .name = "cio-das1402/12",
1580 .ai = das16_ai_rinsn,
1583 .ai_pg = das16_pg_1602,
1585 .di = das16_di_rbits,
1586 .do_ = das16_do_wbits,
1588 .i8254_offset = 0x0c,
1592 .name = "cio-das1402/16",
1593 .ai = das16_ai_rinsn,
1596 .ai_pg = das16_pg_1602,
1598 .di = das16_di_rbits,
1599 .do_ = das16_do_wbits,
1601 .i8254_offset = 0x0c,
1605 .name = "cio-das1601/12",
1606 .ai = das16_ai_rinsn,
1609 .ai_pg = das16_pg_1601,
1610 .ao = das16_ao_winsn,
1612 .di = das16_di_rbits,
1613 .do_ = das16_do_wbits,
1614 .i8255_offset = 0x400,
1615 .i8254_offset = 0x0c,
1619 .name = "cio-das1602/12",
1620 .ai = das16_ai_rinsn,
1623 .ai_pg = das16_pg_1602,
1624 .ao = das16_ao_winsn,
1626 .di = das16_di_rbits,
1627 .do_ = das16_do_wbits,
1628 .i8255_offset = 0x400,
1629 .i8254_offset = 0x0c,
1633 .name = "cio-das1602/16",
1634 .ai = das16_ai_rinsn,
1637 .ai_pg = das16_pg_1602,
1638 .ao = das16_ao_winsn,
1640 .di = das16_di_rbits,
1641 .do_ = das16_do_wbits,
1642 .i8255_offset = 0x400,
1643 .i8254_offset = 0x0c,
1647 .name = "cio-das16/330",
1648 .ai = das16_ai_rinsn,
1651 .ai_pg = das16_pg_16jr,
1653 .di = das16_di_rbits,
1654 .do_ = das16_do_wbits,
1656 .i8254_offset = 0x0c,
1662 static struct comedi_driver das16_driver = {
1663 .driver_name = "das16",
1664 .module = THIS_MODULE,
1665 .attach = das16_attach,
1666 .detach = das16_detach,
1667 .board_name = &das16_boards[0].name,
1668 .num_names = ARRAY_SIZE(das16_boards),
1669 .offset = sizeof(das16_boards[0]),
1671 module_comedi_driver(das16_driver);
1673 MODULE_AUTHOR("Comedi http://www.comedi.org");
1674 MODULE_DESCRIPTION("Comedi low-level driver");
1675 MODULE_LICENSE("GPL");