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:
committed by
Greg Kroah-Hartman
parent
b2c20d154a
commit
f6b316bcd8
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user