Lines Matching +full:vref +full:- +full:half
1 // SPDX-License-Identifier: GPL-2.0
4 * Comedi driver for Advantech PCI-1710 series boards
13 * Description: Comedi driver for Advantech PCI-1710 series boards
14 * Devices: [Advantech] PCI-1710 (adv_pci1710), PCI-1710HG, PCI-1711,
15 * PCI-1713, PCI-1731
17 * Updated: Fri, 29 Oct 2015 17:19:35 -0700
26 * The PCI-1710 and PCI-1710HG have the same PCI device ID, so the
39 * PCI BAR2 Register map (dev->iobase)
54 #define PCI171X_STATUS_FH BIT(9) /* 1=FIFO is half full */
58 #define PCI171X_CTRL_ONEFH BIT(5) /* 1=on FIFO half full, 0=on sample */
117 UNI_RANGE(5), /* internal -5V ref */
118 UNI_RANGE(10), /* internal -10V ref */
119 RANGE_ext(0, 1) /* external -Vref (+/-10V max) */
175 unsigned char saved_seglen; /* len of the non-repeating chanlist */
184 struct pci1710_private *devpriv = dev->private; in pci1710_ai_check_chanlist()
185 unsigned int chan0 = CR_CHAN(cmd->chanlist[0]); in pci1710_ai_check_chanlist()
186 unsigned int last_aref = CR_AREF(cmd->chanlist[0]); in pci1710_ai_check_chanlist()
187 unsigned int next_chan = (chan0 + 1) % s->n_chan; in pci1710_ai_check_chanlist()
192 if (cmd->chanlist_len == 1) { in pci1710_ai_check_chanlist()
193 devpriv->saved_seglen = cmd->chanlist_len; in pci1710_ai_check_chanlist()
198 chansegment[0] = cmd->chanlist[0]; in pci1710_ai_check_chanlist()
200 for (i = 1; i < cmd->chanlist_len; i++) { in pci1710_ai_check_chanlist()
201 unsigned int chan = CR_CHAN(cmd->chanlist[i]); in pci1710_ai_check_chanlist()
202 unsigned int aref = CR_AREF(cmd->chanlist[i]); in pci1710_ai_check_chanlist()
204 if (cmd->chanlist[0] == cmd->chanlist[i]) in pci1710_ai_check_chanlist()
208 dev_err(dev->class_dev, in pci1710_ai_check_chanlist()
210 return -EINVAL; in pci1710_ai_check_chanlist()
214 next_chan = (next_chan + 1) % s->n_chan; in pci1710_ai_check_chanlist()
216 dev_err(dev->class_dev, in pci1710_ai_check_chanlist()
219 return -EINVAL; in pci1710_ai_check_chanlist()
223 chansegment[i] = cmd->chanlist[i]; in pci1710_ai_check_chanlist()
228 for (i = 0; i < cmd->chanlist_len; i++) { in pci1710_ai_check_chanlist()
229 if (cmd->chanlist[i] != chansegment[i % seglen]) { in pci1710_ai_check_chanlist()
230 dev_err(dev->class_dev, in pci1710_ai_check_chanlist()
235 CR_CHAN(cmd->chanlist[i % seglen]), in pci1710_ai_check_chanlist()
236 CR_RANGE(cmd->chanlist[i % seglen]), in pci1710_ai_check_chanlist()
238 return -EINVAL; in pci1710_ai_check_chanlist()
241 devpriv->saved_seglen = seglen; in pci1710_ai_check_chanlist()
252 struct pci1710_private *devpriv = dev->private; in pci1710_ai_setup_chanlist()
254 unsigned int last_chan = CR_CHAN(chanlist[seglen - 1]); in pci1710_ai_setup_chanlist()
267 range -= devpriv->unipolar_gain; in pci1710_ai_setup_chanlist()
272 outw(PCI171X_MUX_CHAN(chan), dev->iobase + PCI171X_MUX_REG); in pci1710_ai_setup_chanlist()
273 outw(rangeval, dev->iobase + PCI171X_RANGE_REG); in pci1710_ai_setup_chanlist()
275 devpriv->act_chanlist[i] = chan; in pci1710_ai_setup_chanlist()
278 devpriv->act_chanlist[i] = CR_CHAN(chanlist[i]); in pci1710_ai_setup_chanlist()
281 devpriv->mux_scan = PCI171X_MUX_CHANL(first_chan) | in pci1710_ai_setup_chanlist()
283 outw(devpriv->mux_scan, dev->iobase + PCI171X_MUX_REG); in pci1710_ai_setup_chanlist()
293 status = inw(dev->iobase + PCI171X_STATUS_REG); in pci1710_ai_eoc()
296 return -EBUSY; in pci1710_ai_eoc()
304 const struct boardtype *board = dev->board_ptr; in pci1710_ai_read_sample()
305 struct pci1710_private *devpriv = dev->private; in pci1710_ai_read_sample()
309 sample = inw(dev->iobase + PCI171X_AD_DATA_REG); in pci1710_ai_read_sample()
310 if (!board->is_pci1713) { in pci1710_ai_read_sample()
312 * The upper 4 bits of the 16-bit sample are the channel number in pci1710_ai_read_sample()
317 if (chan != devpriv->act_chanlist[cur_chan]) { in pci1710_ai_read_sample()
318 dev_err(dev->class_dev, in pci1710_ai_read_sample()
320 chan, devpriv->act_chanlist[cur_chan]); in pci1710_ai_read_sample()
321 return -ENODATA; in pci1710_ai_read_sample()
324 *val = sample & s->maxdata; in pci1710_ai_read_sample()
333 struct pci1710_private *devpriv = dev->private; in pci1710_ai_insn_read()
338 devpriv->ctrl |= PCI171X_CTRL_SW; in pci1710_ai_insn_read()
339 outw(devpriv->ctrl, dev->iobase + PCI171X_CTRL_REG); in pci1710_ai_insn_read()
341 outb(0, dev->iobase + PCI171X_CLRFIFO_REG); in pci1710_ai_insn_read()
342 outb(0, dev->iobase + PCI171X_CLRINT_REG); in pci1710_ai_insn_read()
344 pci1710_ai_setup_chanlist(dev, s, &insn->chanspec, 1, 1); in pci1710_ai_insn_read()
346 for (i = 0; i < insn->n; i++) { in pci1710_ai_insn_read()
350 outw(0, dev->iobase + PCI171X_SOFTTRG_REG); in pci1710_ai_insn_read()
364 devpriv->ctrl &= ~PCI171X_CTRL_SW; in pci1710_ai_insn_read()
365 outw(devpriv->ctrl, dev->iobase + PCI171X_CTRL_REG); in pci1710_ai_insn_read()
367 outb(0, dev->iobase + PCI171X_CLRFIFO_REG); in pci1710_ai_insn_read()
368 outb(0, dev->iobase + PCI171X_CLRINT_REG); in pci1710_ai_insn_read()
370 return ret ? ret : insn->n; in pci1710_ai_insn_read()
376 struct pci1710_private *devpriv = dev->private; in pci1710_ai_cancel()
379 devpriv->ctrl &= PCI171X_CTRL_CNT0; /* preserve counter 0 clk src */ in pci1710_ai_cancel()
380 outw(devpriv->ctrl, dev->iobase + PCI171X_CTRL_REG); in pci1710_ai_cancel()
383 comedi_8254_pacer_enable(dev->pacer, 1, 2, false); in pci1710_ai_cancel()
386 outb(0, dev->iobase + PCI171X_CLRFIFO_REG); in pci1710_ai_cancel()
387 outb(0, dev->iobase + PCI171X_CLRINT_REG); in pci1710_ai_cancel()
395 struct comedi_cmd *cmd = &s->async->cmd; in pci1710_handle_every_sample()
400 status = inw(dev->iobase + PCI171X_STATUS_REG); in pci1710_handle_every_sample()
402 dev_dbg(dev->class_dev, "A/D FIFO empty (%4x)\n", status); in pci1710_handle_every_sample()
403 s->async->events |= COMEDI_CB_ERROR; in pci1710_handle_every_sample()
407 dev_dbg(dev->class_dev, in pci1710_handle_every_sample()
409 s->async->events |= COMEDI_CB_ERROR; in pci1710_handle_every_sample()
413 outb(0, dev->iobase + PCI171X_CLRINT_REG); in pci1710_handle_every_sample()
415 for (; !(inw(dev->iobase + PCI171X_STATUS_REG) & PCI171X_STATUS_FE);) { in pci1710_handle_every_sample()
416 ret = pci1710_ai_read_sample(dev, s, s->async->cur_chan, &val); in pci1710_handle_every_sample()
418 s->async->events |= COMEDI_CB_ERROR; in pci1710_handle_every_sample()
424 if (cmd->stop_src == TRIG_COUNT && in pci1710_handle_every_sample()
425 s->async->scans_done >= cmd->stop_arg) { in pci1710_handle_every_sample()
426 s->async->events |= COMEDI_CB_EOA; in pci1710_handle_every_sample()
431 outb(0, dev->iobase + PCI171X_CLRINT_REG); in pci1710_handle_every_sample()
437 struct pci1710_private *devpriv = dev->private; in pci1710_handle_fifo()
438 struct comedi_async *async = s->async; in pci1710_handle_fifo()
439 struct comedi_cmd *cmd = &async->cmd; in pci1710_handle_fifo()
443 status = inw(dev->iobase + PCI171X_STATUS_REG); in pci1710_handle_fifo()
445 dev_dbg(dev->class_dev, "A/D FIFO not half full!\n"); in pci1710_handle_fifo()
446 async->events |= COMEDI_CB_ERROR; in pci1710_handle_fifo()
450 dev_dbg(dev->class_dev, in pci1710_handle_fifo()
452 async->events |= COMEDI_CB_ERROR; in pci1710_handle_fifo()
456 for (i = 0; i < devpriv->max_samples; i++) { in pci1710_handle_fifo()
460 ret = pci1710_ai_read_sample(dev, s, s->async->cur_chan, &val); in pci1710_handle_fifo()
462 s->async->events |= COMEDI_CB_ERROR; in pci1710_handle_fifo()
469 if (cmd->stop_src == TRIG_COUNT && in pci1710_handle_fifo()
470 async->scans_done >= cmd->stop_arg) { in pci1710_handle_fifo()
471 async->events |= COMEDI_CB_EOA; in pci1710_handle_fifo()
476 outb(0, dev->iobase + PCI171X_CLRINT_REG); in pci1710_handle_fifo()
482 struct pci1710_private *devpriv = dev->private; in pci1710_irq_handler()
486 if (!dev->attached) /* is device attached? */ in pci1710_irq_handler()
489 s = dev->read_subdev; in pci1710_irq_handler()
490 cmd = &s->async->cmd; in pci1710_irq_handler()
493 if (!(inw(dev->iobase + PCI171X_STATUS_REG) & PCI171X_STATUS_IRQ)) in pci1710_irq_handler()
496 if (devpriv->ai_et) { /* Switch from initial TRIG_EXT to TRIG_xxx. */ in pci1710_irq_handler()
497 devpriv->ai_et = 0; in pci1710_irq_handler()
498 devpriv->ctrl &= PCI171X_CTRL_CNT0; in pci1710_irq_handler()
499 devpriv->ctrl |= PCI171X_CTRL_SW; /* set software trigger */ in pci1710_irq_handler()
500 outw(devpriv->ctrl, dev->iobase + PCI171X_CTRL_REG); in pci1710_irq_handler()
501 devpriv->ctrl = devpriv->ctrl_ext; in pci1710_irq_handler()
502 outb(0, dev->iobase + PCI171X_CLRFIFO_REG); in pci1710_irq_handler()
503 outb(0, dev->iobase + PCI171X_CLRINT_REG); in pci1710_irq_handler()
505 outw(devpriv->mux_scan, dev->iobase + PCI171X_MUX_REG); in pci1710_irq_handler()
506 outw(devpriv->ctrl, dev->iobase + PCI171X_CTRL_REG); in pci1710_irq_handler()
507 comedi_8254_pacer_enable(dev->pacer, 1, 2, true); in pci1710_irq_handler()
511 if (cmd->flags & CMDF_WAKE_EOS) in pci1710_irq_handler()
523 struct pci1710_private *devpriv = dev->private; in pci1710_ai_cmd()
524 struct comedi_cmd *cmd = &s->async->cmd; in pci1710_ai_cmd()
526 pci1710_ai_setup_chanlist(dev, s, cmd->chanlist, cmd->chanlist_len, in pci1710_ai_cmd()
527 devpriv->saved_seglen); in pci1710_ai_cmd()
529 outb(0, dev->iobase + PCI171X_CLRFIFO_REG); in pci1710_ai_cmd()
530 outb(0, dev->iobase + PCI171X_CLRINT_REG); in pci1710_ai_cmd()
532 devpriv->ctrl &= PCI171X_CTRL_CNT0; in pci1710_ai_cmd()
533 if ((cmd->flags & CMDF_WAKE_EOS) == 0) in pci1710_ai_cmd()
534 devpriv->ctrl |= PCI171X_CTRL_ONEFH; in pci1710_ai_cmd()
536 if (cmd->convert_src == TRIG_TIMER) { in pci1710_ai_cmd()
537 comedi_8254_update_divisors(dev->pacer); in pci1710_ai_cmd()
539 devpriv->ctrl |= PCI171X_CTRL_PACER | PCI171X_CTRL_IRQEN; in pci1710_ai_cmd()
540 if (cmd->start_src == TRIG_EXT) { in pci1710_ai_cmd()
541 devpriv->ctrl_ext = devpriv->ctrl; in pci1710_ai_cmd()
542 devpriv->ctrl &= ~(PCI171X_CTRL_PACER | in pci1710_ai_cmd()
545 devpriv->ctrl |= PCI171X_CTRL_EXT; in pci1710_ai_cmd()
546 devpriv->ai_et = 1; in pci1710_ai_cmd()
548 devpriv->ai_et = 0; in pci1710_ai_cmd()
550 outw(devpriv->ctrl, dev->iobase + PCI171X_CTRL_REG); in pci1710_ai_cmd()
552 if (cmd->start_src == TRIG_NOW) in pci1710_ai_cmd()
553 comedi_8254_pacer_enable(dev->pacer, 1, 2, true); in pci1710_ai_cmd()
555 devpriv->ctrl |= PCI171X_CTRL_EXT | PCI171X_CTRL_IRQEN; in pci1710_ai_cmd()
556 outw(devpriv->ctrl, dev->iobase + PCI171X_CTRL_REG); in pci1710_ai_cmd()
570 err |= comedi_check_trigger_src(&cmd->start_src, TRIG_NOW | TRIG_EXT); in pci1710_ai_cmdtest()
571 err |= comedi_check_trigger_src(&cmd->scan_begin_src, TRIG_FOLLOW); in pci1710_ai_cmdtest()
572 err |= comedi_check_trigger_src(&cmd->convert_src, in pci1710_ai_cmdtest()
574 err |= comedi_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT); in pci1710_ai_cmdtest()
575 err |= comedi_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE); in pci1710_ai_cmdtest()
582 err |= comedi_check_trigger_is_unique(cmd->start_src); in pci1710_ai_cmdtest()
583 err |= comedi_check_trigger_is_unique(cmd->convert_src); in pci1710_ai_cmdtest()
584 err |= comedi_check_trigger_is_unique(cmd->stop_src); in pci1710_ai_cmdtest()
593 err |= comedi_check_trigger_arg_is(&cmd->start_arg, 0); in pci1710_ai_cmdtest()
594 err |= comedi_check_trigger_arg_is(&cmd->scan_begin_arg, 0); in pci1710_ai_cmdtest()
596 if (cmd->convert_src == TRIG_TIMER) in pci1710_ai_cmdtest()
597 err |= comedi_check_trigger_arg_min(&cmd->convert_arg, 10000); in pci1710_ai_cmdtest()
599 err |= comedi_check_trigger_arg_is(&cmd->convert_arg, 0); in pci1710_ai_cmdtest()
601 err |= comedi_check_trigger_arg_is(&cmd->scan_end_arg, in pci1710_ai_cmdtest()
602 cmd->chanlist_len); in pci1710_ai_cmdtest()
604 if (cmd->stop_src == TRIG_COUNT) in pci1710_ai_cmdtest()
605 err |= comedi_check_trigger_arg_min(&cmd->stop_arg, 1); in pci1710_ai_cmdtest()
607 err |= comedi_check_trigger_arg_is(&cmd->stop_arg, 0); in pci1710_ai_cmdtest()
614 if (cmd->convert_src == TRIG_TIMER) { in pci1710_ai_cmdtest()
615 unsigned int arg = cmd->convert_arg; in pci1710_ai_cmdtest()
617 comedi_8254_cascade_ns_to_timer(dev->pacer, &arg, cmd->flags); in pci1710_ai_cmdtest()
618 err |= comedi_check_trigger_arg_is(&cmd->convert_arg, arg); in pci1710_ai_cmdtest()
639 struct pci1710_private *devpriv = dev->private; in pci1710_ao_insn_write()
640 unsigned int chan = CR_CHAN(insn->chanspec); in pci1710_ao_insn_write()
641 unsigned int range = CR_RANGE(insn->chanspec); in pci1710_ao_insn_write()
642 unsigned int val = s->readback[chan]; in pci1710_ao_insn_write()
645 devpriv->da_ranges &= ~PCI171X_DAREF_MASK(chan); in pci1710_ao_insn_write()
646 devpriv->da_ranges |= PCI171X_DAREF(chan, range); in pci1710_ao_insn_write()
647 outw(devpriv->da_ranges, dev->iobase + PCI171X_DAREF_REG); in pci1710_ao_insn_write()
649 for (i = 0; i < insn->n; i++) { in pci1710_ao_insn_write()
651 outw(val, dev->iobase + PCI171X_DA_REG(chan)); in pci1710_ao_insn_write()
654 s->readback[chan] = val; in pci1710_ao_insn_write()
656 return insn->n; in pci1710_ao_insn_write()
664 data[1] = inw(dev->iobase + PCI171X_DI_REG); in pci1710_di_insn_bits()
666 return insn->n; in pci1710_di_insn_bits()
675 outw(s->state, dev->iobase + PCI171X_DO_REG); in pci1710_do_insn_bits()
677 data[1] = s->state; in pci1710_do_insn_bits()
679 return insn->n; in pci1710_do_insn_bits()
687 struct pci1710_private *devpriv = dev->private; in pci1710_counter_insn_config()
693 devpriv->ctrl_ext &= ~PCI171X_CTRL_CNT0; in pci1710_counter_insn_config()
696 devpriv->ctrl_ext |= PCI171X_CTRL_CNT0; in pci1710_counter_insn_config()
699 return -EINVAL; in pci1710_counter_insn_config()
701 outw(devpriv->ctrl_ext, dev->iobase + PCI171X_CTRL_REG); in pci1710_counter_insn_config()
704 if (devpriv->ctrl_ext & PCI171X_CTRL_CNT0) { in pci1710_counter_insn_config()
713 return -EINVAL; in pci1710_counter_insn_config()
716 return insn->n; in pci1710_counter_insn_config()
721 const struct boardtype *board = dev->board_ptr; in pci1710_reset()
727 outw(0, dev->iobase + PCI171X_CTRL_REG); in pci1710_reset()
730 outb(0, dev->iobase + PCI171X_CLRFIFO_REG); in pci1710_reset()
731 outb(0, dev->iobase + PCI171X_CLRINT_REG); in pci1710_reset()
733 if (board->has_ao) { in pci1710_reset()
735 outb(0, dev->iobase + PCI171X_DAREF_REG); in pci1710_reset()
736 outw(0, dev->iobase + PCI171X_DA_REG(0)); in pci1710_reset()
737 outw(0, dev->iobase + PCI171X_DA_REG(1)); in pci1710_reset()
741 outw(0, dev->iobase + PCI171X_DO_REG); in pci1710_reset()
757 return -ENODEV; in pci1710_auto_attach()
758 dev->board_ptr = board; in pci1710_auto_attach()
759 dev->board_name = board->name; in pci1710_auto_attach()
763 return -ENOMEM; in pci1710_auto_attach()
768 dev->iobase = pci_resource_start(pcidev, 2); in pci1710_auto_attach()
770 dev->pacer = comedi_8254_io_alloc(dev->iobase + PCI171X_TIMER_BASE, in pci1710_auto_attach()
772 if (IS_ERR(dev->pacer)) in pci1710_auto_attach()
773 return PTR_ERR(dev->pacer); in pci1710_auto_attach()
776 if (board->has_ao) in pci1710_auto_attach()
778 if (!board->is_pci1713) { in pci1710_auto_attach()
792 if (pcidev->irq) { in pci1710_auto_attach()
793 ret = request_irq(pcidev->irq, pci1710_irq_handler, in pci1710_auto_attach()
794 IRQF_SHARED, dev->board_name, dev); in pci1710_auto_attach()
796 dev->irq = pcidev->irq; in pci1710_auto_attach()
802 s = &dev->subdevices[subdev++]; in pci1710_auto_attach()
803 s->type = COMEDI_SUBD_AI; in pci1710_auto_attach()
804 s->subdev_flags = SDF_READABLE | SDF_GROUND; in pci1710_auto_attach()
805 if (!board->is_pci1711) in pci1710_auto_attach()
806 s->subdev_flags |= SDF_DIFF; in pci1710_auto_attach()
807 s->n_chan = board->is_pci1713 ? 32 : 16; in pci1710_auto_attach()
808 s->maxdata = 0x0fff; in pci1710_auto_attach()
809 s->range_table = board->ai_range; in pci1710_auto_attach()
810 s->insn_read = pci1710_ai_insn_read; in pci1710_auto_attach()
811 if (dev->irq) { in pci1710_auto_attach()
812 dev->read_subdev = s; in pci1710_auto_attach()
813 s->subdev_flags |= SDF_CMD_READ; in pci1710_auto_attach()
814 s->len_chanlist = s->n_chan; in pci1710_auto_attach()
815 s->do_cmdtest = pci1710_ai_cmdtest; in pci1710_auto_attach()
816 s->do_cmd = pci1710_ai_cmd; in pci1710_auto_attach()
817 s->cancel = pci1710_ai_cancel; in pci1710_auto_attach()
821 for (i = 0; i < s->range_table->length; i++) { in pci1710_auto_attach()
823 devpriv->unipolar_gain = i; in pci1710_auto_attach()
828 if (board->has_ao) { in pci1710_auto_attach()
830 s = &dev->subdevices[subdev++]; in pci1710_auto_attach()
831 s->type = COMEDI_SUBD_AO; in pci1710_auto_attach()
832 s->subdev_flags = SDF_WRITABLE | SDF_GROUND; in pci1710_auto_attach()
833 s->n_chan = 2; in pci1710_auto_attach()
834 s->maxdata = 0x0fff; in pci1710_auto_attach()
835 s->range_table = &pci171x_ao_range; in pci1710_auto_attach()
836 s->insn_write = pci1710_ao_insn_write; in pci1710_auto_attach()
843 if (!board->is_pci1713) { in pci1710_auto_attach()
845 s = &dev->subdevices[subdev++]; in pci1710_auto_attach()
846 s->type = COMEDI_SUBD_DI; in pci1710_auto_attach()
847 s->subdev_flags = SDF_READABLE; in pci1710_auto_attach()
848 s->n_chan = 16; in pci1710_auto_attach()
849 s->maxdata = 1; in pci1710_auto_attach()
850 s->range_table = &range_digital; in pci1710_auto_attach()
851 s->insn_bits = pci1710_di_insn_bits; in pci1710_auto_attach()
854 s = &dev->subdevices[subdev++]; in pci1710_auto_attach()
855 s->type = COMEDI_SUBD_DO; in pci1710_auto_attach()
856 s->subdev_flags = SDF_WRITABLE; in pci1710_auto_attach()
857 s->n_chan = 16; in pci1710_auto_attach()
858 s->maxdata = 1; in pci1710_auto_attach()
859 s->range_table = &range_digital; in pci1710_auto_attach()
860 s->insn_bits = pci1710_do_insn_bits; in pci1710_auto_attach()
863 s = &dev->subdevices[subdev++]; in pci1710_auto_attach()
864 comedi_8254_subdevice_init(s, dev->pacer); in pci1710_auto_attach()
866 dev->pacer->insn_config = pci1710_counter_insn_config; in pci1710_auto_attach()
869 comedi_8254_set_busy(dev->pacer, 1, true); in pci1710_auto_attach()
870 comedi_8254_set_busy(dev->pacer, 2, true); in pci1710_auto_attach()
873 /* max_samples is half the FIFO size (2 bytes/sample) */ in pci1710_auto_attach()
874 devpriv->max_samples = (board->is_pci1711) ? 512 : 2048; in pci1710_auto_attach()
890 id->driver_data); in adv_pci1710_pci_probe()
961 MODULE_DESCRIPTION("Comedi: Advantech PCI-1710 Series Multifunction DAS Cards");