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: H Hartley Sweeten <hsweeten@visionengravers.com> Reviewed-by: Ian Abbott <abbotti@mev.co.uk> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
committed by
Greg Kroah-Hartman
parent
169f35e82c
commit
e451dfeb4c
@@ -224,6 +224,153 @@ static int apci3120_ai_cmdtest(struct comedi_device *dev,
|
||||
return 0;
|
||||
}
|
||||
|
||||
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;
|
||||
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);
|
||||
|
||||
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))
|
||||
dmalen0 = cmd->stop_arg * scan_bytes;
|
||||
else if (dmalen1 > (cmd->stop_arg * scan_bytes - dmalen0))
|
||||
dmalen1 = cmd->stop_arg * scan_bytes - dmalen0;
|
||||
}
|
||||
|
||||
if (cmd->flags & CMDF_WAKE_EOS) {
|
||||
/* don't we want wake up every scan? */
|
||||
if (dmalen0 > scan_bytes) {
|
||||
dmalen0 = scan_bytes;
|
||||
if (cmd->scan_end_arg & 1)
|
||||
dmalen0 += 2;
|
||||
}
|
||||
if (dmalen1 > scan_bytes) {
|
||||
dmalen1 = scan_bytes;
|
||||
if (cmd->scan_end_arg & 1)
|
||||
dmalen1 -= 2;
|
||||
if (dmalen1 < 4)
|
||||
dmalen1 = 4;
|
||||
}
|
||||
} 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)
|
||||
dmalen1 = s->async->prealloc_bufsz;
|
||||
}
|
||||
dmabuf0->use_size = dmalen0;
|
||||
dmabuf1->use_size = dmalen1;
|
||||
|
||||
/* Initialize DMA */
|
||||
|
||||
/*
|
||||
* Set Transfer count enable bit and A2P_fifo reset bit in AGCSTS
|
||||
* register 1
|
||||
*/
|
||||
outl(AGCSTS_TC_ENABLE | AGCSTS_RESET_A2P_FIFO,
|
||||
devpriv->amcc + AMCC_OP_REG_AGCSTS);
|
||||
|
||||
/* changed since 16 bit interface for add on */
|
||||
/* ENABLE BUS MASTER */
|
||||
outw(APCI3120_ADD_ON_AGCSTS_LOW, devpriv->addon + 0);
|
||||
outw(APCI3120_ENABLE_TRANSFER_ADD_ON_LOW, devpriv->addon + 2);
|
||||
|
||||
outw(APCI3120_ADD_ON_AGCSTS_HIGH, devpriv->addon + 0);
|
||||
outw(APCI3120_ENABLE_TRANSFER_ADD_ON_HIGH, devpriv->addon + 2);
|
||||
|
||||
/*
|
||||
* TO VERIFIED BEGIN JK 07.05.04: Comparison between WIN32 and Linux
|
||||
* driver
|
||||
*/
|
||||
outw(0x1000, devpriv->addon + 2);
|
||||
/* END JK 07.05.04: Comparison between WIN32 and Linux driver */
|
||||
|
||||
/* 2 No change */
|
||||
/* A2P FIFO MANAGEMENT */
|
||||
/* A2P fifo reset & transfer control enable */
|
||||
outl(APCI3120_A2P_FIFO_MANAGEMENT,
|
||||
devpriv->amcc + APCI3120_AMCC_OP_MCSR);
|
||||
|
||||
/*
|
||||
* 3
|
||||
* beginning address of dma buf The 32 bit address of dma buffer
|
||||
* is converted into two 16 bit addresses Can done by using _attach
|
||||
* and put into into an array array used may be for differnet pages
|
||||
*/
|
||||
|
||||
/* DMA Start Address Low */
|
||||
outw(APCI3120_ADD_ON_MWAR_LOW, devpriv->addon + 0);
|
||||
outw(dmabuf0->hw & 0xffff, devpriv->addon + 2);
|
||||
|
||||
/* DMA Start Address High */
|
||||
outw(APCI3120_ADD_ON_MWAR_HIGH, devpriv->addon + 0);
|
||||
outw((dmabuf0->hw >> 16) & 0xffff, devpriv->addon + 2);
|
||||
|
||||
/*
|
||||
* 4
|
||||
* amount of bytes to be transferred set transfer count used ADDON
|
||||
* MWTC register commented testing
|
||||
*/
|
||||
|
||||
/* Nbr of acquisition LOW */
|
||||
outw(APCI3120_ADD_ON_MWTC_LOW, devpriv->addon + 0);
|
||||
outw(dmabuf0->use_size & 0xffff, devpriv->addon + 2);
|
||||
|
||||
/* Nbr of acquisition HIGH */
|
||||
outw(APCI3120_ADD_ON_MWTC_HIGH, devpriv->addon + 0);
|
||||
outw((dmabuf0->use_size >> 16) & 0xffff, devpriv->addon + 2);
|
||||
|
||||
/*
|
||||
* 5
|
||||
* To configure A2P FIFO testing outl(
|
||||
* FIFO_ADVANCE_ON_BYTE_2, devpriv->amcc + AMCC_OP_REG_INTCSR);
|
||||
*/
|
||||
|
||||
/* A2P FIFO RESET */
|
||||
/*
|
||||
* TO VERIFY BEGIN JK 07.05.04: Comparison between WIN32 and Linux
|
||||
* driver
|
||||
*/
|
||||
outl(0x04000000UL, devpriv->amcc + AMCC_OP_REG_MCSR);
|
||||
/* END JK 07.05.04: Comparison between WIN32 and Linux driver */
|
||||
|
||||
/*
|
||||
* 6
|
||||
* ENABLE A2P FIFO WRITE AND ENABLE AMWEN AMWEN_ENABLE |
|
||||
* A2P_FIFO_WRITE_ENABLE (0x01|0x02)=0x03
|
||||
*/
|
||||
|
||||
/*
|
||||
* 7
|
||||
* initialise end of dma interrupt AINT_WRITE_COMPL =
|
||||
* 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,
|
||||
devpriv->amcc + AMCC_OP_REG_INTCSR);
|
||||
|
||||
/* BEGIN JK 07.05.04: Comparison between WIN32 and Linux driver */
|
||||
/* ENABLE A2P FIFO WRITE AND ENABLE AMWEN */
|
||||
outw(3, devpriv->addon + 4);
|
||||
/* END JK 07.05.04: Comparison between WIN32 and Linux driver */
|
||||
|
||||
/* A2P FIFO RESET */
|
||||
/* BEGIN JK 07.05.04: Comparison between WIN32 and Linux driver */
|
||||
outl(0x04000000UL, devpriv->amcc + APCI3120_AMCC_OP_MCSR);
|
||||
/* END JK 07.05.04: Comparison between WIN32 and Linux driver */
|
||||
}
|
||||
|
||||
/*
|
||||
* This is used for analog input cyclic acquisition.
|
||||
* Performs the command operations.
|
||||
@@ -237,8 +384,6 @@ static int apci3120_cyclic_ai(int mode,
|
||||
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 */
|
||||
@@ -320,152 +465,8 @@ static int apci3120_cyclic_ai(int mode,
|
||||
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 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)) {
|
||||
dmalen0 = cmd->stop_arg * scan_bytes;
|
||||
} else if (dmalen1 > (cmd->stop_arg * scan_bytes -
|
||||
dmalen0))
|
||||
dmalen1 = cmd->stop_arg * scan_bytes -
|
||||
dmalen0;
|
||||
}
|
||||
|
||||
if (cmd->flags & CMDF_WAKE_EOS) {
|
||||
/* don't we want wake up every scan? */
|
||||
if (dmalen0 > scan_bytes) {
|
||||
dmalen0 = scan_bytes;
|
||||
if (cmd->scan_end_arg & 1)
|
||||
dmalen0 += 2;
|
||||
}
|
||||
if (dmalen1 > scan_bytes) {
|
||||
dmalen1 = scan_bytes;
|
||||
if (cmd->scan_end_arg & 1)
|
||||
dmalen1 -= 2;
|
||||
if (dmalen1 < 4)
|
||||
dmalen1 = 4;
|
||||
}
|
||||
} 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)
|
||||
dmalen1 = s->async->prealloc_bufsz;
|
||||
}
|
||||
dmabuf0->use_size = dmalen0;
|
||||
dmabuf1->use_size = dmalen1;
|
||||
|
||||
/* Initialize DMA */
|
||||
|
||||
/*
|
||||
* Set Transfer count enable bit and A2P_fifo reset bit in AGCSTS
|
||||
* register 1
|
||||
*/
|
||||
outl(AGCSTS_TC_ENABLE | AGCSTS_RESET_A2P_FIFO,
|
||||
devpriv->amcc + AMCC_OP_REG_AGCSTS);
|
||||
|
||||
/* changed since 16 bit interface for add on */
|
||||
/* ENABLE BUS MASTER */
|
||||
outw(APCI3120_ADD_ON_AGCSTS_LOW, devpriv->addon + 0);
|
||||
outw(APCI3120_ENABLE_TRANSFER_ADD_ON_LOW, devpriv->addon + 2);
|
||||
|
||||
outw(APCI3120_ADD_ON_AGCSTS_HIGH, devpriv->addon + 0);
|
||||
outw(APCI3120_ENABLE_TRANSFER_ADD_ON_HIGH, devpriv->addon + 2);
|
||||
|
||||
/*
|
||||
* TO VERIFIED BEGIN JK 07.05.04: Comparison between WIN32 and Linux
|
||||
* driver
|
||||
*/
|
||||
outw(0x1000, devpriv->addon + 2);
|
||||
/* END JK 07.05.04: Comparison between WIN32 and Linux driver */
|
||||
|
||||
/* 2 No change */
|
||||
/* A2P FIFO MANAGEMENT */
|
||||
/* A2P fifo reset & transfer control enable */
|
||||
outl(APCI3120_A2P_FIFO_MANAGEMENT,
|
||||
devpriv->amcc + APCI3120_AMCC_OP_MCSR);
|
||||
|
||||
/*
|
||||
* 3
|
||||
* beginning address of dma buf The 32 bit address of dma buffer
|
||||
* is converted into two 16 bit addresses Can done by using _attach
|
||||
* and put into into an array array used may be for differnet pages
|
||||
*/
|
||||
|
||||
/* DMA Start Address Low */
|
||||
outw(APCI3120_ADD_ON_MWAR_LOW, devpriv->addon + 0);
|
||||
outw(dmabuf0->hw & 0xffff, devpriv->addon + 2);
|
||||
|
||||
/* DMA Start Address High */
|
||||
outw(APCI3120_ADD_ON_MWAR_HIGH, devpriv->addon + 0);
|
||||
outw((dmabuf0->hw >> 16) & 0xffff, devpriv->addon + 2);
|
||||
|
||||
/*
|
||||
* 4
|
||||
* amount of bytes to be transferred set transfer count used ADDON
|
||||
* MWTC register commented testing
|
||||
*/
|
||||
|
||||
/* Nbr of acquisition LOW */
|
||||
outw(APCI3120_ADD_ON_MWTC_LOW, devpriv->addon + 0);
|
||||
outw(dmabuf0->use_size & 0xffff, devpriv->addon + 2);
|
||||
|
||||
/* Nbr of acquisition HIGH */
|
||||
outw(APCI3120_ADD_ON_MWTC_HIGH, devpriv->addon + 0);
|
||||
outw((dmabuf0->use_size >> 16) & 0xffff, devpriv->addon + 2);
|
||||
|
||||
/*
|
||||
* 5
|
||||
* To configure A2P FIFO testing outl(
|
||||
* FIFO_ADVANCE_ON_BYTE_2, devpriv->amcc + AMCC_OP_REG_INTCSR);
|
||||
*/
|
||||
|
||||
/* A2P FIFO RESET */
|
||||
/*
|
||||
* TO VERIFY BEGIN JK 07.05.04: Comparison between WIN32 and Linux
|
||||
* driver
|
||||
*/
|
||||
outl(0x04000000UL, devpriv->amcc + AMCC_OP_REG_MCSR);
|
||||
/* END JK 07.05.04: Comparison between WIN32 and Linux driver */
|
||||
|
||||
/*
|
||||
* 6
|
||||
* ENABLE A2P FIFO WRITE AND ENABLE AMWEN AMWEN_ENABLE |
|
||||
* A2P_FIFO_WRITE_ENABLE (0x01|0x02)=0x03
|
||||
*/
|
||||
|
||||
/*
|
||||
* 7
|
||||
* initialise end of dma interrupt AINT_WRITE_COMPL =
|
||||
* 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),
|
||||
devpriv->amcc + AMCC_OP_REG_INTCSR);
|
||||
|
||||
/* BEGIN JK 07.05.04: Comparison between WIN32 and Linux driver */
|
||||
/* ENABLE A2P FIFO WRITE AND ENABLE AMWEN */
|
||||
outw(3, devpriv->addon + 4);
|
||||
/* END JK 07.05.04: Comparison between WIN32 and Linux driver */
|
||||
|
||||
/* A2P FIFO RESET */
|
||||
/* BEGIN JK 07.05.04: Comparison between WIN32 and Linux driver */
|
||||
outl(0x04000000UL, devpriv->amcc + APCI3120_AMCC_OP_MCSR);
|
||||
/* END JK 07.05.04: Comparison between WIN32 and Linux driver */
|
||||
apci3120_setup_dma(dev, s);
|
||||
}
|
||||
|
||||
if (devpriv->us_UseDma == APCI3120_DISABLE &&
|
||||
|
||||
Reference in New Issue
Block a user