Lines Matching +full:async +full:- +full:enum

1 // SPDX-License-Identifier: GPL-2.0+
3 * Comedi driver for National Instruments PCI-DIO-32HS
5 * COMEDI - Linux Control and Measurement Device Interface
11 * Description: National Instruments PCI-DIO32HS, PCI-6533
14 * Devices: [National Instruments] PCI-DIO-32HS (ni_pcidio)
15 * [National Instruments] PXI-6533, PCI-6533 (pxi-6533)
16 * [National Instruments] PCI-6534 (pci-6534)
24 * DMA mostly works for the PCI-DIO32HS, but only in timed input mode.
26 * The PCI-DIO-32HS/PCI-6533 has a configurable external trigger. Setting
31 * This driver could be easily modified to support AT-MIO32HS and AT-MIO96.
33 * The PCI-6534 requires a firmware upload after power-up to work, the
49 /* defines for the PCI-DIO-32HS */
209 /* Firmware files for PCI-6524 */
217 enum pci_6534_firmware_registers { /* 16 bit */
226 enum pci_6534_fpga_registers {
232 FPGA_SCALS_Counter_Register = 0x280, /*write-clear */
233 FPGA_SCAMS_Counter_Register = 0x284, /*write-clear */
234 FPGA_SCBLS_Counter_Register = 0x288, /*write-clear */
235 FPGA_SCBMS_Counter_Register = 0x28c, /*write-clear */
242 enum FPGA_Control_Bits {
255 enum nidio_boardid {
269 .name = "pci-dio-32hs",
273 .name = "pxi-6533",
277 .name = "pci-6534",
295 struct nidio96_private *devpriv = dev->private; in ni_pcidio_request_di_mite_channel()
298 spin_lock_irqsave(&devpriv->mite_channel_lock, flags); in ni_pcidio_request_di_mite_channel()
299 BUG_ON(devpriv->di_mite_chan); in ni_pcidio_request_di_mite_channel()
300 devpriv->di_mite_chan = in ni_pcidio_request_di_mite_channel()
301 mite_request_channel_in_range(devpriv->mite, in ni_pcidio_request_di_mite_channel()
302 devpriv->di_mite_ring, 1, 2); in ni_pcidio_request_di_mite_channel()
303 if (!devpriv->di_mite_chan) { in ni_pcidio_request_di_mite_channel()
304 spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags); in ni_pcidio_request_di_mite_channel()
305 dev_err(dev->class_dev, "failed to reserve mite dma channel\n"); in ni_pcidio_request_di_mite_channel()
306 return -EBUSY; in ni_pcidio_request_di_mite_channel()
308 devpriv->di_mite_chan->dir = COMEDI_INPUT; in ni_pcidio_request_di_mite_channel()
309 writeb(primary_DMAChannel_bits(devpriv->di_mite_chan->channel) | in ni_pcidio_request_di_mite_channel()
310 secondary_DMAChannel_bits(devpriv->di_mite_chan->channel), in ni_pcidio_request_di_mite_channel()
311 dev->mmio + DMA_LINE_CONTROL_GROUP1); in ni_pcidio_request_di_mite_channel()
312 spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags); in ni_pcidio_request_di_mite_channel()
318 struct nidio96_private *devpriv = dev->private; in ni_pcidio_release_di_mite_channel()
321 spin_lock_irqsave(&devpriv->mite_channel_lock, flags); in ni_pcidio_release_di_mite_channel()
322 if (devpriv->di_mite_chan) { in ni_pcidio_release_di_mite_channel()
323 mite_release_channel(devpriv->di_mite_chan); in ni_pcidio_release_di_mite_channel()
324 devpriv->di_mite_chan = NULL; in ni_pcidio_release_di_mite_channel()
327 dev->mmio + DMA_LINE_CONTROL_GROUP1); in ni_pcidio_release_di_mite_channel()
329 spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags); in ni_pcidio_release_di_mite_channel()
334 struct nidio96_private *devpriv = dev->private; in setup_mite_dma()
343 comedi_buf_write_alloc(s, s->async->prealloc_bufsz); in setup_mite_dma()
345 spin_lock_irqsave(&devpriv->mite_channel_lock, flags); in setup_mite_dma()
346 if (devpriv->di_mite_chan) { in setup_mite_dma()
347 mite_prep_dma(devpriv->di_mite_chan, 32, 32); in setup_mite_dma()
348 mite_dma_arm(devpriv->di_mite_chan); in setup_mite_dma()
350 retval = -EIO; in setup_mite_dma()
352 spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags); in setup_mite_dma()
359 struct nidio96_private *devpriv = dev->private; in ni_pcidio_poll()
363 spin_lock_irqsave(&dev->spinlock, irq_flags); in ni_pcidio_poll()
364 spin_lock(&devpriv->mite_channel_lock); in ni_pcidio_poll()
365 if (devpriv->di_mite_chan) in ni_pcidio_poll()
366 mite_sync_dma(devpriv->di_mite_chan, s); in ni_pcidio_poll()
367 spin_unlock(&devpriv->mite_channel_lock); in ni_pcidio_poll()
369 spin_unlock_irqrestore(&dev->spinlock, irq_flags); in ni_pcidio_poll()
376 struct nidio96_private *devpriv = dev->private; in nidio_interrupt()
377 struct comedi_subdevice *s = dev->read_subdev; in nidio_interrupt()
378 struct comedi_async *async = s->async; in nidio_interrupt() local
385 if (!dev->attached) { in nidio_interrupt()
391 spin_lock(&dev->spinlock); in nidio_interrupt()
393 status = readb(dev->mmio + INTERRUPT_AND_WINDOW_STATUS); in nidio_interrupt()
394 flags = readb(dev->mmio + GROUP_1_FLAGS); in nidio_interrupt()
396 spin_lock(&devpriv->mite_channel_lock); in nidio_interrupt()
397 if (devpriv->di_mite_chan) { in nidio_interrupt()
398 mite_ack_linkc(devpriv->di_mite_chan, s, false); in nidio_interrupt()
401 spin_unlock(&devpriv->mite_channel_lock); in nidio_interrupt()
406 dev_dbg(dev->class_dev, "too much work in interrupt\n"); in nidio_interrupt()
408 dev->mmio + MASTER_DMA_AND_INTERRUPT_CONTROL); in nidio_interrupt()
418 dev_dbg(dev->class_dev, in nidio_interrupt()
420 writeb(0x00, dev->mmio + in nidio_interrupt()
425 auxdata = readl(dev->mmio + GROUP_1_FIFO); in nidio_interrupt()
427 flags = readb(dev->mmio + GROUP_1_FLAGS); in nidio_interrupt()
432 writeb(CLEAR_EXPIRED, dev->mmio + GROUP_1_SECOND_CLEAR); in nidio_interrupt()
433 async->events |= COMEDI_CB_EOA; in nidio_interrupt()
435 writeb(0x00, dev->mmio + OP_MODE); in nidio_interrupt()
438 writeb(CLEAR_WAITED, dev->mmio + GROUP_1_FIRST_CLEAR); in nidio_interrupt()
439 async->events |= COMEDI_CB_ERROR; in nidio_interrupt()
443 dev->mmio + GROUP_1_FIRST_CLEAR); in nidio_interrupt()
444 async->events |= COMEDI_CB_EOA; in nidio_interrupt()
447 dev->mmio + GROUP_1_FIRST_CLEAR); in nidio_interrupt()
448 async->events |= COMEDI_CB_EOA; in nidio_interrupt()
451 flags = readb(dev->mmio + GROUP_1_FLAGS); in nidio_interrupt()
452 status = readb(dev->mmio + INTERRUPT_AND_WINDOW_STATUS); in nidio_interrupt()
459 writeb(0x03, dev->mmio + MASTER_DMA_AND_INTERRUPT_CONTROL); in nidio_interrupt()
462 spin_unlock(&dev->spinlock); in nidio_interrupt()
474 const struct nidio_board *board = dev->board_ptr; in ni_pcidio_insn_config()
477 data[1] = board->dio_speed; in ni_pcidio_insn_config()
486 writel(s->io_bits, dev->mmio + PORT_PIN_DIRECTIONS(0)); in ni_pcidio_insn_config()
488 return insn->n; in ni_pcidio_insn_config()
497 writel(s->state, dev->mmio + PORT_IO(0)); in ni_pcidio_insn_bits()
499 data[1] = readl(dev->mmio + PORT_IO(0)); in ni_pcidio_insn_bits()
501 return insn->n; in ni_pcidio_insn_bits()
535 err |= comedi_check_trigger_src(&cmd->start_src, TRIG_NOW | TRIG_INT); in ni_pcidio_cmdtest()
536 err |= comedi_check_trigger_src(&cmd->scan_begin_src, in ni_pcidio_cmdtest()
538 err |= comedi_check_trigger_src(&cmd->convert_src, TRIG_NOW); in ni_pcidio_cmdtest()
539 err |= comedi_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT); in ni_pcidio_cmdtest()
540 err |= comedi_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE); in ni_pcidio_cmdtest()
547 err |= comedi_check_trigger_is_unique(cmd->start_src); in ni_pcidio_cmdtest()
548 err |= comedi_check_trigger_is_unique(cmd->scan_begin_src); in ni_pcidio_cmdtest()
549 err |= comedi_check_trigger_is_unique(cmd->stop_src); in ni_pcidio_cmdtest()
558 err |= comedi_check_trigger_arg_is(&cmd->start_arg, 0); in ni_pcidio_cmdtest()
562 if (cmd->scan_begin_src == TRIG_TIMER) { in ni_pcidio_cmdtest()
563 err |= comedi_check_trigger_arg_min(&cmd->scan_begin_arg, in ni_pcidio_cmdtest()
569 if ((cmd->scan_begin_arg & ~(CR_EDGE | CR_INVERT)) != 0) { in ni_pcidio_cmdtest()
570 cmd->scan_begin_arg &= (CR_EDGE | CR_INVERT); in ni_pcidio_cmdtest()
571 err |= -EINVAL; in ni_pcidio_cmdtest()
575 err |= comedi_check_trigger_arg_is(&cmd->convert_arg, 0); in ni_pcidio_cmdtest()
576 err |= comedi_check_trigger_arg_is(&cmd->scan_end_arg, in ni_pcidio_cmdtest()
577 cmd->chanlist_len); in ni_pcidio_cmdtest()
579 if (cmd->stop_src == TRIG_COUNT) in ni_pcidio_cmdtest()
580 err |= comedi_check_trigger_arg_min(&cmd->stop_arg, 1); in ni_pcidio_cmdtest()
582 err |= comedi_check_trigger_arg_is(&cmd->stop_arg, 0); in ni_pcidio_cmdtest()
589 if (cmd->scan_begin_src == TRIG_TIMER) { in ni_pcidio_cmdtest()
590 arg = cmd->scan_begin_arg; in ni_pcidio_cmdtest()
591 ni_pcidio_ns_to_timer(&arg, cmd->flags); in ni_pcidio_cmdtest()
592 err |= comedi_check_trigger_arg_is(&cmd->scan_begin_arg, arg); in ni_pcidio_cmdtest()
605 struct nidio96_private *devpriv = dev->private; in ni_pcidio_inttrig()
606 struct comedi_cmd *cmd = &s->async->cmd; in ni_pcidio_inttrig()
608 if (trig_num != cmd->start_arg) in ni_pcidio_inttrig()
609 return -EINVAL; in ni_pcidio_inttrig()
611 writeb(devpriv->OP_MODEBits, dev->mmio + OP_MODE); in ni_pcidio_inttrig()
612 s->async->inttrig = NULL; in ni_pcidio_inttrig()
619 struct nidio96_private *devpriv = dev->private; in ni_pcidio_cmd()
620 struct comedi_cmd *cmd = &s->async->cmd; in ni_pcidio_cmd()
623 writel(0x0000, dev->mmio + PORT_PIN_DIRECTIONS(0)); in ni_pcidio_cmd()
627 writeb(0x0f, dev->mmio + DATA_PATH); in ni_pcidio_cmd()
631 dev->mmio + TRANSFER_SIZE_CONTROL); in ni_pcidio_cmd()
633 writeb(0x03, dev->mmio + DATA_PATH); in ni_pcidio_cmd()
635 dev->mmio + TRANSFER_SIZE_CONTROL); in ni_pcidio_cmd()
639 if (cmd->scan_begin_src == TRIG_TIMER) { in ni_pcidio_cmd()
640 /* page 4-5, "input with internal REQs" */ in ni_pcidio_cmd()
641 writeb(0, dev->mmio + OP_MODE); in ni_pcidio_cmd()
642 writeb(0x00, dev->mmio + CLOCK_REG); in ni_pcidio_cmd()
643 writeb(1, dev->mmio + SEQUENCE); in ni_pcidio_cmd()
644 writeb(0x04, dev->mmio + REQ_REG); in ni_pcidio_cmd()
645 writeb(4, dev->mmio + BLOCK_MODE); in ni_pcidio_cmd()
646 writeb(3, dev->mmio + LINE_POLARITIES); in ni_pcidio_cmd()
647 writeb(0xc0, dev->mmio + ACK_SER); in ni_pcidio_cmd()
648 writel(ni_pcidio_ns_to_timer(&cmd->scan_begin_arg, in ni_pcidio_cmd()
650 dev->mmio + START_DELAY); in ni_pcidio_cmd()
651 writeb(1, dev->mmio + REQ_DELAY); in ni_pcidio_cmd()
652 writeb(1, dev->mmio + REQ_NOT_DELAY); in ni_pcidio_cmd()
653 writeb(1, dev->mmio + ACK_DELAY); in ni_pcidio_cmd()
654 writeb(0x0b, dev->mmio + ACK_NOT_DELAY); in ni_pcidio_cmd()
655 writeb(0x01, dev->mmio + DATA_1_DELAY); in ni_pcidio_cmd()
657 * manual, page 4-5: in ni_pcidio_cmd()
660 writew(0, dev->mmio + CLOCK_SPEED); in ni_pcidio_cmd()
661 writeb(0, dev->mmio + DAQ_OPTIONS); in ni_pcidio_cmd()
664 /* page 4-5, "input with external REQs" */ in ni_pcidio_cmd()
665 writeb(0, dev->mmio + OP_MODE); in ni_pcidio_cmd()
666 writeb(0x00, dev->mmio + CLOCK_REG); in ni_pcidio_cmd()
667 writeb(0, dev->mmio + SEQUENCE); in ni_pcidio_cmd()
668 writeb(0x00, dev->mmio + REQ_REG); in ni_pcidio_cmd()
669 writeb(4, dev->mmio + BLOCK_MODE); in ni_pcidio_cmd()
670 if (!(cmd->scan_begin_arg & CR_INVERT)) /* Leading Edge */ in ni_pcidio_cmd()
671 writeb(0, dev->mmio + LINE_POLARITIES); in ni_pcidio_cmd()
673 writeb(2, dev->mmio + LINE_POLARITIES); in ni_pcidio_cmd()
674 writeb(0x00, dev->mmio + ACK_SER); in ni_pcidio_cmd()
675 writel(1, dev->mmio + START_DELAY); in ni_pcidio_cmd()
676 writeb(1, dev->mmio + REQ_DELAY); in ni_pcidio_cmd()
677 writeb(1, dev->mmio + REQ_NOT_DELAY); in ni_pcidio_cmd()
678 writeb(1, dev->mmio + ACK_DELAY); in ni_pcidio_cmd()
679 writeb(0x0C, dev->mmio + ACK_NOT_DELAY); in ni_pcidio_cmd()
680 writeb(0x10, dev->mmio + DATA_1_DELAY); in ni_pcidio_cmd()
681 writew(0, dev->mmio + CLOCK_SPEED); in ni_pcidio_cmd()
682 writeb(0x60, dev->mmio + DAQ_OPTIONS); in ni_pcidio_cmd()
685 if (cmd->stop_src == TRIG_COUNT) { in ni_pcidio_cmd()
686 writel(cmd->stop_arg, in ni_pcidio_cmd()
687 dev->mmio + TRANSFER_COUNT); in ni_pcidio_cmd()
694 dev->mmio + GROUP_1_FIRST_CLEAR); in ni_pcidio_cmd()
703 writeb(0x00, dev->mmio + DMA_LINE_CONTROL_GROUP1); in ni_pcidio_cmd()
705 writeb(0x00, dev->mmio + DMA_LINE_CONTROL_GROUP2); in ni_pcidio_cmd()
708 writeb(0xff, dev->mmio + GROUP_1_FIRST_CLEAR); in ni_pcidio_cmd()
709 /* writeb(CLEAR_EXPIRED, dev->mmio+GROUP_1_SECOND_CLEAR); */ in ni_pcidio_cmd()
711 writeb(INT_EN, dev->mmio + INTERRUPT_CONTROL); in ni_pcidio_cmd()
712 writeb(0x03, dev->mmio + MASTER_DMA_AND_INTERRUPT_CONTROL); in ni_pcidio_cmd()
714 if (cmd->stop_src == TRIG_NONE) { in ni_pcidio_cmd()
715 devpriv->OP_MODEBits = DATA_LATCHING(0) | RUN_MODE(7); in ni_pcidio_cmd()
717 devpriv->OP_MODEBits = NUMBERED | RUN_MODE(7); in ni_pcidio_cmd()
719 if (cmd->start_src == TRIG_NOW) { in ni_pcidio_cmd()
721 writeb(devpriv->OP_MODEBits, dev->mmio + OP_MODE); in ni_pcidio_cmd()
722 s->async->inttrig = NULL; in ni_pcidio_cmd()
725 s->async->inttrig = ni_pcidio_inttrig; in ni_pcidio_cmd()
734 writeb(0x00, dev->mmio + MASTER_DMA_AND_INTERRUPT_CONTROL); in ni_pcidio_cancel()
743 struct nidio96_private *devpriv = dev->private; in ni_pcidio_change()
746 ret = mite_buf_change(devpriv->di_mite_ring, s); in ni_pcidio_change()
750 memset(s->async->prealloc_buf, 0xaa, s->async->prealloc_bufsz); in ni_pcidio_change()
764 writew(0x80 | fpga_index, dev->mmio + Firmware_Control_Register); in pci_6534_load_fpga()
765 writew(0xc0 | fpga_index, dev->mmio + Firmware_Control_Register); in pci_6534_load_fpga()
767 (readw(dev->mmio + Firmware_Status_Register) & 0x2) == 0 && in pci_6534_load_fpga()
772 dev_warn(dev->class_dev, in pci_6534_load_fpga()
775 return -EIO; in pci_6534_load_fpga()
777 writew(0x80 | fpga_index, dev->mmio + Firmware_Control_Register); in pci_6534_load_fpga()
779 readw(dev->mmio + Firmware_Status_Register) != 0x3 && in pci_6534_load_fpga()
784 dev_warn(dev->class_dev, in pci_6534_load_fpga()
787 return -EIO; in pci_6534_load_fpga()
793 writew(value, dev->mmio + Firmware_Data_Register); in pci_6534_load_fpga()
795 (readw(dev->mmio + Firmware_Status_Register) & 0x2) == 0 in pci_6534_load_fpga()
800 dev_warn(dev->class_dev, in pci_6534_load_fpga()
803 return -EIO; in pci_6534_load_fpga()
808 writew(0x0, dev->mmio + Firmware_Control_Register); in pci_6534_load_fpga()
822 writew(0x0, dev->mmio + Firmware_Control_Register); in pci_6534_reset_fpgas()
828 writew(0x0, dev->mmio + Firmware_Mask_Register); in pci_6534_reset_fpgas()
834 writel(0, dev->mmio + FPGA_Control1_Register); in pci_6534_init_main_fpga()
835 writel(0, dev->mmio + FPGA_Control2_Register); in pci_6534_init_main_fpga()
836 writel(0, dev->mmio + FPGA_SCALS_Counter_Register); in pci_6534_init_main_fpga()
837 writel(0, dev->mmio + FPGA_SCAMS_Counter_Register); in pci_6534_init_main_fpga()
838 writel(0, dev->mmio + FPGA_SCBLS_Counter_Register); in pci_6534_init_main_fpga()
839 writel(0, dev->mmio + FPGA_SCBMS_Counter_Register); in pci_6534_init_main_fpga()
844 struct nidio96_private *devpriv = dev->private; in pci_6534_upload_firmware()
857 for (n = 2; n >= 0; n--) { in pci_6534_upload_firmware()
858 ret = comedi_load_firmware(dev, &devpriv->mite->pcidev->dev, in pci_6534_upload_firmware()
871 writel(0, dev->mmio + PORT_IO(0)); in nidio_reset_board()
872 writel(0, dev->mmio + PORT_PIN_DIRECTIONS(0)); in nidio_reset_board()
873 writel(0, dev->mmio + PORT_PIN_MASK(0)); in nidio_reset_board()
876 writeb(0, dev->mmio + MASTER_DMA_AND_INTERRUPT_CONTROL); in nidio_reset_board()
892 return -ENODEV; in nidio_auto_attach()
893 dev->board_ptr = board; in nidio_auto_attach()
894 dev->board_name = board->name; in nidio_auto_attach()
902 return -ENOMEM; in nidio_auto_attach()
904 spin_lock_init(&devpriv->mite_channel_lock); in nidio_auto_attach()
906 devpriv->mite = mite_attach(dev, false); /* use win0 */ in nidio_auto_attach()
907 if (!devpriv->mite) in nidio_auto_attach()
908 return -ENOMEM; in nidio_auto_attach()
910 devpriv->di_mite_ring = mite_alloc_ring(devpriv->mite); in nidio_auto_attach()
911 if (!devpriv->di_mite_ring) in nidio_auto_attach()
912 return -ENOMEM; in nidio_auto_attach()
914 if (board->uses_firmware) { in nidio_auto_attach()
926 dev_info(dev->class_dev, "%s rev=%d\n", dev->board_name, in nidio_auto_attach()
927 readb(dev->mmio + CHIP_VERSION)); in nidio_auto_attach()
929 s = &dev->subdevices[0]; in nidio_auto_attach()
931 dev->read_subdev = s; in nidio_auto_attach()
932 s->type = COMEDI_SUBD_DIO; in nidio_auto_attach()
933 s->subdev_flags = in nidio_auto_attach()
936 s->n_chan = 32; in nidio_auto_attach()
937 s->range_table = &range_digital; in nidio_auto_attach()
938 s->maxdata = 1; in nidio_auto_attach()
939 s->insn_config = &ni_pcidio_insn_config; in nidio_auto_attach()
940 s->insn_bits = &ni_pcidio_insn_bits; in nidio_auto_attach()
941 s->do_cmd = &ni_pcidio_cmd; in nidio_auto_attach()
942 s->do_cmdtest = &ni_pcidio_cmdtest; in nidio_auto_attach()
943 s->cancel = &ni_pcidio_cancel; in nidio_auto_attach()
944 s->len_chanlist = 32; /* XXX */ in nidio_auto_attach()
945 s->buf_change = &ni_pcidio_change; in nidio_auto_attach()
946 s->async_dma_dir = DMA_BIDIRECTIONAL; in nidio_auto_attach()
947 s->poll = &ni_pcidio_poll; in nidio_auto_attach()
949 irq = pcidev->irq; in nidio_auto_attach()
952 dev->board_name, dev); in nidio_auto_attach()
954 dev->irq = irq; in nidio_auto_attach()
962 struct nidio96_private *devpriv = dev->private; in nidio_detach()
964 if (dev->irq) in nidio_detach()
965 free_irq(dev->irq, dev); in nidio_detach()
967 if (devpriv->di_mite_ring) { in nidio_detach()
968 mite_free_ring(devpriv->di_mite_ring); in nidio_detach()
969 devpriv->di_mite_ring = NULL; in nidio_detach()
971 mite_detach(devpriv->mite); in nidio_detach()
973 if (dev->mmio) in nidio_detach()
974 iounmap(dev->mmio); in nidio_detach()
988 return comedi_pci_auto_config(dev, &ni_pcidio_driver, id->driver_data); in ni_pcidio_pci_probe()
1008 MODULE_DESCRIPTION("Comedi low-level driver");