Lines Matching +full:ref +full:- +full:clock +full:- +full:period +full:- +full:ns
1 // SPDX-License-Identifier: GPL-2.0+
6 * COMEDI - Linux Control and Measurement Device Interface
13 * Devices: [Real Time Devices] DM7520HR-1 (DM7520), DM7520HR-8,
14 * PCI4520 (PCI4520), PCI4520-8
16 * Status: Works. Only tested on DM7520-8. Not SMP safe.
24 * The PCI4520 is a PCI card. The DM7520 is a PC/104-plus card.
40 * These boards can support external multiplexors and multi-board
71 * Analog-In supports instruction and command mode.
73 * With DMA, you can sample at 1.15Mhz with 70% idle on a 400Mhz K6-2
75 * using DMA with ALI-15xx based systems. I haven't been able to test
79 * Without DMA, you can do 620Khz sampling with 20% idle on a 400Mhz K6-2
82 * Digital-IO and Analog-Out only support instruction mode.
128 #define IRQM_ETRIG_RISING BIT(14) /* Ext Trigger rising-edge */
129 #define IRQM_ETRIG_FALLING BIT(15) /* Ext Trigger falling-edge */
132 #define LAS0_PCLK 0x0040 /* Pacer Clock (24bit) */
133 #define LAS0_BCLK 0x0044 /* Burst Clock (10bit) */
139 #define LAS0_DAC_CLK 0x005c /* DAC clock (16bit) */
149 #define LAS0_BURST_START 0x0110 /* Burst Clock Start Trigger select */
150 #define LAS0_PACER_START 0x0114 /* Pacer Clock Start Trigger select */
151 #define LAS0_PACER_STOP 0x0118 /* Pacer Clock Stop Trigger select */
171 #define LAS0_PACER_SELECT 0x0180 /* Pacer Clock select */
180 #define LAS0_8254_CLK_SEL(x) (0x01ac + ((x) * 0x8)) /* 8254 clock select */
204 /* Target period for periodic transfers. This sets the user read latency. */
217 #define RTD_CLOCK_RATE 8000000 /* 8Mhz onboard clock */
218 #define RTD_CLOCK_BASE 125 /* clock period in ns */
253 /* +-5V input range gain steps */
260 /* +-10V input range gain steps */
280 /* +-5V input range gain steps */
289 /* +-10V input range gain steps */
327 int range_bip10; /* start of +-10V range */
353 int xfer_count; /* # to transfer data. 0->1/2FIFO */
357 /* 8254 Timer/Counter gate and clock sources */
368 * Given a desired period and the clock period (both in ns), return the
369 * proper counter value (divider-1). Sets the original period to be the
399 return divider - 1; /* countdown is divisor+1 */ in rtd_ns_to_timer_base()
403 * Given a desired period (in ns), return the proper counter value
404 * (divider-1) for the internal clock. Sets the original period to
407 static int rtd_ns_to_timer(unsigned int *ns, unsigned int flags) in rtd_ns_to_timer() argument
409 return rtd_ns_to_timer_base(ns, flags, RTD_CLOCK_BASE); in rtd_ns_to_timer()
412 /* Convert a single comedi channel-gain entry to a RTD520 table entry */
416 const struct rtd_boardinfo *board = dev->board_ptr; in rtd_convert_chan_gain()
425 if (range < board->range_bip10) { in rtd_convert_chan_gain()
426 /* +-5 range */ in rtd_convert_chan_gain()
429 } else if (range < board->range_uni10) { in rtd_convert_chan_gain()
430 /* +-10 range */ in rtd_convert_chan_gain()
432 r |= ((range - board->range_bip10) & 0x7) << 4; in rtd_convert_chan_gain()
436 r |= ((range - board->range_uni10) & 0x7) << 4; in rtd_convert_chan_gain()
440 case AREF_GROUND: /* on-board ground */ in rtd_convert_chan_gain()
444 r |= 0x80; /* ref external analog common */ in rtd_convert_chan_gain()
457 /* Setup the channel-gain table from a comedi list */
464 writel(0, dev->mmio + LAS0_CGT_CLEAR); in rtd_load_channelgain_list()
465 writel(1, dev->mmio + LAS0_CGT_ENABLE); in rtd_load_channelgain_list()
468 dev->mmio + LAS0_CGT_WRITE); in rtd_load_channelgain_list()
471 writel(0, dev->mmio + LAS0_CGT_ENABLE); in rtd_load_channelgain_list()
473 dev->mmio + LAS0_CGL_WRITE); in rtd_load_channelgain_list()
488 writel(0, dev->mmio + LAS0_ADC_FIFO_CLEAR); in rtd520_probe_fifo_depth()
491 writel(0, dev->mmio + LAS0_ADC_CONVERSION); in rtd520_probe_fifo_depth()
496 writew(0, dev->mmio + LAS0_ADC); in rtd520_probe_fifo_depth()
498 fifo_status = readl(dev->mmio + LAS0_ADC); in rtd520_probe_fifo_depth()
505 dev_info(dev->class_dev, "failed to probe fifo size.\n"); in rtd520_probe_fifo_depth()
506 return -EIO; in rtd520_probe_fifo_depth()
508 writel(0, dev->mmio + LAS0_ADC_FIFO_CLEAR); in rtd520_probe_fifo_depth()
510 dev_info(dev->class_dev, in rtd520_probe_fifo_depth()
513 return -EIO; in rtd520_probe_fifo_depth()
525 status = readl(dev->mmio + LAS0_ADC); in rtd_ai_eoc()
528 return -EBUSY; in rtd_ai_eoc()
535 struct rtd_private *devpriv = dev->private; in rtd_ai_rinsn()
536 unsigned int range = CR_RANGE(insn->chanspec); in rtd_ai_rinsn()
541 writel(0, dev->mmio + LAS0_ADC_FIFO_CLEAR); in rtd_ai_rinsn()
544 rtd_load_channelgain_list(dev, 1, &insn->chanspec); in rtd_ai_rinsn()
547 writel(0, dev->mmio + LAS0_ADC_CONVERSION); in rtd_ai_rinsn()
550 for (n = 0; n < insn->n; n++) { in rtd_ai_rinsn()
553 writew(0, dev->mmio + LAS0_ADC); in rtd_ai_rinsn()
560 d = readw(devpriv->las1 + LAS1_ADC_FIFO); in rtd_ai_rinsn()
567 data[n] = d & s->maxdata; in rtd_ai_rinsn()
577 struct rtd_private *devpriv = dev->private; in ai_read_n()
578 struct comedi_async *async = s->async; in ai_read_n()
579 struct comedi_cmd *cmd = &async->cmd; in ai_read_n()
583 unsigned int range = CR_RANGE(cmd->chanlist[async->cur_chan]); in ai_read_n()
586 if (devpriv->ai_count == 0) { /* done */ in ai_read_n()
587 d = readw(devpriv->las1 + LAS1_ADC_FIFO); in ai_read_n()
591 d = readw(devpriv->las1 + LAS1_ADC_FIFO); in ai_read_n()
597 d &= s->maxdata; in ai_read_n()
600 return -1; in ai_read_n()
602 if (devpriv->ai_count > 0) /* < 0, means read forever */ in ai_read_n()
603 devpriv->ai_count--; in ai_read_n()
611 struct comedi_subdevice *s = dev->read_subdev; in rtd_interrupt()
612 struct rtd_private *devpriv = dev->private; in rtd_interrupt()
617 if (!dev->attached) in rtd_interrupt()
620 fifo_status = readl(dev->mmio + LAS0_ADC); in rtd_interrupt()
622 if (!(fifo_status & FS_ADC_NOT_FULL)) /* 0 -> full */ in rtd_interrupt()
625 status = readw(dev->mmio + LAS0_IT); in rtd_interrupt()
630 if (status & IRQM_ADC_ABOUT_CNT) { /* sample count -> read FIFO */ in rtd_interrupt()
639 if (ai_read_n(dev, s, devpriv->fifosz / 2) < 0) in rtd_interrupt()
642 if (devpriv->ai_count == 0) in rtd_interrupt()
644 } else if (devpriv->xfer_count > 0) { in rtd_interrupt()
647 if (ai_read_n(dev, s, devpriv->xfer_count) < 0) in rtd_interrupt()
650 if (devpriv->ai_count == 0) in rtd_interrupt()
656 overrun = readl(dev->mmio + LAS0_OVERRUN) & 0xffff; in rtd_interrupt()
661 writew(status, dev->mmio + LAS0_CLEAR); in rtd_interrupt()
662 readw(dev->mmio + LAS0_CLEAR); in rtd_interrupt()
669 s->async->events |= COMEDI_CB_ERROR; in rtd_interrupt()
672 s->async->events |= COMEDI_CB_EOA; in rtd_interrupt()
675 status = readw(dev->mmio + LAS0_IT); in rtd_interrupt()
676 writew(status, dev->mmio + LAS0_CLEAR); in rtd_interrupt()
677 readw(dev->mmio + LAS0_CLEAR); in rtd_interrupt()
679 fifo_status = readl(dev->mmio + LAS0_ADC); in rtd_interrupt()
680 overrun = readl(dev->mmio + LAS0_OVERRUN) & 0xffff; in rtd_interrupt()
695 err |= comedi_check_trigger_src(&cmd->start_src, TRIG_NOW); in rtd_ai_cmdtest()
696 err |= comedi_check_trigger_src(&cmd->scan_begin_src, in rtd_ai_cmdtest()
698 err |= comedi_check_trigger_src(&cmd->convert_src, in rtd_ai_cmdtest()
700 err |= comedi_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT); in rtd_ai_cmdtest()
701 err |= comedi_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE); in rtd_ai_cmdtest()
708 err |= comedi_check_trigger_is_unique(cmd->scan_begin_src); in rtd_ai_cmdtest()
709 err |= comedi_check_trigger_is_unique(cmd->convert_src); in rtd_ai_cmdtest()
710 err |= comedi_check_trigger_is_unique(cmd->stop_src); in rtd_ai_cmdtest()
719 err |= comedi_check_trigger_arg_is(&cmd->start_arg, 0); in rtd_ai_cmdtest()
721 if (cmd->scan_begin_src == TRIG_TIMER) { in rtd_ai_cmdtest()
723 if (cmd->chanlist_len == 1) { /* no scanning */ in rtd_ai_cmdtest()
724 if (comedi_check_trigger_arg_min(&cmd->scan_begin_arg, in rtd_ai_cmdtest()
726 rtd_ns_to_timer(&cmd->scan_begin_arg, in rtd_ai_cmdtest()
728 err |= -EINVAL; in rtd_ai_cmdtest()
730 if (comedi_check_trigger_arg_max(&cmd->scan_begin_arg, in rtd_ai_cmdtest()
732 rtd_ns_to_timer(&cmd->scan_begin_arg, in rtd_ai_cmdtest()
734 err |= -EINVAL; in rtd_ai_cmdtest()
737 if (comedi_check_trigger_arg_min(&cmd->scan_begin_arg, in rtd_ai_cmdtest()
739 rtd_ns_to_timer(&cmd->scan_begin_arg, in rtd_ai_cmdtest()
741 err |= -EINVAL; in rtd_ai_cmdtest()
743 if (comedi_check_trigger_arg_max(&cmd->scan_begin_arg, in rtd_ai_cmdtest()
745 rtd_ns_to_timer(&cmd->scan_begin_arg, in rtd_ai_cmdtest()
747 err |= -EINVAL; in rtd_ai_cmdtest()
754 err |= comedi_check_trigger_arg_max(&cmd->scan_begin_arg, 9); in rtd_ai_cmdtest()
757 if (cmd->convert_src == TRIG_TIMER) { in rtd_ai_cmdtest()
758 if (cmd->chanlist_len == 1) { /* no scanning */ in rtd_ai_cmdtest()
759 if (comedi_check_trigger_arg_min(&cmd->convert_arg, in rtd_ai_cmdtest()
761 rtd_ns_to_timer(&cmd->convert_arg, in rtd_ai_cmdtest()
763 err |= -EINVAL; in rtd_ai_cmdtest()
765 if (comedi_check_trigger_arg_max(&cmd->convert_arg, in rtd_ai_cmdtest()
767 rtd_ns_to_timer(&cmd->convert_arg, in rtd_ai_cmdtest()
769 err |= -EINVAL; in rtd_ai_cmdtest()
772 if (comedi_check_trigger_arg_min(&cmd->convert_arg, in rtd_ai_cmdtest()
774 rtd_ns_to_timer(&cmd->convert_arg, in rtd_ai_cmdtest()
776 err |= -EINVAL; in rtd_ai_cmdtest()
778 if (comedi_check_trigger_arg_max(&cmd->convert_arg, in rtd_ai_cmdtest()
780 rtd_ns_to_timer(&cmd->convert_arg, in rtd_ai_cmdtest()
782 err |= -EINVAL; in rtd_ai_cmdtest()
788 err |= comedi_check_trigger_arg_max(&cmd->convert_arg, 9); in rtd_ai_cmdtest()
791 err |= comedi_check_trigger_arg_is(&cmd->scan_end_arg, in rtd_ai_cmdtest()
792 cmd->chanlist_len); in rtd_ai_cmdtest()
794 if (cmd->stop_src == TRIG_COUNT) in rtd_ai_cmdtest()
795 err |= comedi_check_trigger_arg_min(&cmd->stop_arg, 1); in rtd_ai_cmdtest()
797 err |= comedi_check_trigger_arg_is(&cmd->stop_arg, 0); in rtd_ai_cmdtest()
804 if (cmd->scan_begin_src == TRIG_TIMER) { in rtd_ai_cmdtest()
805 arg = cmd->scan_begin_arg; in rtd_ai_cmdtest()
806 rtd_ns_to_timer(&arg, cmd->flags); in rtd_ai_cmdtest()
807 err |= comedi_check_trigger_arg_is(&cmd->scan_begin_arg, arg); in rtd_ai_cmdtest()
810 if (cmd->convert_src == TRIG_TIMER) { in rtd_ai_cmdtest()
811 arg = cmd->convert_arg; in rtd_ai_cmdtest()
812 rtd_ns_to_timer(&arg, cmd->flags); in rtd_ai_cmdtest()
813 err |= comedi_check_trigger_arg_is(&cmd->convert_arg, arg); in rtd_ai_cmdtest()
815 if (cmd->scan_begin_src == TRIG_TIMER) { in rtd_ai_cmdtest()
816 arg = cmd->convert_arg * cmd->scan_end_arg; in rtd_ai_cmdtest()
818 &cmd->scan_begin_arg, arg); in rtd_ai_cmdtest()
830 struct rtd_private *devpriv = dev->private; in rtd_ai_cmd()
831 struct comedi_cmd *cmd = &s->async->cmd; in rtd_ai_cmd()
836 writel(0, dev->mmio + LAS0_PACER_STOP); in rtd_ai_cmd()
837 writel(0, dev->mmio + LAS0_PACER); /* stop pacer */ in rtd_ai_cmd()
838 writel(0, dev->mmio + LAS0_ADC_CONVERSION); in rtd_ai_cmd()
839 writew(0, dev->mmio + LAS0_IT); in rtd_ai_cmd()
840 writel(0, dev->mmio + LAS0_ADC_FIFO_CLEAR); in rtd_ai_cmd()
841 writel(0, dev->mmio + LAS0_OVERRUN); in rtd_ai_cmd()
845 rtd_load_channelgain_list(dev, cmd->chanlist_len, cmd->chanlist); in rtd_ai_cmd()
848 if (cmd->chanlist_len > 1) { in rtd_ai_cmd()
850 writel(0, dev->mmio + LAS0_PACER_START); in rtd_ai_cmd()
852 writel(1, dev->mmio + LAS0_BURST_START); in rtd_ai_cmd()
854 writel(2, dev->mmio + LAS0_ADC_CONVERSION); in rtd_ai_cmd()
857 writel(0, dev->mmio + LAS0_PACER_START); in rtd_ai_cmd()
859 writel(1, dev->mmio + LAS0_ADC_CONVERSION); in rtd_ai_cmd()
861 writel((devpriv->fifosz / 2 - 1) & 0xffff, dev->mmio + LAS0_ACNT); in rtd_ai_cmd()
863 if (cmd->scan_begin_src == TRIG_TIMER) { in rtd_ai_cmd()
866 if (cmd->flags & CMDF_WAKE_EOS) { in rtd_ai_cmd()
868 * this may generate un-sustainable interrupt rates in rtd_ai_cmd()
872 devpriv->xfer_count = cmd->chanlist_len; in rtd_ai_cmd()
873 devpriv->flags |= SEND_EOS; in rtd_ai_cmd()
876 devpriv->xfer_count = in rtd_ai_cmd()
877 (TRANS_TARGET_PERIOD * cmd->chanlist_len) / in rtd_ai_cmd()
878 cmd->scan_begin_arg; in rtd_ai_cmd()
879 if (devpriv->xfer_count < cmd->chanlist_len) { in rtd_ai_cmd()
881 devpriv->xfer_count = cmd->chanlist_len; in rtd_ai_cmd()
883 devpriv->xfer_count = in rtd_ai_cmd()
884 DIV_ROUND_UP(devpriv->xfer_count, in rtd_ai_cmd()
885 cmd->chanlist_len); in rtd_ai_cmd()
886 devpriv->xfer_count *= cmd->chanlist_len; in rtd_ai_cmd()
888 devpriv->flags |= SEND_EOS; in rtd_ai_cmd()
890 if (devpriv->xfer_count >= (devpriv->fifosz / 2)) { in rtd_ai_cmd()
892 devpriv->xfer_count = 0; in rtd_ai_cmd()
893 devpriv->flags &= ~SEND_EOS; in rtd_ai_cmd()
896 writel((devpriv->xfer_count - 1) & 0xffff, in rtd_ai_cmd()
897 dev->mmio + LAS0_ACNT); in rtd_ai_cmd()
900 devpriv->xfer_count = 0; in rtd_ai_cmd()
901 devpriv->flags &= ~SEND_EOS; in rtd_ai_cmd()
903 /* pacer clock source: INTERNAL 8MHz */ in rtd_ai_cmd()
904 writel(1, dev->mmio + LAS0_PACER_SELECT); in rtd_ai_cmd()
906 writel(1, dev->mmio + LAS0_ACNT_STOP_ENABLE); in rtd_ai_cmd()
911 switch (cmd->stop_src) { in rtd_ai_cmd()
913 devpriv->ai_count = cmd->stop_arg * cmd->chanlist_len; in rtd_ai_cmd()
914 if ((devpriv->xfer_count > 0) && in rtd_ai_cmd()
915 (devpriv->xfer_count > devpriv->ai_count)) { in rtd_ai_cmd()
916 devpriv->xfer_count = devpriv->ai_count; in rtd_ai_cmd()
921 devpriv->ai_count = -1; /* read forever */ in rtd_ai_cmd()
926 switch (cmd->scan_begin_src) { in rtd_ai_cmd()
928 timer = rtd_ns_to_timer(&cmd->scan_begin_arg, in rtd_ai_cmd()
930 /* set PACER clock */ in rtd_ai_cmd()
931 writel(timer & 0xffffff, dev->mmio + LAS0_PCLK); in rtd_ai_cmd()
937 writel(1, dev->mmio + LAS0_PACER_START); in rtd_ai_cmd()
942 switch (cmd->convert_src) { in rtd_ai_cmd()
944 if (cmd->chanlist_len > 1) { in rtd_ai_cmd()
945 /* only needed for multi-channel */ in rtd_ai_cmd()
946 timer = rtd_ns_to_timer(&cmd->convert_arg, in rtd_ai_cmd()
948 /* setup BURST clock */ in rtd_ai_cmd()
949 writel(timer & 0x3ff, dev->mmio + LAS0_BCLK); in rtd_ai_cmd()
956 writel(2, dev->mmio + LAS0_BURST_START); in rtd_ai_cmd()
965 writew(~0, dev->mmio + LAS0_CLEAR); in rtd_ai_cmd()
966 readw(dev->mmio + LAS0_CLEAR); in rtd_ai_cmd()
970 writew(IRQM_ADC_ABOUT_CNT, dev->mmio + LAS0_IT); in rtd_ai_cmd()
974 readl(dev->mmio + LAS0_PACER); /* start pacer */ in rtd_ai_cmd()
980 struct rtd_private *devpriv = dev->private; in rtd_ai_cancel()
983 writel(0, dev->mmio + LAS0_PACER_STOP); in rtd_ai_cancel()
984 writel(0, dev->mmio + LAS0_PACER); /* stop pacer */ in rtd_ai_cancel()
985 writel(0, dev->mmio + LAS0_ADC_CONVERSION); in rtd_ai_cancel()
986 writew(0, dev->mmio + LAS0_IT); in rtd_ai_cancel()
987 devpriv->ai_count = 0; /* stop and don't transfer any more */ in rtd_ai_cancel()
988 writel(0, dev->mmio + LAS0_ADC_FIFO_CLEAR); in rtd_ai_cancel()
997 unsigned int chan = CR_CHAN(insn->chanspec); in rtd_ao_eoc()
1001 status = readl(dev->mmio + LAS0_ADC); in rtd_ao_eoc()
1004 return -EBUSY; in rtd_ao_eoc()
1012 struct rtd_private *devpriv = dev->private; in rtd_ao_insn_write()
1013 unsigned int chan = CR_CHAN(insn->chanspec); in rtd_ao_insn_write()
1014 unsigned int range = CR_RANGE(insn->chanspec); in rtd_ao_insn_write()
1019 writew(range & 7, dev->mmio + LAS0_DAC_CTRL(chan)); in rtd_ao_insn_write()
1021 for (i = 0; i < insn->n; ++i) { in rtd_ao_insn_write()
1027 val |= (val & ((s->maxdata + 1) >> 1)) << 1; in rtd_ao_insn_write()
1030 /* shift the 12-bit data (+ sign) to match the register */ in rtd_ao_insn_write()
1033 writew(val, devpriv->las1 + LAS1_DAC_FIFO(chan)); in rtd_ao_insn_write()
1034 writew(0, dev->mmio + LAS0_UPDATE_DAC(chan)); in rtd_ao_insn_write()
1040 s->readback[chan] = data[i]; in rtd_ao_insn_write()
1043 return insn->n; in rtd_ao_insn_write()
1052 writew(s->state & 0xff, dev->mmio + LAS0_DIO0); in rtd_dio_insn_bits()
1054 data[1] = readw(dev->mmio + LAS0_DIO0) & 0xff; in rtd_dio_insn_bits()
1056 return insn->n; in rtd_dio_insn_bits()
1073 writew(0x01, dev->mmio + LAS0_DIO_STATUS); in rtd_dio_insn_config()
1074 writew(s->io_bits & 0xff, dev->mmio + LAS0_DIO0_CTRL); in rtd_dio_insn_config()
1077 writew(0x00, dev->mmio + LAS0_DIO_STATUS); in rtd_dio_insn_config()
1083 return insn->n; in rtd_dio_insn_config()
1091 struct rtd_private *devpriv = dev->private; in rtd_counter_insn_config()
1092 unsigned int chan = CR_CHAN(insn->chanspec); in rtd_counter_insn_config()
1110 return -EINVAL; in rtd_counter_insn_config()
1112 devpriv->timer_gate_src[chan] = src; in rtd_counter_insn_config()
1113 writeb(src, dev->mmio + LAS0_8254_GATE_SEL(chan)); in rtd_counter_insn_config()
1116 data[2] = devpriv->timer_gate_src[chan]; in rtd_counter_insn_config()
1120 * 8254 Timer/Counter clock sources: in rtd_counter_insn_config()
1123 * 1 = Ext. TC Clock 1 in rtd_counter_insn_config()
1124 * 2 = Ext. TX Clock 2 in rtd_counter_insn_config()
1125 * 3 = Ext. Pacer Clock in rtd_counter_insn_config()
1127 * 5 = High-Speed Digital Input Sampling signal (chan 1 only) in rtd_counter_insn_config()
1141 return -EINVAL; in rtd_counter_insn_config()
1144 return -EINVAL; in rtd_counter_insn_config()
1146 devpriv->timer_clk_src[chan] = src; in rtd_counter_insn_config()
1147 writeb(src, dev->mmio + LAS0_8254_CLK_SEL(chan)); in rtd_counter_insn_config()
1150 src = devpriv->timer_clk_src[chan]; in rtd_counter_insn_config()
1151 data[1] = devpriv->timer_clk_src[chan]; in rtd_counter_insn_config()
1155 return -EINVAL; in rtd_counter_insn_config()
1158 return insn->n; in rtd_counter_insn_config()
1163 struct rtd_private *devpriv = dev->private; in rtd_reset()
1165 writel(0, dev->mmio + LAS0_BOARD_RESET); in rtd_reset()
1167 writel(0, devpriv->lcfg + PLX_REG_INTCSR); in rtd_reset()
1168 writew(0, dev->mmio + LAS0_IT); in rtd_reset()
1169 writew(~0, dev->mmio + LAS0_CLEAR); in rtd_reset()
1170 readw(dev->mmio + LAS0_CLEAR); in rtd_reset()
1181 writel(0, dev->mmio + LAS0_OVERRUN); in rtd_init_board()
1182 writel(0, dev->mmio + LAS0_CGT_CLEAR); in rtd_init_board()
1183 writel(0, dev->mmio + LAS0_ADC_FIFO_CLEAR); in rtd_init_board()
1184 writel(0, dev->mmio + LAS0_DAC_RESET(0)); in rtd_init_board()
1185 writel(0, dev->mmio + LAS0_DAC_RESET(1)); in rtd_init_board()
1187 writew(0, dev->mmio + LAS0_DIO_STATUS); in rtd_init_board()
1199 dev_info(dev->class_dev, in rtd_pci_latency_quirk()
1218 return -ENODEV; in rtd_auto_attach()
1219 dev->board_ptr = board; in rtd_auto_attach()
1220 dev->board_name = board->name; in rtd_auto_attach()
1224 return -ENOMEM; in rtd_auto_attach()
1230 dev->mmio = pci_ioremap_bar(pcidev, 2); in rtd_auto_attach()
1231 devpriv->las1 = pci_ioremap_bar(pcidev, 3); in rtd_auto_attach()
1232 devpriv->lcfg = pci_ioremap_bar(pcidev, 0); in rtd_auto_attach()
1233 if (!dev->mmio || !devpriv->las1 || !devpriv->lcfg) in rtd_auto_attach()
1234 return -ENOMEM; in rtd_auto_attach()
1238 if (pcidev->irq) { in rtd_auto_attach()
1239 ret = request_irq(pcidev->irq, rtd_interrupt, IRQF_SHARED, in rtd_auto_attach()
1240 dev->board_name, dev); in rtd_auto_attach()
1242 dev->irq = pcidev->irq; in rtd_auto_attach()
1249 s = &dev->subdevices[0]; in rtd_auto_attach()
1251 s->type = COMEDI_SUBD_AI; in rtd_auto_attach()
1252 s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_COMMON | SDF_DIFF; in rtd_auto_attach()
1253 s->n_chan = 16; in rtd_auto_attach()
1254 s->maxdata = 0x0fff; in rtd_auto_attach()
1255 s->range_table = board->ai_range; in rtd_auto_attach()
1256 s->len_chanlist = RTD_MAX_CHANLIST; in rtd_auto_attach()
1257 s->insn_read = rtd_ai_rinsn; in rtd_auto_attach()
1258 if (dev->irq) { in rtd_auto_attach()
1259 dev->read_subdev = s; in rtd_auto_attach()
1260 s->subdev_flags |= SDF_CMD_READ; in rtd_auto_attach()
1261 s->do_cmd = rtd_ai_cmd; in rtd_auto_attach()
1262 s->do_cmdtest = rtd_ai_cmdtest; in rtd_auto_attach()
1263 s->cancel = rtd_ai_cancel; in rtd_auto_attach()
1266 s = &dev->subdevices[1]; in rtd_auto_attach()
1268 s->type = COMEDI_SUBD_AO; in rtd_auto_attach()
1269 s->subdev_flags = SDF_WRITABLE; in rtd_auto_attach()
1270 s->n_chan = 2; in rtd_auto_attach()
1271 s->maxdata = 0x0fff; in rtd_auto_attach()
1272 s->range_table = &rtd_ao_range; in rtd_auto_attach()
1273 s->insn_write = rtd_ao_insn_write; in rtd_auto_attach()
1279 s = &dev->subdevices[2]; in rtd_auto_attach()
1281 s->type = COMEDI_SUBD_DIO; in rtd_auto_attach()
1282 s->subdev_flags = SDF_READABLE | SDF_WRITABLE; in rtd_auto_attach()
1284 s->n_chan = 8; in rtd_auto_attach()
1285 s->maxdata = 1; in rtd_auto_attach()
1286 s->range_table = &range_digital; in rtd_auto_attach()
1287 s->insn_bits = rtd_dio_insn_bits; in rtd_auto_attach()
1288 s->insn_config = rtd_dio_insn_config; in rtd_auto_attach()
1291 s = &dev->subdevices[3]; in rtd_auto_attach()
1292 dev->pacer = comedi_8254_mm_alloc(dev->mmio + LAS0_8254_TIMER_BASE, in rtd_auto_attach()
1294 if (IS_ERR(dev->pacer)) in rtd_auto_attach()
1295 return -ENOMEM; in rtd_auto_attach()
1297 comedi_8254_subdevice_init(s, dev->pacer); in rtd_auto_attach()
1298 dev->pacer->insn_config = rtd_counter_insn_config; in rtd_auto_attach()
1305 devpriv->fifosz = ret; in rtd_auto_attach()
1307 if (dev->irq) in rtd_auto_attach()
1309 devpriv->lcfg + PLX_REG_INTCSR); in rtd_auto_attach()
1316 struct rtd_private *devpriv = dev->private; in rtd_detach()
1320 if (dev->mmio && devpriv->lcfg) in rtd_detach()
1322 if (dev->irq) in rtd_detach()
1323 free_irq(dev->irq, dev); in rtd_detach()
1324 if (dev->mmio) in rtd_detach()
1325 iounmap(dev->mmio); in rtd_detach()
1326 if (devpriv->las1) in rtd_detach()
1327 iounmap(devpriv->las1); in rtd_detach()
1328 if (devpriv->lcfg) in rtd_detach()
1329 iounmap(devpriv->lcfg); in rtd_detach()
1344 return comedi_pci_auto_config(dev, &rtd520_driver, id->driver_data); in rtd520_pci_probe()
1363 MODULE_DESCRIPTION("Comedi low-level driver");