mirror of https://gitee.com/openkylin/linux.git
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: H Hartley Sweeten <hsweeten@visionengravers.com> Reviewed-by: Ian Abbott <abbotti@mev.co.uk> Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
987f3c86a1
commit
e523c6c862
|
@ -342,6 +342,10 @@ void comedi_buf_memcpy_from(struct comedi_async *async, unsigned int offset,
|
||||||
|
|
||||||
/* drivers.c - general comedi driver functions */
|
/* 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);
|
void *comedi_alloc_devpriv(struct comedi_device *, size_t);
|
||||||
int comedi_alloc_subdevices(struct comedi_device *, int);
|
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;
|
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,
|
static int insn_rw_emulate_bits(struct comedi_device *dev,
|
||||||
struct comedi_subdevice *s,
|
struct comedi_subdevice *s,
|
||||||
struct comedi_insn *insn, unsigned int *data)
|
struct comedi_insn *insn, unsigned int *data)
|
||||||
|
|
Loading…
Reference in New Issue