Commit e523c6c8 authored by H Hartley Sweeten's avatar H Hartley Sweeten Committed by Greg Kroah-Hartman

staging: comedi: drivers: introduce comedi_dio_insn_config()

DIO subdevices always handle the INSN_CONFIG_DIO_{INPUT,OUTPUT} instructions
to configure the DIO channels. They also always handle the INSN_CONFIG_DIO_QUERY
instruction to query the configuration of a DIO channel.

Introduce a helper function to handle the (*insn_config) boilerplate for
comedi DIO subdevices. This function has the same paramters as (*insn_config)
functions with an additional parameter to allow the caller to pass a 'mask'
value for grouped DIO channels.

This function returns:

  0 if the instruction was successful but requires additional handling by
  the caller (INSN_CONFIG_DIO_{INPUT,OUTPUT}

  insn->n if the instruction was handled (INSN_CONFIG_DIO_QUERY)

  -EINVAL for all unhandled instructions

The caller is responsible for actually configuring the hardware based on
the configuration (s->io_bits).
Signed-off-by: default avatarH Hartley Sweeten <hsweeten@visionengravers.com>
Reviewed-by: default avatarIan Abbott <abbotti@mev.co.uk>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 987f3c86
......@@ -342,6 +342,10 @@ void comedi_buf_memcpy_from(struct comedi_async *async, unsigned int offset,
/* drivers.c - general comedi driver functions */
int comedi_dio_insn_config(struct comedi_device *, struct comedi_subdevice *,
struct comedi_insn *, unsigned int *data,
unsigned int mask);
void *comedi_alloc_devpriv(struct comedi_device *, size_t);
int comedi_alloc_subdevices(struct comedi_device *, int);
......
......@@ -150,6 +150,46 @@ int insn_inval(struct comedi_device *dev, struct comedi_subdevice *s,
return -EINVAL;
}
/**
* comedi_dio_insn_config() - boilerplate (*insn_config) for DIO subdevices.
* @dev: comedi_device struct
* @s: comedi_subdevice struct
* @insn: comedi_insn struct
* @data: parameters for the @insn
* @mask: io_bits mask for grouped channels
*/
int comedi_dio_insn_config(struct comedi_device *dev,
struct comedi_subdevice *s,
struct comedi_insn *insn,
unsigned int *data,
unsigned int mask)
{
unsigned int chan_mask = 1 << CR_CHAN(insn->chanspec);
if (!mask)
mask = chan_mask;
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 insn->n;
default:
return -EINVAL;
}
return 0;
}
EXPORT_SYMBOL_GPL(comedi_dio_insn_config);
static int insn_rw_emulate_bits(struct comedi_device *dev,
struct comedi_subdevice *s,
struct comedi_insn *insn, unsigned int *data)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment