From f6b316bcd8c421acd6fa5a6e18b4c846ecb9d965 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Fri, 30 Aug 2013 11:08:50 -0700 Subject: staging: comedi: ssv_dnp: use comedi_dio_update_state() Use comedi_dio_update_state() to handle the boilerplate code to update the subdevice s->state. Also, fix a bug where the state of the channels is returned in data[0]. The comedi core expects it to be returned in data[1]. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ssv_dnp.c | 48 +++++++++++++------------------- 1 file changed, 20 insertions(+), 28 deletions(-) diff --git a/drivers/staging/comedi/drivers/ssv_dnp.c b/drivers/staging/comedi/drivers/ssv_dnp.c index 11758a515c1b..df22a78d2b7e 100644 --- a/drivers/staging/comedi/drivers/ssv_dnp.c +++ b/drivers/staging/comedi/drivers/ssv_dnp.c @@ -46,51 +46,43 @@ Status: unknown #define PCMR 0xa3 /* Port C Mode Register */ #define PCDR 0xa7 /* Port C Data Register */ -/* ------------------------------------------------------------------------- */ -/* The insn_bits interface allows packed reading/writing of DIO channels. */ -/* The comedi core can convert between insn_bits and insn_read/write, so you */ -/* are able to use these instructions as well. */ -/* ------------------------------------------------------------------------- */ - static int dnp_dio_insn_bits(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) + struct comedi_insn *insn, + unsigned int *data) { - /* The insn data is a mask in data[0] and the new data in data[1], */ - /* each channel cooresponding to a bit. */ - - /* Ports A and B are straight forward: each bit corresponds to an */ - /* output pin with the same order. Port C is different: bits 0...3 */ - /* correspond to bits 4...7 of the output register (PCDR). */ + unsigned int mask; + unsigned int val; - if (data[0]) { + /* + * Ports A and B are straight forward: each bit corresponds to an + * output pin with the same order. Port C is different: bits 0...3 + * correspond to bits 4...7 of the output register (PCDR). + */ + mask = comedi_dio_update_state(s, data); + if (mask) { outb(PADR, CSCIR); - outb((inb(CSCDR) - & ~(u8) (data[0] & 0x0000FF)) - | (u8) (data[1] & 0x0000FF), CSCDR); + outb(s->state & 0xff, CSCDR); outb(PBDR, CSCIR); - outb((inb(CSCDR) - & ~(u8) ((data[0] & 0x00FF00) >> 8)) - | (u8) ((data[1] & 0x00FF00) >> 8), CSCDR); + outb((s->state >> 8) & 0xff, CSCDR); outb(PCDR, CSCIR); - outb((inb(CSCDR) - & ~(u8) ((data[0] & 0x0F0000) >> 12)) - | (u8) ((data[1] & 0x0F0000) >> 12), CSCDR); + val = inb(CSCDR) & 0x0f; + outb(((s->state >> 12) & 0xf0) | val, CSCDR); } - /* on return, data[1] contains the value of the digital input lines. */ outb(PADR, CSCIR); - data[0] = inb(CSCDR); + val = inb(CSCDR); outb(PBDR, CSCIR); - data[0] += inb(CSCDR) << 8; + val |= (inb(CSCDR) << 8); outb(PCDR, CSCIR); - data[0] += ((inb(CSCDR) & 0xF0) << 12); + val |= ((inb(CSCDR) & 0xf0) << 12); - return insn->n; + data[1] = val; + return insn->n; } static int dnp_dio_insn_config(struct comedi_device *dev, -- cgit v1.2.3