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 <hsweeten@visionengravers.com>
Reviewed-by: Ian Abbott <abbotti@mev.co.uk>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
H Hartley Sweeten 2013-08-06 09:32:33 -07:00 committed by Greg Kroah-Hartman
parent f3508b2294
commit ddf62f2c7b
12 changed files with 112 additions and 300 deletions

View File

@ -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;
int ret;
mask = 1 << CR_CHAN(insn->chanspec);
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,

View File

@ -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;

View File

@ -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);
int ret;
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;
}
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;
}

View File

@ -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,

View File

@ -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,

View File

@ -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;
unsigned int chan = CR_CHAN(insn->chanspec);
int byte_no = chan / 8;
int bit_no = chan % 8;
int ret;
/* Compute ioaddr for this channel */
ioaddr = subpriv->iobases[byte_no];
ret = comedi_dio_insn_config(dev, s, insn, data, 0);
if (ret)
return ret;
/* NOTE:
writing a 0 an IO channel's bit sets the channel to INPUT
and pulls the line high as well
if (data[0] == INSN_CONFIG_DIO_INPUT) {
unsigned long ioaddr = subpriv->iobases[byte_no];
unsigned char val;
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);
/* save to io_bits */
s->io_bits &= ~(1 << chan);
break;
case INSN_CONFIG_DIO_QUERY:
/* retrieve from shadow register */
data[1] =
(s->io_bits & (1 << chan)) ? COMEDI_OUTPUT : COMEDI_INPUT;
return insn->n;
break;
default:
return -EINVAL;
break;
val = inb(ioaddr);
val &= ~(1 << bit_no);
outb(val, ioaddr);
}
return insn->n;

View File

@ -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;
}

View File

@ -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 */

View File

@ -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;

View File

@ -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;
ret = comedi_dio_insn_config(dev, s, insn, data, 0);
if (ret)
return ret;
/* 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 */
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);
val &= ~mask;
outb(val, CSCDR);
outb(register_buffer, CSCDR);
return 1;
return insn->n;
}

View File

@ -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

View File

@ -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