• Home
  • Raw
  • Download

Lines Matching +full:differential +full:- +full:pair

1 // SPDX-License-Identifier: GPL-2.0+
8 * COMEDI - Linux Control and Measurement Device Interface
35 * --------- ---------
43 * The AI subdevice has 16 single-ended channels or 8 differential
46 * The PCI230 and PCI260 cards have 12-bit resolution. The PCI230+ and
47 * PCI260+ cards have 16-bit resolution.
49 * For differential mode, use inputs 2N and 2N+1 for channel N (e.g. use
51 * or PCI260 then it actually uses a "pseudo-differential" mode where the
53 * use true differential sampling. Another difference is that if the
57 * PCI260+) and differential mode is used, the differential inputs need
62 * 0 => [-10, +10] V
63 * 1 => [-5, +5] V
64 * 2 => [-2.5, +2.5] V
65 * 3 => [-1.25, +1.25] V
78 * | |--------------|-----------| | |
82 * +---------+--------------+-----------+------------+----------+
104 * If the analogue reference is not AREF_DIFF (not differential) each
105 * pair of channel numbers (0 and 1, 2 and 3, etc.) must use the same
120 * The AO subdevice has 2 channels with 12-bit resolution.
123 * 1 => [-10, +10] V
133 * +---------+--------------+-----------+------------+----------+
155 * Port A - channels 0 to 7
156 * Port B - channels 8 to 15
157 * Port CL - channels 16 to 19
158 * Port CH - channels 20 to 23
168 * Extra triggered scan functionality, interrupt bug-fix added by Steve
217 #define PCI230P_ADCPTSC 0x18 /* ADC pre-trigger sample count (r) */
227 * DACCON read-write values.
246 #define PCI230P2_DAC_TRIG_EXTN PCI230P2_DAC_TRIG(3) /* ext - edge */
262 * DACCON read-only values.
275 * DACCON write-only, transient values.
292 (PCI230P2_DAC_FIFOLEVEL_FULL - PCI230P2_DAC_FIFOLEVEL_HALF)
303 #define PCI230_ADC_TRIG_EXTN PCI230_ADC_TRIG(3) /* ext - edge */
314 #define PCI230_ADC_IM_DIF PCI230_ADC_IM(1) /* differential */
328 * ADCCON write-only, transient values.
334 * ADCCON read-only values.
360 #define CLK_CLK 0 /* reserved (channel-specific clock) */
366 #define CLK_OUTNM1 6 /* output of channel-1 modulo total */
380 #define GAT_NOUTNM2 3 /* inverted output of channel-2 modulo total */
393 * ------- ---------- -----------
394 * Z2-CT0 Z2-CT2-OUT /Z2-CT1-OUT
395 * Z2-CT1 Z2-CT0-OUT /Z2-CT2-OUT
396 * Z2-CT2 Z2-CT1-OUT /Z2-CT0-OUT
414 RES_Z2CT0 = BIT(0), /* Z2-CT0 */
415 RES_Z2CT1 = BIT(1), /* Z2-CT1 */
416 RES_Z2CT2 = BIT(2) /* Z2-CT2 */
533 const struct pci230_board *board = dev->board_ptr; in pci230_ai_read()
534 struct pci230_private *devpriv = dev->private; in pci230_ai_read()
538 data = inw(devpriv->daqio + PCI230_ADCDATA); in pci230_ai_read()
540 * PCI230 is 12 bit - stored in upper bits of 16 bit register in pci230_ai_read()
544 * (twos complement->straight binary). in pci230_ai_read()
546 if (devpriv->ai_bipolar) in pci230_ai_read()
548 data >>= (16 - board->ai_bits); in pci230_ai_read()
555 const struct pci230_board *board = dev->board_ptr; in pci230_ao_mangle_datum()
556 struct pci230_private *devpriv = dev->private; in pci230_ao_mangle_datum()
559 * PCI230 is 12 bit - stored in upper bits of 16 bit register (lower in pci230_ao_mangle_datum()
562 datum <<= (16 - board->ao_bits); in pci230_ao_mangle_datum()
565 * (straight binary->twos complement). in pci230_ao_mangle_datum()
567 if (devpriv->ao_bipolar) in pci230_ao_mangle_datum()
575 struct pci230_private *devpriv = dev->private; in pci230_ao_write_nofifo()
579 devpriv->daqio + ((chan == 0) ? PCI230_DACOUT1 : PCI230_DACOUT2)); in pci230_ao_write_nofifo()
585 struct pci230_private *devpriv = dev->private; in pci230_ao_write_fifo()
589 devpriv->daqio + PCI230P2_DACDATA); in pci230_ao_write_fifo()
595 struct pci230_private *devpriv = dev->private; in pci230_claim_shared()
599 spin_lock_irqsave(&devpriv->res_spinlock, irqflags); in pci230_claim_shared()
603 if (devpriv->res_owned[o] & res_mask) { in pci230_claim_shared()
604 spin_unlock_irqrestore(&devpriv->res_spinlock, in pci230_claim_shared()
609 devpriv->res_owned[owner] |= res_mask; in pci230_claim_shared()
610 spin_unlock_irqrestore(&devpriv->res_spinlock, irqflags); in pci230_claim_shared()
617 struct pci230_private *devpriv = dev->private; in pci230_release_shared()
620 spin_lock_irqsave(&devpriv->res_spinlock, irqflags); in pci230_release_shared()
621 devpriv->res_owned[owner] &= ~res_mask; in pci230_release_shared()
622 spin_unlock_irqrestore(&devpriv->res_spinlock, irqflags); in pci230_release_shared()
688 comedi_8254_set_mode(dev->pacer, ct, mode); in pci230_ct_setup_ns_mode()
692 outb(pci230_clk_config(ct, clk_src), dev->iobase + PCI230_ZCLK_SCE); in pci230_ct_setup_ns_mode()
697 comedi_8254_write(dev->pacer, ct, count); in pci230_ct_setup_ns_mode()
703 comedi_8254_set_mode(dev->pacer, ct, I8254_MODE1); in pci230_cancel_ct()
711 struct pci230_private *devpriv = dev->private; in pci230_ai_eoc()
714 status = inw(devpriv->daqio + PCI230_ADCCON); in pci230_ai_eoc()
717 return -EBUSY; in pci230_ai_eoc()
724 struct pci230_private *devpriv = dev->private; in pci230_ai_insn_read()
732 chan = CR_CHAN(insn->chanspec); in pci230_ai_insn_read()
733 range = CR_RANGE(insn->chanspec); in pci230_ai_insn_read()
734 aref = CR_AREF(insn->chanspec); in pci230_ai_insn_read()
736 /* Differential. */ in pci230_ai_insn_read()
737 if (chan >= s->n_chan / 2) { in pci230_ai_insn_read()
738 dev_dbg(dev->class_dev, in pci230_ai_insn_read()
739 "%s: differential channel number out of range 0 to %u\n", in pci230_ai_insn_read()
740 __func__, (s->n_chan / 2) - 1); in pci230_ai_insn_read()
741 return -EINVAL; in pci230_ai_insn_read()
746 * Use Z2-CT2 as a conversion trigger instead of the built-in in pci230_ai_insn_read()
747 * software trigger, as otherwise triggering of differential channels in pci230_ai_insn_read()
752 /* Set Z2-CT2 output low to avoid any false triggers. */ in pci230_ai_insn_read()
753 comedi_8254_set_mode(dev->pacer, 2, I8254_MODE0); in pci230_ai_insn_read()
754 devpriv->ai_bipolar = comedi_range_is_bipolar(s, range); in pci230_ai_insn_read()
756 /* Differential. */ in pci230_ai_insn_read()
758 if (devpriv->hwver == 0) { in pci230_ai_insn_read()
761 * differential channel to be enabled. in pci230_ai_insn_read()
767 * differential channel to be enabled. in pci230_ai_insn_read()
778 devpriv->adcg = (devpriv->adcg & ~(3 << gainshift)) | in pci230_ai_insn_read()
780 if (devpriv->ai_bipolar) in pci230_ai_insn_read()
786 * Enable only this channel in the scan list - otherwise by default in pci230_ai_insn_read()
789 outw(adcen, devpriv->daqio + PCI230_ADCEN); in pci230_ai_insn_read()
792 outw(devpriv->adcg, devpriv->daqio + PCI230_ADCG); in pci230_ai_insn_read()
795 devpriv->adccon = adccon; in pci230_ai_insn_read()
796 outw(adccon | PCI230_ADC_FIFO_RESET, devpriv->daqio + PCI230_ADCCON); in pci230_ai_insn_read()
799 for (n = 0; n < insn->n; n++) { in pci230_ai_insn_read()
801 * Trigger conversion by toggling Z2-CT2 output in pci230_ai_insn_read()
804 comedi_8254_set_mode(dev->pacer, 2, I8254_MODE0); in pci230_ai_insn_read()
805 comedi_8254_set_mode(dev->pacer, 2, I8254_MODE1); in pci230_ai_insn_read()
825 struct pci230_private *devpriv = dev->private; in pci230_ao_insn_write()
826 unsigned int chan = CR_CHAN(insn->chanspec); in pci230_ao_insn_write()
827 unsigned int range = CR_RANGE(insn->chanspec); in pci230_ao_insn_write()
828 unsigned int val = s->readback[chan]; in pci230_ao_insn_write()
832 * Set range - see analogue output range table; 0 => unipolar 10V, in pci230_ao_insn_write()
833 * 1 => bipolar +/-10V range scale in pci230_ao_insn_write()
835 devpriv->ao_bipolar = comedi_range_is_bipolar(s, range); in pci230_ao_insn_write()
836 outw(range, devpriv->daqio + PCI230_DACCON); in pci230_ao_insn_write()
838 for (i = 0; i < insn->n; i++) { in pci230_ao_insn_write()
842 s->readback[chan] = val; in pci230_ao_insn_write()
844 return insn->n; in pci230_ao_insn_write()
851 unsigned int prev_chan = CR_CHAN(cmd->chanlist[0]); in pci230_ao_check_chanlist()
852 unsigned int range0 = CR_RANGE(cmd->chanlist[0]); in pci230_ao_check_chanlist()
855 for (i = 1; i < cmd->chanlist_len; i++) { in pci230_ao_check_chanlist()
856 unsigned int chan = CR_CHAN(cmd->chanlist[i]); in pci230_ao_check_chanlist()
857 unsigned int range = CR_RANGE(cmd->chanlist[i]); in pci230_ao_check_chanlist()
860 dev_dbg(dev->class_dev, in pci230_ao_check_chanlist()
863 return -EINVAL; in pci230_ao_check_chanlist()
867 dev_dbg(dev->class_dev, in pci230_ao_check_chanlist()
870 return -EINVAL; in pci230_ao_check_chanlist()
882 const struct pci230_board *board = dev->board_ptr; in pci230_ao_cmdtest()
883 struct pci230_private *devpriv = dev->private; in pci230_ao_cmdtest()
889 err |= comedi_check_trigger_src(&cmd->start_src, TRIG_INT); in pci230_ao_cmdtest()
892 if (board->min_hwver > 0 && devpriv->hwver >= 2) { in pci230_ao_cmdtest()
898 * on devpriv->hwver (the detected card's actual hardware in pci230_ao_cmdtest()
899 * version). They should only depend on board->min_hwver in pci230_ao_cmdtest()
909 err |= comedi_check_trigger_src(&cmd->scan_begin_src, tmp); in pci230_ao_cmdtest()
911 err |= comedi_check_trigger_src(&cmd->convert_src, TRIG_NOW); in pci230_ao_cmdtest()
912 err |= comedi_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT); in pci230_ao_cmdtest()
913 err |= comedi_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE); in pci230_ao_cmdtest()
920 err |= comedi_check_trigger_is_unique(cmd->scan_begin_src); in pci230_ao_cmdtest()
921 err |= comedi_check_trigger_is_unique(cmd->stop_src); in pci230_ao_cmdtest()
930 err |= comedi_check_trigger_arg_is(&cmd->start_arg, 0); in pci230_ao_cmdtest()
939 switch (cmd->scan_begin_src) { in pci230_ao_cmdtest()
941 err |= comedi_check_trigger_arg_min(&cmd->scan_begin_arg, in pci230_ao_cmdtest()
943 err |= comedi_check_trigger_arg_max(&cmd->scan_begin_arg, in pci230_ao_cmdtest()
948 * External trigger - for PCI230+ hardware version 2 onwards. in pci230_ao_cmdtest()
951 if (cmd->scan_begin_arg & ~CR_FLAGS_MASK) { in pci230_ao_cmdtest()
952 cmd->scan_begin_arg = COMBINE(cmd->scan_begin_arg, 0, in pci230_ao_cmdtest()
954 err |= -EINVAL; in pci230_ao_cmdtest()
960 if (cmd->scan_begin_arg & CR_FLAGS_MASK & in pci230_ao_cmdtest()
962 cmd->scan_begin_arg = in pci230_ao_cmdtest()
963 COMBINE(cmd->scan_begin_arg, 0, in pci230_ao_cmdtest()
965 err |= -EINVAL; in pci230_ao_cmdtest()
969 err |= comedi_check_trigger_arg_is(&cmd->scan_begin_arg, 0); in pci230_ao_cmdtest()
973 err |= comedi_check_trigger_arg_is(&cmd->scan_end_arg, in pci230_ao_cmdtest()
974 cmd->chanlist_len); in pci230_ao_cmdtest()
976 if (cmd->stop_src == TRIG_COUNT) in pci230_ao_cmdtest()
977 err |= comedi_check_trigger_arg_min(&cmd->stop_arg, 1); in pci230_ao_cmdtest()
979 err |= comedi_check_trigger_arg_is(&cmd->stop_arg, 0); in pci230_ao_cmdtest()
986 if (cmd->scan_begin_src == TRIG_TIMER) { in pci230_ao_cmdtest()
987 tmp = cmd->scan_begin_arg; in pci230_ao_cmdtest()
988 pci230_ns_to_single_timer(&cmd->scan_begin_arg, cmd->flags); in pci230_ao_cmdtest()
989 if (tmp != cmd->scan_begin_arg) in pci230_ao_cmdtest()
997 if (cmd->chanlist && cmd->chanlist_len > 0) in pci230_ao_cmdtest()
1009 struct pci230_private *devpriv = dev->private; in pci230_ao_stop()
1015 spin_lock_irqsave(&devpriv->ao_stop_spinlock, irqflags); in pci230_ao_stop()
1016 started = devpriv->ao_cmd_started; in pci230_ao_stop()
1017 devpriv->ao_cmd_started = false; in pci230_ao_stop()
1018 spin_unlock_irqrestore(&devpriv->ao_stop_spinlock, irqflags); in pci230_ao_stop()
1021 cmd = &s->async->cmd; in pci230_ao_stop()
1022 if (cmd->scan_begin_src == TRIG_TIMER) { in pci230_ao_stop()
1027 if (devpriv->hwver < 2) { in pci230_ao_stop()
1038 spin_lock_irqsave(&devpriv->isr_spinlock, irqflags); in pci230_ao_stop()
1039 devpriv->ier &= ~intsrc; in pci230_ao_stop()
1040 while (devpriv->intr_running && devpriv->intr_cpuid != THISCPU) { in pci230_ao_stop()
1041 spin_unlock_irqrestore(&devpriv->isr_spinlock, irqflags); in pci230_ao_stop()
1042 spin_lock_irqsave(&devpriv->isr_spinlock, irqflags); in pci230_ao_stop()
1044 outb(devpriv->ier, dev->iobase + PCI230_INT_SCE); in pci230_ao_stop()
1045 spin_unlock_irqrestore(&devpriv->isr_spinlock, irqflags); in pci230_ao_stop()
1046 if (devpriv->hwver >= 2) { in pci230_ao_stop()
1051 devpriv->daccon &= PCI230_DAC_OR_MASK; in pci230_ao_stop()
1052 outw(devpriv->daccon | PCI230P2_DAC_FIFO_RESET | in pci230_ao_stop()
1054 devpriv->daqio + PCI230_DACCON); in pci230_ao_stop()
1063 struct comedi_async *async = s->async; in pci230_handle_ao_nofifo()
1064 struct comedi_cmd *cmd = &async->cmd; in pci230_handle_ao_nofifo()
1068 if (cmd->stop_src == TRIG_COUNT && async->scans_done >= cmd->stop_arg) in pci230_handle_ao_nofifo()
1071 for (i = 0; i < cmd->chanlist_len; i++) { in pci230_handle_ao_nofifo()
1072 unsigned int chan = CR_CHAN(cmd->chanlist[i]); in pci230_handle_ao_nofifo()
1075 async->events |= COMEDI_CB_OVERFLOW; in pci230_handle_ao_nofifo()
1079 s->readback[chan] = data; in pci230_handle_ao_nofifo()
1082 if (cmd->stop_src == TRIG_COUNT && async->scans_done >= cmd->stop_arg) in pci230_handle_ao_nofifo()
1083 async->events |= COMEDI_CB_EOA; in pci230_handle_ao_nofifo()
1093 struct pci230_private *devpriv = dev->private; in pci230_handle_ao_fifo()
1094 struct comedi_async *async = s->async; in pci230_handle_ao_fifo()
1095 struct comedi_cmd *cmd = &async->cmd; in pci230_handle_ao_fifo()
1103 dacstat = inw(devpriv->daqio + PCI230_DACCON); in pci230_handle_ao_fifo()
1105 if (cmd->stop_src == TRIG_COUNT && num_scans == 0) in pci230_handle_ao_fifo()
1111 dev_err(dev->class_dev, "AO FIFO underrun\n"); in pci230_handle_ao_fifo()
1121 dev_err(dev->class_dev, "AO buffer underrun\n"); in pci230_handle_ao_fifo()
1136 room /= cmd->chanlist_len; in pci230_handle_ao_fifo()
1142 for (i = 0; i < cmd->chanlist_len; i++) { in pci230_handle_ao_fifo()
1143 unsigned int chan = CR_CHAN(cmd->chanlist[i]); in pci230_handle_ao_fifo()
1148 s->readback[chan] = datum; in pci230_handle_ao_fifo()
1152 if (cmd->stop_src == TRIG_COUNT && in pci230_handle_ao_fifo()
1153 async->scans_done >= cmd->stop_arg) { in pci230_handle_ao_fifo()
1159 devpriv->daccon &= ~PCI230P2_DAC_INT_FIFO_MASK; in pci230_handle_ao_fifo()
1160 devpriv->daccon |= PCI230P2_DAC_INT_FIFO_EMPTY; in pci230_handle_ao_fifo()
1161 outw(devpriv->daccon, devpriv->daqio + PCI230_DACCON); in pci230_handle_ao_fifo()
1164 dacstat = inw(devpriv->daqio + PCI230_DACCON); in pci230_handle_ao_fifo()
1166 dev_err(dev->class_dev, "AO FIFO underrun\n"); in pci230_handle_ao_fifo()
1170 async->events |= events; in pci230_handle_ao_fifo()
1171 return !(async->events & COMEDI_CB_CANCEL_MASK); in pci230_handle_ao_fifo()
1178 struct pci230_private *devpriv = dev->private; in pci230_ao_inttrig_scan_begin()
1182 return -EINVAL; in pci230_ao_inttrig_scan_begin()
1184 spin_lock_irqsave(&devpriv->ao_stop_spinlock, irqflags); in pci230_ao_inttrig_scan_begin()
1185 if (!devpriv->ao_cmd_started) { in pci230_ao_inttrig_scan_begin()
1186 spin_unlock_irqrestore(&devpriv->ao_stop_spinlock, irqflags); in pci230_ao_inttrig_scan_begin()
1190 if (devpriv->hwver < 2) { in pci230_ao_inttrig_scan_begin()
1192 spin_unlock_irqrestore(&devpriv->ao_stop_spinlock, irqflags); in pci230_ao_inttrig_scan_begin()
1198 inw(devpriv->daqio + PCI230P2_DACSWTRIG); in pci230_ao_inttrig_scan_begin()
1199 spin_unlock_irqrestore(&devpriv->ao_stop_spinlock, irqflags); in pci230_ao_inttrig_scan_begin()
1210 struct pci230_private *devpriv = dev->private; in pci230_ao_start()
1211 struct comedi_async *async = s->async; in pci230_ao_start()
1212 struct comedi_cmd *cmd = &async->cmd; in pci230_ao_start()
1215 devpriv->ao_cmd_started = true; in pci230_ao_start()
1217 if (devpriv->hwver >= 2) { in pci230_ao_start()
1230 switch (cmd->scan_begin_src) { in pci230_ao_start()
1236 if ((cmd->scan_begin_arg & CR_INVERT) == 0) { in pci230_ao_start()
1240 /* -ve edge */ in pci230_ao_start()
1252 devpriv->daccon = in pci230_ao_start()
1253 (devpriv->daccon & ~PCI230P2_DAC_TRIG_MASK) | scantrig; in pci230_ao_start()
1254 outw(devpriv->daccon, devpriv->daqio + PCI230_DACCON); in pci230_ao_start()
1256 switch (cmd->scan_begin_src) { in pci230_ao_start()
1258 if (devpriv->hwver < 2) { in pci230_ao_start()
1261 spin_lock_irqsave(&devpriv->isr_spinlock, irqflags); in pci230_ao_start()
1262 devpriv->ier |= PCI230_INT_ZCLK_CT1; in pci230_ao_start()
1263 outb(devpriv->ier, dev->iobase + PCI230_INT_SCE); in pci230_ao_start()
1264 spin_unlock_irqrestore(&devpriv->isr_spinlock, in pci230_ao_start()
1269 dev->iobase + PCI230_ZGAT_SCE); in pci230_ao_start()
1272 async->inttrig = pci230_ao_inttrig_scan_begin; in pci230_ao_start()
1275 if (devpriv->hwver >= 2) { in pci230_ao_start()
1277 spin_lock_irqsave(&devpriv->isr_spinlock, irqflags); in pci230_ao_start()
1278 devpriv->ier |= PCI230P2_INT_DAC; in pci230_ao_start()
1279 outb(devpriv->ier, dev->iobase + PCI230_INT_SCE); in pci230_ao_start()
1280 spin_unlock_irqrestore(&devpriv->isr_spinlock, irqflags); in pci230_ao_start()
1288 struct comedi_cmd *cmd = &s->async->cmd; in pci230_ao_inttrig_start()
1290 if (trig_num != cmd->start_src) in pci230_ao_inttrig_start()
1291 return -EINVAL; in pci230_ao_inttrig_start()
1293 s->async->inttrig = NULL; in pci230_ao_inttrig_start()
1301 struct pci230_private *devpriv = dev->private; in pci230_ao_cmd()
1306 struct comedi_cmd *cmd = &s->async->cmd; in pci230_ao_cmd()
1308 if (cmd->scan_begin_src == TRIG_TIMER) { in pci230_ao_cmd()
1309 /* Claim Z2-CT1. */ in pci230_ao_cmd()
1311 return -EBUSY; in pci230_ao_cmd()
1315 * Set range - see analogue output range table; 0 => unipolar 10V, in pci230_ao_cmd()
1316 * 1 => bipolar +/-10V range scale in pci230_ao_cmd()
1318 range = CR_RANGE(cmd->chanlist[0]); in pci230_ao_cmd()
1319 devpriv->ao_bipolar = comedi_range_is_bipolar(s, range); in pci230_ao_cmd()
1320 daccon = devpriv->ao_bipolar ? PCI230_DAC_OR_BIP : PCI230_DAC_OR_UNI; in pci230_ao_cmd()
1322 if (devpriv->hwver >= 2) { in pci230_ao_cmd()
1327 for (i = 0; i < cmd->chanlist_len; i++) in pci230_ao_cmd()
1328 dacen |= 1 << CR_CHAN(cmd->chanlist[i]); in pci230_ao_cmd()
1331 outw(dacen, devpriv->daqio + PCI230P2_DACEN); in pci230_ao_cmd()
1346 outw(daccon, devpriv->daqio + PCI230_DACCON); in pci230_ao_cmd()
1347 /* Preserve most of DACCON apart from write-only, transient bits. */ in pci230_ao_cmd()
1348 devpriv->daccon = daccon & ~(PCI230P2_DAC_FIFO_RESET | in pci230_ao_cmd()
1351 if (cmd->scan_begin_src == TRIG_TIMER) { in pci230_ao_cmd()
1354 * cmd->scan_begin_arg is sampling period in ns. in pci230_ao_cmd()
1358 dev->iobase + PCI230_ZGAT_SCE); in pci230_ao_cmd()
1360 cmd->scan_begin_arg, in pci230_ao_cmd()
1361 cmd->flags); in pci230_ao_cmd()
1364 /* N.B. cmd->start_src == TRIG_INT */ in pci230_ao_cmd()
1365 s->async->inttrig = pci230_ao_inttrig_start; in pci230_ao_cmd()
1382 chanlist_len = cmd->chanlist_len; in pci230_ai_check_scan_period()
1383 if (cmd->chanlist_len == 0) in pci230_ai_check_scan_period()
1386 min_scan_period = chanlist_len * cmd->convert_arg; in pci230_ai_check_scan_period()
1388 min_scan_period < cmd->convert_arg) { in pci230_ai_check_scan_period()
1393 if (cmd->scan_begin_arg < min_scan_period) { in pci230_ai_check_scan_period()
1394 cmd->scan_begin_arg = min_scan_period; in pci230_ai_check_scan_period()
1405 struct pci230_private *devpriv = dev->private; in pci230_ai_check_chanlist()
1406 unsigned int max_diff_chan = (s->n_chan / 2) - 1; in pci230_ai_check_chanlist()
1414 for (i = 0; i < cmd->chanlist_len; i++) { in pci230_ai_check_chanlist()
1415 unsigned int chanspec = cmd->chanlist[i]; in pci230_ai_check_chanlist()
1422 dev_dbg(dev->class_dev, in pci230_ai_check_chanlist()
1423 "%s: differential channel number out of range 0 to %u\n", in pci230_ai_check_chanlist()
1425 return -EINVAL; in pci230_ai_check_chanlist()
1437 cmd->chanlist[i % subseq_len] != chanspec) { in pci230_ai_check_chanlist()
1438 dev_dbg(dev->class_dev, in pci230_ai_check_chanlist()
1441 return -EINVAL; in pci230_ai_check_chanlist()
1445 dev_dbg(dev->class_dev, in pci230_ai_check_chanlist()
1446 … "%s: channel sequence analogue references must be all the same (single-ended or differential)\n", in pci230_ai_check_chanlist()
1448 return -EINVAL; in pci230_ai_check_chanlist()
1452 dev_dbg(dev->class_dev, in pci230_ai_check_chanlist()
1455 return -EINVAL; in pci230_ai_check_chanlist()
1460 dev_dbg(dev->class_dev, in pci230_ai_check_chanlist()
1461 "%s: single-ended channel pairs must have the same range\n", in pci230_ai_check_chanlist()
1463 return -EINVAL; in pci230_ai_check_chanlist()
1473 subseq_len = cmd->chanlist_len; in pci230_ai_check_chanlist()
1475 if (cmd->chanlist_len % subseq_len) { in pci230_ai_check_chanlist()
1476 dev_dbg(dev->class_dev, in pci230_ai_check_chanlist()
1478 return -EINVAL; in pci230_ai_check_chanlist()
1492 if (devpriv->hwver > 0 && devpriv->hwver < 4) { in pci230_ai_check_chanlist()
1493 if (subseq_len > 1 && CR_CHAN(cmd->chanlist[0])) { in pci230_ai_check_chanlist()
1494 dev_info(dev->class_dev, in pci230_ai_check_chanlist()
1495 …"amplc_pci230: ai_cmdtest: Buggy PCI230+/260+ h/w version %u requires first channel of multi-chann… in pci230_ai_check_chanlist()
1496 devpriv->hwver); in pci230_ai_check_chanlist()
1497 return -EINVAL; in pci230_ai_check_chanlist()
1507 const struct pci230_board *board = dev->board_ptr; in pci230_ai_cmdtest()
1508 struct pci230_private *devpriv = dev->private; in pci230_ai_cmdtest()
1514 err |= comedi_check_trigger_src(&cmd->start_src, TRIG_NOW | TRIG_INT); in pci230_ai_cmdtest()
1517 if (board->have_dio || board->min_hwver > 0) { in pci230_ai_cmdtest()
1526 err |= comedi_check_trigger_src(&cmd->scan_begin_src, tmp); in pci230_ai_cmdtest()
1527 err |= comedi_check_trigger_src(&cmd->convert_src, in pci230_ai_cmdtest()
1529 err |= comedi_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT); in pci230_ai_cmdtest()
1530 err |= comedi_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE); in pci230_ai_cmdtest()
1537 err |= comedi_check_trigger_is_unique(cmd->start_src); in pci230_ai_cmdtest()
1538 err |= comedi_check_trigger_is_unique(cmd->scan_begin_src); in pci230_ai_cmdtest()
1539 err |= comedi_check_trigger_is_unique(cmd->convert_src); in pci230_ai_cmdtest()
1540 err |= comedi_check_trigger_is_unique(cmd->stop_src); in pci230_ai_cmdtest()
1548 if (cmd->scan_begin_src != TRIG_FOLLOW && in pci230_ai_cmdtest()
1549 cmd->convert_src != TRIG_TIMER) in pci230_ai_cmdtest()
1550 err |= -EINVAL; in pci230_ai_cmdtest()
1557 err |= comedi_check_trigger_arg_is(&cmd->start_arg, 0); in pci230_ai_cmdtest()
1568 if (cmd->convert_src == TRIG_TIMER) { in pci230_ai_cmdtest()
1571 if (devpriv->hwver == 0) { in pci230_ai_cmdtest()
1574 * single-ended or pseudo-differential. in pci230_ai_cmdtest()
1576 if (cmd->chanlist && cmd->chanlist_len > 0) { in pci230_ai_cmdtest()
1578 if (CR_AREF(cmd->chanlist[0]) == AREF_DIFF) in pci230_ai_cmdtest()
1584 /* No channel list. Assume single-ended. */ in pci230_ai_cmdtest()
1592 err |= comedi_check_trigger_arg_min(&cmd->convert_arg, in pci230_ai_cmdtest()
1594 err |= comedi_check_trigger_arg_max(&cmd->convert_arg, in pci230_ai_cmdtest()
1596 } else if (cmd->convert_src == TRIG_EXT) { in pci230_ai_cmdtest()
1603 * => trigger on -ve edge. in pci230_ai_cmdtest()
1605 if (cmd->convert_arg & CR_FLAGS_MASK) { in pci230_ai_cmdtest()
1607 if (cmd->convert_arg & ~CR_FLAGS_MASK) { in pci230_ai_cmdtest()
1608 cmd->convert_arg = COMBINE(cmd->convert_arg, 0, in pci230_ai_cmdtest()
1610 err |= -EINVAL; in pci230_ai_cmdtest()
1616 if ((cmd->convert_arg & CR_FLAGS_MASK & ~CR_INVERT) != in pci230_ai_cmdtest()
1619 cmd->convert_arg = in pci230_ai_cmdtest()
1620 COMBINE(cmd->start_arg, CR_EDGE | 0, in pci230_ai_cmdtest()
1622 err |= -EINVAL; in pci230_ai_cmdtest()
1627 * convert_arg == 0 => trigger on -ve edge. in pci230_ai_cmdtest()
1630 err |= comedi_check_trigger_arg_max(&cmd->convert_arg, in pci230_ai_cmdtest()
1634 err |= comedi_check_trigger_arg_is(&cmd->convert_arg, 0); in pci230_ai_cmdtest()
1637 err |= comedi_check_trigger_arg_is(&cmd->scan_end_arg, in pci230_ai_cmdtest()
1638 cmd->chanlist_len); in pci230_ai_cmdtest()
1640 if (cmd->stop_src == TRIG_COUNT) in pci230_ai_cmdtest()
1641 err |= comedi_check_trigger_arg_min(&cmd->stop_arg, 1); in pci230_ai_cmdtest()
1643 err |= comedi_check_trigger_arg_is(&cmd->stop_arg, 0); in pci230_ai_cmdtest()
1645 if (cmd->scan_begin_src == TRIG_EXT) { in pci230_ai_cmdtest()
1648 * scan_begin_arg==0 => use PPC0 input -> gate of CT0 -> gate in pci230_ai_cmdtest()
1651 if (cmd->scan_begin_arg & ~CR_FLAGS_MASK) { in pci230_ai_cmdtest()
1652 cmd->scan_begin_arg = COMBINE(cmd->scan_begin_arg, 0, in pci230_ai_cmdtest()
1654 err |= -EINVAL; in pci230_ai_cmdtest()
1657 if (cmd->scan_begin_arg & CR_FLAGS_MASK & ~CR_EDGE) { in pci230_ai_cmdtest()
1658 cmd->scan_begin_arg = COMBINE(cmd->scan_begin_arg, 0, in pci230_ai_cmdtest()
1660 err |= -EINVAL; in pci230_ai_cmdtest()
1662 } else if (cmd->scan_begin_src == TRIG_TIMER) { in pci230_ai_cmdtest()
1663 /* N.B. cmd->convert_arg is also TRIG_TIMER */ in pci230_ai_cmdtest()
1665 err |= -EINVAL; in pci230_ai_cmdtest()
1668 err |= comedi_check_trigger_arg_is(&cmd->scan_begin_arg, 0); in pci230_ai_cmdtest()
1676 if (cmd->convert_src == TRIG_TIMER) { in pci230_ai_cmdtest()
1677 tmp = cmd->convert_arg; in pci230_ai_cmdtest()
1678 pci230_ns_to_single_timer(&cmd->convert_arg, cmd->flags); in pci230_ai_cmdtest()
1679 if (tmp != cmd->convert_arg) in pci230_ai_cmdtest()
1683 if (cmd->scan_begin_src == TRIG_TIMER) { in pci230_ai_cmdtest()
1684 /* N.B. cmd->convert_arg is also TRIG_TIMER */ in pci230_ai_cmdtest()
1685 tmp = cmd->scan_begin_arg; in pci230_ai_cmdtest()
1686 pci230_ns_to_single_timer(&cmd->scan_begin_arg, cmd->flags); in pci230_ai_cmdtest()
1689 pci230_ns_to_single_timer(&cmd->scan_begin_arg, in pci230_ai_cmdtest()
1693 if (tmp != cmd->scan_begin_arg) in pci230_ai_cmdtest()
1701 if (cmd->chanlist && cmd->chanlist_len > 0) in pci230_ai_cmdtest()
1713 struct pci230_private *devpriv = dev->private; in pci230_ai_update_fifo_trigger_level()
1714 struct comedi_cmd *cmd = &s->async->cmd; in pci230_ai_update_fifo_trigger_level()
1719 if (cmd->flags & CMDF_WAKE_EOS) in pci230_ai_update_fifo_trigger_level()
1720 wake = cmd->scan_end_arg - s->async->cur_chan; in pci230_ai_update_fifo_trigger_level()
1726 } else if (wake > 1 && devpriv->hwver > 0) { in pci230_ai_update_fifo_trigger_level()
1728 if (devpriv->adcfifothresh != wake) { in pci230_ai_update_fifo_trigger_level()
1729 devpriv->adcfifothresh = wake; in pci230_ai_update_fifo_trigger_level()
1730 outw(wake, devpriv->daqio + PCI230P_ADCFFTH); in pci230_ai_update_fifo_trigger_level()
1736 adccon = (devpriv->adccon & ~PCI230_ADC_INT_FIFO_MASK) | triglev; in pci230_ai_update_fifo_trigger_level()
1737 if (adccon != devpriv->adccon) { in pci230_ai_update_fifo_trigger_level()
1738 devpriv->adccon = adccon; in pci230_ai_update_fifo_trigger_level()
1739 outw(adccon, devpriv->daqio + PCI230_ADCCON); in pci230_ai_update_fifo_trigger_level()
1747 struct pci230_private *devpriv = dev->private; in pci230_ai_inttrig_convert()
1752 return -EINVAL; in pci230_ai_inttrig_convert()
1754 spin_lock_irqsave(&devpriv->ai_stop_spinlock, irqflags); in pci230_ai_inttrig_convert()
1755 if (!devpriv->ai_cmd_started) { in pci230_ai_inttrig_convert()
1756 spin_unlock_irqrestore(&devpriv->ai_stop_spinlock, irqflags); in pci230_ai_inttrig_convert()
1760 * Trigger conversion by toggling Z2-CT2 output. in pci230_ai_inttrig_convert()
1763 comedi_8254_set_mode(dev->pacer, 2, I8254_MODE0); in pci230_ai_inttrig_convert()
1764 comedi_8254_set_mode(dev->pacer, 2, I8254_MODE1); in pci230_ai_inttrig_convert()
1772 if ((devpriv->adccon & PCI230_ADC_IM_MASK) == PCI230_ADC_IM_DIF && in pci230_ai_inttrig_convert()
1773 devpriv->hwver == 0) { in pci230_ai_inttrig_convert()
1774 /* PCI230/260 in differential mode */ in pci230_ai_inttrig_convert()
1777 /* single-ended or PCI230+/260+ */ in pci230_ai_inttrig_convert()
1780 spin_unlock_irqrestore(&devpriv->ai_stop_spinlock, irqflags); in pci230_ai_inttrig_convert()
1789 struct pci230_private *devpriv = dev->private; in pci230_ai_inttrig_scan_begin()
1794 return -EINVAL; in pci230_ai_inttrig_scan_begin()
1796 spin_lock_irqsave(&devpriv->ai_stop_spinlock, irqflags); in pci230_ai_inttrig_scan_begin()
1797 if (devpriv->ai_cmd_started) { in pci230_ai_inttrig_scan_begin()
1800 outb(zgat, dev->iobase + PCI230_ZGAT_SCE); in pci230_ai_inttrig_scan_begin()
1802 outb(zgat, dev->iobase + PCI230_ZGAT_SCE); in pci230_ai_inttrig_scan_begin()
1804 spin_unlock_irqrestore(&devpriv->ai_stop_spinlock, irqflags); in pci230_ai_inttrig_scan_begin()
1812 struct pci230_private *devpriv = dev->private; in pci230_ai_stop()
1817 spin_lock_irqsave(&devpriv->ai_stop_spinlock, irqflags); in pci230_ai_stop()
1818 started = devpriv->ai_cmd_started; in pci230_ai_stop()
1819 devpriv->ai_cmd_started = false; in pci230_ai_stop()
1820 spin_unlock_irqrestore(&devpriv->ai_stop_spinlock, irqflags); in pci230_ai_stop()
1823 cmd = &s->async->cmd; in pci230_ai_stop()
1824 if (cmd->convert_src == TRIG_TIMER) { in pci230_ai_stop()
1828 if (cmd->scan_begin_src != TRIG_FOLLOW) { in pci230_ai_stop()
1832 spin_lock_irqsave(&devpriv->isr_spinlock, irqflags); in pci230_ai_stop()
1837 devpriv->ier &= ~PCI230_INT_ADC; in pci230_ai_stop()
1838 while (devpriv->intr_running && devpriv->intr_cpuid != THISCPU) { in pci230_ai_stop()
1839 spin_unlock_irqrestore(&devpriv->isr_spinlock, irqflags); in pci230_ai_stop()
1840 spin_lock_irqsave(&devpriv->isr_spinlock, irqflags); in pci230_ai_stop()
1842 outb(devpriv->ier, dev->iobase + PCI230_INT_SCE); in pci230_ai_stop()
1843 spin_unlock_irqrestore(&devpriv->isr_spinlock, irqflags); in pci230_ai_stop()
1848 devpriv->adccon = in pci230_ai_stop()
1849 (devpriv->adccon & (PCI230_ADC_IR_MASK | PCI230_ADC_IM_MASK)) | in pci230_ai_stop()
1851 outw(devpriv->adccon | PCI230_ADC_FIFO_RESET, in pci230_ai_stop()
1852 devpriv->daqio + PCI230_ADCCON); in pci230_ai_stop()
1860 struct pci230_private *devpriv = dev->private; in pci230_ai_start()
1863 struct comedi_async *async = s->async; in pci230_ai_start()
1864 struct comedi_cmd *cmd = &async->cmd; in pci230_ai_start()
1866 devpriv->ai_cmd_started = true; in pci230_ai_start()
1869 spin_lock_irqsave(&devpriv->isr_spinlock, irqflags); in pci230_ai_start()
1870 devpriv->ier |= PCI230_INT_ADC; in pci230_ai_start()
1871 outb(devpriv->ier, dev->iobase + PCI230_INT_SCE); in pci230_ai_start()
1872 spin_unlock_irqrestore(&devpriv->isr_spinlock, irqflags); in pci230_ai_start()
1878 switch (cmd->convert_src) { in pci230_ai_start()
1887 if (cmd->convert_arg & CR_EDGE) { in pci230_ai_start()
1888 if ((cmd->convert_arg & CR_INVERT) == 0) { in pci230_ai_start()
1892 /* Trigger on -ve edge. */ in pci230_ai_start()
1897 if (cmd->convert_arg) { in pci230_ai_start()
1901 /* Trigger on -ve edge. */ in pci230_ai_start()
1909 * in differential mode on PCI230/260. in pci230_ai_start()
1914 devpriv->adccon = (devpriv->adccon & ~PCI230_ADC_TRIG_MASK) | conv; in pci230_ai_start()
1915 outw(devpriv->adccon, devpriv->daqio + PCI230_ADCCON); in pci230_ai_start()
1916 if (cmd->convert_src == TRIG_INT) in pci230_ai_start()
1917 async->inttrig = pci230_ai_inttrig_convert; in pci230_ai_start()
1924 if (cmd->convert_src == TRIG_TIMER) { in pci230_ai_start()
1928 if (cmd->scan_begin_src != TRIG_FOLLOW) { in pci230_ai_start()
1941 outb(zgat, dev->iobase + PCI230_ZGAT_SCE); in pci230_ai_start()
1942 if (cmd->scan_begin_src != TRIG_FOLLOW) { in pci230_ai_start()
1944 switch (cmd->scan_begin_src) { in pci230_ai_start()
1974 outb(zgat, dev->iobase + PCI230_ZGAT_SCE); in pci230_ai_start()
1975 switch (cmd->scan_begin_src) { in pci230_ai_start()
1982 outb(zgat, dev->iobase + PCI230_ZGAT_SCE); in pci230_ai_start()
1985 async->inttrig = pci230_ai_inttrig_scan_begin; in pci230_ai_start()
1989 } else if (cmd->convert_src != TRIG_INT) { in pci230_ai_start()
1990 /* No longer need Z2-CT2. */ in pci230_ai_start()
1999 struct comedi_cmd *cmd = &s->async->cmd; in pci230_ai_inttrig_start()
2001 if (trig_num != cmd->start_arg) in pci230_ai_inttrig_start()
2002 return -EINVAL; in pci230_ai_inttrig_start()
2004 s->async->inttrig = NULL; in pci230_ai_inttrig_start()
2013 struct pci230_private *devpriv = dev->private; in pci230_handle_ai()
2014 struct comedi_async *async = s->async; in pci230_handle_ai()
2015 struct comedi_cmd *cmd = &async->cmd; in pci230_handle_ai()
2031 status_fifo = inw(devpriv->daqio + PCI230_ADCCON); in pci230_handle_ai()
2037 dev_err(dev->class_dev, "AI FIFO overrun\n"); in pci230_handle_ai()
2038 async->events |= COMEDI_CB_ERROR; in pci230_handle_ai()
2046 } else if (devpriv->hwver > 0) { in pci230_handle_ai()
2048 fifoamount = inw(devpriv->daqio + in pci230_handle_ai()
2062 fifoamount--; in pci230_handle_ai()
2064 if (cmd->stop_src == TRIG_COUNT && in pci230_handle_ai()
2065 async->scans_done >= cmd->stop_arg) { in pci230_handle_ai()
2066 async->events |= COMEDI_CB_EOA; in pci230_handle_ai()
2072 if (!(async->events & COMEDI_CB_CANCEL_MASK)) in pci230_handle_ai()
2078 struct pci230_private *devpriv = dev->private; in pci230_ai_cmd()
2085 struct comedi_async *async = s->async; in pci230_ai_cmd()
2086 struct comedi_cmd *cmd = &async->cmd; in pci230_ai_cmd()
2093 * Need Z2-CT2 to supply a conversion trigger source at a high in pci230_ai_cmd()
2097 if (cmd->scan_begin_src != TRIG_FOLLOW) { in pci230_ai_cmd()
2098 /* Using Z2-CT0 monostable to gate Z2-CT2 conversion timer */ in pci230_ai_cmd()
2100 if (cmd->scan_begin_src == TRIG_TIMER) { in pci230_ai_cmd()
2101 /* Using Z2-CT1 for scan frequency */ in pci230_ai_cmd()
2107 return -EBUSY; in pci230_ai_cmd()
2111 * - Set channel scan list. in pci230_ai_cmd()
2112 * - Set channel gains. in pci230_ai_cmd()
2113 * - Enable and reset FIFO, specify uni/bip, se/diff, and set in pci230_ai_cmd()
2116 * - PAUSE to allow things to settle down. in pci230_ai_cmd()
2117 * - Reset the FIFO again because it needs resetting twice and there in pci230_ai_cmd()
2121 * - Enable ADC FIFO level interrupt. in pci230_ai_cmd()
2122 * - Set actual conversion trigger source and FIFO interrupt trigger in pci230_ai_cmd()
2124 * - If convert_src is TRIG_TIMER, set up the timers. in pci230_ai_cmd()
2130 if (CR_AREF(cmd->chanlist[0]) == AREF_DIFF) { in pci230_ai_cmd()
2131 /* Differential - all channels must be differential. */ in pci230_ai_cmd()
2135 /* Single ended - all channels must be single-ended. */ in pci230_ai_cmd()
2140 range = CR_RANGE(cmd->chanlist[0]); in pci230_ai_cmd()
2141 devpriv->ai_bipolar = comedi_range_is_bipolar(s, range); in pci230_ai_cmd()
2142 if (devpriv->ai_bipolar) in pci230_ai_cmd()
2147 for (i = 0; i < cmd->chanlist_len; i++) { in pci230_ai_cmd()
2150 chan = CR_CHAN(cmd->chanlist[i]); in pci230_ai_cmd()
2151 range = CR_RANGE(cmd->chanlist[i]); in pci230_ai_cmd()
2154 if (devpriv->hwver == 0) { in pci230_ai_cmd()
2157 * the differential channel to be enabled. in pci230_ai_cmd()
2163 * differential channel to be enabled. in pci230_ai_cmd()
2171 devpriv->adcg = (devpriv->adcg & ~(3 << gainshift)) | in pci230_ai_cmd()
2176 outw(adcen, devpriv->daqio + PCI230_ADCEN); in pci230_ai_cmd()
2179 outw(devpriv->adcg, devpriv->daqio + PCI230_ADCG); in pci230_ai_cmd()
2185 comedi_8254_set_mode(dev->pacer, 2, I8254_MODE1); in pci230_ai_cmd()
2200 devpriv->adccon = adccon; in pci230_ai_cmd()
2201 outw(adccon | PCI230_ADC_FIFO_RESET, devpriv->daqio + PCI230_ADCCON); in pci230_ai_cmd()
2204 * Delay - in pci230_ai_cmd()
2205 * Failure to include this will result in the first few channels'-worth in pci230_ai_cmd()
2215 outw(adccon | PCI230_ADC_FIFO_RESET, devpriv->daqio + PCI230_ADCCON); in pci230_ai_cmd()
2217 if (cmd->convert_src == TRIG_TIMER) { in pci230_ai_cmd()
2224 outb(zgat, dev->iobase + PCI230_ZGAT_SCE); in pci230_ai_cmd()
2226 pci230_ct_setup_ns_mode(dev, 2, I8254_MODE3, cmd->convert_arg, in pci230_ai_cmd()
2227 cmd->flags); in pci230_ai_cmd()
2228 if (cmd->scan_begin_src != TRIG_FOLLOW) { in pci230_ai_cmd()
2242 outb(zgat, dev->iobase + PCI230_ZGAT_SCE); in pci230_ai_cmd()
2244 ((u64)cmd->convert_arg * in pci230_ai_cmd()
2245 cmd->scan_end_arg), in pci230_ai_cmd()
2247 if (cmd->scan_begin_src == TRIG_TIMER) { in pci230_ai_cmd()
2255 outb(zgat, dev->iobase + PCI230_ZGAT_SCE); in pci230_ai_cmd()
2257 cmd->scan_begin_arg, in pci230_ai_cmd()
2258 cmd->flags); in pci230_ai_cmd()
2263 if (cmd->start_src == TRIG_INT) in pci230_ai_cmd()
2264 s->async->inttrig = pci230_ai_inttrig_start; in pci230_ai_cmd()
2283 struct pci230_private *devpriv = dev->private; in pci230_interrupt()
2284 struct comedi_subdevice *s_ao = dev->write_subdev; in pci230_interrupt()
2285 struct comedi_subdevice *s_ai = dev->read_subdev; in pci230_interrupt()
2289 status_int = inb(dev->iobase + PCI230_INT_STAT); in pci230_interrupt()
2294 spin_lock_irqsave(&devpriv->isr_spinlock, irqflags); in pci230_interrupt()
2295 valid_status_int = devpriv->ier & status_int; in pci230_interrupt()
2298 * (Only those interrupts that need re-enabling, are, later in the in pci230_interrupt()
2301 temp_ier = devpriv->ier & ~status_int; in pci230_interrupt()
2302 outb(temp_ier, dev->iobase + PCI230_INT_SCE); in pci230_interrupt()
2303 devpriv->intr_running = true; in pci230_interrupt()
2304 devpriv->intr_cpuid = THISCPU; in pci230_interrupt()
2305 spin_unlock_irqrestore(&devpriv->isr_spinlock, irqflags); in pci230_interrupt()
2310 * interrupts. However, at present (Comedi-0.7.60) does not allow in pci230_interrupt()
2325 spin_lock_irqsave(&devpriv->isr_spinlock, irqflags); in pci230_interrupt()
2326 if (devpriv->ier != temp_ier) in pci230_interrupt()
2327 outb(devpriv->ier, dev->iobase + PCI230_INT_SCE); in pci230_interrupt()
2328 devpriv->intr_running = false; in pci230_interrupt()
2329 spin_unlock_irqrestore(&devpriv->isr_spinlock, irqflags); in pci230_interrupt()
2342 /* assume pci_dev->device != PCI_DEVICE_ID_INVALID */ in pci230_match_pci_board()
2343 if (board->id != pci_dev->device) in pci230_match_pci_board()
2345 if (board->min_hwver == 0) in pci230_match_pci_board()
2377 dev_info(dev->class_dev, "amplc_pci230: attach pci %s\n", in pci230_auto_attach()
2382 return -ENOMEM; in pci230_auto_attach()
2384 spin_lock_init(&devpriv->isr_spinlock); in pci230_auto_attach()
2385 spin_lock_init(&devpriv->res_spinlock); in pci230_auto_attach()
2386 spin_lock_init(&devpriv->ai_stop_spinlock); in pci230_auto_attach()
2387 spin_lock_init(&devpriv->ao_stop_spinlock); in pci230_auto_attach()
2391 dev_err(dev->class_dev, in pci230_auto_attach()
2393 return -EINVAL; in pci230_auto_attach()
2395 dev->board_ptr = board; in pci230_auto_attach()
2396 dev->board_name = board->name; in pci230_auto_attach()
2406 dev->iobase = pci_resource_start(pci_dev, 2); in pci230_auto_attach()
2407 devpriv->daqio = pci_resource_start(pci_dev, 3); in pci230_auto_attach()
2408 dev_dbg(dev->class_dev, in pci230_auto_attach()
2410 dev->board_name, dev->iobase, devpriv->daqio); in pci230_auto_attach()
2411 /* Read bits of DACCON register - only the output range. */ in pci230_auto_attach()
2412 devpriv->daccon = inw(devpriv->daqio + PCI230_DACCON) & in pci230_auto_attach()
2421 devpriv->hwver = inw(devpriv->daqio + PCI230P_HWVER); in pci230_auto_attach()
2422 if (devpriv->hwver < board->min_hwver) { in pci230_auto_attach()
2423 dev_err(dev->class_dev, in pci230_auto_attach()
2424 "%s - bad hardware version - got %u, need %u\n", in pci230_auto_attach()
2425 dev->board_name, devpriv->hwver, in pci230_auto_attach()
2426 board->min_hwver); in pci230_auto_attach()
2427 return -EIO; in pci230_auto_attach()
2429 if (devpriv->hwver > 0) { in pci230_auto_attach()
2430 if (!board->have_dio) { in pci230_auto_attach()
2440 if (board->ao_bits && devpriv->hwver >= 2) { in pci230_auto_attach()
2445 outw(extfunc, devpriv->daqio + PCI230P_EXTFUNC); in pci230_auto_attach()
2451 outw(devpriv->daccon | PCI230P2_DAC_FIFO_EN | in pci230_auto_attach()
2453 devpriv->daqio + PCI230_DACCON); in pci230_auto_attach()
2455 outw(0, devpriv->daqio + PCI230P2_DACEN); in pci230_auto_attach()
2457 outw(devpriv->daccon, devpriv->daqio + PCI230_DACCON); in pci230_auto_attach()
2461 outb(0, dev->iobase + PCI230_INT_SCE); in pci230_auto_attach()
2463 devpriv->adcg = 0; in pci230_auto_attach()
2464 devpriv->adccon = PCI230_ADC_TRIG_NONE | PCI230_ADC_IM_SE | in pci230_auto_attach()
2466 outw(BIT(0), devpriv->daqio + PCI230_ADCEN); in pci230_auto_attach()
2467 outw(devpriv->adcg, devpriv->daqio + PCI230_ADCG); in pci230_auto_attach()
2468 outw(devpriv->adccon | PCI230_ADC_FIFO_RESET, in pci230_auto_attach()
2469 devpriv->daqio + PCI230_ADCCON); in pci230_auto_attach()
2471 if (pci_dev->irq) { in pci230_auto_attach()
2472 rc = request_irq(pci_dev->irq, pci230_interrupt, IRQF_SHARED, in pci230_auto_attach()
2473 dev->board_name, dev); in pci230_auto_attach()
2475 dev->irq = pci_dev->irq; in pci230_auto_attach()
2478 dev->pacer = comedi_8254_init(dev->iobase + PCI230_Z2_CT_BASE, in pci230_auto_attach()
2480 if (!dev->pacer) in pci230_auto_attach()
2481 return -ENOMEM; in pci230_auto_attach()
2487 s = &dev->subdevices[0]; in pci230_auto_attach()
2489 s->type = COMEDI_SUBD_AI; in pci230_auto_attach()
2490 s->subdev_flags = SDF_READABLE | SDF_DIFF | SDF_GROUND; in pci230_auto_attach()
2491 s->n_chan = 16; in pci230_auto_attach()
2492 s->maxdata = (1 << board->ai_bits) - 1; in pci230_auto_attach()
2493 s->range_table = &pci230_ai_range; in pci230_auto_attach()
2494 s->insn_read = pci230_ai_insn_read; in pci230_auto_attach()
2495 s->len_chanlist = 256; /* but there are restrictions. */ in pci230_auto_attach()
2496 if (dev->irq) { in pci230_auto_attach()
2497 dev->read_subdev = s; in pci230_auto_attach()
2498 s->subdev_flags |= SDF_CMD_READ; in pci230_auto_attach()
2499 s->do_cmd = pci230_ai_cmd; in pci230_auto_attach()
2500 s->do_cmdtest = pci230_ai_cmdtest; in pci230_auto_attach()
2501 s->cancel = pci230_ai_cancel; in pci230_auto_attach()
2504 s = &dev->subdevices[1]; in pci230_auto_attach()
2506 if (board->ao_bits) { in pci230_auto_attach()
2507 s->type = COMEDI_SUBD_AO; in pci230_auto_attach()
2508 s->subdev_flags = SDF_WRITABLE | SDF_GROUND; in pci230_auto_attach()
2509 s->n_chan = 2; in pci230_auto_attach()
2510 s->maxdata = (1 << board->ao_bits) - 1; in pci230_auto_attach()
2511 s->range_table = &pci230_ao_range; in pci230_auto_attach()
2512 s->insn_write = pci230_ao_insn_write; in pci230_auto_attach()
2513 s->len_chanlist = 2; in pci230_auto_attach()
2514 if (dev->irq) { in pci230_auto_attach()
2515 dev->write_subdev = s; in pci230_auto_attach()
2516 s->subdev_flags |= SDF_CMD_WRITE; in pci230_auto_attach()
2517 s->do_cmd = pci230_ao_cmd; in pci230_auto_attach()
2518 s->do_cmdtest = pci230_ao_cmdtest; in pci230_auto_attach()
2519 s->cancel = pci230_ao_cancel; in pci230_auto_attach()
2526 s->type = COMEDI_SUBD_UNUSED; in pci230_auto_attach()
2529 s = &dev->subdevices[2]; in pci230_auto_attach()
2531 if (board->have_dio) { in pci230_auto_attach()
2536 s->type = COMEDI_SUBD_UNUSED; in pci230_auto_attach()
2553 id->driver_data); in amplc_pci230_pci_probe()