diff options
author | H Hartley Sweeten <hsweeten@visionengravers.com> | 2014-02-19 18:11:31 +0100 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2014-02-21 21:39:38 +0100 |
commit | c36d44ace681cdbed05d06df736e772a80e20992 (patch) | |
tree | fa70bc2e5af3b3b5fcb675ef7df747c561f12c10 /drivers | |
parent | staging: comedi: pcl816: remove unnecessary function separation comments (diff) | |
download | linux-c36d44ace681cdbed05d06df736e772a80e20992.tar.xz linux-c36d44ace681cdbed05d06df736e772a80e20992.zip |
staging: comedi: pcl816: tidy up pcl818_check()
This function probes a number of the boards registers during the
(*attach) to verify that it is actually a PCL-816 compatible board.
For aesthetics, move the function closer to the (*attach).
To better match the pcl818 driver, allocate the private data before
calling pcl816_check().
Refactor the function to return an errno if fails. Change the errno
from -EIO to -ENODEV and remove the unnecessary dev_err() noise.
Make sure the CONTROL register is reset to a known state after the
check. The 0x18 value actually defines an invalid interrupt selection
and sets an undefined bit.
Add a couple comments to clarify the magic values.
Signed-off-by: H Hartley Sweeten <hsweeten@visionengravers.com>
Reviewed-by: Ian Abbott <abbotti@mev.co.uk>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/staging/comedi/drivers/pcl816.c | 58 |
1 files changed, 31 insertions, 27 deletions
diff --git a/drivers/staging/comedi/drivers/pcl816.c b/drivers/staging/comedi/drivers/pcl816.c index aae2947281df..2e383ebde119 100644 --- a/drivers/staging/comedi/drivers/pcl816.c +++ b/drivers/staging/comedi/drivers/pcl816.c @@ -614,25 +614,6 @@ static int pcl816_ai_cancel(struct comedi_device *dev, return 0; } -static int pcl816_check(unsigned long iobase) -{ - outb(0x00, iobase + PCL816_MUX); - udelay(1); - if (inb(iobase + PCL816_MUX) != 0x00) - return 1; /* there isn't card */ - outb(0x55, iobase + PCL816_MUX); - udelay(1); - if (inb(iobase + PCL816_MUX) != 0x55) - return 1; /* there isn't card */ - outb(0x00, iobase + PCL816_MUX); - udelay(1); - outb(0x18, iobase + PCL816_CONTROL); - udelay(1); - if (inb(iobase + PCL816_CONTROL) != 0x18) - return 1; /* there isn't card */ - return 0; /* ok, card exist */ -} - static void pcl816_reset(struct comedi_device *dev) { unsigned long timer_base = dev->iobase + PCL816_TIMER_BASE; @@ -733,6 +714,30 @@ setup_channel_list(struct comedi_device *dev, dev->iobase + PCL816_MUX); } +static int pcl816_check(struct comedi_device *dev) +{ + /* the MUX register should return the same value written */ + outb(0x00, dev->iobase + PCL816_MUX); + if (inb(dev->iobase + PCL816_MUX) != 0x00) + return -ENODEV; + outb(0x55, dev->iobase + PCL816_MUX); + if (inb(dev->iobase + PCL816_MUX) != 0x55) + return -ENODEV; + + /* reset the MUX register to a known state */ + outb(0x00, dev->iobase + PCL816_MUX); + + /* the CONTROL register should return the same value written */ + outb(0x18, dev->iobase + PCL816_CONTROL); + if (inb(dev->iobase + PCL816_CONTROL) != 0x18) + return -ENODEV; + + /* reset the CONTROL register to a known state */ + outb(0x00, dev->iobase + PCL816_CONTROL); + + return 0; +} + static int pcl816_attach(struct comedi_device *dev, struct comedi_devconfig *it) { const struct pcl816_board *board = comedi_board(dev); @@ -741,18 +746,17 @@ static int pcl816_attach(struct comedi_device *dev, struct comedi_devconfig *it) int ret; int i; + devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv)); + if (!devpriv) + return -ENOMEM; + ret = comedi_request_region(dev, it->options[0], 0x10); if (ret) return ret; - if (pcl816_check(dev->iobase)) { - dev_err(dev->class_dev, "I can't detect board. FAIL!\n"); - return -EIO; - } - - devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv)); - if (!devpriv) - return -ENOMEM; + ret = pcl816_check(dev); + if (ret) + return ret; /* we can use IRQ 2-7 for async command support */ if (it->options[1] >= 2 && it->options[1] <= 7) { |