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