Commit b986be85 authored by H Hartley Sweeten's avatar H Hartley Sweeten Committed by Greg Kroah-Hartman

staging: comedi: usbduxsigma: tidy up analog input command support

Rename the (*do_cmdtest) and (*do_cmd) functions so they have namespace
associated with the driver. Rename the local variable used for the
private data pointer.

Move all the command argument initialization and testing into the
(*do_cmdtest) function. That function is always called by the comedi
core before the (*do_cmd) function. The only thing the (*do_cmd) function
should have to do is setup the channel list, send the command to start
the analog input sampling, initialize the counter for the conversion,
then either read the acquisition data (submit the urbs) or set the
trigger to read the data later.
Signed-off-by: default avatarH Hartley Sweeten <hsweeten@visionengravers.com>
Cc: Ian Abbott <abbotti@mev.co.uk>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent c5db3b75
......@@ -521,13 +521,14 @@ static int chanToInterval(int nChannels)
return 8;
}
static int usbdux_ai_cmdtest(struct comedi_device *dev,
struct comedi_subdevice *s,
struct comedi_cmd *cmd)
static int usbduxsigma_ai_cmdtest(struct comedi_device *dev,
struct comedi_subdevice *s,
struct comedi_cmd *cmd)
{
struct usbduxsigma_private *this_usbduxsub = dev->private;
int err = 0, i;
unsigned int tmpTimer;
struct usbduxsigma_private *devpriv = dev->private;
int high_speed = devpriv->high_speed;
int interval = chanToInterval(cmd->chanlist_len);
int err = 0;
/* Step 1 : check if triggers are trivially valid */
......@@ -558,34 +559,28 @@ static int usbdux_ai_cmdtest(struct comedi_device *dev,
err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, 0);
if (cmd->scan_begin_src == TRIG_TIMER) {
if (this_usbduxsub->high_speed) {
unsigned int tmp;
if (high_speed) {
/*
* In high speed mode microframes are possible.
* However, during one microframe we can roughly
* sample two channels. Thus, the more channels
* are in the channel list the more time we need.
*/
i = chanToInterval(cmd->chanlist_len);
err |= cfc_check_trigger_arg_min(&cmd->scan_begin_arg,
(1000000 / 8 * i));
/* now calc the real sampling rate with all the
* rounding errors */
tmpTimer =
((unsigned int)(cmd->scan_begin_arg / 125000)) *
125000;
(1000000 / 8 * interval));
tmp = (cmd->scan_begin_arg / 125000) * 125000;
} else {
/* full speed */
/* 1kHz scans every USB frame */
err |= cfc_check_trigger_arg_min(&cmd->scan_begin_arg,
1000000);
/*
* calc the real sampling rate with the rounding errors
*/
tmpTimer = ((unsigned int)(cmd->scan_begin_arg /
1000000)) * 1000000;
tmp = (cmd->scan_begin_arg / 1000000) * 1000000;
}
err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg,
tmpTimer);
err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, tmp);
}
err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len);
......@@ -600,6 +595,37 @@ static int usbdux_ai_cmdtest(struct comedi_device *dev,
if (err)
return 3;
/* Step 4: fix up any arguments */
if (high_speed) {
/*
* every 2 channels get a time window of 125us. Thus, if we
* sample all 16 channels we need 1ms. If we sample only one
* channel we need only 125us
*/
devpriv->ai_interval = interval;
devpriv->ai_timer = cmd->scan_begin_arg / (125000 * interval);
} else {
/* interval always 1ms */
devpriv->ai_interval = 1;
devpriv->ai_timer = cmd->scan_begin_arg / 1000000;
}
if (devpriv->ai_timer < 1)
err |= -EINVAL;
if (cmd->stop_src == TRIG_COUNT) {
/* data arrives as one packet */
devpriv->ai_sample_count = cmd->stop_arg;
devpriv->ai_continuous = 0;
} else {
/* continuous acquisition */
devpriv->ai_continuous = 1;
devpriv->ai_sample_count = 0;
}
if (err)
return 4;
return 0;
}
......@@ -692,102 +718,61 @@ static int usbduxsigma_ai_inttrig(struct comedi_device *dev,
return 1;
}
static int usbdux_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
static int usbduxsigma_ai_cmd(struct comedi_device *dev,
struct comedi_subdevice *s)
{
struct usbduxsigma_private *this_usbduxsub = dev->private;
struct usbduxsigma_private *devpriv = dev->private;
struct comedi_cmd *cmd = &s->async->cmd;
unsigned int chan;
int i, ret;
int result;
unsigned int len = cmd->chanlist_len;
uint8_t muxsg0 = 0;
uint8_t muxsg1 = 0;
uint8_t sysred = 0;
int ret;
int i;
down(&devpriv->sem);
/* block other CPUs from starting an ai_cmd */
down(&this_usbduxsub->sem);
if (this_usbduxsub->ai_cmd_running) {
up(&this_usbduxsub->sem);
return -EBUSY;
}
/* set current channel of the running acquisition to zero */
s->async->cur_chan = 0;
for (i = 0; i < len; i++) {
unsigned int chan = CR_CHAN(cmd->chanlist[i]);
/* first the number of channels per time step */
this_usbduxsub->dux_commands[1] = cmd->chanlist_len;
/* CONFIG0 */
this_usbduxsub->dux_commands[2] = 0x12;
/* CONFIG1: 23kHz sampling rate, delay = 0us, */
this_usbduxsub->dux_commands[3] = 0x03;
/* CONFIG3: differential channels off */
this_usbduxsub->dux_commands[4] = 0x00;
for (i = 0; i < cmd->chanlist_len; i++) {
chan = CR_CHAN(cmd->chanlist[i]);
create_adc_command(chan, &muxsg0, &muxsg1);
}
this_usbduxsub->dux_commands[5] = muxsg0;
this_usbduxsub->dux_commands[6] = muxsg1;
this_usbduxsub->dux_commands[7] = sysred;
result = send_dux_commands(dev, SENDADCOMMANDS);
if (result < 0) {
up(&this_usbduxsub->sem);
return result;
}
if (this_usbduxsub->high_speed) {
/*
* every 2 channels get a time window of 125us. Thus, if we
* sample all 16 channels we need 1ms. If we sample only one
* channel we need only 125us
*/
this_usbduxsub->ai_interval =
chanToInterval(cmd->chanlist_len);
this_usbduxsub->ai_timer = cmd->scan_begin_arg / (125000 *
(this_usbduxsub->
ai_interval));
} else {
/* interval always 1ms */
this_usbduxsub->ai_interval = 1;
this_usbduxsub->ai_timer = cmd->scan_begin_arg / 1000000;
}
if (this_usbduxsub->ai_timer < 1) {
up(&this_usbduxsub->sem);
return -EINVAL;
}
this_usbduxsub->ai_counter = this_usbduxsub->ai_timer;
devpriv->dux_commands[1] = len; /* num channels per time step */
devpriv->dux_commands[2] = 0x12; /* CONFIG0 */
devpriv->dux_commands[3] = 0x03; /* CONFIG1: 23kHz sample, delay 0us */
devpriv->dux_commands[4] = 0x00; /* CONFIG3: diff. channels off */
devpriv->dux_commands[5] = muxsg0;
devpriv->dux_commands[6] = muxsg1;
devpriv->dux_commands[7] = sysred;
if (cmd->stop_src == TRIG_COUNT) {
/* data arrives as one packet */
this_usbduxsub->ai_sample_count = cmd->stop_arg;
this_usbduxsub->ai_continuous = 0;
} else {
/* continuous acquisition */
this_usbduxsub->ai_continuous = 1;
this_usbduxsub->ai_sample_count = 0;
ret = send_dux_commands(dev, SENDADCOMMANDS);
if (ret < 0) {
up(&devpriv->sem);
return ret;
}
devpriv->ai_counter = devpriv->ai_timer;
if (cmd->start_src == TRIG_NOW) {
/* enable this acquisition operation */
ret = usbduxsigma_submit_urbs(dev, this_usbduxsub->urbIn,
this_usbduxsub->numOfInBuffers,
1);
ret = usbduxsigma_submit_urbs(dev, devpriv->urbIn,
devpriv->numOfInBuffers, 1);
if (ret < 0) {
up(&this_usbduxsub->sem);
up(&devpriv->sem);
return ret;
}
this_usbduxsub->ai_cmd_running = 1;
s->async->inttrig = NULL;
} else {
/* TRIG_INT */
/* don't enable the acquision operation */
/* wait for an internal signal */
devpriv->ai_cmd_running = 1;
} else { /* TRIG_INT */
/* wait for an internal signal and submit the urbs later */
s->async->inttrig = usbduxsigma_ai_inttrig;
}
up(&this_usbduxsub->sem);
up(&devpriv->sem);
return 0;
}
......@@ -1448,8 +1433,8 @@ static int usbduxsigma_attach_common(struct comedi_device *dev)
s->maxdata = 0x00ffffff;
s->range_table = &range_usbdux_ai_range;
s->insn_read = usbduxsigma_ai_insn_read;
s->do_cmdtest = usbdux_ai_cmdtest;
s->do_cmd = usbdux_ai_cmd;
s->do_cmdtest = usbduxsigma_ai_cmdtest;
s->do_cmd = usbduxsigma_ai_cmd;
s->cancel = usbdux_ai_cancel;
/* Analog Output subdevice */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment