Commit e451dfeb authored by H Hartley Sweeten's avatar H Hartley Sweeten Committed by Greg Kroah-Hartman
Browse files

staging: comedi: addi_apci_3120: factor DMA setup out of apci3120_cyclic_ai()



For aesthetics, factor the DMA setup code out of apci3120_cyclic_ai().

Signed-off-by: default avatarH Hartley Sweeten <hsweeten@visionengravers.com>
Reviewed-by: default avatarIan Abbott <abbotti@mev.co.uk>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 169f35e8
Loading
Loading
Loading
Loading
+148 −147
Original line number Diff line number Diff line
@@ -224,125 +224,28 @@ static int apci3120_ai_cmdtest(struct comedi_device *dev,
	return 0;
}

/*
 * This is used for analog input cyclic acquisition.
 * Performs the command operations.
 * If DMA is configured does DMA initialization otherwise does the
 * acquisition with EOS interrupt.
 */
static int apci3120_cyclic_ai(int mode,
			      struct comedi_device *dev,
static void apci3120_setup_dma(struct comedi_device *dev,
			       struct comedi_subdevice *s)
{
	struct apci3120_private *devpriv = dev->private;
	struct comedi_cmd *cmd = &s->async->cmd;
	unsigned int divisor1 = 0;
	unsigned int dmalen0 = 0;
	unsigned int dmalen1 = 0;
	unsigned int divisor0;

	/*  clear software  registers */
	devpriv->timer_mode = 0;
	devpriv->mode = 0;

	/* Clear Timer Write TC int */
	outl(APCI3120_CLEAR_WRITE_TC_INT,
	     devpriv->amcc + APCI3120_AMCC_OP_REG_INTCSR);

	apci3120_ai_reset_fifo(dev);

	devpriv->ui_DmaActualBuffer = 0;

	/* load chanlist for command scan */
	apci3120_set_chanlist(dev, s, cmd->chanlist_len, cmd->chanlist);

	divisor0 = apci3120_ns_to_timer(dev, 0, cmd->convert_arg, cmd->flags);
	if (mode == 2) {
		divisor1 = apci3120_ns_to_timer(dev, 1, cmd->scan_begin_arg,
						cmd->flags);
	}

	if (devpriv->b_ExttrigEnable == APCI3120_ENABLE)
		apci3120_exttrig_enable(dev, true);

	switch (mode) {
	case 1:
		/*  init timer0 in mode 2 */
		apci3120_timer_set_mode(dev, 0, APCI3120_TIMER_MODE2);

		/* Set the conversion time */
		apci3120_timer_write(dev, 0, divisor0);
		break;

	case 2:
		/*  init timer1 in mode 2 */
		apci3120_timer_set_mode(dev, 1, APCI3120_TIMER_MODE2);

		/* Set the scan begin time */
		apci3120_timer_write(dev, 1, divisor1);

		/*  init timer0 in mode 2 */
		apci3120_timer_set_mode(dev, 0, APCI3120_TIMER_MODE2);

		/* Set the conversion time */
		apci3120_timer_write(dev, 0, divisor0);
		break;

	}

	outb(devpriv->mode, dev->iobase + APCI3120_MODE_REG);

	/*  If DMA is disabled */
	if (devpriv->us_UseDma == APCI3120_DISABLE) {
		/*  disable EOC and enable EOS */
		devpriv->b_InterruptMode = APCI3120_EOS_MODE;

		devpriv->mode |= APCI3120_MODE_EOS_IRQ_ENA;
		outb(devpriv->mode, dev->iobase + APCI3120_MODE_REG);

		if (cmd->stop_src == TRIG_COUNT) {
			/* configure Timer2 For counting EOS */

			/* (1) Init timer 2 in mode 0 and write timer value */
			apci3120_timer_set_mode(dev, 2, APCI3120_TIMER_MODE0);

			/* Set the scan stop count (not sure about the -2) */
			apci3120_timer_write(dev, 2, cmd->stop_arg - 2);

			apci3120_clr_timer2_interrupt(dev);

			devpriv->mode |= APCI3120_MODE_TIMER2_AS_COUNTER |
					 APCI3120_MODE_TIMER2_CLK_EOS |
					 APCI3120_MODE_TIMER2_IRQ_ENA;
			outb(devpriv->mode, dev->iobase + APCI3120_MODE_REG);

			devpriv->b_Timer2Mode = APCI3120_COUNTER;
			devpriv->b_Timer2Interrupt = APCI3120_ENABLE;
		}
	} else {
		/* If DMA Enabled */
	struct apci3120_dmabuf *dmabuf0 = &devpriv->dmabuf[0];
	struct apci3120_dmabuf *dmabuf1 = &devpriv->dmabuf[1];
	unsigned int dmalen0 = dmabuf0->size;
	unsigned int dmalen1 = dmabuf1->size;
	unsigned int scan_bytes;

	scan_bytes = comedi_samples_to_bytes(s, cmd->scan_end_arg);

		devpriv->b_InterruptMode = APCI3120_DMA_MODE;

		dmalen0 = dmabuf0->size;
		dmalen1 = dmabuf1->size;

	if (cmd->stop_src == TRIG_COUNT) {
		/*
		 * Must we fill full first buffer? And must we fill
		 * full second buffer when first is once filled?
		 */
			if (dmalen0 > (cmd->stop_arg * scan_bytes)) {
		if (dmalen0 > (cmd->stop_arg * scan_bytes))
			dmalen0 = cmd->stop_arg * scan_bytes;
			} else if (dmalen1 > (cmd->stop_arg * scan_bytes -
					      dmalen0))
				dmalen1 = cmd->stop_arg * scan_bytes -
					  dmalen0;
		else if (dmalen1 > (cmd->stop_arg * scan_bytes - dmalen0))
			dmalen1 = cmd->stop_arg * scan_bytes - dmalen0;
	}

	if (cmd->flags & CMDF_WAKE_EOS) {
@@ -359,7 +262,8 @@ static int apci3120_cyclic_ai(int mode,
			if (dmalen1 < 4)
				dmalen1 = 4;
		}
		} else {	/*  isn't output buff smaller that our DMA buff? */
	} else {
		/* isn't output buff smaller that our DMA buff? */
		if (dmalen0 > s->async->prealloc_bufsz)
			dmalen0 = s->async->prealloc_bufsz;
		if (dmalen1 > s->async->prealloc_bufsz)
@@ -453,8 +357,7 @@ static int apci3120_cyclic_ai(int mode,
	 * ENABLE_WRITE_TC_INT(ADDI)
	 */
	/* A2P FIFO CONFIGURATE, END OF DMA intERRUPT INIT */
		outl((APCI3120_FIFO_ADVANCE_ON_BYTE_2 |
				APCI3120_ENABLE_WRITE_TC_INT),
	outl(APCI3120_FIFO_ADVANCE_ON_BYTE_2 | APCI3120_ENABLE_WRITE_TC_INT,
	     devpriv->amcc + AMCC_OP_REG_INTCSR);

	/* BEGIN JK 07.05.04: Comparison between WIN32 and Linux driver */
@@ -468,6 +371,104 @@ static int apci3120_cyclic_ai(int mode,
	/* END JK 07.05.04: Comparison between WIN32 and Linux driver */
}

/*
 * This is used for analog input cyclic acquisition.
 * Performs the command operations.
 * If DMA is configured does DMA initialization otherwise does the
 * acquisition with EOS interrupt.
 */
static int apci3120_cyclic_ai(int mode,
			      struct comedi_device *dev,
			      struct comedi_subdevice *s)
{
	struct apci3120_private *devpriv = dev->private;
	struct comedi_cmd *cmd = &s->async->cmd;
	unsigned int divisor1 = 0;
	unsigned int divisor0;

	/*  clear software  registers */
	devpriv->timer_mode = 0;
	devpriv->mode = 0;

	/* Clear Timer Write TC int */
	outl(APCI3120_CLEAR_WRITE_TC_INT,
	     devpriv->amcc + APCI3120_AMCC_OP_REG_INTCSR);

	apci3120_ai_reset_fifo(dev);

	devpriv->ui_DmaActualBuffer = 0;

	/* load chanlist for command scan */
	apci3120_set_chanlist(dev, s, cmd->chanlist_len, cmd->chanlist);

	divisor0 = apci3120_ns_to_timer(dev, 0, cmd->convert_arg, cmd->flags);
	if (mode == 2) {
		divisor1 = apci3120_ns_to_timer(dev, 1, cmd->scan_begin_arg,
						cmd->flags);
	}

	if (devpriv->b_ExttrigEnable == APCI3120_ENABLE)
		apci3120_exttrig_enable(dev, true);

	switch (mode) {
	case 1:
		/*  init timer0 in mode 2 */
		apci3120_timer_set_mode(dev, 0, APCI3120_TIMER_MODE2);

		/* Set the conversion time */
		apci3120_timer_write(dev, 0, divisor0);
		break;

	case 2:
		/*  init timer1 in mode 2 */
		apci3120_timer_set_mode(dev, 1, APCI3120_TIMER_MODE2);

		/* Set the scan begin time */
		apci3120_timer_write(dev, 1, divisor1);

		/*  init timer0 in mode 2 */
		apci3120_timer_set_mode(dev, 0, APCI3120_TIMER_MODE2);

		/* Set the conversion time */
		apci3120_timer_write(dev, 0, divisor0);
		break;

	}

	outb(devpriv->mode, dev->iobase + APCI3120_MODE_REG);

	/*  If DMA is disabled */
	if (devpriv->us_UseDma == APCI3120_DISABLE) {
		/*  disable EOC and enable EOS */
		devpriv->b_InterruptMode = APCI3120_EOS_MODE;

		devpriv->mode |= APCI3120_MODE_EOS_IRQ_ENA;
		outb(devpriv->mode, dev->iobase + APCI3120_MODE_REG);

		if (cmd->stop_src == TRIG_COUNT) {
			/* configure Timer2 For counting EOS */

			/* (1) Init timer 2 in mode 0 and write timer value */
			apci3120_timer_set_mode(dev, 2, APCI3120_TIMER_MODE0);

			/* Set the scan stop count (not sure about the -2) */
			apci3120_timer_write(dev, 2, cmd->stop_arg - 2);

			apci3120_clr_timer2_interrupt(dev);

			devpriv->mode |= APCI3120_MODE_TIMER2_AS_COUNTER |
					 APCI3120_MODE_TIMER2_CLK_EOS |
					 APCI3120_MODE_TIMER2_IRQ_ENA;
			outb(devpriv->mode, dev->iobase + APCI3120_MODE_REG);

			devpriv->b_Timer2Mode = APCI3120_COUNTER;
			devpriv->b_Timer2Interrupt = APCI3120_ENABLE;
		}
	} else {
		devpriv->b_InterruptMode = APCI3120_DMA_MODE;
		apci3120_setup_dma(dev, s);
	}

	if (devpriv->us_UseDma == APCI3120_DISABLE &&
	    cmd->stop_src == TRIG_COUNT)
		apci3120_timer_enable(dev, 2, true);