|
@@ -214,9 +214,12 @@ struct pcl816_private {
|
|
|
/*
|
|
|
==============================================================================
|
|
|
*/
|
|
|
-static int check_and_setup_channel_list(struct comedi_device *dev,
|
|
|
- struct comedi_subdevice *s,
|
|
|
- unsigned int *chanlist, int chanlen);
|
|
|
+static int check_channel_list(struct comedi_device *dev,
|
|
|
+ struct comedi_subdevice *s,
|
|
|
+ unsigned int *chanlist, unsigned int chanlen);
|
|
|
+static void setup_channel_list(struct comedi_device *dev,
|
|
|
+ struct comedi_subdevice *s,
|
|
|
+ unsigned int *chanlist, unsigned int seglen);
|
|
|
static int pcl816_ai_cancel(struct comedi_device *dev,
|
|
|
struct comedi_subdevice *s);
|
|
|
static void start_pacer(struct comedi_device *dev, int mode,
|
|
@@ -566,14 +569,6 @@ static int pcl816_ai_cmdtest(struct comedi_device *dev,
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- if (!cmd->chanlist_len) {
|
|
|
- cmd->chanlist_len = 1;
|
|
|
- err++;
|
|
|
- }
|
|
|
- if (cmd->chanlist_len > this_board->n_aichan) {
|
|
|
- cmd->chanlist_len = this_board->n_aichan;
|
|
|
- err++;
|
|
|
- }
|
|
|
if (cmd->scan_end_arg != cmd->chanlist_len) {
|
|
|
cmd->scan_end_arg = cmd->chanlist_len;
|
|
|
err++;
|
|
@@ -611,6 +606,14 @@ static int pcl816_ai_cmdtest(struct comedi_device *dev,
|
|
|
return 4;
|
|
|
}
|
|
|
|
|
|
+ /* step 5: complain about special chanlist considerations */
|
|
|
+
|
|
|
+ if (cmd->chanlist) {
|
|
|
+ if (!check_channel_list(dev, s, cmd->chanlist,
|
|
|
+ cmd->chanlist_len))
|
|
|
+ return 5; /* incorrect channels list */
|
|
|
+ }
|
|
|
+
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
@@ -618,6 +621,7 @@ static int pcl816_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
|
|
|
{
|
|
|
unsigned int divisor1 = 0, divisor2 = 0, dma_flags, bytes, dmairq;
|
|
|
struct comedi_cmd *cmd = &s->async->cmd;
|
|
|
+ unsigned int seglen;
|
|
|
|
|
|
if (cmd->start_src != TRIG_NOW)
|
|
|
return -EINVAL;
|
|
@@ -650,9 +654,10 @@ static int pcl816_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
|
|
|
|
|
|
start_pacer(dev, -1, 0, 0); /* stop pacer */
|
|
|
|
|
|
- if (!check_and_setup_channel_list(dev, s, cmd->chanlist,
|
|
|
- cmd->chanlist_len))
|
|
|
+ seglen = check_channel_list(dev, s, cmd->chanlist, cmd->chanlist_len);
|
|
|
+ if (seglen < 1)
|
|
|
return -EINVAL;
|
|
|
+ setup_channel_list(dev, s, cmd->chanlist, seglen);
|
|
|
udelay(1);
|
|
|
|
|
|
devpriv->ai_n_chan = cmd->chanlist_len;
|
|
@@ -880,12 +885,12 @@ start_pacer(struct comedi_device *dev, int mode, unsigned int divisor1,
|
|
|
/*
|
|
|
==============================================================================
|
|
|
Check if channel list from user is builded correctly
|
|
|
- If it's ok, then program scan/gain logic
|
|
|
+ If it's ok, then return non-zero length of repeated segment of channel list
|
|
|
*/
|
|
|
static int
|
|
|
-check_and_setup_channel_list(struct comedi_device *dev,
|
|
|
- struct comedi_subdevice *s, unsigned int *chanlist,
|
|
|
- int chanlen)
|
|
|
+check_channel_list(struct comedi_device *dev,
|
|
|
+ struct comedi_subdevice *s, unsigned int *chanlist,
|
|
|
+ unsigned int chanlen)
|
|
|
{
|
|
|
unsigned int chansegment[16];
|
|
|
unsigned int i, nowmustbechan, seglen, segpos;
|
|
@@ -939,6 +944,20 @@ check_and_setup_channel_list(struct comedi_device *dev,
|
|
|
seglen = 1;
|
|
|
}
|
|
|
|
|
|
+ return seglen; /* we can serve this with MUX logic */
|
|
|
+}
|
|
|
+
|
|
|
+/*
|
|
|
+==============================================================================
|
|
|
+ Program scan/gain logic with channel list.
|
|
|
+*/
|
|
|
+static void
|
|
|
+setup_channel_list(struct comedi_device *dev,
|
|
|
+ struct comedi_subdevice *s, unsigned int *chanlist,
|
|
|
+ unsigned int seglen)
|
|
|
+{
|
|
|
+ unsigned int i;
|
|
|
+
|
|
|
devpriv->ai_act_chanlist_len = seglen;
|
|
|
devpriv->ai_act_chanlist_pos = 0;
|
|
|
|
|
@@ -951,8 +970,6 @@ check_and_setup_channel_list(struct comedi_device *dev,
|
|
|
udelay(1);
|
|
|
|
|
|
outb(devpriv->ai_act_chanlist[0] | (devpriv->ai_act_chanlist[seglen - 1] << 4), dev->iobase + PCL816_MUX); /* select channel interval to scan */
|
|
|
-
|
|
|
- return 1; /* we can serve this with MUX logic */
|
|
|
}
|
|
|
|
|
|
#ifdef unused
|