From ddf62f2c7bd041d35095b525ab33e3a3e0829aaa Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 6 Aug 2013 09:32:33 -0700 Subject: [PATCH] staging: comedi: drivers: use comedi_dio_insn_config() for simple cases Convert the drivers with simple, per channel programmable i/o, to use the comedi_dio_insn_config() helper function. All of these pass a 'mask' of '0' to comedi_dio_insn_config() this causes the per channel mask to be used to configure the i/o direction. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/cb_pcidas64.c | 25 +++------ drivers/staging/comedi/drivers/ni_670x.c | 25 +++------ drivers/staging/comedi/drivers/ni_daq_700.c | 24 ++++---- drivers/staging/comedi/drivers/ni_mio_common.c | 57 ++++--------------- drivers/staging/comedi/drivers/ni_pcidio.c | 29 +++------- drivers/staging/comedi/drivers/pcmmio.c | 71 +++++------------------ drivers/staging/comedi/drivers/pcmuio.c | 24 +++----- drivers/staging/comedi/drivers/rtd520.c | 20 ++----- drivers/staging/comedi/drivers/s626.c | 22 ++------ drivers/staging/comedi/drivers/ssv_dnp.c | 78 ++++++++++---------------- drivers/staging/comedi/drivers/usbdux.c | 19 ++----- drivers/staging/comedi/drivers/usbduxsigma.c | 20 ++----- 12 files changed, 113 insertions(+), 301 deletions(-) diff --git a/drivers/staging/comedi/drivers/cb_pcidas64.c b/drivers/staging/comedi/drivers/cb_pcidas64.c index e6e4561..388dbd7 100644 --- a/drivers/staging/comedi/drivers/cb_pcidas64.c +++ b/drivers/staging/comedi/drivers/cb_pcidas64.c @@ -3510,31 +3510,20 @@ static int do_wbits(struct comedi_device *dev, struct comedi_subdevice *s, static int dio_60xx_config_insn(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) + struct comedi_insn *insn, + unsigned int *data) { struct pcidas64_private *devpriv = dev->private; - unsigned int mask; - - mask = 1 << CR_CHAN(insn->chanspec); + int ret; - switch (data[0]) { - case INSN_CONFIG_DIO_INPUT: - s->io_bits &= ~mask; - break; - case INSN_CONFIG_DIO_OUTPUT: - s->io_bits |= mask; - break; - case INSN_CONFIG_DIO_QUERY: - data[1] = (s->io_bits & mask) ? COMEDI_OUTPUT : COMEDI_INPUT; - return 2; - default: - return -EINVAL; - } + ret = comedi_dio_insn_config(dev, s, insn, data, 0); + if (ret) + return ret; writeb(s->io_bits, devpriv->dio_counter_iobase + DIO_DIRECTION_60XX_REG); - return 1; + return insn->n; } static int dio_60xx_wbits(struct comedi_device *dev, struct comedi_subdevice *s, diff --git a/drivers/staging/comedi/drivers/ni_670x.c b/drivers/staging/comedi/drivers/ni_670x.c index 0201625..e2926ce 100644 --- a/drivers/staging/comedi/drivers/ni_670x.c +++ b/drivers/staging/comedi/drivers/ni_670x.c @@ -158,27 +158,16 @@ static int ni_670x_dio_insn_bits(struct comedi_device *dev, static int ni_670x_dio_insn_config(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) + struct comedi_insn *insn, + unsigned int *data) { struct ni_670x_private *devpriv = dev->private; - int chan = CR_CHAN(insn->chanspec); + int ret; + + ret = comedi_dio_insn_config(dev, s, insn, data, 0); + if (ret) + return ret; - switch (data[0]) { - case INSN_CONFIG_DIO_OUTPUT: - s->io_bits |= 1 << chan; - break; - case INSN_CONFIG_DIO_INPUT: - s->io_bits &= ~(1 << chan); - break; - case INSN_CONFIG_DIO_QUERY: - data[1] = - (s->io_bits & (1 << chan)) ? COMEDI_OUTPUT : COMEDI_INPUT; - return insn->n; - break; - default: - return -EINVAL; - break; - } writel(s->io_bits, devpriv->mite->daq_io_addr + DIO_PORT0_DIR_OFFSET); return insn->n; diff --git a/drivers/staging/comedi/drivers/ni_daq_700.c b/drivers/staging/comedi/drivers/ni_daq_700.c index 4165965..404f83d 100644 --- a/drivers/staging/comedi/drivers/ni_daq_700.c +++ b/drivers/staging/comedi/drivers/ni_daq_700.c @@ -90,21 +90,17 @@ static int daq700_dio_insn_bits(struct comedi_device *dev, static int daq700_dio_insn_config(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) + struct comedi_insn *insn, + unsigned int *data) { - unsigned int chan = 1 << CR_CHAN(insn->chanspec); - - switch (data[0]) { - case INSN_CONFIG_DIO_INPUT: - break; - case INSN_CONFIG_DIO_OUTPUT: - break; - case INSN_CONFIG_DIO_QUERY: - data[1] = (s->io_bits & chan) ? COMEDI_OUTPUT : COMEDI_INPUT; - break; - default: - return -EINVAL; - } + int ret; + + ret = comedi_dio_insn_config(dev, s, insn, data, 0); + if (ret) + return ret; + + /* The DIO channels are not configurable, fix the io_bits */ + s->io_bits = 0x00ff; return insn->n; } diff --git a/drivers/staging/comedi/drivers/ni_mio_common.c b/drivers/staging/comedi/drivers/ni_mio_common.c index 04f4b7d..4e02770 100644 --- a/drivers/staging/comedi/drivers/ni_mio_common.c +++ b/drivers/staging/comedi/drivers/ni_mio_common.c @@ -3528,37 +3528,21 @@ static int ni_ao_reset(struct comedi_device *dev, struct comedi_subdevice *s) static int ni_dio_insn_config(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) + struct comedi_insn *insn, + unsigned int *data) { struct ni_private *devpriv = dev->private; + int ret; -#ifdef DEBUG_DIO - printk("ni_dio_insn_config() chan=%d io=%d\n", - CR_CHAN(insn->chanspec), data[0]); -#endif - switch (data[0]) { - case INSN_CONFIG_DIO_OUTPUT: - s->io_bits |= 1 << CR_CHAN(insn->chanspec); - break; - case INSN_CONFIG_DIO_INPUT: - s->io_bits &= ~(1 << CR_CHAN(insn->chanspec)); - break; - case INSN_CONFIG_DIO_QUERY: - data[1] = - (s-> - io_bits & (1 << CR_CHAN(insn->chanspec))) ? COMEDI_OUTPUT : - COMEDI_INPUT; - return insn->n; - break; - default: - return -EINVAL; - } + ret = comedi_dio_insn_config(dev, s, insn, data, 0); + if (ret) + return ret; devpriv->dio_control &= ~DIO_Pins_Dir_Mask; devpriv->dio_control |= DIO_Pins_Dir(s->io_bits); devpriv->stc_writew(dev, devpriv->dio_control, DIO_Control_Register); - return 1; + return insn->n; } static int ni_dio_insn_bits(struct comedi_device *dev, @@ -3596,32 +3580,15 @@ static int ni_m_series_dio_insn_config(struct comedi_device *dev, unsigned int *data) { struct ni_private *devpriv __maybe_unused = dev->private; + int ret; -#ifdef DEBUG_DIO - printk("ni_m_series_dio_insn_config() chan=%d io=%d\n", - CR_CHAN(insn->chanspec), data[0]); -#endif - switch (data[0]) { - case INSN_CONFIG_DIO_OUTPUT: - s->io_bits |= 1 << CR_CHAN(insn->chanspec); - break; - case INSN_CONFIG_DIO_INPUT: - s->io_bits &= ~(1 << CR_CHAN(insn->chanspec)); - break; - case INSN_CONFIG_DIO_QUERY: - data[1] = - (s-> - io_bits & (1 << CR_CHAN(insn->chanspec))) ? COMEDI_OUTPUT : - COMEDI_INPUT; - return insn->n; - break; - default: - return -EINVAL; - } + ret = comedi_dio_insn_config(dev, s, insn, data, 0); + if (ret) + return ret; ni_writel(s->io_bits, M_Offset_DIO_Direction); - return 1; + return insn->n; } static int ni_m_series_dio_insn_bits(struct comedi_device *dev, diff --git a/drivers/staging/comedi/drivers/ni_pcidio.c b/drivers/staging/comedi/drivers/ni_pcidio.c index 8ac7a7c..fad81bc 100644 --- a/drivers/staging/comedi/drivers/ni_pcidio.c +++ b/drivers/staging/comedi/drivers/ni_pcidio.c @@ -640,32 +640,19 @@ static void debug_int(struct comedi_device *dev) static int ni_pcidio_insn_config(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) + struct comedi_insn *insn, + unsigned int *data) { struct nidio96_private *devpriv = dev->private; + int ret; + + ret = comedi_dio_insn_config(dev, s, insn, data, 0); + if (ret) + return ret; - if (insn->n != 1) - return -EINVAL; - switch (data[0]) { - case INSN_CONFIG_DIO_OUTPUT: - s->io_bits |= 1 << CR_CHAN(insn->chanspec); - break; - case INSN_CONFIG_DIO_INPUT: - s->io_bits &= ~(1 << CR_CHAN(insn->chanspec)); - break; - case INSN_CONFIG_DIO_QUERY: - data[1] = - (s-> - io_bits & (1 << CR_CHAN(insn->chanspec))) ? COMEDI_OUTPUT : - COMEDI_INPUT; - return insn->n; - break; - default: - return -EINVAL; - } writel(s->io_bits, devpriv->mite->daq_io_addr + Port_Pin_Directions(0)); - return 1; + return insn->n; } static int ni_pcidio_insn_bits(struct comedi_device *dev, diff --git a/drivers/staging/comedi/drivers/pcmmio.c b/drivers/staging/comedi/drivers/pcmmio.c index fab93a7..aa3c030 100644 --- a/drivers/staging/comedi/drivers/pcmmio.c +++ b/drivers/staging/comedi/drivers/pcmmio.c @@ -310,68 +310,27 @@ static int pcmmio_dio_insn_bits(struct comedi_device *dev, return insn->n; } -/* The input or output configuration of each digital line is - * configured by a special insn_config instruction. chanspec - * contains the channel to be changed, and data[0] contains the - * value COMEDI_INPUT or COMEDI_OUTPUT. */ static int pcmmio_dio_insn_config(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) + struct comedi_insn *insn, + unsigned int *data) { - int chan = CR_CHAN(insn->chanspec), byte_no = chan / 8, bit_no = - chan % 8; - unsigned long ioaddr; - unsigned char byte; - - /* Compute ioaddr for this channel */ - ioaddr = subpriv->iobases[byte_no]; - - /* NOTE: - writing a 0 an IO channel's bit sets the channel to INPUT - and pulls the line high as well - - writing a 1 to an IO channel's bit pulls the line low - - All channels are implicitly always in OUTPUT mode -- but when - they are high they can be considered to be in INPUT mode.. - - Thus, we only force channels low if the config request was INPUT, - otherwise we do nothing to the hardware. */ - - switch (data[0]) { - case INSN_CONFIG_DIO_OUTPUT: - /* save to io_bits -- don't actually do anything since - all input channels are also output channels... */ - s->io_bits |= 1 << chan; - break; - case INSN_CONFIG_DIO_INPUT: - /* write a 0 to the actual register representing the channel - to set it to 'input'. 0 means "float high". */ - byte = inb(ioaddr); - byte &= ~(1 << bit_no); - /**< set input channel to '0' */ - - /* - * write out byte -- this is the only time we actually affect - * the hardware as all channels are implicitly output - * -- but input channels are set to float-high - */ - outb(byte, ioaddr); + unsigned int chan = CR_CHAN(insn->chanspec); + int byte_no = chan / 8; + int bit_no = chan % 8; + int ret; - /* save to io_bits */ - s->io_bits &= ~(1 << chan); - break; + ret = comedi_dio_insn_config(dev, s, insn, data, 0); + if (ret) + return ret; - case INSN_CONFIG_DIO_QUERY: - /* retrieve from shadow register */ - data[1] = - (s->io_bits & (1 << chan)) ? COMEDI_OUTPUT : COMEDI_INPUT; - return insn->n; - break; + if (data[0] == INSN_CONFIG_DIO_INPUT) { + unsigned long ioaddr = subpriv->iobases[byte_no]; + unsigned char val; - default: - return -EINVAL; - break; + val = inb(ioaddr); + val &= ~(1 << bit_no); + outb(val, ioaddr); } return insn->n; diff --git a/drivers/staging/comedi/drivers/pcmuio.c b/drivers/staging/comedi/drivers/pcmuio.c index 13f1943..f942455 100644 --- a/drivers/staging/comedi/drivers/pcmuio.c +++ b/drivers/staging/comedi/drivers/pcmuio.c @@ -233,27 +233,19 @@ static int pcmuio_dio_insn_bits(struct comedi_device *dev, static int pcmuio_dio_insn_config(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) + struct comedi_insn *insn, + unsigned int *data) { - unsigned int chan_mask = 1 << CR_CHAN(insn->chanspec); int asic = s->index / 2; int port = (s->index % 2) ? 3 : 0; + int ret; - switch (data[0]) { - case INSN_CONFIG_DIO_OUTPUT: - s->io_bits |= chan_mask; - break; - case INSN_CONFIG_DIO_INPUT: - s->io_bits &= ~chan_mask; + ret = comedi_dio_insn_config(dev, s, insn, data, 0); + if (ret) + return ret; + + if (data[0] == INSN_CONFIG_DIO_INPUT) pcmuio_write(dev, s->io_bits, asic, 0, port); - break; - case INSN_CONFIG_DIO_QUERY: - data[1] = (s->io_bits & chan_mask) ? COMEDI_OUTPUT : COMEDI_INPUT; - break; - default: - return -EINVAL; - break; - } return insn->n; } diff --git a/drivers/staging/comedi/drivers/rtd520.c b/drivers/staging/comedi/drivers/rtd520.c index 635c8f5..93c980c 100644 --- a/drivers/staging/comedi/drivers/rtd520.c +++ b/drivers/staging/comedi/drivers/rtd520.c @@ -1238,23 +1238,11 @@ static int rtd_dio_insn_config(struct comedi_device *dev, unsigned int *data) { struct rtd_private *devpriv = dev->private; - unsigned int chan = CR_CHAN(insn->chanspec); - unsigned int mask = 1 << chan; + int ret; - switch (data[0]) { - case INSN_CONFIG_DIO_OUTPUT: - s->io_bits |= mask; - break; - case INSN_CONFIG_DIO_INPUT: - s->io_bits &= ~mask; - break; - case INSN_CONFIG_DIO_QUERY: - data[1] = (s->io_bits & mask) ? COMEDI_OUTPUT : COMEDI_INPUT; - return insn->n; - break; - default: - return -EINVAL; - } + ret = comedi_dio_insn_config(dev, s, insn, data, 0); + if (ret) + return ret; /* TODO support digital match interrupts and strobes */ diff --git a/drivers/staging/comedi/drivers/s626.c b/drivers/staging/comedi/drivers/s626.c index b0ba9b9..d22b95d 100644 --- a/drivers/staging/comedi/drivers/s626.c +++ b/drivers/staging/comedi/drivers/s626.c @@ -1662,24 +1662,12 @@ static int s626_dio_insn_config(struct comedi_device *dev, unsigned int *data) { unsigned long group = (unsigned long)s->private; - unsigned int chan = CR_CHAN(insn->chanspec); - unsigned int mask = 1 << chan; + int ret; + + ret = comedi_dio_insn_config(dev, s, insn, data, 0); + if (ret) + return ret; - switch (data[0]) { - case INSN_CONFIG_DIO_QUERY: - data[1] = (s->io_bits & mask) ? COMEDI_OUTPUT : COMEDI_INPUT; - return insn->n; - break; - case COMEDI_INPUT: - s->io_bits &= ~mask; - break; - case COMEDI_OUTPUT: - s->io_bits |= mask; - break; - default: - return -EINVAL; - break; - } DEBIwrite(dev, LP_WRDOUT(group), s->io_bits); return insn->n; diff --git a/drivers/staging/comedi/drivers/ssv_dnp.c b/drivers/staging/comedi/drivers/ssv_dnp.c index 4da4d32..11758a5 100644 --- a/drivers/staging/comedi/drivers/ssv_dnp.c +++ b/drivers/staging/comedi/drivers/ssv_dnp.c @@ -93,68 +93,48 @@ static int dnp_dio_insn_bits(struct comedi_device *dev, } -/* ------------------------------------------------------------------------- */ -/* Configure the direction of the bidirectional digital i/o pins. chanspec */ -/* contains the channel to be changed and data[0] contains either */ -/* COMEDI_INPUT or COMEDI_OUTPUT. */ -/* ------------------------------------------------------------------------- */ - static int dnp_dio_insn_config(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) + struct comedi_insn *insn, + unsigned int *data) { + unsigned int chan = CR_CHAN(insn->chanspec); + unsigned int mask; + unsigned int val; + int ret; - u8 register_buffer; - - /* reduces chanspec to lower 16 bits */ - int chan = CR_CHAN(insn->chanspec); - - switch (data[0]) { - case INSN_CONFIG_DIO_OUTPUT: - case INSN_CONFIG_DIO_INPUT: - break; - case INSN_CONFIG_DIO_QUERY: - data[1] = - (inb(CSCDR) & (1 << chan)) ? COMEDI_OUTPUT : COMEDI_INPUT; - return insn->n; - break; - default: - return -EINVAL; - break; - } - /* Test: which port does the channel belong to? */ - - /* We have to pay attention with port C: this is the meaning of PCMR: */ - /* Bit in PCMR: 7 6 5 4 3 2 1 0 */ - /* Corresponding port C pin: d 3 d 2 d 1 d 0 d= don't touch */ + ret = comedi_dio_insn_config(dev, s, insn, data, 0); + if (ret) + return ret; - if ((chan >= 0) && (chan <= 7)) { - /* this is port A */ + if (chan < 8) { /* Port A */ + mask = 1 << chan; outb(PAMR, CSCIR); - } else if ((chan >= 8) && (chan <= 15)) { - /* this is port B */ - chan -= 8; + } else if (chan < 16) { /* Port B */ + mask = 1 << (chan - 8); outb(PBMR, CSCIR); - } else if ((chan >= 16) && (chan <= 19)) { - /* this is port C; multiplication with 2 brings bits into */ - /* correct position for PCMR! */ - chan -= 16; - chan *= 2; + } else { /* Port C */ + /* + * We have to pay attention with port C. + * This is the meaning of PCMR: + * Bit in PCMR: 7 6 5 4 3 2 1 0 + * Corresponding port C pin: d 3 d 2 d 1 d 0 d= don't touch + * + * Multiplication by 2 brings bits into correct position + * for PCMR! + */ + mask = 1 << ((chan - 16) * 2); outb(PCMR, CSCIR); - } else { - return -EINVAL; } - /* read 'old' direction of the port and set bits (out=1, in=0) */ - register_buffer = inb(CSCDR); + val = inb(CSCDR); if (data[0] == COMEDI_OUTPUT) - register_buffer |= (1 << chan); + val |= mask; else - register_buffer &= ~(1 << chan); - - outb(register_buffer, CSCDR); + val &= ~mask; + outb(val, CSCDR); - return 1; + return insn->n; } diff --git a/drivers/staging/comedi/drivers/usbdux.c b/drivers/staging/comedi/drivers/usbdux.c index 689b452..7e91f15 100644 --- a/drivers/staging/comedi/drivers/usbdux.c +++ b/drivers/staging/comedi/drivers/usbdux.c @@ -1113,22 +1113,11 @@ static int usbdux_dio_insn_config(struct comedi_device *dev, struct comedi_insn *insn, unsigned int *data) { - unsigned int mask = 1 << CR_CHAN(insn->chanspec); + int ret; - switch (data[0]) { - case INSN_CONFIG_DIO_OUTPUT: - s->io_bits |= mask; - break; - case INSN_CONFIG_DIO_INPUT: - s->io_bits &= ~mask; - break; - case INSN_CONFIG_DIO_QUERY: - data[1] = (s->io_bits & mask) ? COMEDI_OUTPUT : COMEDI_INPUT; - break; - default: - return -EINVAL; - break; - } + ret = comedi_dio_insn_config(dev, s, insn, data, 0); + if (ret) + return ret; /* * We don't tell the firmware here as it would take 8 frames diff --git a/drivers/staging/comedi/drivers/usbduxsigma.c b/drivers/staging/comedi/drivers/usbduxsigma.c index fca89c3..c47f408 100644 --- a/drivers/staging/comedi/drivers/usbduxsigma.c +++ b/drivers/staging/comedi/drivers/usbduxsigma.c @@ -1040,23 +1040,11 @@ static int usbduxsigma_dio_insn_config(struct comedi_device *dev, struct comedi_insn *insn, unsigned int *data) { - unsigned int chan = CR_CHAN(insn->chanspec); - unsigned int mask = 1 << chan; + int ret; - switch (data[0]) { - case INSN_CONFIG_DIO_OUTPUT: - s->io_bits |= mask; - break; - case INSN_CONFIG_DIO_INPUT: - s->io_bits &= ~mask; - break; - case INSN_CONFIG_DIO_QUERY: - data[1] = (s->io_bits & mask) ? COMEDI_OUTPUT : COMEDI_INPUT; - break; - default: - return -EINVAL; - break; - } + ret = comedi_dio_insn_config(dev, s, insn, data, 0); + if (ret) + return ret; /* * We don't tell the firmware here as it would take 8 frames -- 2.7.4