Exemplo n.º 1
0
static int ni_pcidio_insn_config(struct comedi_device *dev,
				 struct comedi_subdevice *s,
				 struct comedi_insn *insn, unsigned int *data)
{
	if (insn->n != 1)
		return -EINVAL;
	switch (data[0]) {
	case INSN_CONFIG_DIO_OUTPUT:
		s->io_bits |= 1 << CR_CHAN(insn->chanspec);
		break;
	case INSN_CONFIG_DIO_INPUT:
		s->io_bits &= ~(1 << CR_CHAN(insn->chanspec));
		break;
	case INSN_CONFIG_DIO_QUERY:
		data[1] =
		    (s->
		     io_bits & (1 << CR_CHAN(insn->chanspec))) ? COMEDI_OUTPUT :
		    COMEDI_INPUT;
		return insn->n;
		break;
	default:
		return -EINVAL;
	}
	writel(s->io_bits, devpriv->mite->daq_io_addr + Port_Pin_Directions(0));

	return 1;
}
Exemplo n.º 2
0
static int ni_pcidio_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
{
	struct comedi_cmd *cmd = &s->async->cmd;

	
	writel(0x0000, devpriv->mite->daq_io_addr + Port_Pin_Directions(0));

	if (1) {
		
		writeb(0x0f, devpriv->mite->daq_io_addr + Data_Path);

		
		writeb(TransferWidth(0) | TransferLength(0),
		       devpriv->mite->daq_io_addr + Transfer_Size_Control);
	} else {
		writeb(0x03, devpriv->mite->daq_io_addr + Data_Path);
		writeb(TransferWidth(3) | TransferLength(0),
		       devpriv->mite->daq_io_addr + Transfer_Size_Control);
	}

	
	if (cmd->scan_begin_src == TRIG_TIMER) {
		
		writeb(0, devpriv->mite->daq_io_addr + OpMode);
		writeb(0x00, devpriv->mite->daq_io_addr + ClockReg);
		writeb(1, devpriv->mite->daq_io_addr + Sequence);
		writeb(0x04, devpriv->mite->daq_io_addr + ReqReg);
		writeb(4, devpriv->mite->daq_io_addr + BlockMode);
		writeb(3, devpriv->mite->daq_io_addr + LinePolarities);
		writeb(0xc0, devpriv->mite->daq_io_addr + AckSer);
		writel(ni_pcidio_ns_to_timer(&cmd->scan_begin_arg,
					     TRIG_ROUND_NEAREST),
		       devpriv->mite->daq_io_addr + StartDelay);
		writeb(1, devpriv->mite->daq_io_addr + ReqDelay);
		writeb(1, devpriv->mite->daq_io_addr + ReqNotDelay);
		writeb(1, devpriv->mite->daq_io_addr + AckDelay);
		writeb(0x0b, devpriv->mite->daq_io_addr + AckNotDelay);
		writeb(0x01, devpriv->mite->daq_io_addr + Data1Delay);
		
		writew(0, devpriv->mite->daq_io_addr + ClockSpeed);
		writeb(0, devpriv->mite->daq_io_addr + DAQOptions);
	} else {
		
		
		writeb(0, devpriv->mite->daq_io_addr + OpMode);
		writeb(0x00, devpriv->mite->daq_io_addr + ClockReg);
		writeb(0, devpriv->mite->daq_io_addr + Sequence);
		writeb(0x00, devpriv->mite->daq_io_addr + ReqReg);
		writeb(4, devpriv->mite->daq_io_addr + BlockMode);
		writeb(0, devpriv->mite->daq_io_addr + LinePolarities);
		writeb(0x00, devpriv->mite->daq_io_addr + AckSer);
		writel(1, devpriv->mite->daq_io_addr + StartDelay);
		writeb(1, devpriv->mite->daq_io_addr + ReqDelay);
		writeb(1, devpriv->mite->daq_io_addr + ReqNotDelay);
		writeb(1, devpriv->mite->daq_io_addr + AckDelay);
		writeb(0x0C, devpriv->mite->daq_io_addr + AckNotDelay);
		writeb(0x10, devpriv->mite->daq_io_addr + Data1Delay);
		writew(0, devpriv->mite->daq_io_addr + ClockSpeed);
		writeb(0x60, devpriv->mite->daq_io_addr + DAQOptions);
	}

	if (cmd->stop_src == TRIG_COUNT) {
		writel(cmd->stop_arg,
		       devpriv->mite->daq_io_addr + Transfer_Count);
	} else {
		
	}

#ifdef USE_DMA
	writeb(ClearPrimaryTC | ClearSecondaryTC,
	       devpriv->mite->daq_io_addr + Group_1_First_Clear);

	{
		int retval = setup_mite_dma(dev, s);
		if (retval)
			return retval;
	}
#else
	writeb(0x00, devpriv->mite->daq_io_addr + DMA_Line_Control_Group1);
#endif
	writeb(0x00, devpriv->mite->daq_io_addr + DMA_Line_Control_Group2);

	
	writeb(0xff, devpriv->mite->daq_io_addr + Group_1_First_Clear);
	

	writeb(IntEn, devpriv->mite->daq_io_addr + Interrupt_Control);
	writeb(0x03,
	       devpriv->mite->daq_io_addr + Master_DMA_And_Interrupt_Control);

	if (cmd->stop_src == TRIG_NONE) {
		devpriv->OpModeBits = DataLatching(0) | RunMode(7);
	} else {		
		devpriv->OpModeBits = Numbered | RunMode(7);
	}
	if (cmd->start_src == TRIG_NOW) {
		
		writeb(devpriv->OpModeBits,
		       devpriv->mite->daq_io_addr + OpMode);
		s->async->inttrig = NULL;
	} else {
		
		s->async->inttrig = ni_pcidio_inttrig;
	}

	DPRINTK("ni_pcidio: command started\n");
	return 0;
}
Exemplo n.º 3
0
static int nidio_attach(struct comedi_device *dev, struct comedi_devconfig *it)
{
	struct comedi_subdevice *s;
	int i;
	int ret;
	int n_subdevices;
	unsigned int irq;

	printk("comedi%d: nidio:", dev->minor);

	if ((ret = alloc_private(dev, sizeof(struct nidio96_private))) < 0)
		return ret;
	spin_lock_init(&devpriv->mite_channel_lock);

	ret = nidio_find_device(dev, it->options[0], it->options[1]);
	if (ret < 0)
		return ret;

	ret = mite_setup(devpriv->mite);
	if (ret < 0) {
		printk("error setting up mite\n");
		return ret;
	}
	comedi_set_hw_dev(dev, &devpriv->mite->pcidev->dev);
	devpriv->di_mite_ring = mite_alloc_ring(devpriv->mite);
	if (devpriv->di_mite_ring == NULL)
		return -ENOMEM;

	dev->board_name = this_board->name;
	irq = mite_irq(devpriv->mite);
	printk(" %s", dev->board_name);
	if (this_board->uses_firmware) {
		ret = pci_6534_upload_firmware(dev, it->options);
		if (ret < 0)
			return ret;
	}
	if (!this_board->is_diodaq) {
		n_subdevices = this_board->n_8255;
	} else {
		n_subdevices = 1;
	}
	if ((ret = alloc_subdevices(dev, n_subdevices)) < 0)
		return ret;

	if (!this_board->is_diodaq) {
		for (i = 0; i < this_board->n_8255; i++) {
			subdev_8255_init(dev, dev->subdevices + i,
					 nidio96_8255_cb,
					 (unsigned long)(devpriv->mite->
							 daq_io_addr +
							 NIDIO_8255_BASE(i)));
		}
	} else {

		printk(" rev=%d",
		       readb(devpriv->mite->daq_io_addr + Chip_Version));

		s = dev->subdevices + 0;

		dev->read_subdev = s;
		s->type = COMEDI_SUBD_DIO;
		s->subdev_flags =
		    SDF_READABLE | SDF_WRITABLE | SDF_LSAMPL | SDF_PACKED |
		    SDF_CMD_READ;
		s->n_chan = 32;
		s->range_table = &range_digital;
		s->maxdata = 1;
		s->insn_config = &ni_pcidio_insn_config;
		s->insn_bits = &ni_pcidio_insn_bits;
		s->do_cmd = &ni_pcidio_cmd;
		s->do_cmdtest = &ni_pcidio_cmdtest;
		s->cancel = &ni_pcidio_cancel;
		s->len_chanlist = 32;	
		s->buf_change = &ni_pcidio_change;
		s->async_dma_dir = DMA_BIDIRECTIONAL;

		writel(0, devpriv->mite->daq_io_addr + Port_IO(0));
		writel(0, devpriv->mite->daq_io_addr + Port_Pin_Directions(0));
		writel(0, devpriv->mite->daq_io_addr + Port_Pin_Mask(0));

		
		writeb(0x00,
		       devpriv->mite->daq_io_addr +
		       Master_DMA_And_Interrupt_Control);

		ret = request_irq(irq, nidio_interrupt, IRQF_SHARED,
				  "ni_pcidio", dev);
		if (ret < 0) {
			printk(" irq not available");
		}
		dev->irq = irq;
	}

	printk("\n");

	return 0;
}
Exemplo n.º 4
0
static int ni_pcidio_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
{
	struct comedi_cmd *cmd = &s->async->cmd;

	/* XXX configure ports for input */
	writel(0x0000, devpriv->mite->daq_io_addr + Port_Pin_Directions(0));

	if (1) {
		/* enable fifos A B C D */
		writeb(0x0f, devpriv->mite->daq_io_addr + Data_Path);

		/* set transfer width a 32 bits */
		writeb(TransferWidth(0) | TransferLength(0),
		       devpriv->mite->daq_io_addr + Transfer_Size_Control);
	} else {
		writeb(0x03, devpriv->mite->daq_io_addr + Data_Path);
		writeb(TransferWidth(3) | TransferLength(0),
		       devpriv->mite->daq_io_addr + Transfer_Size_Control);
	}

	/* protocol configuration */
	if (cmd->scan_begin_src == TRIG_TIMER) {
		/* page 4-5, "input with internal REQs" */
		writeb(0, devpriv->mite->daq_io_addr + OpMode);
		writeb(0x00, devpriv->mite->daq_io_addr + ClockReg);
		writeb(1, devpriv->mite->daq_io_addr + Sequence);
		writeb(0x04, devpriv->mite->daq_io_addr + ReqReg);
		writeb(4, devpriv->mite->daq_io_addr + BlockMode);
		writeb(3, devpriv->mite->daq_io_addr + LinePolarities);
		writeb(0xc0, devpriv->mite->daq_io_addr + AckSer);
		writel(ni_pcidio_ns_to_timer(&cmd->scan_begin_arg,
					     TRIG_ROUND_NEAREST),
		       devpriv->mite->daq_io_addr + StartDelay);
		writeb(1, devpriv->mite->daq_io_addr + ReqDelay);
		writeb(1, devpriv->mite->daq_io_addr + ReqNotDelay);
		writeb(1, devpriv->mite->daq_io_addr + AckDelay);
		writeb(0x0b, devpriv->mite->daq_io_addr + AckNotDelay);
		writeb(0x01, devpriv->mite->daq_io_addr + Data1Delay);
		/* manual, page 4-5: ClockSpeed comment is incorrectly listed
		 * on DAQOptions */
		writew(0, devpriv->mite->daq_io_addr + ClockSpeed);
		writeb(0, devpriv->mite->daq_io_addr + DAQOptions);
	} else {
		/* TRIG_EXT */
		/* page 4-5, "input with external REQs" */
		writeb(0, devpriv->mite->daq_io_addr + OpMode);
		writeb(0x00, devpriv->mite->daq_io_addr + ClockReg);
		writeb(0, devpriv->mite->daq_io_addr + Sequence);
		writeb(0x00, devpriv->mite->daq_io_addr + ReqReg);
		writeb(4, devpriv->mite->daq_io_addr + BlockMode);
		writeb(0, devpriv->mite->daq_io_addr + LinePolarities);
		writeb(0x00, devpriv->mite->daq_io_addr + AckSer);
		writel(1, devpriv->mite->daq_io_addr + StartDelay);
		writeb(1, devpriv->mite->daq_io_addr + ReqDelay);
		writeb(1, devpriv->mite->daq_io_addr + ReqNotDelay);
		writeb(1, devpriv->mite->daq_io_addr + AckDelay);
		writeb(0x0C, devpriv->mite->daq_io_addr + AckNotDelay);
		writeb(0x10, devpriv->mite->daq_io_addr + Data1Delay);
		writew(0, devpriv->mite->daq_io_addr + ClockSpeed);
		writeb(0x60, devpriv->mite->daq_io_addr + DAQOptions);
	}

	if (cmd->stop_src == TRIG_COUNT) {
		writel(cmd->stop_arg,
		       devpriv->mite->daq_io_addr + Transfer_Count);
	} else {
		/* XXX */
	}

#ifdef USE_DMA
	writeb(ClearPrimaryTC | ClearSecondaryTC,
	       devpriv->mite->daq_io_addr + Group_1_First_Clear);

	{
		int retval = setup_mite_dma(dev, s);
		if (retval)
			return retval;
	}
#else
	writeb(0x00, devpriv->mite->daq_io_addr + DMA_Line_Control_Group1);
#endif
	writeb(0x00, devpriv->mite->daq_io_addr + DMA_Line_Control_Group2);

	/* clear and enable interrupts */
	writeb(0xff, devpriv->mite->daq_io_addr + Group_1_First_Clear);
	/* writeb(ClearExpired,
	       devpriv->mite->daq_io_addr+Group_1_Second_Clear); */

	writeb(IntEn, devpriv->mite->daq_io_addr + Interrupt_Control);
	writeb(0x03,
	       devpriv->mite->daq_io_addr + Master_DMA_And_Interrupt_Control);

	if (cmd->stop_src == TRIG_NONE) {
		devpriv->OpModeBits = DataLatching(0) | RunMode(7);
	} else {		/* TRIG_TIMER */
		devpriv->OpModeBits = Numbered | RunMode(7);
	}
	if (cmd->start_src == TRIG_NOW) {
		/* start */
		writeb(devpriv->OpModeBits,
		       devpriv->mite->daq_io_addr + OpMode);
		s->async->inttrig = NULL;
	} else {
		/* TRIG_INT */
		s->async->inttrig = ni_pcidio_inttrig;
	}

	DPRINTK("ni_pcidio: command started\n");
	return 0;
}