Lines Matching +full:acquisition +full:- +full:time +full:- +full:ns

1 // SPDX-License-Identifier: GPL-2.0+
3 * Comedi driver for Keithley DAS-1700/DAS-1800 series boards
6 * COMEDI - Linux Control and Measurement Device Interface
14 * Devices: [Keithley Metrabyte] DAS-1701ST (das-1701st),
15 * DAS-1701ST-DA (das-1701st-da), DAS-1701/AO (das-1701ao),
16 * DAS-1702ST (das-1702st), DAS-1702ST-DA (das-1702st-da),
17 * DAS-1702HR (das-1702hr), DAS-1702HR-DA (das-1702hr-da),
18 * DAS-1702/AO (das-1702ao), DAS-1801ST (das-1801st),
19 * DAS-1801ST-DA (das-1801st-da), DAS-1801HC (das-1801hc),
20 * DAS-1801AO (das-1801ao), DAS-1802ST (das-1802st),
21 * DAS-1802ST-DA (das-1802st-da), DAS-1802HR (das-1802hr),
22 * DAS-1802HR-DA (das-1802hr-da), DAS-1802HC (das-1802hc),
23 * DAS-1802AO (das-1802ao)
27 * [0] - I/O port base address
28 * [1] - IRQ (optional, required for analog input cmd support)
29 * [2] - DMA0 (optional, requires irq)
30 * [3] - DMA1 (optional, requires irq and dma0)
65 * Only the DAS-1801ST has been tested by me.
213 .name = "das-1701st",
219 .name = "das-1701st-da",
225 .name = "das-1702st",
230 .name = "das-1702st-da",
235 .name = "das-1702hr",
240 .name = "das-1702hr-da",
245 .name = "das-1701ao",
251 .name = "das-1702ao",
256 .name = "das-1801st",
262 .name = "das-1801st-da",
268 .name = "das-1802st",
273 .name = "das-1802st-da",
278 .name = "das-1802hr",
283 .name = "das-1802hr-da",
288 .name = "das-1801hc",
294 .name = "das-1802hc",
299 .name = "das-1801ao",
305 .name = "das-1802ao",
325 struct das1800_private *devpriv = dev->private; in das1800_ai_munge()
330 if (devpriv->ai_is_unipolar) in das1800_ai_munge()
340 struct das1800_private *devpriv = dev->private; in das1800_handle_fifo_half_full()
343 insw(dev->iobase + DAS1800_FIFO, devpriv->fifo_buf, nsamples); in das1800_handle_fifo_half_full()
344 comedi_buf_write_samples(s, devpriv->fifo_buf, nsamples); in das1800_handle_fifo_half_full()
350 struct comedi_cmd *cmd = &s->async->cmd; in das1800_handle_fifo_not_empty()
353 while (inb(dev->iobase + DAS1800_STATUS) & FNE) { in das1800_handle_fifo_not_empty()
354 dpnt = inw(dev->iobase + DAS1800_FIFO); in das1800_handle_fifo_not_empty()
357 if (cmd->stop_src == TRIG_COUNT && in das1800_handle_fifo_not_empty()
358 s->async->scans_done >= cmd->stop_arg) in das1800_handle_fifo_not_empty()
367 unsigned int residue = comedi_isadma_disable(desc->chan); in das1800_flush_dma_channel()
368 unsigned int nbytes = desc->size - residue; in das1800_flush_dma_channel()
375 comedi_buf_write_samples(s, desc->virt_addr, nsamples); in das1800_flush_dma_channel()
381 struct das1800_private *devpriv = dev->private; in das1800_flush_dma()
382 struct comedi_isadma *dma = devpriv->dma; in das1800_flush_dma()
383 struct comedi_isadma_desc *desc = &dma->desc[dma->cur_dma]; in das1800_flush_dma()
384 const int dual_dma = devpriv->irq_dma_bits & DMA_DUAL; in das1800_flush_dma()
390 dma->cur_dma = 1 - dma->cur_dma; in das1800_flush_dma()
391 desc = &dma->desc[dma->cur_dma]; in das1800_flush_dma()
402 struct das1800_private *devpriv = dev->private; in das1800_handle_dma()
403 struct comedi_isadma *dma = devpriv->dma; in das1800_handle_dma()
404 struct comedi_isadma_desc *desc = &dma->desc[dma->cur_dma]; in das1800_handle_dma()
405 const int dual_dma = devpriv->irq_dma_bits & DMA_DUAL; in das1800_handle_dma()
409 /* re-enable dma channel */ in das1800_handle_dma()
414 outb(CLEAR_INTR_MASK & ~DMATC, dev->iobase + DAS1800_STATUS); in das1800_handle_dma()
415 /* switch dma channels for next time, if appropriate */ in das1800_handle_dma()
417 dma->cur_dma = 1 - dma->cur_dma; in das1800_handle_dma()
424 struct das1800_private *devpriv = dev->private; in das1800_ai_cancel()
425 struct comedi_isadma *dma = devpriv->dma; in das1800_ai_cancel()
430 outb(0x0, dev->iobase + DAS1800_STATUS); in das1800_ai_cancel()
431 outb(0x0, dev->iobase + DAS1800_CONTROL_B); in das1800_ai_cancel()
432 outb(0x0, dev->iobase + DAS1800_CONTROL_A); in das1800_ai_cancel()
436 desc = &dma->desc[i]; in das1800_ai_cancel()
437 if (desc->chan) in das1800_ai_cancel()
438 comedi_isadma_disable(desc->chan); in das1800_ai_cancel()
447 struct das1800_private *devpriv = dev->private; in das1800_ai_handler()
448 struct comedi_subdevice *s = dev->read_subdev; in das1800_ai_handler()
449 struct comedi_async *async = s->async; in das1800_ai_handler()
450 struct comedi_cmd *cmd = &async->cmd; in das1800_ai_handler()
451 unsigned int status = inb(dev->iobase + DAS1800_STATUS); in das1800_ai_handler()
454 outb(ADC, dev->iobase + DAS1800_SELECT); in das1800_ai_handler()
457 if (devpriv->irq_dma_bits & DMA_ENABLED) in das1800_ai_handler()
467 outb(CLEAR_INTR_MASK & ~OVF, dev->iobase + DAS1800_STATUS); in das1800_ai_handler()
468 dev_err(dev->class_dev, "FIFO overflow\n"); in das1800_ai_handler()
469 async->events |= COMEDI_CB_ERROR; in das1800_ai_handler()
477 outb(CLEAR_INTR_MASK & ~CT0TC, dev->iobase + DAS1800_STATUS); in das1800_ai_handler()
479 if (devpriv->irq_dma_bits & DMA_ENABLED) in das1800_ai_handler()
483 async->events |= COMEDI_CB_EOA; in das1800_ai_handler()
484 } else if (cmd->stop_src == TRIG_COUNT && in das1800_ai_handler()
485 async->scans_done >= cmd->stop_arg) { in das1800_ai_handler()
486 async->events |= COMEDI_CB_EOA; in das1800_ai_handler()
501 spin_lock_irqsave(&dev->spinlock, flags); in das1800_ai_poll()
505 spin_unlock_irqrestore(&dev->spinlock, flags); in das1800_ai_poll()
515 if (!dev->attached) { in das1800_interrupt()
516 dev_err(dev->class_dev, "premature interrupt\n"); in das1800_interrupt()
524 spin_lock(&dev->spinlock); in das1800_interrupt()
526 status = inb(dev->iobase + DAS1800_STATUS); in das1800_interrupt()
528 /* if interrupt was not caused by das-1800 */ in das1800_interrupt()
530 spin_unlock(&dev->spinlock); in das1800_interrupt()
534 outb(CLEAR_INTR_MASK & ~INT, dev->iobase + DAS1800_STATUS); in das1800_interrupt()
538 spin_unlock(&dev->spinlock); in das1800_interrupt()
545 unsigned int arg = cmd->convert_arg; in das1800_ai_fixup_paced_timing()
552 * The convert_arg sets the pacer sample acquisition time. in das1800_ai_fixup_paced_timing()
553 * The max acquisition speed is limited to the boards in das1800_ai_fixup_paced_timing()
557 comedi_8254_cascade_ns_to_timer(dev->pacer, &arg, cmd->flags); in das1800_ai_fixup_paced_timing()
558 return comedi_check_trigger_arg_is(&cmd->convert_arg, arg); in das1800_ai_fixup_paced_timing()
564 unsigned int arg = cmd->convert_arg; in das1800_ai_fixup_burst_timing()
572 * The convert_arg sets burst sample acquisition time. in das1800_ai_fixup_burst_timing()
573 * The max acquisition speed is limited to the boards in das1800_ai_fixup_burst_timing()
580 switch (cmd->flags & CMDF_ROUND_MASK) { in das1800_ai_fixup_burst_timing()
592 err |= comedi_check_trigger_arg_is(&cmd->convert_arg, arg * 1000); in das1800_ai_fixup_burst_timing()
599 if (cmd->scan_begin_src == TRIG_TIMER) { in das1800_ai_fixup_burst_timing()
600 arg = cmd->convert_arg * cmd->chanlist_len; in das1800_ai_fixup_burst_timing()
601 err |= comedi_check_trigger_arg_min(&cmd->scan_begin_arg, arg); in das1800_ai_fixup_burst_timing()
603 arg = cmd->scan_begin_arg; in das1800_ai_fixup_burst_timing()
604 comedi_8254_cascade_ns_to_timer(dev->pacer, &arg, cmd->flags); in das1800_ai_fixup_burst_timing()
605 err |= comedi_check_trigger_arg_is(&cmd->scan_begin_arg, arg); in das1800_ai_fixup_burst_timing()
615 unsigned int range = CR_RANGE(cmd->chanlist[0]); in das1800_ai_check_chanlist()
619 for (i = 1; i < cmd->chanlist_len; i++) { in das1800_ai_check_chanlist()
620 range = CR_RANGE(cmd->chanlist[i]); in das1800_ai_check_chanlist()
623 dev_dbg(dev->class_dev, in das1800_ai_check_chanlist()
625 return -EINVAL; in das1800_ai_check_chanlist()
636 const struct das1800_board *board = dev->board_ptr; in das1800_ai_cmdtest()
641 err |= comedi_check_trigger_src(&cmd->start_src, TRIG_NOW | TRIG_EXT); in das1800_ai_cmdtest()
642 err |= comedi_check_trigger_src(&cmd->scan_begin_src, in das1800_ai_cmdtest()
644 err |= comedi_check_trigger_src(&cmd->convert_src, in das1800_ai_cmdtest()
646 err |= comedi_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT); in das1800_ai_cmdtest()
647 err |= comedi_check_trigger_src(&cmd->stop_src, in das1800_ai_cmdtest()
655 err |= comedi_check_trigger_is_unique(cmd->start_src); in das1800_ai_cmdtest()
656 err |= comedi_check_trigger_is_unique(cmd->scan_begin_src); in das1800_ai_cmdtest()
657 err |= comedi_check_trigger_is_unique(cmd->convert_src); in das1800_ai_cmdtest()
658 err |= comedi_check_trigger_is_unique(cmd->stop_src); in das1800_ai_cmdtest()
663 if (cmd->scan_begin_src != TRIG_FOLLOW && in das1800_ai_cmdtest()
664 cmd->convert_src != TRIG_TIMER) in das1800_ai_cmdtest()
665 err |= -EINVAL; in das1800_ai_cmdtest()
668 if (cmd->start_src == TRIG_EXT && cmd->stop_src == TRIG_EXT) in das1800_ai_cmdtest()
669 err |= comedi_check_trigger_arg_is(&cmd->start_arg, in das1800_ai_cmdtest()
670 cmd->stop_arg); in das1800_ai_cmdtest()
677 if (cmd->start_arg == TRIG_NOW) in das1800_ai_cmdtest()
678 err |= comedi_check_trigger_arg_is(&cmd->start_arg, 0); in das1800_ai_cmdtest()
680 if (cmd->convert_src == TRIG_TIMER) { in das1800_ai_cmdtest()
681 err |= comedi_check_trigger_arg_min(&cmd->convert_arg, in das1800_ai_cmdtest()
682 board->ai_speed); in das1800_ai_cmdtest()
685 err |= comedi_check_trigger_arg_min(&cmd->chanlist_len, 1); in das1800_ai_cmdtest()
686 err |= comedi_check_trigger_arg_is(&cmd->scan_end_arg, in das1800_ai_cmdtest()
687 cmd->chanlist_len); in das1800_ai_cmdtest()
689 switch (cmd->stop_src) { in das1800_ai_cmdtest()
691 err |= comedi_check_trigger_arg_min(&cmd->stop_arg, 1); in das1800_ai_cmdtest()
694 err |= comedi_check_trigger_arg_is(&cmd->stop_arg, 0); in das1800_ai_cmdtest()
705 if (cmd->convert_src == TRIG_TIMER) { in das1800_ai_cmdtest()
706 if (cmd->scan_begin_src == TRIG_FOLLOW) in das1800_ai_cmdtest()
716 if (cmd->chanlist && cmd->chanlist_len > 0) in das1800_ai_cmdtest()
746 unsigned int ns) in das1800_ai_transfer_size() argument
748 struct comedi_cmd *cmd = &s->async->cmd; in das1800_ai_transfer_size()
754 /* for timed modes, make dma buffer fill in 'ns' time */ in das1800_ai_transfer_size()
755 switch (cmd->scan_begin_src) { in das1800_ai_transfer_size()
757 if (cmd->convert_src == TRIG_TIMER) in das1800_ai_transfer_size()
758 samples = ns / cmd->convert_arg; in das1800_ai_transfer_size()
761 samples = ns / (cmd->scan_begin_arg * cmd->chanlist_len); in das1800_ai_transfer_size()
779 struct das1800_private *devpriv = dev->private; in das1800_ai_setup_dma()
780 struct comedi_isadma *dma = devpriv->dma; in das1800_ai_setup_dma()
784 if ((devpriv->irq_dma_bits & DMA_ENABLED) == 0) in das1800_ai_setup_dma()
787 dma->cur_dma = 0; in das1800_ai_setup_dma()
788 desc = &dma->desc[0]; in das1800_ai_setup_dma()
791 bytes = das1800_ai_transfer_size(dev, s, desc->maxsize, 300000000); in das1800_ai_setup_dma()
793 desc->size = bytes; in das1800_ai_setup_dma()
797 if (devpriv->irq_dma_bits & DMA_DUAL) { in das1800_ai_setup_dma()
798 desc = &dma->desc[1]; in das1800_ai_setup_dma()
799 desc->size = bytes; in das1800_ai_setup_dma()
811 spin_lock_irqsave(&dev->spinlock, flags); in das1800_ai_set_chanlist()
814 outb(QRAM, dev->iobase + DAS1800_SELECT); in das1800_ai_set_chanlist()
815 outb(len - 1, dev->iobase + DAS1800_QRAM_ADDRESS); in das1800_ai_set_chanlist()
824 outw(val, dev->iobase + DAS1800_QRAM); in das1800_ai_set_chanlist()
828 outb(len - 1, dev->iobase + DAS1800_QRAM_ADDRESS); in das1800_ai_set_chanlist()
830 spin_unlock_irqrestore(&dev->spinlock, flags); in das1800_ai_set_chanlist()
836 struct das1800_private *devpriv = dev->private; in das1800_ai_cmd()
838 struct comedi_async *async = s->async; in das1800_ai_cmd()
839 const struct comedi_cmd *cmd = &async->cmd; in das1800_ai_cmd()
840 unsigned int range0 = CR_RANGE(cmd->chanlist[0]); in das1800_ai_cmd()
844 * handler is unsafe at hard real-time priority). in das1800_ai_cmd()
846 if (cmd->flags & (CMDF_WAKE_EOS | CMDF_PRIORITY)) in das1800_ai_cmd()
847 devpriv->irq_dma_bits &= ~DMA_ENABLED; in das1800_ai_cmd()
849 devpriv->irq_dma_bits |= devpriv->dma_bits; in das1800_ai_cmd()
851 if (cmd->flags & CMDF_WAKE_EOS) { in das1800_ai_cmd()
853 devpriv->irq_dma_bits &= ~FIMD; in das1800_ai_cmd()
856 devpriv->irq_dma_bits |= FIMD; in das1800_ai_cmd()
861 devpriv->ai_is_unipolar = comedi_range_is_unipolar(s, range0); in das1800_ai_cmd()
864 if (cmd->stop_src == TRIG_EXT) in das1800_ai_cmd()
866 if (cmd->start_src == TRIG_EXT) in das1800_ai_cmd()
871 if ((cmd->start_arg & CR_INVERT) || (cmd->stop_arg & CR_INVERT)) in das1800_ai_cmd()
875 control_c = das1800_ai_chanspec_bits(s, cmd->chanlist[0]); in das1800_ai_cmd()
877 if (cmd->scan_begin_src == TRIG_FOLLOW) { in das1800_ai_cmd()
879 if (cmd->convert_src == TRIG_TIMER) { in das1800_ai_cmd()
886 } else if (cmd->scan_begin_src == TRIG_TIMER) { in das1800_ai_cmd()
894 das1800_ai_set_chanlist(dev, cmd->chanlist, cmd->chanlist_len); in das1800_ai_cmd()
897 if ((cmd->scan_begin_src == TRIG_FOLLOW || in das1800_ai_cmd()
898 cmd->scan_begin_src == TRIG_TIMER) && in das1800_ai_cmd()
899 cmd->convert_src == TRIG_TIMER) { in das1800_ai_cmd()
900 comedi_8254_update_divisors(dev->pacer); in das1800_ai_cmd()
901 comedi_8254_pacer_enable(dev->pacer, 1, 2, true); in das1800_ai_cmd()
905 if (cmd->stop_src == TRIG_EXT) in das1800_ai_cmd()
906 comedi_8254_load(dev->pacer, 0, 1, I8254_MODE0 | I8254_BINARY); in das1800_ai_cmd()
909 outb(control_c, dev->iobase + DAS1800_CONTROL_C); in das1800_ai_cmd()
912 outb(cmd->convert_arg / 1000 - 1, /* microseconds - 1 */ in das1800_ai_cmd()
913 dev->iobase + DAS1800_BURST_RATE); in das1800_ai_cmd()
914 outb(cmd->chanlist_len - 1, dev->iobase + DAS1800_BURST_LENGTH); in das1800_ai_cmd()
918 outb(devpriv->irq_dma_bits, dev->iobase + DAS1800_CONTROL_B); in das1800_ai_cmd()
919 outb(control_a, dev->iobase + DAS1800_CONTROL_A); in das1800_ai_cmd()
920 outb(CVEN, dev->iobase + DAS1800_STATUS); in das1800_ai_cmd()
932 status = inb(dev->iobase + DAS1800_STATUS); in das1800_ai_eoc()
935 return -EBUSY; in das1800_ai_eoc()
943 unsigned int range = CR_RANGE(insn->chanspec); in das1800_ai_insn_read()
950 outb(das1800_ai_chanspec_bits(s, insn->chanspec), in das1800_ai_insn_read()
951 dev->iobase + DAS1800_CONTROL_C); /* software pacer */ in das1800_ai_insn_read()
952 outb(CVEN, dev->iobase + DAS1800_STATUS); /* enable conversions */ in das1800_ai_insn_read()
953 outb(0x0, dev->iobase + DAS1800_CONTROL_A); /* reset fifo */ in das1800_ai_insn_read()
954 outb(FFEN, dev->iobase + DAS1800_CONTROL_A); in das1800_ai_insn_read()
956 das1800_ai_set_chanlist(dev, &insn->chanspec, 1); in das1800_ai_insn_read()
959 spin_lock_irqsave(&dev->spinlock, flags); in das1800_ai_insn_read()
962 outb(ADC, dev->iobase + DAS1800_SELECT); in das1800_ai_insn_read()
964 for (n = 0; n < insn->n; n++) { in das1800_ai_insn_read()
966 outb(0, dev->iobase + DAS1800_FIFO); in das1800_ai_insn_read()
972 dpnt = inw(dev->iobase + DAS1800_FIFO); in das1800_ai_insn_read()
977 spin_unlock_irqrestore(&dev->spinlock, flags); in das1800_ai_insn_read()
979 return ret ? ret : insn->n; in das1800_ai_insn_read()
987 unsigned int chan = CR_CHAN(insn->chanspec); in das1800_ao_insn_write()
988 unsigned int update_chan = s->n_chan - 1; in das1800_ao_insn_write()
993 spin_lock_irqsave(&dev->spinlock, flags); in das1800_ao_insn_write()
995 for (i = 0; i < insn->n; i++) { in das1800_ao_insn_write()
998 s->readback[chan] = val; in das1800_ao_insn_write()
1003 outb(DAC(chan), dev->iobase + DAS1800_SELECT); in das1800_ao_insn_write()
1004 outw(val, dev->iobase + DAS1800_DAC); in das1800_ao_insn_write()
1008 val = comedi_offset_munge(s, s->readback[update_chan]); in das1800_ao_insn_write()
1010 outb(DAC(update_chan), dev->iobase + DAS1800_SELECT); in das1800_ao_insn_write()
1011 outw(val, dev->iobase + DAS1800_DAC); in das1800_ao_insn_write()
1014 spin_unlock_irqrestore(&dev->spinlock, flags); in das1800_ao_insn_write()
1016 return insn->n; in das1800_ao_insn_write()
1024 data[1] = inb(dev->iobase + DAS1800_DIGITAL) & 0xf; in das1800_di_insn_bits()
1027 return insn->n; in das1800_di_insn_bits()
1036 outb(s->state, dev->iobase + DAS1800_DIGITAL); in das1800_do_insn_bits()
1038 data[1] = s->state; in das1800_do_insn_bits()
1040 return insn->n; in das1800_do_insn_bits()
1046 struct das1800_private *devpriv = dev->private; in das1800_init_dma()
1050 * it->options[2] is DMA channel 0 in das1800_init_dma()
1051 * it->options[3] is DMA channel 1 in das1800_init_dma()
1055 dma_chan = &it->options[2]; in das1800_init_dma()
1059 devpriv->dma_bits = DMA_CH5; in das1800_init_dma()
1062 devpriv->dma_bits = DMA_CH6; in das1800_init_dma()
1065 devpriv->dma_bits = DMA_CH7; in das1800_init_dma()
1068 devpriv->dma_bits = DMA_CH5_CH6; in das1800_init_dma()
1071 devpriv->dma_bits = DMA_CH6_CH7; in das1800_init_dma()
1074 devpriv->dma_bits = DMA_CH7_CH5; in das1800_init_dma()
1081 devpriv->dma = comedi_isadma_alloc(dev, dma_chan[1] ? 2 : 1, in das1800_init_dma()
1084 if (!devpriv->dma) in das1800_init_dma()
1085 devpriv->dma_bits = 0; in das1800_init_dma()
1090 struct das1800_private *devpriv = dev->private; in das1800_free_dma()
1093 comedi_isadma_free(devpriv->dma); in das1800_free_dma()
1098 const struct das1800_board *board = dev->board_ptr; in das1800_probe()
1101 id = (inb(dev->iobase + DAS1800_DIGITAL) >> 4) & 0xf; in das1800_probe()
1104 * The dev->board_ptr will be set by comedi_device_attach() if the in das1800_probe()
1105 * board name provided by the user matches a board->name in this in das1800_probe()
1110 if (board->id == id) in das1800_probe()
1112 dev_err(dev->class_dev, in das1800_probe()
1114 id, board->id); in das1800_probe()
1115 return -ENODEV; in das1800_probe()
1119 * If the dev->board_ptr is not set, the user is trying to attach in das1800_probe()
1121 * to 'probe' for the dev->board_ptr. in das1800_probe()
1125 /* das-1701st-da, das-1702st-da, das-1801st-da, das-1802st-da */ in das1800_probe()
1129 /* das-1702hr-da, das-1802hr-da */ in das1800_probe()
1133 /* das-1701ao, das-1702ao, das-1801ao, das-1802ao */ in das1800_probe()
1137 /* das-1702hr, das-1802hr */ in das1800_probe()
1141 /* das-1701st, das-1702st, das-1801st, das-1802st */ in das1800_probe()
1145 /* das-1801hc, das-1802hc */ in das1800_probe()
1149 dev_err(dev->class_dev, "invalid probe id 0x%x\n", id); in das1800_probe()
1150 return -ENODEV; in das1800_probe()
1152 dev->board_ptr = board; in das1800_probe()
1153 dev->board_name = board->name; in das1800_probe()
1154 dev_warn(dev->class_dev, in das1800_probe()
1156 id, board->name); in das1800_probe()
1166 unsigned int irq = it->options[1]; in das1800_attach()
1173 return -ENOMEM; in das1800_attach()
1175 ret = comedi_request_region(dev, it->options[0], DAS1800_SIZE); in das1800_attach()
1182 board = dev->board_ptr; in das1800_attach()
1184 is_16bit = board->id == DAS1800_ID_HR || board->id == DAS1800_ID_HR_DA; in das1800_attach()
1187 if (board->id == DAS1800_ID_AO) { in das1800_attach()
1188 unsigned long iobase2 = dev->iobase + IOBASE2; in das1800_attach()
1193 devpriv->iobase2 = iobase2; in das1800_attach()
1199 dev->board_name, dev); in das1800_attach()
1201 dev->irq = irq; in das1800_attach()
1205 devpriv->irq_dma_bits |= 0x8; in das1800_attach()
1208 devpriv->irq_dma_bits |= 0x10; in das1800_attach()
1211 devpriv->irq_dma_bits |= 0x18; in das1800_attach()
1214 devpriv->irq_dma_bits |= 0x28; in das1800_attach()
1217 devpriv->irq_dma_bits |= 0x30; in das1800_attach()
1220 devpriv->irq_dma_bits |= 0x38; in das1800_attach()
1227 if (dev->irq & it->options[2]) in das1800_attach()
1230 devpriv->fifo_buf = kmalloc_array(FIFO_SIZE, in das1800_attach()
1231 sizeof(*devpriv->fifo_buf), in das1800_attach()
1233 if (!devpriv->fifo_buf) in das1800_attach()
1234 return -ENOMEM; in das1800_attach()
1236 dev->pacer = comedi_8254_init(dev->iobase + DAS1800_COUNTER, in das1800_attach()
1238 if (!dev->pacer) in das1800_attach()
1239 return -ENOMEM; in das1800_attach()
1251 * All the other board types have 16 on-board channels. Each channel in das1800_attach()
1252 * can be expanded to 16 channels with the addition of an EXP-1800 in das1800_attach()
1257 * actual physical channel mapping is when EXP-1800 boards are used. in das1800_attach()
1259 s = &dev->subdevices[0]; in das1800_attach()
1260 s->type = COMEDI_SUBD_AI; in das1800_attach()
1261 s->subdev_flags = SDF_READABLE | SDF_DIFF | SDF_GROUND; in das1800_attach()
1262 if (board->id != DAS1800_ID_HC) in das1800_attach()
1263 s->subdev_flags |= SDF_COMMON; in das1800_attach()
1264 s->n_chan = (board->id == DAS1800_ID_HC) ? 64 : 256; in das1800_attach()
1265 s->maxdata = is_16bit ? 0xffff : 0x0fff; in das1800_attach()
1266 s->range_table = board->is_01_series ? &das1801_ai_range in das1800_attach()
1268 s->insn_read = das1800_ai_insn_read; in das1800_attach()
1269 if (dev->irq) { in das1800_attach()
1270 dev->read_subdev = s; in das1800_attach()
1271 s->subdev_flags |= SDF_CMD_READ; in das1800_attach()
1272 s->len_chanlist = s->n_chan; in das1800_attach()
1273 s->do_cmd = das1800_ai_cmd; in das1800_attach()
1274 s->do_cmdtest = das1800_ai_cmdtest; in das1800_attach()
1275 s->poll = das1800_ai_poll; in das1800_attach()
1276 s->cancel = das1800_ai_cancel; in das1800_attach()
1277 s->munge = das1800_ai_munge; in das1800_attach()
1281 s = &dev->subdevices[1]; in das1800_attach()
1282 if (board->id == DAS1800_ID_ST_DA || board->id == DAS1800_ID_HR_DA) { in das1800_attach()
1283 s->type = COMEDI_SUBD_AO; in das1800_attach()
1284 s->subdev_flags = SDF_WRITABLE; in das1800_attach()
1285 s->n_chan = (board->id == DAS1800_ID_ST_DA) ? 4 : 2; in das1800_attach()
1286 s->maxdata = is_16bit ? 0xffff : 0x0fff; in das1800_attach()
1287 s->range_table = &range_bipolar10; in das1800_attach()
1288 s->insn_write = das1800_ao_insn_write; in das1800_attach()
1295 for (i = 0; i < s->n_chan; i++) { in das1800_attach()
1297 outb(DAC(i), dev->iobase + DAS1800_SELECT); in das1800_attach()
1298 outw(0, dev->iobase + DAS1800_DAC); in das1800_attach()
1300 } else if (board->id == DAS1800_ID_AO) { in das1800_attach()
1305 s->type = COMEDI_SUBD_UNUSED; in das1800_attach()
1307 s->type = COMEDI_SUBD_UNUSED; in das1800_attach()
1311 s = &dev->subdevices[2]; in das1800_attach()
1312 s->type = COMEDI_SUBD_DI; in das1800_attach()
1313 s->subdev_flags = SDF_READABLE; in das1800_attach()
1314 s->n_chan = 4; in das1800_attach()
1315 s->maxdata = 1; in das1800_attach()
1316 s->range_table = &range_digital; in das1800_attach()
1317 s->insn_bits = das1800_di_insn_bits; in das1800_attach()
1320 s = &dev->subdevices[3]; in das1800_attach()
1321 s->type = COMEDI_SUBD_DO; in das1800_attach()
1322 s->subdev_flags = SDF_WRITABLE; in das1800_attach()
1323 s->n_chan = (board->id == DAS1800_ID_HC) ? 8 : 4; in das1800_attach()
1324 s->maxdata = 1; in das1800_attach()
1325 s->range_table = &range_digital; in das1800_attach()
1326 s->insn_bits = das1800_do_insn_bits; in das1800_attach()
1328 das1800_ai_cancel(dev, dev->read_subdev); in das1800_attach()
1331 outb(0, dev->iobase + DAS1800_DIGITAL); in das1800_attach()
1338 struct das1800_private *devpriv = dev->private; in das1800_detach()
1342 kfree(devpriv->fifo_buf); in das1800_detach()
1343 if (devpriv->iobase2) in das1800_detach()
1344 release_region(devpriv->iobase2, DAS1800_SIZE); in das1800_detach()