From: H Hartley Sweeten Date: Tue, 11 Nov 2014 23:55:28 +0000 (-0700) Subject: staging: comedi: dmm32at: use 8255 module for Digital I/O subdevice X-Git-Url: https://git.karo-electronics.de/?a=commitdiff_plain;h=387ca51f7c403b342a9e382ac15c6df461ea2190;p=linux-beck.git staging: comedi: dmm32at: use 8255 module for Digital I/O subdevice The Dimond-MM-32-AT board uses an internal 82C55-type digital I/O circuit to provide the 24 digital I/O lines. The only quirk is the need to set the page selection bits in the control register to select page 1 addresses. Instead of duplicating the 8255 code, provide an (*io) callback and use the 8255 module to support this subdevice. This also removes the need for the private data in this driver. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- diff --git a/drivers/staging/comedi/Kconfig b/drivers/staging/comedi/Kconfig index cf52577349a7..a8201fe87512 100644 --- a/drivers/staging/comedi/Kconfig +++ b/drivers/staging/comedi/Kconfig @@ -384,6 +384,7 @@ config COMEDI_DT282X config COMEDI_DMM32AT tristate "Diamond Systems MM-32-AT PC/104 board support" + select COMEDI_8255 ---help--- Enable support for Diamond Systems MM-32-AT PC/104 boards diff --git a/drivers/staging/comedi/drivers/dmm32at.c b/drivers/staging/comedi/drivers/dmm32at.c index dc222d13e318..df0a47fe0d11 100644 --- a/drivers/staging/comedi/drivers/dmm32at.c +++ b/drivers/staging/comedi/drivers/dmm32at.c @@ -37,6 +37,7 @@ Configuration Options: #include #include "../comedidev.h" +#include "8255.h" #include "comedi_fc.h" /* Board register addresses */ @@ -69,10 +70,7 @@ Configuration Options: #define DMM32AT_CLK2 0x0e #define DMM32AT_CLKCT 0x0f -#define DMM32AT_DIOA 0x0c -#define DMM32AT_DIOB 0x0d -#define DMM32AT_DIOC 0x0e -#define DMM32AT_DIOCONF 0x0f +#define DMM32AT_8255_IOBASE 0x0c /* Page 1 registers */ /* Board register values. */ @@ -113,13 +111,6 @@ Configuration Options: #define DMM32AT_CLKCT1 0x56 /* mode3 counter 1 - write low byte only */ #define DMM32AT_CLKCT2 0xb6 /* mode3 counter 2 - write high and low byte */ -/* DMM32AT_DIOCONF 0x0f */ -#define DMM32AT_DIENABLE 0x80 -#define DMM32AT_DIRA 0x10 -#define DMM32AT_DIRB 0x02 -#define DMM32AT_DIRCL 0x01 -#define DMM32AT_DIRCH 0x08 - /* board AI ranges in comedi structure */ static const struct comedi_lrange dmm32at_airanges = { 4, { @@ -150,10 +141,6 @@ static const struct comedi_lrange dmm32at_aoranges = { } }; -struct dmm32at_private { - unsigned char dio_config; -}; - static void dmm32at_ai_set_chanspec(struct comedi_device *dev, struct comedi_subdevice *s, unsigned int chanspec, int nchan) @@ -472,91 +459,22 @@ static int dmm32at_ao_insn_write(struct comedi_device *dev, return insn->n; } -static int dmm32at_dio_insn_bits(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data) -{ - struct dmm32at_private *devpriv = dev->private; - unsigned int mask; - unsigned int val; - - mask = comedi_dio_update_state(s, data); - if (mask) { - /* get access to the DIO regs */ - outb(DMM32AT_DIOACC, dev->iobase + DMM32AT_CNTRL); - - /* if either part of dio is set for output */ - if (((devpriv->dio_config & DMM32AT_DIRCL) == 0) || - ((devpriv->dio_config & DMM32AT_DIRCH) == 0)) { - val = (s->state & 0x00ff0000) >> 16; - outb(val, dev->iobase + DMM32AT_DIOC); - } - if ((devpriv->dio_config & DMM32AT_DIRB) == 0) { - val = (s->state & 0x0000ff00) >> 8; - outb(val, dev->iobase + DMM32AT_DIOB); - } - if ((devpriv->dio_config & DMM32AT_DIRA) == 0) { - val = (s->state & 0x000000ff); - outb(val, dev->iobase + DMM32AT_DIOA); - } - } - - val = inb(dev->iobase + DMM32AT_DIOA); - val |= inb(dev->iobase + DMM32AT_DIOB) << 8; - val |= inb(dev->iobase + DMM32AT_DIOC) << 16; - s->state = val; - - data[1] = val; - - return insn->n; -} - -static int dmm32at_dio_insn_config(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data) +static int dmm32at_8255_io(struct comedi_device *dev, + int dir, int port, int data, unsigned long regbase) { - struct dmm32at_private *devpriv = dev->private; - unsigned int chan = CR_CHAN(insn->chanspec); - unsigned int mask; - unsigned char chanbit; - int ret; - - if (chan < 8) { - mask = 0x0000ff; - chanbit = DMM32AT_DIRA; - } else if (chan < 16) { - mask = 0x00ff00; - chanbit = DMM32AT_DIRB; - } else if (chan < 20) { - mask = 0x0f0000; - chanbit = DMM32AT_DIRCL; - } else { - mask = 0xf00000; - chanbit = DMM32AT_DIRCH; - } - - ret = comedi_dio_insn_config(dev, s, insn, data, mask); - if (ret) - return ret; - - if (data[0] == INSN_CONFIG_DIO_OUTPUT) - devpriv->dio_config &= ~chanbit; - else - devpriv->dio_config |= chanbit; /* get access to the DIO regs */ outb(DMM32AT_DIOACC, dev->iobase + DMM32AT_CNTRL); - /* set the DIO's to the new configuration setting */ - outb(devpriv->dio_config, dev->iobase + DMM32AT_DIOCONF); - return insn->n; + if (dir) { + outb(data, dev->iobase + regbase + port); + return 0; + } + return inb(dev->iobase + regbase + port); } /* Make sure the board is there and put it to a known state */ static int dmm32at_reset(struct comedi_device *dev) { - struct dmm32at_private *devpriv = dev->private; unsigned char aihi, ailo, fifostat, aistat, intstat, airback; /* reset the board */ @@ -593,28 +511,15 @@ static int dmm32at_reset(struct comedi_device *dev) aistat != 0x60 || intstat != 0x00 || airback != 0x0c) return -EIO; - /* get access to the DIO regs */ - outb(DMM32AT_DIOACC, dev->iobase + DMM32AT_CNTRL); - /* set the DIO's to the defualt input setting */ - devpriv->dio_config = DMM32AT_DIRA | DMM32AT_DIRB | - DMM32AT_DIRCL | DMM32AT_DIRCH | - DMM32AT_DIENABLE; - outb(devpriv->dio_config, dev->iobase + DMM32AT_DIOCONF); - return 0; } static int dmm32at_attach(struct comedi_device *dev, struct comedi_devconfig *it) { - struct dmm32at_private *devpriv; struct comedi_subdevice *s; int ret; - devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv)); - if (!devpriv) - return -ENOMEM; - ret = comedi_request_region(dev, it->options[0], 0x10); if (ret) return ret; @@ -669,13 +574,9 @@ static int dmm32at_attach(struct comedi_device *dev, /* Digital I/O subdevice */ s = &dev->subdevices[2]; - s->type = COMEDI_SUBD_DIO; - s->subdev_flags = SDF_READABLE | SDF_WRITABLE; - s->n_chan = 24; - s->maxdata = 1; - s->range_table = &range_digital; - s->insn_bits = dmm32at_dio_insn_bits; - s->insn_config = dmm32at_dio_insn_config; + ret = subdev_8255_init(dev, s, dmm32at_8255_io, DMM32AT_8255_IOBASE); + if (ret) + return ret; return 0; }