diff options
Diffstat (limited to 'drivers/staging/comedi/drivers/comedi_test.c')
-rw-r--r-- | drivers/staging/comedi/drivers/comedi_test.c | 75 |
1 files changed, 37 insertions, 38 deletions
diff --git a/drivers/staging/comedi/drivers/comedi_test.c b/drivers/staging/comedi/drivers/comedi_test.c index 01de996239f1..270fea5c6b51 100644 --- a/drivers/staging/comedi/drivers/comedi_test.c +++ b/drivers/staging/comedi/drivers/comedi_test.c @@ -62,15 +62,14 @@ zero volts). /* Data unique to this driver */ struct waveform_private { struct timer_list timer; - struct timeval last; /* time at which last timer interrupt occurred */ + struct timeval last; /* time last timer interrupt occurred */ unsigned int uvolt_amplitude; /* waveform amplitude in microvolts */ unsigned long usec_period; /* waveform period in microseconds */ - unsigned long usec_current; /* current time (modulo waveform period) */ - unsigned long usec_remainder; /* usec since last scan; */ - unsigned long ai_count; /* number of conversions remaining */ + unsigned long usec_current; /* current time (mod waveform period) */ + unsigned long usec_remainder; /* usec since last scan */ + unsigned long ai_count; /* number of conversions remaining */ unsigned int scan_period; /* scan period in usec */ unsigned int convert_period; /* conversion period in usec */ - unsigned timer_running:1; unsigned int ao_loopbacks[N_CHANS]; }; @@ -86,8 +85,9 @@ static const struct comedi_lrange waveform_ai_ranges = { } }; -static short fake_sawtooth(struct comedi_device *dev, unsigned int range_index, - unsigned long current_time) +static unsigned short fake_sawtooth(struct comedi_device *dev, + unsigned int range_index, + unsigned long current_time) { struct waveform_private *devpriv = dev->private; struct comedi_subdevice *s = dev->read_subdev; @@ -110,9 +110,9 @@ static short fake_sawtooth(struct comedi_device *dev, unsigned int range_index, return offset + value; } -static short fake_squarewave(struct comedi_device *dev, - unsigned int range_index, - unsigned long current_time) +static unsigned short fake_squarewave(struct comedi_device *dev, + unsigned int range_index, + unsigned long current_time) { struct waveform_private *devpriv = dev->private; struct comedi_subdevice *s = dev->read_subdev; @@ -132,15 +132,17 @@ static short fake_squarewave(struct comedi_device *dev, return offset + value; } -static short fake_flatline(struct comedi_device *dev, unsigned int range_index, - unsigned long current_time) +static unsigned short fake_flatline(struct comedi_device *dev, + unsigned int range_index, + unsigned long current_time) { return dev->read_subdev->maxdata / 2; } /* generates a different waveform depending on what channel is read */ -static short fake_waveform(struct comedi_device *dev, unsigned int channel, - unsigned int range, unsigned long current_time) +static unsigned short fake_waveform(struct comedi_device *dev, + unsigned int channel, unsigned int range, + unsigned long current_time) { enum { SAWTOOTH_CHAN, @@ -176,6 +178,7 @@ static void waveform_ai_interrupt(unsigned long arg) unsigned long elapsed_time; unsigned int num_scans; struct timeval now; + bool stopping = false; do_gettimeofday(&now); @@ -189,37 +192,35 @@ static void waveform_ai_interrupt(unsigned long arg) (devpriv->usec_remainder + elapsed_time) % devpriv->scan_period; async->events = 0; + if (cmd->stop_src == TRIG_COUNT) { + unsigned int remaining = cmd->stop_arg - devpriv->ai_count; + if (num_scans >= remaining) { + /* about to finish */ + num_scans = remaining; + stopping = true; + } + } + for (i = 0; i < num_scans; i++) { for (j = 0; j < cmd->chanlist_len; j++) { - cfc_write_to_buffer(dev->read_subdev, - fake_waveform(dev, - CR_CHAN(cmd-> - chanlist[j]), - CR_RANGE(cmd-> - chanlist[j]), - devpriv-> - usec_current + - i * - devpriv->scan_period + - j * - devpriv-> - convert_period)); - } - devpriv->ai_count++; - if (cmd->stop_src == TRIG_COUNT - && devpriv->ai_count >= cmd->stop_arg) { - async->events |= COMEDI_CB_EOA; - break; + unsigned short sample; + sample = fake_waveform(dev, CR_CHAN(cmd->chanlist[j]), + CR_RANGE(cmd->chanlist[j]), + devpriv->usec_current + + i * devpriv->scan_period + + j * devpriv->convert_period); + cfc_write_to_buffer(dev->read_subdev, sample); } } + devpriv->ai_count += i; devpriv->usec_current += elapsed_time; devpriv->usec_current %= devpriv->usec_period; - if ((async->events & COMEDI_CB_EOA) == 0 && devpriv->timer_running) - mod_timer(&devpriv->timer, jiffies + 1); + if (stopping) + async->events |= COMEDI_CB_EOA; else - del_timer(&devpriv->timer); + mod_timer(&devpriv->timer, jiffies + 1); comedi_event(dev, dev->read_subdev); } @@ -317,7 +318,6 @@ static int waveform_ai_cmd(struct comedi_device *dev, return -1; } - devpriv->timer_running = 1; devpriv->ai_count = 0; devpriv->scan_period = cmd->scan_begin_arg / nano_per_micro; @@ -344,7 +344,6 @@ static int waveform_ai_cancel(struct comedi_device *dev, { struct waveform_private *devpriv = dev->private; - devpriv->timer_running = 0; del_timer_sync(&devpriv->timer); return 0; } |