コード例 #1
0
ファイル: amplc_pc236_common.c プロジェクト: 020gzh/linux
static irqreturn_t pc236_interrupt(int irq, void *d)
{
	struct comedi_device *dev = d;
	struct comedi_subdevice *s = dev->read_subdev;
	bool handled;

	handled = pc236_intr_check(dev);
	if (dev->attached && handled) {
		comedi_buf_write_samples(s, &s->state, 1);
		comedi_handle_events(dev, s);
	}
	return IRQ_RETVAL(handled);
}
コード例 #2
0
ファイル: ni_labpc_isadma.c プロジェクト: 383530895/linux
void labpc_drain_dma(struct comedi_device *dev)
{
	struct labpc_private *devpriv = dev->private;
	struct comedi_subdevice *s = dev->read_subdev;
	struct comedi_async *async = s->async;
	struct comedi_cmd *cmd = &async->cmd;
	int status;
	unsigned long flags;
	unsigned int max_points, num_points, residue, leftover;

	status = devpriv->stat1;

	flags = claim_dma_lock();
	disable_dma(devpriv->dma_chan);
	/* clear flip-flop to make sure 2-byte registers for
	 * count and address get set correctly */
	clear_dma_ff(devpriv->dma_chan);

	/* figure out how many points to read */
	max_points = devpriv->dma_transfer_size / sample_size;
	/* residue is the number of points left to be done on the dma
	 * transfer.  It should always be zero at this point unless
	 * the stop_src is set to external triggering.
	 */
	residue = get_dma_residue(devpriv->dma_chan) / sample_size;
	num_points = max_points - residue;
	if (cmd->stop_src == TRIG_COUNT && devpriv->count < num_points)
		num_points = devpriv->count;

	/* figure out how many points will be stored next time */
	leftover = 0;
	if (cmd->stop_src != TRIG_COUNT) {
		leftover = devpriv->dma_transfer_size / sample_size;
	} else if (devpriv->count > num_points) {
		leftover = devpriv->count - num_points;
		if (leftover > max_points)
			leftover = max_points;
	}

	comedi_buf_write_samples(s, devpriv->dma_buffer, num_points);

	if (cmd->stop_src == TRIG_COUNT)
		devpriv->count -= num_points;

	/* set address and count for next transfer */
	set_dma_addr(devpriv->dma_chan, devpriv->dma_addr);
	set_dma_count(devpriv->dma_chan, leftover * sample_size);
	release_dma_lock(flags);
}
コード例 #3
0
ファイル: usbduxsigma.c プロジェクト: DenisLug/mptcp
static void usbduxsigma_ai_handle_urb(struct comedi_device *dev,
				      struct comedi_subdevice *s,
				      struct urb *urb)
{
	struct usbduxsigma_private *devpriv = dev->private;
	struct comedi_async *async = s->async;
	struct comedi_cmd *cmd = &async->cmd;
	uint32_t val;
	int ret;
	int i;

	if ((urb->actual_length > 0) && (urb->status != -EXDEV)) {
		devpriv->ai_counter--;
		if (devpriv->ai_counter == 0) {
			devpriv->ai_counter = devpriv->ai_timer;

			/* get the data from the USB bus
			   and hand it over to comedi */
			for (i = 0; i < cmd->chanlist_len; i++) {
				/* transfer data,
				   note first byte is the DIO state */
				val = be32_to_cpu(devpriv->in_buf[i+1]);
				val &= 0x00ffffff; /* strip status byte */
				val ^= 0x00800000; /* convert to unsigned */

				if (!comedi_buf_write_samples(s, &val, 1))
					return;
			}

			if (cmd->stop_src == TRIG_COUNT &&
			    async->scans_done >= cmd->stop_arg)
				async->events |= COMEDI_CB_EOA;
		}
	}

	/* if command is still running, resubmit urb */
	if (!(async->events & COMEDI_CB_CANCEL_MASK)) {
		urb->dev = comedi_to_usb_dev(dev);
		ret = usb_submit_urb(urb, GFP_ATOMIC);
		if (ret < 0) {
			dev_err(dev->class_dev, "urb resubmit failed (%d)\n",
				ret);
			if (ret == -EL2NSYNC)
				dev_err(dev->class_dev,
					"buggy USB host controller or bug in IRQ handler\n");
			async->events |= COMEDI_CB_ERROR;
		}
	}
}
コード例 #4
0
ファイル: ni_labpc_isadma.c プロジェクト: AlexShiLucky/linux
void labpc_drain_dma(struct comedi_device *dev)
{
	struct labpc_private *devpriv = dev->private;
	struct comedi_isadma_desc *desc = &devpriv->dma->desc[0];
	struct comedi_subdevice *s = dev->read_subdev;
	struct comedi_async *async = s->async;
	struct comedi_cmd *cmd = &async->cmd;
	unsigned int max_samples = comedi_bytes_to_samples(s, desc->size);
	unsigned int residue;
	unsigned int nsamples;
	unsigned int leftover;

	/*
	 * residue is the number of bytes left to be done on the dma
	 * transfer.  It should always be zero at this point unless
	 * the stop_src is set to external triggering.
	 */
	residue = comedi_isadma_disable(desc->chan);

	/*
	 * Figure out how many samples to read for this transfer and
	 * how many will be stored for next time.
	 */
	nsamples = max_samples - comedi_bytes_to_samples(s, residue);
	if (cmd->stop_src == TRIG_COUNT) {
		if (devpriv->count <= nsamples) {
			nsamples = devpriv->count;
			leftover = 0;
		} else {
			leftover = devpriv->count - nsamples;
			if (leftover > max_samples)
				leftover = max_samples;
		}
		devpriv->count -= nsamples;
	} else {
		leftover = max_samples;
	}
	desc->size = comedi_samples_to_bytes(s, leftover);

	comedi_buf_write_samples(s, desc->virt_addr, nsamples);
}
コード例 #5
0
static void dio200_read_scan_intr(struct comedi_device *dev,
                                  struct comedi_subdevice *s,
                                  unsigned int triggered)
{
    struct comedi_cmd *cmd = &s->async->cmd;
    unsigned short val;
    unsigned int n, ch;

    val = 0;
    for (n = 0; n < cmd->chanlist_len; n++) {
        ch = CR_CHAN(cmd->chanlist[n]);
        if (triggered & (1U << ch))
            val |= (1U << n);
    }

    comedi_buf_write_samples(s, &val, 1);

    if (cmd->stop_src == TRIG_COUNT &&
            s->async->scans_done >= cmd->stop_arg)
        s->async->events |= COMEDI_CB_EOA;
}