Commit 3457bfd6 authored by Greg Kroah-Hartman's avatar Greg Kroah-Hartman

Revert "staging: comedi: drivers: use comedi_dio_insn_config() for complex cases"

This reverts commit f21c5394.

I applied the wrong patch :(

Cc: H Hartley Sweeten <hsweeten@visionengravers.com>
Cc: Ian Abbott <abbotti@mev.co.uk>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 96256460
...@@ -184,29 +184,39 @@ static void subdev_8255_do_config(struct comedi_device *dev, ...@@ -184,29 +184,39 @@ static void subdev_8255_do_config(struct comedi_device *dev,
static int subdev_8255_insn_config(struct comedi_device *dev, static int subdev_8255_insn_config(struct comedi_device *dev,
struct comedi_subdevice *s, struct comedi_subdevice *s,
struct comedi_insn *insn, struct comedi_insn *insn, unsigned int *data)
unsigned int *data)
{ {
unsigned int chan = CR_CHAN(insn->chanspec);
unsigned int mask; unsigned int mask;
int ret; unsigned int bits;
if (chan < 8) mask = 1 << CR_CHAN(insn->chanspec);
mask = 0x0000ff; if (mask & 0x0000ff)
else if (chan < 16) bits = 0x0000ff;
mask = 0x00ff00; else if (mask & 0x00ff00)
else if (chan < 20) bits = 0x00ff00;
mask = 0x0f0000; else if (mask & 0x0f0000)
bits = 0x0f0000;
else else
mask = 0xf00000; bits = 0xf00000;
ret = comedi_dio_insn_config(dev, s, insn, data, mask); switch (data[0]) {
if (ret) case INSN_CONFIG_DIO_INPUT:
return ret; s->io_bits &= ~bits;
break;
case INSN_CONFIG_DIO_OUTPUT:
s->io_bits |= bits;
break;
case INSN_CONFIG_DIO_QUERY:
data[1] = (s->io_bits & bits) ? COMEDI_OUTPUT : COMEDI_INPUT;
return insn->n;
break;
default:
return -EINVAL;
}
subdev_8255_do_config(dev, s); subdev_8255_do_config(dev, s);
return insn->n; return 1;
} }
static int subdev_8255_cmdtest(struct comedi_device *dev, static int subdev_8255_cmdtest(struct comedi_device *dev,
......
...@@ -60,22 +60,36 @@ static int apci16xx_insn_config(struct comedi_device *dev, ...@@ -60,22 +60,36 @@ static int apci16xx_insn_config(struct comedi_device *dev,
struct comedi_insn *insn, struct comedi_insn *insn,
unsigned int *data) unsigned int *data)
{ {
unsigned int chan = CR_CHAN(insn->chanspec); unsigned int chan_mask = 1 << CR_CHAN(insn->chanspec);
unsigned int mask; unsigned int bits;
int ret;
if (chan < 8) /*
mask = 0x000000ff; * Each 8-bit "port" is configurable as either input or
else if (chan < 16) * output. Changing the configuration of any channel in
mask = 0x0000ff00; * a port changes the entire port.
else if (chan < 24) */
mask = 0x00ff0000; if (chan_mask & 0x000000ff)
bits = 0x000000ff;
else if (chan_mask & 0x0000ff00)
bits = 0x0000ff00;
else if (chan_mask & 0x00ff0000)
bits = 0x00ff0000;
else else
mask = 0xff000000; bits = 0xff000000;
ret = comedi_dio_insn_config(dev, s, insn, data, mask); switch (data[0]) {
if (ret) case INSN_CONFIG_DIO_INPUT:
return ret; s->io_bits &= ~bits;
break;
case INSN_CONFIG_DIO_OUTPUT:
s->io_bits |= bits;
break;
case INSN_CONFIG_DIO_QUERY:
data[1] = (s->io_bits & bits) ? COMEDI_INPUT : COMEDI_OUTPUT;
return insn->n;
default:
return -EINVAL;
}
outl(s->io_bits, dev->iobase + APCI16XX_DIR_REG(s->index)); outl(s->io_bits, dev->iobase + APCI16XX_DIR_REG(s->index));
......
...@@ -686,27 +686,37 @@ static int apci3xxx_dio_insn_config(struct comedi_device *dev, ...@@ -686,27 +686,37 @@ static int apci3xxx_dio_insn_config(struct comedi_device *dev,
unsigned int *data) unsigned int *data)
{ {
unsigned int chan = CR_CHAN(insn->chanspec); unsigned int chan = CR_CHAN(insn->chanspec);
unsigned int mask; unsigned int mask = 1 << chan;
int ret; unsigned int bits;
/* /*
* Port 0 (channels 0-7) are always inputs * Port 0 (channels 0-7) are always inputs
* Port 1 (channels 8-15) are always outputs * Port 1 (channels 8-15) are always outputs
* Port 2 (channels 16-23) are programmable i/o * Port 2 (channels 16-23) are programmable i/o
*
* Changing any channel in port 2 changes the entire port.
*/ */
if (chan < 16) { if (mask & 0xff0000)
if (data[0] != INSN_CONFIG_DIO_QUERY) bits = 0xff0000;
else
bits = 0;
switch (data[0]) {
case INSN_CONFIG_DIO_INPUT:
s->io_bits &= ~bits;
break;
case INSN_CONFIG_DIO_OUTPUT:
s->io_bits |= bits;
break;
case INSN_CONFIG_DIO_QUERY:
data[1] = (s->io_bits & bits) ? COMEDI_OUTPUT : COMEDI_INPUT;
return insn->n;
default:
return -EINVAL; return -EINVAL;
} else {
/* changing any channel in port 2 changes the entire port */
mask = 0xff0000;
} }
ret = comedi_dio_insn_config(dev, s, insn, data, mask);
if (ret)
return ret;
/* update port 2 configuration */ /* update port 2 configuration */
if (bits)
outl((s->io_bits >> 24) & 0xff, dev->iobase + 224); outl((s->io_bits >> 24) & 0xff, dev->iobase + 224);
return insn->n; return insn->n;
......
...@@ -180,29 +180,38 @@ static int pci1723_dio_insn_config(struct comedi_device *dev, ...@@ -180,29 +180,38 @@ static int pci1723_dio_insn_config(struct comedi_device *dev,
struct comedi_subdevice *s, struct comedi_subdevice *s,
struct comedi_insn *insn, unsigned int *data) struct comedi_insn *insn, unsigned int *data)
{ {
unsigned int chan = CR_CHAN(insn->chanspec);
unsigned int mask; unsigned int mask;
unsigned short mode; unsigned int bits;
int ret; unsigned short dio_mode;
if (chan < 8) mask = 1 << CR_CHAN(insn->chanspec);
mask = 0x00ff; if (mask & 0x00FF)
bits = 0x00FF;
else else
mask = 0xff00; bits = 0xFF00;
ret = comedi_dio_insn_config(dev, s, insn, data, mask); switch (data[0]) {
if (ret) case INSN_CONFIG_DIO_INPUT:
return ret; s->io_bits &= ~bits;
break;
case INSN_CONFIG_DIO_OUTPUT:
s->io_bits |= bits;
break;
case INSN_CONFIG_DIO_QUERY:
data[1] = (s->io_bits & bits) ? COMEDI_OUTPUT : COMEDI_INPUT;
return insn->n;
default:
return -EINVAL;
}
/* update hardware DIO mode */ /* update hardware DIO mode */
mode = 0x0000; /* assume output */ dio_mode = 0x0000; /* low byte output, high byte output */
if (!(s->io_bits & 0x00ff)) if ((s->io_bits & 0x00FF) == 0)
mode |= 0x0001; /* low byte input */ dio_mode |= 0x0001; /* low byte input */
if (!(s->io_bits & 0xff00)) if ((s->io_bits & 0xFF00) == 0)
mode |= 0x0002; /* high byte input */ dio_mode |= 0x0002; /* high byte input */
outw(mode, dev->iobase + PCI1723_DIGITAL_IO_PORT_SET); outw(dio_mode, dev->iobase + PCI1723_DIGITAL_IO_PORT_SET);
return 1;
return insn->n;
} }
/* /*
......
...@@ -976,26 +976,34 @@ static int dio200_subdev_8255_config(struct comedi_device *dev, ...@@ -976,26 +976,34 @@ static int dio200_subdev_8255_config(struct comedi_device *dev,
struct comedi_insn *insn, struct comedi_insn *insn,
unsigned int *data) unsigned int *data)
{ {
unsigned int chan = CR_CHAN(insn->chanspec);
unsigned int mask; unsigned int mask;
int ret; unsigned int bits;
if (chan < 8) mask = 1 << CR_CHAN(insn->chanspec);
mask = 0x0000ff; if (mask & 0x0000ff)
else if (chan < 16) bits = 0x0000ff;
mask = 0x00ff00; else if (mask & 0x00ff00)
else if (chan < 20) bits = 0x00ff00;
mask = 0x0f0000; else if (mask & 0x0f0000)
bits = 0x0f0000;
else else
mask = 0xf00000; bits = 0xf00000;
switch (data[0]) {
ret = comedi_dio_insn_config(dev, s, insn, data, mask); case INSN_CONFIG_DIO_INPUT:
if (ret) s->io_bits &= ~bits;
return ret; break;
case INSN_CONFIG_DIO_OUTPUT:
dio200_subdev_8255_set_dir(dev, s); s->io_bits |= bits;
break;
case INSN_CONFIG_DIO_QUERY:
data[1] = (s->io_bits & bits) ? COMEDI_OUTPUT : COMEDI_INPUT;
return insn->n; return insn->n;
break;
default:
return -EINVAL;
}
dio200_subdev_8255_set_dir(dev, s);
return 1;
} }
/* /*
......
...@@ -341,22 +341,33 @@ static int das16cs_dio_insn_bits(struct comedi_device *dev, ...@@ -341,22 +341,33 @@ static int das16cs_dio_insn_bits(struct comedi_device *dev,
static int das16cs_dio_insn_config(struct comedi_device *dev, static int das16cs_dio_insn_config(struct comedi_device *dev,
struct comedi_subdevice *s, struct comedi_subdevice *s,
struct comedi_insn *insn, struct comedi_insn *insn, unsigned int *data)
unsigned int *data)
{ {
struct das16cs_private *devpriv = dev->private; struct das16cs_private *devpriv = dev->private;
unsigned int chan = CR_CHAN(insn->chanspec); int chan = CR_CHAN(insn->chanspec);
unsigned int mask; int bits;
int ret;
if (chan < 4) if (chan < 4)
mask = 0x0f; bits = 0x0f;
else else
mask = 0xf0; bits = 0xf0;
ret = comedi_dio_insn_config(dev, s, insn, data, mask); switch (data[0]) {
if (ret) case INSN_CONFIG_DIO_OUTPUT:
return ret; s->io_bits |= bits;
break;
case INSN_CONFIG_DIO_INPUT:
s->io_bits &= bits;
break;
case INSN_CONFIG_DIO_QUERY:
data[1] =
(s->io_bits & (1 << chan)) ? COMEDI_OUTPUT : COMEDI_INPUT;
return insn->n;
break;
default:
return -EINVAL;
break;
}
devpriv->status2 &= ~0x00c0; devpriv->status2 &= ~0x00c0;
devpriv->status2 |= (s->io_bits & 0xf0) ? 0x0080 : 0; devpriv->status2 |= (s->io_bits & 0xf0) ? 0x0080 : 0;
......
...@@ -551,19 +551,32 @@ static int dt2801_dio_insn_bits(struct comedi_device *dev, ...@@ -551,19 +551,32 @@ static int dt2801_dio_insn_bits(struct comedi_device *dev,
static int dt2801_dio_insn_config(struct comedi_device *dev, static int dt2801_dio_insn_config(struct comedi_device *dev,
struct comedi_subdevice *s, struct comedi_subdevice *s,
struct comedi_insn *insn, struct comedi_insn *insn, unsigned int *data)
unsigned int *data)
{ {
int ret; int which = 0;
ret = comedi_dio_insn_config(dev, s, insn, data, 0xff);
if (ret)
return ret;
dt2801_writecmd(dev, s->io_bits ? DT_C_SET_DIGOUT : DT_C_SET_DIGIN); if (s == &dev->subdevices[3])
dt2801_writedata(dev, (s == &dev->subdevices[3]) ? 1 : 0); which = 1;
/* configure */
switch (data[0]) {
case INSN_CONFIG_DIO_OUTPUT:
s->io_bits = 0xff;
dt2801_writecmd(dev, DT_C_SET_DIGOUT);
break;
case INSN_CONFIG_DIO_INPUT:
s->io_bits = 0;
dt2801_writecmd(dev, DT_C_SET_DIGIN);
break;
case INSN_CONFIG_DIO_QUERY:
data[1] = s->io_bits ? COMEDI_OUTPUT : COMEDI_INPUT;
return insn->n; return insn->n;
default:
return -EINVAL;
}
dt2801_writedata(dev, which);
return 1;
} }
/* /*
......
...@@ -642,23 +642,32 @@ static void dt3k_dio_config(struct comedi_device *dev, int bits) ...@@ -642,23 +642,32 @@ static void dt3k_dio_config(struct comedi_device *dev, int bits)
static int dt3k_dio_insn_config(struct comedi_device *dev, static int dt3k_dio_insn_config(struct comedi_device *dev,
struct comedi_subdevice *s, struct comedi_subdevice *s,
struct comedi_insn *insn, struct comedi_insn *insn, unsigned int *data)
unsigned int *data)
{ {
unsigned int chan = CR_CHAN(insn->chanspec); int mask;
unsigned int mask;
int ret;
if (chan < 4)
mask = 0x0f;
else
mask = 0xf0;
ret = comedi_dio_insn_config(dev, s, insn, data, mask); mask = (CR_CHAN(insn->chanspec) < 4) ? 0x0f : 0xf0;
if (ret)
return ret;
dt3k_dio_config(dev, (s->io_bits & 0x01) | ((s->io_bits & 0x10) >> 3)); switch (data[0]) {
case INSN_CONFIG_DIO_OUTPUT:
s->io_bits |= mask;
break;
case INSN_CONFIG_DIO_INPUT:
s->io_bits &= ~mask;
break;
case INSN_CONFIG_DIO_QUERY:
data[1] =
(s->
io_bits & (1 << CR_CHAN(insn->chanspec))) ? COMEDI_OUTPUT :
COMEDI_INPUT;
return insn->n;
break;
default:
return -EINVAL;
break;
}
mask = (s->io_bits & 0x01) | ((s->io_bits & 0x10) >> 3);
dt3k_dio_config(dev, mask);
return insn->n; return insn->n;
} }
......
...@@ -224,26 +224,37 @@ struct hpdi_private { ...@@ -224,26 +224,37 @@ struct hpdi_private {
volatile uint32_t bits[24]; volatile uint32_t bits[24];
/* number of bytes at which to generate COMEDI_CB_BLOCK events */ /* number of bytes at which to generate COMEDI_CB_BLOCK events */
volatile unsigned int block_size; volatile unsigned int block_size;
unsigned dio_config_output:1;
}; };
static int dio_config_insn(struct comedi_device *dev, static int dio_config_insn(struct comedi_device *dev,
struct comedi_subdevice *s, struct comedi_subdevice *s, struct comedi_insn *insn,
struct comedi_insn *insn,
unsigned int *data) unsigned int *data)
{ {
int ret; struct hpdi_private *devpriv = dev->private;
switch (data[0]) { switch (data[0]) {
case INSN_CONFIG_DIO_OUTPUT:
devpriv->dio_config_output = 1;
return insn->n;
break;
case INSN_CONFIG_DIO_INPUT:
devpriv->dio_config_output = 0;
return insn->n;
break;
case INSN_CONFIG_DIO_QUERY:
data[1] =
devpriv->dio_config_output ? COMEDI_OUTPUT : COMEDI_INPUT;
return insn->n;
break;
case INSN_CONFIG_BLOCK_SIZE: case INSN_CONFIG_BLOCK_SIZE:
return dio_config_block_size(dev, data); return dio_config_block_size(dev, data);
break;
default: default:
ret = comedi_dio_insn_config(dev, s, insn, data, 0xffffffff);
if (ret)
return ret;
break; break;
} }
return insn->n; return -EINVAL;
} }
static void disable_plx_interrupts(struct comedi_device *dev) static void disable_plx_interrupts(struct comedi_device *dev)
...@@ -662,7 +673,9 @@ static int di_cmd_test(struct comedi_device *dev, struct comedi_subdevice *s, ...@@ -662,7 +673,9 @@ static int di_cmd_test(struct comedi_device *dev, struct comedi_subdevice *s,
static int hpdi_cmd_test(struct comedi_device *dev, struct comedi_subdevice *s, static int hpdi_cmd_test(struct comedi_device *dev, struct comedi_subdevice *s,
struct comedi_cmd *cmd) struct comedi_cmd *cmd)
{ {
if (s->io_bits) struct hpdi_private *devpriv = dev->private;
if (devpriv->dio_config_output)
return -EINVAL; return -EINVAL;
else else
return di_cmd_test(dev, s, cmd); return di_cmd_test(dev, s, cmd);
...@@ -733,7 +746,9 @@ static int di_cmd(struct comedi_device *dev, struct comedi_subdevice *s) ...@@ -733,7 +746,9 @@ static int di_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
static int hpdi_cmd(struct comedi_device *dev, struct comedi_subdevice *s) static int hpdi_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
{ {
if (s->io_bits) struct hpdi_private *devpriv = dev->private;
if (devpriv->dio_config_output)
return -EINVAL; return -EINVAL;
else else
return di_cmd(dev, s); return di_cmd(dev, s);
......
...@@ -350,22 +350,31 @@ static int ii20k_dio_insn_config(struct comedi_device *dev, ...@@ -350,22 +350,31 @@ static int ii20k_dio_insn_config(struct comedi_device *dev,
struct comedi_insn *insn, struct comedi_insn *insn,
unsigned int *data) unsigned int *data)
{ {
unsigned int chan = CR_CHAN(insn->chanspec); unsigned int mask = 1 << CR_CHAN(insn->chanspec);
unsigned int mask; unsigned int bits;
int ret;
if (chan < 8) if (mask & 0x000000ff)
mask = 0x000000ff; bits = 0x000000ff;
else if (chan < 16) else if (mask & 0x0000ff00)
mask = 0x0000ff00; bits = 0x0000ff00;
else if (chan < 24) else if (mask & 0x00ff0000)
mask = 0x00ff0000; bits = 0x00ff0000;
else else
mask = 0xff000000; bits = 0xff000000;
ret = comedi_dio_insn_config(dev, s, insn, data, mask); switch (data[0]) {
if (ret) case INSN_CONFIG_DIO_INPUT:
return ret; s->io_bits &= ~bits;
break;
case INSN_CONFIG_DIO_OUTPUT:
s->io_bits |= bits;
break;
case INSN_CONFIG_DIO_QUERY:
data[1] = (s->io_bits & bits) ? COMEDI_OUTPUT : COMEDI_INPUT;
return insn->n;
default:
return -EINVAL;
}
ii20k_dio_config(dev, s); ii20k_dio_config(dev, s);
......
...@@ -1358,57 +1358,98 @@ static int me4000_dio_insn_bits(struct comedi_device *dev, ...@@ -1358,57 +1358,98 @@ static int me4000_dio_insn_bits(struct comedi_device *dev,
static int me4000_dio_insn_config(struct comedi_device *dev, static int me4000_dio_insn_config(struct comedi_device *dev,
struct comedi_subdevice *s, struct comedi_subdevice *s,
struct comedi_insn *insn, struct comedi_insn *insn, unsigned int *data)
unsigned int *data)
{ {
unsigned int chan = CR_CHAN(insn->chanspec); unsigned long tmp;
unsigned int mask; int chan = CR_CHAN(insn->chanspec);
unsigned int tmp;
int ret; switch (data[0]) {
default:
if (chan < 8) return -EINVAL;
mask = 0x000000ff; case INSN_CONFIG_DIO_QUERY:
else if (chan < 16) data[1] =
mask = 0x0000ff00; (s->io_bits & (1 << chan)) ? COMEDI_OUTPUT : COMEDI_INPUT;
else if (chan < 24) return insn->n;
mask = 0x00ff0000; case INSN_CONFIG_DIO_INPUT:
else case INSN_CONFIG_DIO_OUTPUT:
mask = 0xff000000; break;
}
ret = comedi_dio_insn_config(dev, s, insn, data, mask); /*
if (ret) * The input or output configuration of each digital line is
return ret; * configured by a special insn_config instruction. chanspec
* contains the channel to be changed, and data[0] contains the
* value INSN_CONFIG_DIO_INPUT or INSN_CONFIG_DIO_OUTPUT.
* On the ME-4000 it is only possible to switch port wise (8 bit)
*/
tmp = inl(dev->iobase + ME4000_DIO_CTRL_REG); tmp = inl(dev->iobase + ME4000_DIO_CTRL_REG);
tmp &= ~(ME4000_DIO_CTRL_BIT_MODE_0 | ME4000_DIO_CTRL_BIT_MODE_1 |
ME4000_DIO_CTRL_BIT_MODE_2 | ME4000_DIO_CTRL_BIT_MODE_3 | if (data[0] == INSN_CONFIG_DIO_OUTPUT) {
ME4000_DIO_CTRL_BIT_MODE_4 | ME4000_DIO_CTRL_BIT_MODE_5 | if (chan < 8) {
ME4000_DIO_CTRL_BIT_MODE_6 | ME4000_DIO_CTRL_BIT_MODE_7); s->io_bits |= 0xFF;
if (s->io_bits & 0x000000ff) tmp &= ~(ME4000_DIO_CTRL_BIT_MODE_0 |
ME4000_DIO_CTRL_BIT_MODE_1);
tmp |= ME4000_DIO_CTRL_BIT_MODE_0; tmp |= ME4000_DIO_CTRL_BIT_MODE_0;
if (s->io_bits & 0x0000ff00) } else if (chan < 16) {
/*
* Chech for optoisolated ME-4000 version.
* If one the first port is a fixed output
* port and the second is a fixed input port.
*/
if (!inl(dev->iobase + ME4000_DIO_DIR_REG))
return -ENODEV;
s->io_bits |= 0xFF00;
tmp &= ~(ME4000_DIO_CTRL_BIT_MODE_2 |
ME4000_DIO_CTRL_BIT_MODE_3);
tmp |= ME4000_DIO_CTRL_BIT_MODE_2; tmp |= ME4000_DIO_CTRL_BIT_MODE_2;
if (s->io_bits & 0x00ff0000) } else if (chan < 24) {
s->io_bits |= 0xFF0000;
tmp &= ~(ME4000_DIO_CTRL_BIT_MODE_4 |
ME4000_DIO_CTRL_BIT_MODE_5);
tmp |= ME4000_DIO_CTRL_BIT_MODE_4; tmp |= ME4000_DIO_CTRL_BIT_MODE_4;
if (s->io_bits & 0xff000000) } else if (chan < 32) {
s->io_bits |= 0xFF000000;
tmp &= ~(ME4000_DIO_CTRL_BIT_MODE_6 |
ME4000_DIO_CTRL_BIT_MODE_7);
tmp |= ME4000_DIO_CTRL_BIT_MODE_6; tmp |= ME4000_DIO_CTRL_BIT_MODE_6;
} else {
return -EINVAL;
}
} else {
if (chan < 8) {
/* /*
* Check for optoisolated ME-4000 version. * Chech for optoisolated ME-4000 version.
* If one the first port is a fixed output * If one the first port is a fixed output
* port and the second is a fixed input port. * port and the second is a fixed input port.
*/ */
if (inl(dev->iobase + ME4000_DIO_DIR_REG)) { if (!inl(dev->iobase + ME4000_DIO_DIR_REG))
s->io_bits |= 0x000000ff; return -ENODEV;
s->io_bits &= ~0x0000ff00;
tmp |= ME4000_DIO_CTRL_BIT_MODE_0; s->io_bits &= ~0xFF;
tmp &= ~(ME4000_DIO_CTRL_BIT_MODE_0 |
ME4000_DIO_CTRL_BIT_MODE_1);
} else if (chan < 16) {
s->io_bits &= ~0xFF00;
tmp &= ~(ME4000_DIO_CTRL_BIT_MODE_2 | tmp &= ~(ME4000_DIO_CTRL_BIT_MODE_2 |
ME4000_DIO_CTRL_BIT_MODE_3); ME4000_DIO_CTRL_BIT_MODE_3);
} else if (chan < 24) {
s->io_bits &= ~0xFF0000;
tmp &= ~(ME4000_DIO_CTRL_BIT_MODE_4 |
ME4000_DIO_CTRL_BIT_MODE_5);
} else if (chan < 32) {
s->io_bits &= ~0xFF000000;
tmp &= ~(ME4000_DIO_CTRL_BIT_MODE_6 |
ME4000_DIO_CTRL_BIT_MODE_7);
} else {
return -EINVAL;
}
} }
outl(tmp, dev->iobase + ME4000_DIO_CTRL_REG); outl(tmp, dev->iobase + ME4000_DIO_CTRL_REG);
return insn->n; return 1;
} }
/*============================================================================= /*=============================================================================
......
...@@ -186,30 +186,38 @@ static int me_dio_insn_config(struct comedi_device *dev, ...@@ -186,30 +186,38 @@ static int me_dio_insn_config(struct comedi_device *dev,
struct comedi_insn *insn, struct comedi_insn *insn,
unsigned int *data) unsigned int *data)
{ {
struct me_private_data *devpriv = dev->private; struct me_private_data *dev_private = dev->private;
unsigned int chan = CR_CHAN(insn->chanspec); unsigned int mask = 1 << CR_CHAN(insn->chanspec);
unsigned int mask; unsigned int bits;
int ret; unsigned int port;
if (chan < 16)
mask = 0x0000ffff;
else
mask = 0xffff0000;
ret = comedi_dio_insn_config(dev, s, insn, data, mask); if (mask & 0x0000ffff) {
if (ret) bits = 0x0000ffff;
return ret; port = ENABLE_PORT_A;
} else {
bits = 0xffff0000;
port = ENABLE_PORT_B;
}
if (s->io_bits & 0x0000ffff) switch (data[0]) {
devpriv->control_2 |= ENABLE_PORT_A; case INSN_CONFIG_DIO_INPUT:
else s->io_bits &= ~bits;
devpriv->control_2 &= ~ENABLE_PORT_A; dev_private->control_2 &= ~port;
if (s->io_bits & 0xffff0000) break;
devpriv->control_2 |= ENABLE_PORT_B; case INSN_CONFIG_DIO_OUTPUT:
else s->io_bits |= bits;
devpriv->control_2 &= ~ENABLE_PORT_B; dev_private->control_2 |= port;
break;
case INSN_CONFIG_DIO_QUERY:
data[1] = (s->io_bits & bits) ? COMEDI_OUTPUT : COMEDI_INPUT;
return insn->n;
break;
default:
return -EINVAL;
}
writew(devpriv->control_2, devpriv->me_regbase + ME_CONTROL_2); /* Update the port configuration */
writew(dev_private->control_2, dev_private->me_regbase + ME_CONTROL_2);
return insn->n; return insn->n;
} }
......
...@@ -248,35 +248,42 @@ static int atao_dio_insn_bits(struct comedi_device *dev, ...@@ -248,35 +248,42 @@ static int atao_dio_insn_bits(struct comedi_device *dev,
static int atao_dio_insn_config(struct comedi_device *dev, static int atao_dio_insn_config(struct comedi_device *dev,
struct comedi_subdevice *s, struct comedi_subdevice *s,
struct comedi_insn *insn, struct comedi_insn *insn, unsigned int *data)
unsigned int *data)
{ {
struct atao_private *devpriv = dev->private; struct atao_private *devpriv = dev->private;
unsigned int chan = CR_CHAN(insn->chanspec); int chan = CR_CHAN(insn->chanspec);
unsigned int mask; unsigned int mask, bit;
int ret;
/* The input or output configuration of each digital line is
if (chan < 4) * configured by a special insn_config instruction. chanspec
mask = 0x0f; * contains the channel to be changed, and data[0] contains the
else * value COMEDI_INPUT or COMEDI_OUTPUT. */
mask = 0xf0;
mask = (chan < 4) ? 0x0f : 0xf0;
ret = comedi_dio_insn_config(dev, s, insn, data, mask); bit = (chan < 4) ? DOUTEN1 : DOUTEN2;
if (ret)
return ret; switch (data[0]) {
case INSN_CONFIG_DIO_OUTPUT:
if (s->io_bits & 0x0f) s->io_bits |= mask;
devpriv->cfg3 |= DOUTEN1; devpriv->cfg3 |= bit;
else break;
devpriv->cfg3 &= ~DOUTEN1; case INSN_CONFIG_DIO_INPUT:
if (s->io_bits & 0xf0) s->io_bits &= ~mask;
devpriv->cfg3 |= DOUTEN2; devpriv->cfg3 &= ~bit;
else break;
devpriv->cfg3 &= ~DOUTEN2; case INSN_CONFIG_DIO_QUERY:
data[1] =
(s->io_bits & (1 << chan)) ? COMEDI_OUTPUT : COMEDI_INPUT;
return insn->n;
break;
default:
return -EINVAL;
break;
}
outw(devpriv->cfg3, dev->iobase + ATAO_CFG3); outw(devpriv->cfg3, dev->iobase + ATAO_CFG3);
return insn->n; return 1;
} }
/* /*
......
...@@ -184,30 +184,39 @@ static void enable_chan(struct comedi_device *dev, struct comedi_subdevice *s, ...@@ -184,30 +184,39 @@ static void enable_chan(struct comedi_device *dev, struct comedi_subdevice *s,
/* overriding the 8255 insn config */ /* overriding the 8255 insn config */
static int subdev_3724_insn_config(struct comedi_device *dev, static int subdev_3724_insn_config(struct comedi_device *dev,
struct comedi_subdevice *s, struct comedi_subdevice *s,
struct comedi_insn *insn, struct comedi_insn *insn, unsigned int *data)
unsigned int *data)
{ {
unsigned int chan = CR_CHAN(insn->chanspec);
unsigned int mask; unsigned int mask;
int ret; unsigned int bits;
if (chan < 8) mask = 1 << CR_CHAN(insn->chanspec);
mask = 0x0000ff; if (mask & 0x0000ff)
else if (chan < 16) bits = 0x0000ff;
mask = 0x00ff00; else if (mask & 0x00ff00)
else if (chan < 20) bits = 0x00ff00;
mask = 0x0f0000; else if (mask & 0x0f0000)
bits = 0x0f0000;
else else
mask = 0xf00000; bits = 0xf00000;
ret = comedi_dio_insn_config(dev, s, insn, data, mask); switch (data[0]) {
if (ret) case INSN_CONFIG_DIO_INPUT:
return ret; s->io_bits &= ~bits;
break;
case INSN_CONFIG_DIO_OUTPUT:
s->io_bits |= bits;
break;
case INSN_CONFIG_DIO_QUERY:
data[1] = (s->io_bits & bits) ? COMEDI_OUTPUT : COMEDI_INPUT;
return insn->n;
break;
default:
return -EINVAL;
}
do_3724_config(dev, s, insn->chanspec); do_3724_config(dev, s, insn->chanspec);
enable_chan(dev, s, insn->chanspec); enable_chan(dev, s, insn->chanspec);
return 1;
return insn->n;
} }
static int pcm3724_attach(struct comedi_device *dev, static int pcm3724_attach(struct comedi_device *dev,
......
...@@ -515,35 +515,32 @@ static int s526_dio_insn_bits(struct comedi_device *dev, ...@@ -515,35 +515,32 @@ static int s526_dio_insn_bits(struct comedi_device *dev,
static int s526_dio_insn_config(struct comedi_device *dev, static int s526_dio_insn_config(struct comedi_device *dev,
struct comedi_subdevice *s, struct comedi_subdevice *s,
struct comedi_insn *insn, struct comedi_insn *insn, unsigned int *data)
unsigned int *data)
{ {
unsigned int chan = CR_CHAN(insn->chanspec); unsigned int chan = CR_CHAN(insn->chanspec);
unsigned int mask; int group, mask;
int ret;
if (chan < 4)
mask = 0x0f;
else
mask = 0xf0;
ret = comedi_dio_insn_config(dev, s, insn, data, mask);
if (ret)
return ret;
group = chan >> 2;
mask = 0xF << (group << 2);
switch (data[0]) {
case INSN_CONFIG_DIO_OUTPUT:
/* bit 10/11 set the group 1/2's mode */ /* bit 10/11 set the group 1/2's mode */
if (s->io_bits & 0x0f) s->state |= 1 << (group + 10);
s->state |= (1 << 10); s->io_bits |= mask;
else break;
s->state &= ~(1 << 10); case INSN_CONFIG_DIO_INPUT:
if (s->io_bits & 0xf0) s->state &= ~(1 << (group + 10)); /* 1 is output, 0 is input. */
s->state |= (1 << 11); s->io_bits &= ~mask;
else break;
s->state &= ~(1 << 11); case INSN_CONFIG_DIO_QUERY:
data[1] = (s->io_bits & mask) ? COMEDI_OUTPUT : COMEDI_INPUT;
return insn->n;
default:
return -EINVAL;
}
outw(s->state, dev->iobase + REG_DIO); outw(s->state, dev->iobase + REG_DIO);
return insn->n; return 1;
} }
static int s526_attach(struct comedi_device *dev, struct comedi_devconfig *it) static int s526_attach(struct comedi_device *dev, struct comedi_devconfig *it)
......
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