Lines Matching +full:max +full:- +full:channels +full:- +full:clocked
1 // SPDX-License-Identifier: GPL-2.0+
8 * COMEDI - Linux Control and Measurement Device Interface
22 * - ao_insn read/write
23 * - ao_do_cmd mode with the following sources:
25 * - start_src TRIG_INT TRIG_EXT
26 * - scan_begin_src TRIG_TIMER TRIG_EXT
27 * - convert_src TRIG_NOW
28 * - scan_end_src TRIG_COUNT
29 * - stop_src TRIG_COUNT TRIG_EXT TRIG_NONE
32 * channels. The scan end count must equal the number of channels in
44 * Output range selection - PCI224:
46 * Output ranges on PCI224 are partly software-selectable and partly
47 * hardware-selectable according to jumper LK1. All channels are set
50 * - LK1 position 1-2 (factory default) corresponds to the following
53 * 0: [-10V,+10V]; 1: [-5V,+5V]; 2: [-2.5V,+2.5V], 3: [-1.25V,+1.25V],
56 * - LK1 position 2-3 corresponds to the following Comedi ranges, using
59 * 0: [-Vext,+Vext],
62 * Output range selection - PCI234:
64 * Output ranges on PCI234 are hardware-selectable according to jumper
65 * LK1 which affects all channels, and jumpers LK2, LK3, LK4 and LK5
66 * which affect channels 0, 1, 2 and 3 individually. LK1 chooses between
72 * ------------- ------------- --------------
73 * 2-3 (factory) 1-2 (factory) 0: [-10V,+10V]
74 * 2-3 (factory) 2-3 1: [-5V,+5V]
75 * 1-2 1-2 (factory) 2: [-2*Vext,+2*Vext]
76 * 1-2 2-3 3: [-Vext,+Vext]
80 * 1) All channels on the PCI224 share the same range. Any change to the
82 * the output voltages of all channels, including those not specified
112 * PCI224/234 i/o space 2 (PCIBAR3) 16-bit registers.
114 #define PCI224_DACDATA 0x00 /* (w-o) DAC FIFO data. */
115 #define PCI224_SOFTTRIG 0x00 /* (r-o) DAC software scan trigger. */
117 #define PCI224_FIFOSIZ 0x04 /* (w-o) FIFO size for wraparound mode. */
118 #define PCI224_DACCEN 0x06 /* (w-o) DAC channel enable register. */
129 #define PCI224_DACCON_TRIG_EXTN PCI224_DACCON_TRIG(3) /* ext - edge */
137 #define PCI224_DACCON_POLAR_BI PCI224_DACCON_POLAR(1) /* [-V,+V] */
138 /* (r/w) Internal Vref (PCI224 only, when LK1 in position 1-2). */
158 /* (r-o) FIFO fill level. */
162 #define PCI224_DACCON_FIFOFL_ONETOHALF PCI224_DACCON_FIFOFL(0) /* 1-2048 */
163 #define PCI224_DACCON_FIFOFL_HALFTOFULL PCI224_DACCON_FIFOFL(4) /* 2049-4095 */
165 /* (r-o) DAC busy flag. */
167 /* (w-o) FIFO reset. */
169 /* (w-o) Global reset (not sure what it does). */
190 #define CLK_CLK 0 /* reserved (channel-specific clock) */
196 #define CLK_OUTNM1 6 /* output of channel-1 modulo total */
210 #define GAT_NOUTNM2 3 /* inverted output of channel-2 modulo total */
223 * ------- ---------- -----------
224 * Z2-CT0 Z2-CT2-OUT /Z2-CT1-OUT
225 * Z2-CT1 Z2-CT0-OUT /Z2-CT2-OUT
226 * Z2-CT2 Z2-CT1-OUT /Z2-CT0-OUT
234 #define PCI224_INTR_Z2CT1 0x20 /* rising edge on Z2-CT1 output */
259 * These are partly hardware-selectable by jumper LK1 and partly
260 * software-selectable.
262 * All channels share the same hardware range.
266 /* jumper LK1 in position 1-2 (factory default) */
275 /* jumper LK1 in position 2-3 */
276 RANGE_ext(-1, 1), /* bipolar [-Vext,+Vext] */
282 /* jumper LK1 in position 1-2 (factory default) */
291 /* jumper LK1 in position 2-3 */
296 /* Used to check all channels set to the same range on PCI224. */
304 * These are all hardware-selectable by jumper LK1 affecting all channels,
305 * and jumpers LK2, LK3, LK4 and LK5 affecting channels 0, 1, 2 and 3
310 /* LK1: 1-2 (fact def), LK2/3/4/5: 2-3 (fac def) */
312 /* LK1: 1-2 (fact def), LK2/3/4/5: 1-2 */
314 /* LK1: 2-3, LK2/3/4/5: 2-3 (fac def) */
315 RANGE_ext(-2, 2), /* bipolar [-2*Vext,+2*Vext] */
316 /* LK1: 2-3, LK2/3/4/5: 1-2 */
317 RANGE_ext(-1, 1), /* bipolar [-Vext,+Vext] */
329 /* Used to check all channels use same LK1 setting on PCI234. */
377 unsigned short ao_enab; /* max 16 channels so 'short' will do */
388 const struct pci224_board *board = dev->board_ptr; in pci224_ao_set_data()
389 struct pci224_private *devpriv = dev->private; in pci224_ao_set_data()
393 outw(1 << chan, dev->iobase + PCI224_DACCEN); in pci224_ao_set_data()
395 devpriv->daccon = COMBINE(devpriv->daccon, board->ao_hwrange[range], in pci224_ao_set_data()
398 outw(devpriv->daccon | PCI224_DACCON_FIFORESET, in pci224_ao_set_data()
399 dev->iobase + PCI224_DACCON); in pci224_ao_set_data()
402 * - bipolar: 16-bit 2's complement in pci224_ao_set_data()
403 * - unipolar: 16-bit unsigned in pci224_ao_set_data()
405 mangled = (unsigned short)data << (16 - board->ao_bits); in pci224_ao_set_data()
406 if ((devpriv->daccon & PCI224_DACCON_POLAR_MASK) == in pci224_ao_set_data()
411 outw(mangled, dev->iobase + PCI224_DACDATA); in pci224_ao_set_data()
413 inw(dev->iobase + PCI224_SOFTTRIG); in pci224_ao_set_data()
421 unsigned int chan = CR_CHAN(insn->chanspec); in pci224_ao_insn_write()
422 unsigned int range = CR_RANGE(insn->chanspec); in pci224_ao_insn_write()
423 unsigned int val = s->readback[chan]; in pci224_ao_insn_write()
426 for (i = 0; i < insn->n; i++) { in pci224_ao_insn_write()
430 s->readback[chan] = val; in pci224_ao_insn_write()
432 return insn->n; in pci224_ao_insn_write()
441 struct pci224_private *devpriv = dev->private; in pci224_ao_stop()
444 if (!test_and_clear_bit(AO_CMD_STARTED, &devpriv->state)) in pci224_ao_stop()
447 spin_lock_irqsave(&devpriv->ao_spinlock, flags); in pci224_ao_stop()
449 devpriv->intsce = 0; in pci224_ao_stop()
450 outb(0, devpriv->iobase1 + PCI224_INT_SCE); in pci224_ao_stop()
462 while (devpriv->intr_running && devpriv->intr_cpuid != THISCPU) { in pci224_ao_stop()
463 spin_unlock_irqrestore(&devpriv->ao_spinlock, flags); in pci224_ao_stop()
464 spin_lock_irqsave(&devpriv->ao_spinlock, flags); in pci224_ao_stop()
466 spin_unlock_irqrestore(&devpriv->ao_spinlock, flags); in pci224_ao_stop()
468 outw(0, dev->iobase + PCI224_DACCEN); /* Disable channels. */ in pci224_ao_stop()
469 devpriv->daccon = in pci224_ao_stop()
470 COMBINE(devpriv->daccon, in pci224_ao_stop()
473 outw(devpriv->daccon | PCI224_DACCON_FIFORESET, in pci224_ao_stop()
474 dev->iobase + PCI224_DACCON); in pci224_ao_stop()
483 struct pci224_private *devpriv = dev->private; in pci224_ao_start()
484 struct comedi_cmd *cmd = &s->async->cmd; in pci224_ao_start()
487 set_bit(AO_CMD_STARTED, &devpriv->state); in pci224_ao_start()
490 spin_lock_irqsave(&devpriv->ao_spinlock, flags); in pci224_ao_start()
491 if (cmd->stop_src == TRIG_EXT) in pci224_ao_start()
492 devpriv->intsce = PCI224_INTR_EXT | PCI224_INTR_DAC; in pci224_ao_start()
494 devpriv->intsce = PCI224_INTR_DAC; in pci224_ao_start()
496 outb(devpriv->intsce, devpriv->iobase1 + PCI224_INT_SCE); in pci224_ao_start()
497 spin_unlock_irqrestore(&devpriv->ao_spinlock, flags); in pci224_ao_start()
506 struct pci224_private *devpriv = dev->private; in pci224_ao_handle_fifo()
507 struct comedi_cmd *cmd = &s->async->cmd; in pci224_ao_handle_fifo()
514 dacstat = inw(dev->iobase + PCI224_DACCON); in pci224_ao_handle_fifo()
518 if (cmd->stop_src == TRIG_COUNT && in pci224_ao_handle_fifo()
519 s->async->scans_done >= cmd->stop_arg) { in pci224_ao_handle_fifo()
521 s->async->events |= COMEDI_CB_EOA; in pci224_ao_handle_fifo()
537 /* FIFO is less than half-full. */ in pci224_ao_handle_fifo()
540 dev_err(dev->class_dev, "AO buffer underrun\n"); in pci224_ao_handle_fifo()
541 s->async->events |= COMEDI_CB_OVERFLOW; in pci224_ao_handle_fifo()
545 room /= cmd->chanlist_len; in pci224_ao_handle_fifo()
553 comedi_buf_read_samples(s, &devpriv->ao_scan_vals[0], in pci224_ao_handle_fifo()
554 cmd->chanlist_len); in pci224_ao_handle_fifo()
555 for (i = 0; i < cmd->chanlist_len; i++) { in pci224_ao_handle_fifo()
556 outw(devpriv->ao_scan_vals[devpriv->ao_scan_order[i]], in pci224_ao_handle_fifo()
557 dev->iobase + PCI224_DACDATA); in pci224_ao_handle_fifo()
560 if (cmd->stop_src == TRIG_COUNT && in pci224_ao_handle_fifo()
561 s->async->scans_done >= cmd->stop_arg) { in pci224_ao_handle_fifo()
566 devpriv->daccon = COMBINE(devpriv->daccon, in pci224_ao_handle_fifo()
569 outw(devpriv->daccon, dev->iobase + PCI224_DACCON); in pci224_ao_handle_fifo()
571 if ((devpriv->daccon & PCI224_DACCON_TRIG_MASK) == in pci224_ao_handle_fifo()
587 if (cmd->scan_begin_src == TRIG_TIMER) { in pci224_ao_handle_fifo()
590 /* cmd->scan_begin_src == TRIG_EXT */ in pci224_ao_handle_fifo()
591 if (cmd->scan_begin_arg & CR_INVERT) in pci224_ao_handle_fifo()
596 devpriv->daccon = in pci224_ao_handle_fifo()
597 COMBINE(devpriv->daccon, trig, PCI224_DACCON_TRIG_MASK); in pci224_ao_handle_fifo()
598 outw(devpriv->daccon, dev->iobase + PCI224_DACCON); in pci224_ao_handle_fifo()
608 struct comedi_cmd *cmd = &s->async->cmd; in pci224_ao_inttrig_start()
610 if (trig_num != cmd->start_arg) in pci224_ao_inttrig_start()
611 return -EINVAL; in pci224_ao_inttrig_start()
613 s->async->inttrig = NULL; in pci224_ao_inttrig_start()
623 const struct pci224_board *board = dev->board_ptr; in pci224_ao_check_chanlist()
628 range_check_0 = board->ao_range_check[CR_RANGE(cmd->chanlist[0])]; in pci224_ao_check_chanlist()
629 for (i = 0; i < cmd->chanlist_len; i++) { in pci224_ao_check_chanlist()
630 unsigned int chan = CR_CHAN(cmd->chanlist[i]); in pci224_ao_check_chanlist()
633 dev_dbg(dev->class_dev, in pci224_ao_check_chanlist()
634 "%s: entries in chanlist must contain no duplicate channels\n", in pci224_ao_check_chanlist()
636 return -EINVAL; in pci224_ao_check_chanlist()
640 if (board->ao_range_check[CR_RANGE(cmd->chanlist[i])] != in pci224_ao_check_chanlist()
642 dev_dbg(dev->class_dev, in pci224_ao_check_chanlist()
645 return -EINVAL; in pci224_ao_check_chanlist()
668 err |= comedi_check_trigger_src(&cmd->start_src, TRIG_INT | TRIG_EXT); in pci224_ao_cmdtest()
669 err |= comedi_check_trigger_src(&cmd->scan_begin_src, in pci224_ao_cmdtest()
671 err |= comedi_check_trigger_src(&cmd->convert_src, TRIG_NOW); in pci224_ao_cmdtest()
672 err |= comedi_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT); in pci224_ao_cmdtest()
673 err |= comedi_check_trigger_src(&cmd->stop_src, in pci224_ao_cmdtest()
681 err |= comedi_check_trigger_is_unique(cmd->start_src); in pci224_ao_cmdtest()
682 err |= comedi_check_trigger_is_unique(cmd->scan_begin_src); in pci224_ao_cmdtest()
683 err |= comedi_check_trigger_is_unique(cmd->stop_src); in pci224_ao_cmdtest()
692 if (cmd->start_src & TRIG_EXT) in pci224_ao_cmdtest()
694 if (cmd->scan_begin_src & TRIG_EXT) in pci224_ao_cmdtest()
696 if (cmd->stop_src & TRIG_EXT) in pci224_ao_cmdtest()
699 err |= -EINVAL; in pci224_ao_cmdtest()
706 switch (cmd->start_src) { in pci224_ao_cmdtest()
708 err |= comedi_check_trigger_arg_is(&cmd->start_arg, 0); in pci224_ao_cmdtest()
712 if (cmd->start_arg & ~CR_FLAGS_MASK) { in pci224_ao_cmdtest()
713 cmd->start_arg = in pci224_ao_cmdtest()
714 COMBINE(cmd->start_arg, 0, ~CR_FLAGS_MASK); in pci224_ao_cmdtest()
715 err |= -EINVAL; in pci224_ao_cmdtest()
718 if (cmd->start_arg & CR_FLAGS_MASK & ~CR_EDGE) { in pci224_ao_cmdtest()
719 cmd->start_arg = COMBINE(cmd->start_arg, 0, in pci224_ao_cmdtest()
721 err |= -EINVAL; in pci224_ao_cmdtest()
726 switch (cmd->scan_begin_src) { in pci224_ao_cmdtest()
728 err |= comedi_check_trigger_arg_max(&cmd->scan_begin_arg, in pci224_ao_cmdtest()
731 arg = cmd->chanlist_len * CONVERT_PERIOD; in pci224_ao_cmdtest()
734 err |= comedi_check_trigger_arg_min(&cmd->scan_begin_arg, arg); in pci224_ao_cmdtest()
738 if (cmd->scan_begin_arg & ~CR_FLAGS_MASK) { in pci224_ao_cmdtest()
739 cmd->scan_begin_arg = in pci224_ao_cmdtest()
740 COMBINE(cmd->scan_begin_arg, 0, ~CR_FLAGS_MASK); in pci224_ao_cmdtest()
741 err |= -EINVAL; in pci224_ao_cmdtest()
744 if (cmd->scan_begin_arg & CR_FLAGS_MASK & in pci224_ao_cmdtest()
746 cmd->scan_begin_arg = in pci224_ao_cmdtest()
747 COMBINE(cmd->scan_begin_arg, 0, in pci224_ao_cmdtest()
749 err |= -EINVAL; in pci224_ao_cmdtest()
754 err |= comedi_check_trigger_arg_is(&cmd->convert_arg, 0); in pci224_ao_cmdtest()
755 err |= comedi_check_trigger_arg_is(&cmd->scan_end_arg, in pci224_ao_cmdtest()
756 cmd->chanlist_len); in pci224_ao_cmdtest()
758 switch (cmd->stop_src) { in pci224_ao_cmdtest()
760 err |= comedi_check_trigger_arg_min(&cmd->stop_arg, 1); in pci224_ao_cmdtest()
764 if (cmd->stop_arg & ~CR_FLAGS_MASK) { in pci224_ao_cmdtest()
765 cmd->stop_arg = in pci224_ao_cmdtest()
766 COMBINE(cmd->stop_arg, 0, ~CR_FLAGS_MASK); in pci224_ao_cmdtest()
767 err |= -EINVAL; in pci224_ao_cmdtest()
770 if (cmd->stop_arg & CR_FLAGS_MASK & ~CR_EDGE) { in pci224_ao_cmdtest()
771 cmd->stop_arg = in pci224_ao_cmdtest()
772 COMBINE(cmd->stop_arg, 0, CR_FLAGS_MASK & ~CR_EDGE); in pci224_ao_cmdtest()
776 err |= comedi_check_trigger_arg_is(&cmd->stop_arg, 0); in pci224_ao_cmdtest()
785 if (cmd->scan_begin_src == TRIG_TIMER) { in pci224_ao_cmdtest()
786 arg = cmd->scan_begin_arg; in pci224_ao_cmdtest()
788 comedi_8254_cascade_ns_to_timer(dev->pacer, &arg, cmd->flags); in pci224_ao_cmdtest()
789 err |= comedi_check_trigger_arg_is(&cmd->scan_begin_arg, arg); in pci224_ao_cmdtest()
796 if (cmd->chanlist && cmd->chanlist_len > 0) in pci224_ao_cmdtest()
808 struct pci224_private *devpriv = dev->private; in pci224_ao_start_pacer()
811 * The output of timer Z2-0 will be used as the scan trigger in pci224_ao_start_pacer()
814 /* Make sure Z2-0 is gated on. */ in pci224_ao_start_pacer()
815 outb(pci224_gat_config(0, GAT_VCC), devpriv->iobase1 + PCI224_ZGAT_SCE); in pci224_ao_start_pacer()
816 /* Cascading with Z2-2. */ in pci224_ao_start_pacer()
817 /* Make sure Z2-2 is gated on. */ in pci224_ao_start_pacer()
818 outb(pci224_gat_config(2, GAT_VCC), devpriv->iobase1 + PCI224_ZGAT_SCE); in pci224_ao_start_pacer()
819 /* Z2-2 needs 10 MHz clock. */ in pci224_ao_start_pacer()
821 devpriv->iobase1 + PCI224_ZCLK_SCE); in pci224_ao_start_pacer()
822 /* Z2-0 is clocked from Z2-2's output. */ in pci224_ao_start_pacer()
824 devpriv->iobase1 + PCI224_ZCLK_SCE); in pci224_ao_start_pacer()
826 comedi_8254_pacer_enable(dev->pacer, 2, 0, false); in pci224_ao_start_pacer()
831 const struct pci224_board *board = dev->board_ptr; in pci224_ao_cmd()
832 struct pci224_private *devpriv = dev->private; in pci224_ao_cmd()
833 struct comedi_cmd *cmd = &s->async->cmd; in pci224_ao_cmd()
841 if (!cmd->chanlist || cmd->chanlist_len == 0) in pci224_ao_cmd()
842 return -EINVAL; in pci224_ao_cmd()
844 /* Determine which channels are enabled and their load order. */ in pci224_ao_cmd()
845 devpriv->ao_enab = 0; in pci224_ao_cmd()
847 for (i = 0; i < cmd->chanlist_len; i++) { in pci224_ao_cmd()
848 ch = CR_CHAN(cmd->chanlist[i]); in pci224_ao_cmd()
849 devpriv->ao_enab |= 1U << ch; in pci224_ao_cmd()
851 for (j = 0; j < cmd->chanlist_len; j++) { in pci224_ao_cmd()
852 if (CR_CHAN(cmd->chanlist[j]) < ch) in pci224_ao_cmd()
855 devpriv->ao_scan_order[rank] = i; in pci224_ao_cmd()
858 /* Set enabled channels. */ in pci224_ao_cmd()
859 outw(devpriv->ao_enab, dev->iobase + PCI224_DACCEN); in pci224_ao_cmd()
861 /* Determine range and polarity. All channels the same. */ in pci224_ao_cmd()
862 range = CR_RANGE(cmd->chanlist[0]); in pci224_ao_cmd()
872 devpriv->daccon = in pci224_ao_cmd()
873 COMBINE(devpriv->daccon, in pci224_ao_cmd()
874 board->ao_hwrange[range] | PCI224_DACCON_TRIG_NONE | in pci224_ao_cmd()
878 outw(devpriv->daccon | PCI224_DACCON_FIFORESET, in pci224_ao_cmd()
879 dev->iobase + PCI224_DACCON); in pci224_ao_cmd()
881 if (cmd->scan_begin_src == TRIG_TIMER) { in pci224_ao_cmd()
882 comedi_8254_update_divisors(dev->pacer); in pci224_ao_cmd()
886 spin_lock_irqsave(&devpriv->ao_spinlock, flags); in pci224_ao_cmd()
887 if (cmd->start_src == TRIG_INT) { in pci224_ao_cmd()
888 s->async->inttrig = pci224_ao_inttrig_start; in pci224_ao_cmd()
891 devpriv->intsce |= PCI224_INTR_EXT; in pci224_ao_cmd()
892 outb(devpriv->intsce, devpriv->iobase1 + PCI224_INT_SCE); in pci224_ao_cmd()
894 spin_unlock_irqrestore(&devpriv->ao_spinlock, flags); in pci224_ao_cmd()
916 const struct pci224_board *board = dev->board_ptr; in pci224_ao_munge()
917 struct comedi_cmd *cmd = &s->async->cmd; in pci224_ao_munge()
924 /* The hardware expects 16-bit numbers. */ in pci224_ao_munge()
925 shift = 16 - board->ao_bits; in pci224_ao_munge()
926 /* Channels will be all bipolar or all unipolar. */ in pci224_ao_munge()
927 if ((board->ao_hwrange[CR_RANGE(cmd->chanlist[0])] & in pci224_ao_munge()
937 array[i] = (array[i] << shift) - offset; in pci224_ao_munge()
946 struct pci224_private *devpriv = dev->private; in pci224_interrupt()
947 struct comedi_subdevice *s = dev->write_subdev; in pci224_interrupt()
954 intstat = inb(devpriv->iobase1 + PCI224_INT_SCE) & 0x3F; in pci224_interrupt()
957 spin_lock_irqsave(&devpriv->ao_spinlock, flags); in pci224_interrupt()
958 valid_intstat = devpriv->intsce & intstat; in pci224_interrupt()
960 curenab = devpriv->intsce & ~intstat; in pci224_interrupt()
961 outb(curenab, devpriv->iobase1 + PCI224_INT_SCE); in pci224_interrupt()
962 devpriv->intr_running = 1; in pci224_interrupt()
963 devpriv->intr_cpuid = THISCPU; in pci224_interrupt()
964 spin_unlock_irqrestore(&devpriv->ao_spinlock, flags); in pci224_interrupt()
966 cmd = &s->async->cmd; in pci224_interrupt()
968 devpriv->intsce &= ~PCI224_INTR_EXT; in pci224_interrupt()
969 if (cmd->start_src == TRIG_EXT) in pci224_interrupt()
971 else if (cmd->stop_src == TRIG_EXT) in pci224_interrupt()
978 spin_lock_irqsave(&devpriv->ao_spinlock, flags); in pci224_interrupt()
979 if (curenab != devpriv->intsce) { in pci224_interrupt()
980 outb(devpriv->intsce, in pci224_interrupt()
981 devpriv->iobase1 + PCI224_INT_SCE); in pci224_interrupt()
983 devpriv->intr_running = 0; in pci224_interrupt()
984 spin_unlock_irqrestore(&devpriv->ao_spinlock, flags); in pci224_interrupt()
1001 if (!board || !board->name) { in pci224_auto_attach()
1002 dev_err(dev->class_dev, in pci224_auto_attach()
1004 return -EINVAL; in pci224_auto_attach()
1006 dev->board_ptr = board; in pci224_auto_attach()
1007 dev->board_name = board->name; in pci224_auto_attach()
1009 dev_info(dev->class_dev, "amplc_pci224: attach pci %s - %s\n", in pci224_auto_attach()
1010 pci_name(pci_dev), dev->board_name); in pci224_auto_attach()
1014 return -ENOMEM; in pci224_auto_attach()
1020 spin_lock_init(&devpriv->ao_spinlock); in pci224_auto_attach()
1022 devpriv->iobase1 = pci_resource_start(pci_dev, 2); in pci224_auto_attach()
1023 dev->iobase = pci_resource_start(pci_dev, 3); in pci224_auto_attach()
1024 irq = pci_dev->irq; in pci224_auto_attach()
1027 devpriv->ao_scan_vals = kmalloc_array(board->ao_chans, in pci224_auto_attach()
1028 sizeof(devpriv->ao_scan_vals[0]), in pci224_auto_attach()
1030 if (!devpriv->ao_scan_vals) in pci224_auto_attach()
1031 return -ENOMEM; in pci224_auto_attach()
1034 devpriv->ao_scan_order = in pci224_auto_attach()
1035 kmalloc_array(board->ao_chans, in pci224_auto_attach()
1036 sizeof(devpriv->ao_scan_order[0]), in pci224_auto_attach()
1038 if (!devpriv->ao_scan_order) in pci224_auto_attach()
1039 return -ENOMEM; in pci224_auto_attach()
1042 devpriv->intsce = 0; in pci224_auto_attach()
1043 outb(0, devpriv->iobase1 + PCI224_INT_SCE); in pci224_auto_attach()
1046 outw(PCI224_DACCON_GLOBALRESET, dev->iobase + PCI224_DACCON); in pci224_auto_attach()
1047 outw(0, dev->iobase + PCI224_DACCEN); in pci224_auto_attach()
1048 outw(0, dev->iobase + PCI224_FIFOSIZ); in pci224_auto_attach()
1049 devpriv->daccon = PCI224_DACCON_TRIG_SW | PCI224_DACCON_POLAR_BI | in pci224_auto_attach()
1051 outw(devpriv->daccon | PCI224_DACCON_FIFORESET, in pci224_auto_attach()
1052 dev->iobase + PCI224_DACCON); in pci224_auto_attach()
1054 dev->pacer = comedi_8254_init(devpriv->iobase1 + PCI224_Z2_BASE, in pci224_auto_attach()
1056 if (!dev->pacer) in pci224_auto_attach()
1057 return -ENOMEM; in pci224_auto_attach()
1063 s = &dev->subdevices[0]; in pci224_auto_attach()
1065 s->type = COMEDI_SUBD_AO; in pci224_auto_attach()
1066 s->subdev_flags = SDF_WRITABLE | SDF_GROUND | SDF_CMD_WRITE; in pci224_auto_attach()
1067 s->n_chan = board->ao_chans; in pci224_auto_attach()
1068 s->maxdata = (1 << board->ao_bits) - 1; in pci224_auto_attach()
1069 s->range_table = board->ao_range; in pci224_auto_attach()
1070 s->insn_write = pci224_ao_insn_write; in pci224_auto_attach()
1071 s->len_chanlist = s->n_chan; in pci224_auto_attach()
1072 dev->write_subdev = s; in pci224_auto_attach()
1073 s->do_cmd = pci224_ao_cmd; in pci224_auto_attach()
1074 s->do_cmdtest = pci224_ao_cmdtest; in pci224_auto_attach()
1075 s->cancel = pci224_ao_cancel; in pci224_auto_attach()
1076 s->munge = pci224_ao_munge; in pci224_auto_attach()
1084 dev->board_name, dev); in pci224_auto_attach()
1086 dev_err(dev->class_dev, in pci224_auto_attach()
1090 dev->irq = irq; in pci224_auto_attach()
1098 struct pci224_private *devpriv = dev->private; in pci224_detach()
1102 kfree(devpriv->ao_scan_vals); in pci224_detach()
1103 kfree(devpriv->ao_scan_order); in pci224_detach()
1121 id->driver_data); in amplc_pci224_pci_probe()