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

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: default avatarH Hartley Sweeten <hsweeten@visionengravers.com>
Reviewed-by: default avatarIan Abbott <abbotti@mev.co.uk>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent b2c20d15
......@@ -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,
......
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