From 532a411e8b54418c2aed9e20f02b359002bb7e44 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 25 Feb 2015 16:28:38 -0700 Subject: [PATCH] staging: comedi: cb_pcimdas: fix analog input channel configuration The hardware uses a switch on the board to set the number of analog input channels to either 16 single-ended or 8 differential channels. Currently the switch setting is checked for every (*insn_read) operation to validate the channel number. Check the switch setting during the driver attach and initialize the subdevice accordingly. This allows the core to handle the validation. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/cb_pcimdas.c | 34 +++++++++++++-------- 1 file changed, 22 insertions(+), 12 deletions(-) diff --git a/drivers/staging/comedi/drivers/cb_pcimdas.c b/drivers/staging/comedi/drivers/cb_pcimdas.c index 70dd2c9eecdb..ddaa61c1cc31 100644 --- a/drivers/staging/comedi/drivers/cb_pcimdas.c +++ b/drivers/staging/comedi/drivers/cb_pcimdas.c @@ -109,20 +109,10 @@ static int cb_pcimdas_ai_rinsn(struct comedi_device *dev, unsigned int d; int chan = CR_CHAN(insn->chanspec); unsigned short chanlims; - int maxchans; int ret; /* only support sw initiated reads from a single channel */ - /* check channel number */ - if ((inb(devpriv->BADR3 + 2) & 0x20) == 0) /* differential mode */ - maxchans = s->n_chan / 2; - else - maxchans = s->n_chan; - - if (chan > (maxchans - 1)) - return -ETIMEDOUT; /* *** Wrong error code. Fixme. */ - /* configure for sw initiated read */ d = inb(devpriv->BADR3 + 5); if ((d & 0x03) > 0) { /* only reset if needed. */ @@ -181,6 +171,20 @@ static int cb_pcimdas_ao_insn_write(struct comedi_device *dev, return insn->n; } +static bool cb_pcimdas_is_ai_se(struct comedi_device *dev) +{ + struct cb_pcimdas_private *devpriv = dev->private; + unsigned int status; + + /* + * The number of Analog Input channels is set with the + * Analog Input Mode Switch on the board. The board can + * have 16 single-ended or 8 differential channels. + */ + status = inb(devpriv->BADR3 + 2); + return status & 0x20; +} + static int cb_pcimdas_auto_attach(struct comedi_device *dev, unsigned long context_unused) { @@ -209,8 +213,14 @@ static int cb_pcimdas_auto_attach(struct comedi_device *dev, /* dev->read_subdev=s; */ /* analog input subdevice */ s->type = COMEDI_SUBD_AI; - s->subdev_flags = SDF_READABLE | SDF_GROUND; - s->n_chan = 16; + s->subdev_flags = SDF_READABLE; + if (cb_pcimdas_is_ai_se(dev)) { + s->subdev_flags |= SDF_GROUND; + s->n_chan = 16; + } else { + s->subdev_flags |= SDF_DIFF; + s->n_chan = 8; + } s->maxdata = 0xffff; s->range_table = &range_unknown; s->len_chanlist = 1; /* This is the maximum chanlist length that */ -- 2.34.1