From: H Hartley Sweeten Date: Fri, 30 Aug 2013 18:04:56 +0000 (-0700) Subject: staging: comedi: drivers: introduce comedi_dio_update_state() X-Git-Url: https://git.karo-electronics.de/?a=commitdiff_plain;h=05e60b13a36bf4b6bd4d724b2332d6c3a4023998;p=linux-beck.git staging: comedi: drivers: introduce comedi_dio_update_state() The (*insn_bits) functions for DIO and DO subdevices typically use the subdevice 's->state' to hold the current state of the output channels. The 'insn' passed to these functions, INSN_BITS, specifies two parameters passed in the 'data'. data[0] = 'mask', the channels to update data[1] = 'bits', the new state for the channels Introduce a helper function to handle the boilerplate used to update the internal state. Note that the 'mask' is filtered by the 'chanmask' of the channels actually supported by the subdevice. This is used to protect any non-channel related bits that are stored in the subdevice state. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- diff --git a/drivers/staging/comedi/comedidev.h b/drivers/staging/comedi/comedidev.h index 2e19f659cd22..1d8e61a822fd 100644 --- a/drivers/staging/comedi/comedidev.h +++ b/drivers/staging/comedi/comedidev.h @@ -345,6 +345,8 @@ void comedi_buf_memcpy_from(struct comedi_async *async, unsigned int offset, int comedi_dio_insn_config(struct comedi_device *, struct comedi_subdevice *, struct comedi_insn *, unsigned int *data, unsigned int mask); +unsigned int comedi_dio_update_state(struct comedi_subdevice *, + unsigned int *data); void *comedi_alloc_devpriv(struct comedi_device *, size_t); int comedi_alloc_subdevices(struct comedi_device *, int); diff --git a/drivers/staging/comedi/drivers.c b/drivers/staging/comedi/drivers.c index aeef59492ba2..8f02bf66e20b 100644 --- a/drivers/staging/comedi/drivers.c +++ b/drivers/staging/comedi/drivers.c @@ -190,6 +190,28 @@ int comedi_dio_insn_config(struct comedi_device *dev, } EXPORT_SYMBOL_GPL(comedi_dio_insn_config); +/** + * comedi_dio_update_state() - update the internal state of DIO subdevices. + * @s: comedi_subdevice struct + * @data: the channel mask and bits to update + */ +unsigned int comedi_dio_update_state(struct comedi_subdevice *s, + unsigned int *data) +{ + unsigned int chanmask = (s->n_chan < 32) ? ((1 << s->n_chan) - 1) + : 0xffffffff; + unsigned int mask = data[0] & chanmask; + unsigned int bits = data[1]; + + if (mask) { + s->state &= ~mask; + s->state |= (bits & mask); + } + + return mask; +} +EXPORT_SYMBOL_GPL(comedi_dio_update_state); + static int insn_rw_emulate_bits(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data)