1
0

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 <hsweeten@visionengravers.com>
Reviewed-by: Ian Abbott <abbotti@mev.co.uk>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
H Hartley Sweeten
2013-08-30 11:08:50 -07:00
committed by Greg Kroah-Hartman
parent b2c20d154a
commit f6b316bcd8

View File

@@ -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. */
unsigned int mask;
unsigned int val;
/* 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). */
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);
data[1] = val;
return insn->n;
}
static int dnp_dio_insn_config(struct comedi_device *dev,