Commit 10f27014 authored by Ian Abbott's avatar Ian Abbott Committed by Greg Kroah-Hartman

Staging: comedi: s526: Fix number of channels on DIO subdevice

Correct operation of INSN_CONFIG_DIO_INPUT and INSN_CONFIG_DIO_OUTPUT
and support INSN_CONFIG_DIO_QUERY.  Thanks to Alessio Margan for some
testing.
Signed-off-by: default avatarFrank Mori Hess <fmhess@users.sourceforge.net>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent aa65d22a
...@@ -375,7 +375,7 @@ static int s526_attach(struct comedi_device *dev, struct comedi_devconfig *it) ...@@ -375,7 +375,7 @@ static int s526_attach(struct comedi_device *dev, struct comedi_devconfig *it)
if (thisboard->have_dio) { if (thisboard->have_dio) {
s->type = COMEDI_SUBD_DIO; s->type = COMEDI_SUBD_DIO;
s->subdev_flags = SDF_READABLE | SDF_WRITABLE; s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
s->n_chan = 2; s->n_chan = 8;
s->maxdata = 1; s->maxdata = 1;
s->range_table = &range_digital; s->range_table = &range_digital;
s->insn_bits = s526_dio_insn_bits; s->insn_bits = s526_dio_insn_bits;
...@@ -949,7 +949,7 @@ static int s526_dio_insn_bits(struct comedi_device *dev, ...@@ -949,7 +949,7 @@ static int s526_dio_insn_bits(struct comedi_device *dev,
data[1] = inw(ADDR_REG(REG_DIO)) & 0xFF; /* low 8 bits are the data */ data[1] = inw(ADDR_REG(REG_DIO)) & 0xFF; /* low 8 bits are the data */
/* or we could just return the software copy of the output values if /* or we could just return the software copy of the output values if
* it was a purely digital output subdevice */ * it was a purely digital output subdevice */
/* data[1]=s->state; */ /* data[1]=s->state & 0xFF; */
return 2; return 2;
} }
...@@ -959,28 +959,33 @@ static int s526_dio_insn_config(struct comedi_device *dev, ...@@ -959,28 +959,33 @@ static int s526_dio_insn_config(struct comedi_device *dev,
struct comedi_insn *insn, unsigned int *data) struct comedi_insn *insn, unsigned int *data)
{ {
int chan = CR_CHAN(insn->chanspec); int chan = CR_CHAN(insn->chanspec);
short value; int group, mask;
printk("S526 DIO insn_config\n"); printk("S526 DIO insn_config\n");
if (insn->n != 1)
return -EINVAL;
value = inw(ADDR_REG(REG_DIO));
/* The input or output configuration of each digital line is /* The input or output configuration of each digital line is
* configured by a special insn_config instruction. chanspec * configured by a special insn_config instruction. chanspec
* contains the channel to be changed, and data[0] contains the * contains the channel to be changed, and data[0] contains the
* value COMEDI_INPUT or COMEDI_OUTPUT. */ * value COMEDI_INPUT or COMEDI_OUTPUT. */
if (data[0] == COMEDI_OUTPUT) { group = chan >> 2;
value |= 1 << (chan + 10); /* bit 10/11 set the group 1/2's mode */ mask = 0xF << (group << 2);
s->io_bits |= (0xF << chan); switch (data[0]) {
} else { case INSN_CONFIG_DIO_OUTPUT:
value &= ~(1 << (chan + 10)); /* 1 is output, 0 is input. */ s->state |= 1 << (group + 10); // bit 10/11 set the group 1/2's mode
s->io_bits &= ~(0xF << chan); s->io_bits |= mask;
break;
case INSN_CONFIG_DIO_INPUT:
s->state &= ~(1 << (group + 10));// 1 is output, 0 is input.
s->io_bits &= ~mask;
break;
case INSN_CONFIG_DIO_QUERY:
data[1] = (s->io_bits & mask) ? COMEDI_OUTPUT : COMEDI_INPUT;
return insn->n;
default:
return -EINVAL;
} }
outw(value, ADDR_REG(REG_DIO)); outw(s->state, ADDR_REG(REG_DIO));
return 1; return 1;
} }
......
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