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,
static int subdev_8255_insn_config(struct comedi_device *dev,
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;
int ret;
unsigned int bits;
if (chan < 8)
mask = 0x0000ff;
else if (chan < 16)
mask = 0x00ff00;
else if (chan < 20)
mask = 0x0f0000;
mask = 1 << CR_CHAN(insn->chanspec);
if (mask & 0x0000ff)
bits = 0x0000ff;
else if (mask & 0x00ff00)
bits = 0x00ff00;
else if (mask & 0x0f0000)
bits = 0x0f0000;
else
mask = 0xf00000;
bits = 0xf00000;
ret = comedi_dio_insn_config(dev, s, insn, data, mask);
if (ret)
return ret;
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;
break;
default:
return -EINVAL;
}
subdev_8255_do_config(dev, s);
return insn->n;
return 1;
}
static int subdev_8255_cmdtest(struct comedi_device *dev,
......
......@@ -60,22 +60,36 @@ static int apci16xx_insn_config(struct comedi_device *dev,
struct comedi_insn *insn,
unsigned int *data)
{
unsigned int chan = CR_CHAN(insn->chanspec);
unsigned int mask;
int ret;
unsigned int chan_mask = 1 << CR_CHAN(insn->chanspec);
unsigned int bits;
if (chan < 8)
mask = 0x000000ff;
else if (chan < 16)
mask = 0x0000ff00;
else if (chan < 24)
mask = 0x00ff0000;
/*
* Each 8-bit "port" is configurable as either input or
* output. Changing the configuration of any channel in
* a port changes the entire port.
*/
if (chan_mask & 0x000000ff)
bits = 0x000000ff;
else if (chan_mask & 0x0000ff00)
bits = 0x0000ff00;
else if (chan_mask & 0x00ff0000)
bits = 0x00ff0000;
else
mask = 0xff000000;
ret = comedi_dio_insn_config(dev, s, insn, data, mask);
if (ret)
return ret;
bits = 0xff000000;
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_INPUT : COMEDI_OUTPUT;
return insn->n;
default:
return -EINVAL;
}
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,
unsigned int *data)
{
unsigned int chan = CR_CHAN(insn->chanspec);
unsigned int mask;
int ret;
unsigned int mask = 1 << chan;
unsigned int bits;
/*
* Port 0 (channels 0-7) are always inputs
* Port 1 (channels 8-15) are always outputs
* Port 2 (channels 16-23) are programmable i/o
*
* Changing any channel in port 2 changes the entire port.
*/
if (chan < 16) {
if (data[0] != INSN_CONFIG_DIO_QUERY)
if (mask & 0xff0000)
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;
} 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 */
if (bits)
outl((s->io_bits >> 24) & 0xff, dev->iobase + 224);
return insn->n;
......
......@@ -180,29 +180,38 @@ static int pci1723_dio_insn_config(struct comedi_device *dev,
struct comedi_subdevice *s,
struct comedi_insn *insn, unsigned int *data)
{
unsigned int chan = CR_CHAN(insn->chanspec);
unsigned int mask;
unsigned short mode;
int ret;
unsigned int bits;
unsigned short dio_mode;
if (chan < 8)
mask = 0x00ff;
mask = 1 << CR_CHAN(insn->chanspec);
if (mask & 0x00FF)
bits = 0x00FF;
else
mask = 0xff00;
bits = 0xFF00;
ret = comedi_dio_insn_config(dev, s, insn, data, mask);
if (ret)
return ret;
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;
}
/* update hardware DIO mode */
mode = 0x0000; /* assume output */
if (!(s->io_bits & 0x00ff))
mode |= 0x0001; /* low byte input */
if (!(s->io_bits & 0xff00))
mode |= 0x0002; /* high byte input */
outw(mode, dev->iobase + PCI1723_DIGITAL_IO_PORT_SET);
return insn->n;
dio_mode = 0x0000; /* low byte output, high byte output */
if ((s->io_bits & 0x00FF) == 0)
dio_mode |= 0x0001; /* low byte input */
if ((s->io_bits & 0xFF00) == 0)
dio_mode |= 0x0002; /* high byte input */
outw(dio_mode, dev->iobase + PCI1723_DIGITAL_IO_PORT_SET);
return 1;
}
/*
......
......@@ -976,26 +976,34 @@ static int dio200_subdev_8255_config(struct comedi_device *dev,
struct comedi_insn *insn,
unsigned int *data)
{
unsigned int chan = CR_CHAN(insn->chanspec);
unsigned int mask;
int ret;
if (chan < 8)
mask = 0x0000ff;
else if (chan < 16)
mask = 0x00ff00;
else if (chan < 20)
mask = 0x0f0000;
unsigned int bits;
mask = 1 << CR_CHAN(insn->chanspec);
if (mask & 0x0000ff)
bits = 0x0000ff;
else if (mask & 0x00ff00)
bits = 0x00ff00;
else if (mask & 0x0f0000)
bits = 0x0f0000;
else
mask = 0xf00000;
ret = comedi_dio_insn_config(dev, s, insn, data, mask);
if (ret)
return ret;
dio200_subdev_8255_set_dir(dev, s);
bits = 0xf00000;
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;
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,
static int das16cs_dio_insn_config(struct comedi_device *dev,
struct comedi_subdevice *s,
struct comedi_insn *insn,
unsigned int *data)
struct comedi_insn *insn, unsigned int *data)
{
struct das16cs_private *devpriv = dev->private;
unsigned int chan = CR_CHAN(insn->chanspec);
unsigned int mask;
int ret;
int chan = CR_CHAN(insn->chanspec);
int bits;
if (chan < 4)
mask = 0x0f;
bits = 0x0f;
else
mask = 0xf0;
bits = 0xf0;
ret = comedi_dio_insn_config(dev, s, insn, data, mask);
if (ret)
return ret;
switch (data[0]) {
case INSN_CONFIG_DIO_OUTPUT:
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 |= (s->io_bits & 0xf0) ? 0x0080 : 0;
......
......@@ -551,19 +551,32 @@ static int dt2801_dio_insn_bits(struct comedi_device *dev,
static int dt2801_dio_insn_config(struct comedi_device *dev,
struct comedi_subdevice *s,
struct comedi_insn *insn,
unsigned int *data)
struct comedi_insn *insn, unsigned int *data)
{
int ret;
ret = comedi_dio_insn_config(dev, s, insn, data, 0xff);
if (ret)
return ret;
int which = 0;
dt2801_writecmd(dev, s->io_bits ? DT_C_SET_DIGOUT : DT_C_SET_DIGIN);
dt2801_writedata(dev, (s == &dev->subdevices[3]) ? 1 : 0);
if (s == &dev->subdevices[3])
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;
default:
return -EINVAL;
}
dt2801_writedata(dev, which);
return 1;
}
/*
......
......@@ -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,
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;
int ret;
if (chan < 4)
mask = 0x0f;
else
mask = 0xf0;
int mask;
ret = comedi_dio_insn_config(dev, s, insn, data, mask);
if (ret)
return ret;
mask = (CR_CHAN(insn->chanspec) < 4) ? 0x0f : 0xf0;
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;
}
......
......@@ -224,26 +224,37 @@ struct hpdi_private {
volatile uint32_t bits[24];
/* number of bytes at which to generate COMEDI_CB_BLOCK events */
volatile unsigned int block_size;
unsigned dio_config_output:1;
};
static int dio_config_insn(struct comedi_device *dev,
struct comedi_subdevice *s,
struct comedi_insn *insn,
struct comedi_subdevice *s, struct comedi_insn *insn,
unsigned int *data)
{
int ret;
struct hpdi_private *devpriv = dev->private;
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:
return dio_config_block_size(dev, data);
break;
default:
ret = comedi_dio_insn_config(dev, s, insn, data, 0xffffffff);
if (ret)
return ret;
break;
}
return insn->n;
return -EINVAL;
}
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,
static int hpdi_cmd_test(struct comedi_device *dev, struct comedi_subdevice *s,
struct comedi_cmd *cmd)
{
if (s->io_bits)
struct hpdi_private *devpriv = dev->private;
if (devpriv->dio_config_output)
return -EINVAL;
else
return di_cmd_test(dev, s, cmd);
......@@ -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)
{
if (s->io_bits)
struct hpdi_private *devpriv = dev->private;
if (devpriv->dio_config_output)
return -EINVAL;
else
return di_cmd(dev, s);
......
......@@ -350,22 +350,31 @@ static int ii20k_dio_insn_config(struct comedi_device *dev,
struct comedi_insn *insn,
unsigned int *data)
{
unsigned int chan = CR_CHAN(insn->chanspec);
unsigned int mask;
int ret;
unsigned int mask = 1 << CR_CHAN(insn->chanspec);
unsigned int bits;
if (chan < 8)
mask = 0x000000ff;
else if (chan < 16)
mask = 0x0000ff00;
else if (chan < 24)
mask = 0x00ff0000;
if (mask & 0x000000ff)
bits = 0x000000ff;
else if (mask & 0x0000ff00)
bits = 0x0000ff00;
else if (mask & 0x00ff0000)
bits = 0x00ff0000;
else
mask = 0xff000000;
bits = 0xff000000;
ret = comedi_dio_insn_config(dev, s, insn, data, mask);
if (ret)
return ret;
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;
}
ii20k_dio_config(dev, s);
......
......@@ -1358,57 +1358,98 @@ static int me4000_dio_insn_bits(struct comedi_device *dev,
static int me4000_dio_insn_config(struct comedi_device *dev,
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 tmp;
int ret;
if (chan < 8)
mask = 0x000000ff;
else if (chan < 16)
mask = 0x0000ff00;
else if (chan < 24)
mask = 0x00ff0000;
else
mask = 0xff000000;
unsigned long tmp;
int chan = CR_CHAN(insn->chanspec);
switch (data[0]) {
default:
return -EINVAL;
case INSN_CONFIG_DIO_QUERY:
data[1] =
(s->io_bits & (1 << chan)) ? COMEDI_OUTPUT : COMEDI_INPUT;
return insn->n;
case INSN_CONFIG_DIO_INPUT:
case INSN_CONFIG_DIO_OUTPUT:
break;
}
ret = comedi_dio_insn_config(dev, s, insn, data, mask);
if (ret)
return ret;
/*
* The input or output configuration of each digital line is
* 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 &= ~(ME4000_DIO_CTRL_BIT_MODE_0 | ME4000_DIO_CTRL_BIT_MODE_1 |
ME4000_DIO_CTRL_BIT_MODE_2 | ME4000_DIO_CTRL_BIT_MODE_3 |
ME4000_DIO_CTRL_BIT_MODE_4 | ME4000_DIO_CTRL_BIT_MODE_5 |
ME4000_DIO_CTRL_BIT_MODE_6 | ME4000_DIO_CTRL_BIT_MODE_7);
if (s->io_bits & 0x000000ff)
if (data[0] == INSN_CONFIG_DIO_OUTPUT) {
if (chan < 8) {
s->io_bits |= 0xFF;
tmp &= ~(ME4000_DIO_CTRL_BIT_MODE_0 |
ME4000_DIO_CTRL_BIT_MODE_1);
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;
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;
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;
} 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
* port and the second is a fixed input port.
*/
if (inl(dev->iobase + ME4000_DIO_DIR_REG)) {
s->io_bits |= 0x000000ff;
s->io_bits &= ~0x0000ff00;
tmp |= ME4000_DIO_CTRL_BIT_MODE_0;
if (!inl(dev->iobase + ME4000_DIO_DIR_REG))
return -ENODEV;
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 |
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);
return insn->n;
return 1;
}
/*=============================================================================
......
......@@ -186,30 +186,38 @@ static int me_dio_insn_config(struct comedi_device *dev,
struct comedi_insn *insn,
unsigned int *data)
{
struct me_private_data *devpriv = dev->private;
unsigned int chan = CR_CHAN(insn->chanspec);
unsigned int mask;
int ret;
if (chan < 16)
mask = 0x0000ffff;
else
mask = 0xffff0000;
struct me_private_data *dev_private = dev->private;
unsigned int mask = 1 << CR_CHAN(insn->chanspec);
unsigned int bits;
unsigned int port;
ret = comedi_dio_insn_config(dev, s, insn, data, mask);
if (ret)
return ret;
if (mask & 0x0000ffff) {
bits = 0x0000ffff;
port = ENABLE_PORT_A;
} else {
bits = 0xffff0000;
port = ENABLE_PORT_B;
}
if (s->io_bits & 0x0000ffff)
devpriv->control_2 |= ENABLE_PORT_A;
else
devpriv->control_2 &= ~ENABLE_PORT_A;
if (s->io_bits & 0xffff0000)
devpriv->control_2 |= ENABLE_PORT_B;
else
devpriv->control_2 &= ~ENABLE_PORT_B;
switch (data[0]) {
case INSN_CONFIG_DIO_INPUT:
s->io_bits &= ~bits;
dev_private->control_2 &= ~port;
break;
case INSN_CONFIG_DIO_OUTPUT:
s->io_bits |= bits;
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;
}
......
......@@ -248,35 +248,42 @@ static int atao_dio_insn_bits(struct comedi_device *dev,
static int atao_dio_insn_config(struct comedi_device *dev,
struct comedi_subdevice *s,
struct comedi_insn *insn,
unsigned int *data)
struct comedi_insn *insn, unsigned int *data)
{
struct atao_private *devpriv = dev->private;
unsigned int chan = CR_CHAN(insn->chanspec);
unsigned int 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;
if (s->io_bits & 0x0f)
devpriv->cfg3 |= DOUTEN1;
else
devpriv->cfg3 &= ~DOUTEN1;
if (s->io_bits & 0xf0)
devpriv->cfg3 |= DOUTEN2;
else
devpriv->cfg3 &= ~DOUTEN2;
int chan = CR_CHAN(insn->chanspec);
unsigned int mask, bit;
/* The input or output configuration of each digital line is
* configured by a special insn_config instruction. chanspec
* contains the channel to be changed, and data[0] contains the
* value COMEDI_INPUT or COMEDI_OUTPUT. */
mask = (chan < 4) ? 0x0f : 0xf0;
bit = (chan < 4) ? DOUTEN1 : DOUTEN2;
switch (data[0]) {
case INSN_CONFIG_DIO_OUTPUT:
s->io_bits |= mask;
devpriv->cfg3 |= bit;
break;
case INSN_CONFIG_DIO_INPUT:
s->io_bits &= ~mask;
devpriv->cfg3 &= ~bit;
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;
}
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,
/* overriding the 8255 insn config */
static int subdev_3724_insn_config(struct comedi_device *dev,
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;
int ret;
if (chan < 8)
mask = 0x0000ff;
else if (chan < 16)
mask = 0x00ff00;
else if (chan < 20)
mask = 0x0f0000;
unsigned int bits;
mask = 1 << CR_CHAN(insn->chanspec);
if (mask & 0x0000ff)
bits = 0x0000ff;
else if (mask & 0x00ff00)
bits = 0x00ff00;
else if (mask & 0x0f0000)
bits = 0x0f0000;
else
mask = 0xf00000;
ret = comedi_dio_insn_config(dev, s, insn, data, mask);
if (ret)
return ret;
bits = 0xf00000;
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;
break;
default:
return -EINVAL;
}
do_3724_config(dev, s, insn->chanspec);
enable_chan(dev, s, insn->chanspec);
return insn->n;
return 1;
}
static int pcm3724_attach(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,
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;
int ret;
if (chan < 4)
mask = 0x0f;
else
mask = 0xf0;
ret = comedi_dio_insn_config(dev, s, insn, data, mask);
if (ret)
return ret;
int group, mask;
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 */
if (s->io_bits & 0x0f)
s->state |= (1 << 10);
else
s->state &= ~(1 << 10);
if (s->io_bits & 0xf0)
s->state |= (1 << 11);
else
s->state &= ~(1 << 11);
s->state |= 1 << (group + 10);
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(s->state, dev->iobase + REG_DIO);
return insn->n;
return 1;
}
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