diff options
Diffstat (limited to 'drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c')
-rw-r--r-- | drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c | 169 |
1 files changed, 57 insertions, 112 deletions
diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c index 70e8f426285c..764c8f17f8fa 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c @@ -609,11 +609,10 @@ static int apci3120_reset(struct comedi_device *dev) unsigned int i; unsigned short us_TmpValue; - devpriv->b_AiCyclicAcquisition = APCI3120_DISABLE; + devpriv->ai_running = 0; devpriv->b_EocEosInterrupt = APCI3120_DISABLE; devpriv->b_InterruptMode = APCI3120_EOC_MODE; devpriv->ui_EocEosConversionTime = 0; /* set eoc eos conv time to 0 */ - devpriv->b_OutputMemoryStatus = 0; /* variables used in timer subdevice */ devpriv->b_Timer2Mode = 0; @@ -720,10 +719,9 @@ static int apci3120_cancel(struct comedi_device *dev, inw(dev->iobase + APCI3120_RD_STATUS); devpriv->ui_AiActualScan = 0; s->async->cur_chan = 0; - devpriv->b_AiContinuous = 0; devpriv->ui_DmaActualBuffer = 0; - devpriv->b_AiCyclicAcquisition = APCI3120_DISABLE; + devpriv->ai_running = 0; devpriv->b_InterruptMode = APCI3120_EOC_MODE; devpriv->b_EocEosInterrupt = APCI3120_DISABLE; apci3120_reset(dev); @@ -734,7 +732,6 @@ static int apci3120_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_cmd *cmd) { - const struct addi_board *this_board = comedi_board(dev); int err = 0; /* Step 1 : check if triggers are trivially valid */ @@ -767,20 +764,16 @@ static int apci3120_ai_cmdtest(struct comedi_device *dev, if (cmd->scan_begin_src == TRIG_TIMER) /* Test Delay timing */ err |= cfc_check_trigger_arg_min(&cmd->scan_begin_arg, 100000); - if (cmd->convert_src == TRIG_TIMER) { /* Test Acquisition timing */ - if (cmd->scan_begin_src == TRIG_TIMER) { - if (cmd->convert_arg) - err |= cfc_check_trigger_arg_min( - &cmd->convert_arg, 10000); - } else { + if (cmd->scan_begin_src == TRIG_TIMER) { + if (cmd->convert_arg) err |= cfc_check_trigger_arg_min(&cmd->convert_arg, - 10000); - } + 10000); + } else { + err |= cfc_check_trigger_arg_min(&cmd->convert_arg, 10000); } err |= cfc_check_trigger_arg_min(&cmd->chanlist_len, 1); - err |= cfc_check_trigger_arg_max(&cmd->chanlist_len, - this_board->i_AiChannelList); + err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len); if (cmd->stop_src == TRIG_COUNT) err |= cfc_check_trigger_arg_min(&cmd->stop_arg, 1); @@ -792,15 +785,10 @@ static int apci3120_ai_cmdtest(struct comedi_device *dev, /* step 4: fix up any arguments */ - if (cmd->convert_src == TRIG_TIMER) { - - if (cmd->scan_begin_src == TRIG_TIMER && - cmd->scan_begin_arg < - cmd->convert_arg * cmd->scan_end_arg) { - cmd->scan_begin_arg = - cmd->convert_arg * cmd->scan_end_arg; - err++; - } + if (cmd->scan_begin_src == TRIG_TIMER && + cmd->scan_begin_arg < cmd->convert_arg * cmd->scan_end_arg) { + cmd->scan_begin_arg = cmd->convert_arg * cmd->scan_end_arg; + err |= -EINVAL; } if (err) @@ -821,16 +809,13 @@ static int apci3120_cyclic_ai(int mode, { const struct addi_board *this_board = comedi_board(dev); struct addi_private *devpriv = dev->private; + struct comedi_cmd *cmd = &s->async->cmd; unsigned char b_Tmp; unsigned int ui_Tmp, ui_DelayTiming = 0, ui_TimerValue1 = 0, dmalen0 = 0, dmalen1 = 0, ui_TimerValue2 = 0, ui_TimerValue0, ui_ConvertTiming; unsigned short us_TmpValue; - /* BEGIN JK 07.05.04: Comparison between WIN32 and Linux driver */ - /* devpriv->b_AiCyclicAcquisition=APCI3120_ENABLE; */ - /* END JK 07.05.04: Comparison between WIN32 and Linux driver */ - /*******************/ /* Resets the FIFO */ /*******************/ @@ -840,12 +825,7 @@ static int apci3120_cyclic_ai(int mode, /* inw(dev->iobase+APCI3120_RD_STATUS); */ /* END JK 07.05.04: Comparison between WIN32 and Linux driver */ - /***************************/ - /* Acquisition initialized */ - /***************************/ - /* BEGIN JK 07.05.04: Comparison between WIN32 and Linux driver */ - devpriv->b_AiCyclicAcquisition = APCI3120_ENABLE; - /* END JK 07.05.04: Comparison between WIN32 and Linux driver */ + devpriv->ai_running = 1; /* clear software registers */ devpriv->b_TimerSelectMode = 0; @@ -892,17 +872,17 @@ static int apci3120_cyclic_ai(int mode, devpriv->ui_DmaActualBuffer = 0; /* value for timer2 minus -2 has to be done .....dunno y?? */ - ui_TimerValue2 = devpriv->ui_AiNbrofScans - 2; - ui_ConvertTiming = devpriv->ui_AiTimer0; + ui_TimerValue2 = cmd->stop_arg - 2; + ui_ConvertTiming = cmd->convert_arg; if (mode == 2) - ui_DelayTiming = devpriv->ui_AiTimer1; + ui_DelayTiming = cmd->scan_begin_arg; /**********************************/ /* Initializes the sequence array */ /**********************************/ if (!apci3120_setup_chan_list(dev, s, devpriv->ui_AiNbrofChannels, - devpriv->pui_AiChannelList, 0)) + cmd->chanlist, 0)) return -EINVAL; us_TmpValue = (unsigned short) inw(dev->iobase + APCI3120_RD_STATUS); @@ -1039,7 +1019,7 @@ static int apci3120_cyclic_ai(int mode, outb(devpriv->b_ModeSelectRegister, dev->iobase + APCI3120_WRITE_MODE_SELECT); - if (!devpriv->b_AiContinuous) { + if (cmd->stop_src == TRIG_COUNT) { /* * configure Timer2 For counting EOS Reset gate 2 of Timer 2 to * disable it (Set Bit D14 to 0) @@ -1107,6 +1087,7 @@ static int apci3120_cyclic_ai(int mode, } } else { /* If DMA Enabled */ + unsigned int scan_bytes = cmd->scan_end_arg * sizeof(short); /* BEGIN JK 07.05.04: Comparison between WIN32 and Linux driver */ /* inw(dev->iobase+0); reset EOC bit */ @@ -1125,37 +1106,38 @@ static int apci3120_cyclic_ai(int mode, dmalen0 = devpriv->ui_DmaBufferSize[0]; dmalen1 = devpriv->ui_DmaBufferSize[1]; - if (!devpriv->b_AiContinuous) { - - if (dmalen0 > (devpriv->ui_AiNbrofScans * devpriv->ui_AiScanLength * 2)) { /* must we fill full first buffer? */ - dmalen0 = - devpriv->ui_AiNbrofScans * - devpriv->ui_AiScanLength * 2; - } else if (dmalen1 > (devpriv->ui_AiNbrofScans * devpriv->ui_AiScanLength * 2 - dmalen0)) /* and must we fill full second buffer when first is once filled? */ - dmalen1 = - devpriv->ui_AiNbrofScans * - devpriv->ui_AiScanLength * 2 - dmalen0; + 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 (devpriv->ui_AiFlags & TRIG_WAKE_EOS) { + if (cmd->flags & TRIG_WAKE_EOS) { /* don't we want wake up every scan? */ - if (dmalen0 > (devpriv->ui_AiScanLength * 2)) { - dmalen0 = devpriv->ui_AiScanLength * 2; - if (devpriv->ui_AiScanLength & 1) + if (dmalen0 > scan_bytes) { + dmalen0 = scan_bytes; + if (cmd->scan_end_arg & 1) dmalen0 += 2; } - if (dmalen1 > (devpriv->ui_AiScanLength * 2)) { - dmalen1 = devpriv->ui_AiScanLength * 2; - if (devpriv->ui_AiScanLength & 1) + 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 > (devpriv->ui_AiDataLength)) - dmalen0 = devpriv->ui_AiDataLength; - if (dmalen1 > (devpriv->ui_AiDataLength)) - dmalen1 = devpriv->ui_AiDataLength; + if (dmalen0 > s->async->prealloc_bufsz) + dmalen0 = s->async->prealloc_bufsz; + if (dmalen1 > s->async->prealloc_bufsz) + dmalen1 = s->async->prealloc_bufsz; } devpriv->ui_DmaBufferUsesize[0] = dmalen0; devpriv->ui_DmaBufferUsesize[1] = dmalen1; @@ -1293,8 +1275,8 @@ static int apci3120_cyclic_ai(int mode, /* END JK 07.05.04: Comparison between WIN32 and Linux driver */ } - if ((devpriv->us_UseDma == APCI3120_DISABLE) - && !devpriv->b_AiContinuous) { + if (devpriv->us_UseDma == APCI3120_DISABLE && + cmd->stop_src == TRIG_COUNT) { /* set gate 2 to start conversion */ devpriv->us_OutputRegister = devpriv->us_OutputRegister | APCI3120_ENABLE_TIMER2; @@ -1337,50 +1319,17 @@ static int apci3120_ai_cmd(struct comedi_device *dev, struct comedi_cmd *cmd = &s->async->cmd; /* loading private structure with cmd structure inputs */ - devpriv->ui_AiFlags = cmd->flags; devpriv->ui_AiNbrofChannels = cmd->chanlist_len; - devpriv->ui_AiScanLength = cmd->scan_end_arg; - devpriv->pui_AiChannelList = cmd->chanlist; - - /* UPDATE-0.7.57->0.7.68devpriv->ui_AiDataLength=s->async->data_len; */ - devpriv->ui_AiDataLength = s->async->prealloc_bufsz; - - if (cmd->stop_src == TRIG_COUNT) - devpriv->ui_AiNbrofScans = cmd->stop_arg; - else - devpriv->ui_AiNbrofScans = 0; - - devpriv->ui_AiTimer0 = 0; /* variables changed to timer0,timer1 */ - devpriv->ui_AiTimer1 = 0; - if ((devpriv->ui_AiNbrofScans == 0) || (devpriv->ui_AiNbrofScans == -1)) - devpriv->b_AiContinuous = 1; /* user want neverending analog acquisition */ - /* stopped using cancel */ if (cmd->start_src == TRIG_EXT) devpriv->b_ExttrigEnable = APCI3120_ENABLE; else devpriv->b_ExttrigEnable = APCI3120_DISABLE; - if (cmd->scan_begin_src == TRIG_FOLLOW) { - /* mode 1 or 3 */ - if (cmd->convert_src == TRIG_TIMER) { - /* mode 1 */ - - devpriv->ui_AiTimer0 = cmd->convert_arg; /* timer constant in nano seconds */ - /* return this_board->ai_cmd(1,dev,s); */ - return apci3120_cyclic_ai(1, dev, s); - } - - } - if ((cmd->scan_begin_src == TRIG_TIMER) - && (cmd->convert_src == TRIG_TIMER)) { - /* mode 2 */ - devpriv->ui_AiTimer1 = cmd->scan_begin_arg; - devpriv->ui_AiTimer0 = cmd->convert_arg; /* variable changed timer2 to timer0 */ - /* return this_board->ai_cmd(2,dev,s); */ + if (cmd->scan_begin_src == TRIG_FOLLOW) + return apci3120_cyclic_ai(1, dev, s); + else /* TRIG_TIMER */ return apci3120_cyclic_ai(2, dev, s); - } - return -1; } /* @@ -1392,11 +1341,12 @@ static void v_APCI3120_InterruptDmaMoveBlock16bit(struct comedi_device *dev, unsigned int num_samples) { struct addi_private *devpriv = dev->private; + struct comedi_cmd *cmd = &s->async->cmd; devpriv->ui_AiActualScan += - (s->async->cur_chan + num_samples) / devpriv->ui_AiScanLength; + (s->async->cur_chan + num_samples) / cmd->scan_end_arg; s->async->cur_chan += num_samples; - s->async->cur_chan %= devpriv->ui_AiScanLength; + s->async->cur_chan %= cmd->scan_end_arg; cfc_write_array_to_buffer(s, dma_buffer, num_samples * sizeof(short)); } @@ -1412,6 +1362,7 @@ static void apci3120_interrupt_dma(int irq, void *d) struct comedi_device *dev = d; struct addi_private *devpriv = dev->private; struct comedi_subdevice *s = dev->read_subdev; + struct comedi_cmd *cmd = &s->async->cmd; unsigned int next_dma_buf, samplesinbuf; unsigned long low_word, high_word, var; unsigned int ui_Tmp; @@ -1427,8 +1378,6 @@ static void apci3120_interrupt_dma(int irq, void *d) if (samplesinbuf & 1) { comedi_error(dev, "Odd count of bytes in DMA ring!"); apci3120_cancel(dev, s); - devpriv->b_AiCyclicAcquisition = APCI3120_DISABLE; - return; } samplesinbuf = samplesinbuf >> 1; /* number of received samples */ @@ -1489,16 +1438,15 @@ static void apci3120_interrupt_dma(int irq, void *d) devpriv->ul_DmaBufferVirtual[devpriv-> ui_DmaActualBuffer], samplesinbuf); - if (!(devpriv->ui_AiFlags & TRIG_WAKE_EOS)) { + if (!(cmd->flags & TRIG_WAKE_EOS)) { s->async->events |= COMEDI_CB_EOS; comedi_event(dev, s); } } - if (!devpriv->b_AiContinuous) - if (devpriv->ui_AiActualScan >= devpriv->ui_AiNbrofScans) { + if (cmd->stop_src == TRIG_COUNT) + if (devpriv->ui_AiActualScan >= cmd->stop_arg) { /* all data sampled */ apci3120_cancel(dev, s); - devpriv->b_AiCyclicAcquisition = APCI3120_DISABLE; s->async->events |= COMEDI_CB_EOA; comedi_event(dev, s); return; @@ -1572,7 +1520,7 @@ static int apci3120_interrupt_handle_eos(struct comedi_device *dev) n_chan = devpriv->ui_AiNbrofChannels; for (i = 0; i < n_chan; i++) - err &= comedi_buf_put(s->async, inw(dev->iobase + 0)); + err &= comedi_buf_put(s, inw(dev->iobase + 0)); s->async->events |= COMEDI_CB_EOS; @@ -1648,7 +1596,7 @@ static void apci3120_interrupt(int irq, void *d) if (devpriv->b_EocEosInterrupt == APCI3120_ENABLE) { /* enable this in without DMA ??? */ - if (devpriv->b_AiCyclicAcquisition == APCI3120_ENABLE) { + if (devpriv->ai_running) { ui_Check = 0; apci3120_interrupt_handle_eos(dev); devpriv->ui_AiActualScan++; @@ -1690,8 +1638,6 @@ static void apci3120_interrupt(int irq, void *d) switch (devpriv->b_Timer2Mode) { case APCI3120_COUNTER: - - devpriv->b_AiCyclicAcquisition = APCI3120_DISABLE; devpriv->b_ModeSelectRegister = devpriv-> b_ModeSelectRegister & APCI3120_DISABLE_EOS_INT; @@ -1707,7 +1653,6 @@ static void apci3120_interrupt(int irq, void *d) /* stop timer 0 and timer 1 */ apci3120_cancel(dev, s); - devpriv->b_AiCyclicAcquisition = APCI3120_DISABLE; /* UPDATE-0.7.57->0.7.68comedi_done(dev,s); */ s->async->events |= COMEDI_CB_EOA; @@ -1746,7 +1691,7 @@ static void apci3120_interrupt(int irq, void *d) } if ((int_daq & 0x4) && (devpriv->b_InterruptMode == APCI3120_DMA_MODE)) { - if (devpriv->b_AiCyclicAcquisition == APCI3120_ENABLE) { + if (devpriv->ai_running) { /****************************/ /* Clear Timer Write TC int */ |