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;
-
- 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;
+ }
subdev_8255_do_config(dev, s);
- return insn->n;
+ return 1;
}
static int subdev_8255_cmdtest(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));
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)
- return -EINVAL;
- } else {
- /* changing any channel in port 2 changes the entire port */
- mask = 0xff0000;
+ 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;
}
- ret = comedi_dio_insn_config(dev, s, insn, data, mask);
- if (ret)
- return ret;
-
/* update port 2 configuration */
- outl((s->io_bits >> 24) & 0xff, dev->iobase + 224);
+ if (bits)
+ outl((s->io_bits >> 24) & 0xff, dev->iobase + 224);
return insn->n;
}
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;
}
/*
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;
+ }
dio200_subdev_8255_set_dir(dev, s);
-
- return insn->n;
+ return 1;
}
/*
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;
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;
+ int which = 0;
- ret = comedi_dio_insn_config(dev, s, insn, data, 0xff);
- if (ret)
- return ret;
+ if (s == &dev->subdevices[3])
+ which = 1;
- dt2801_writecmd(dev, s->io_bits ? DT_C_SET_DIGOUT : DT_C_SET_DIGIN);
- dt2801_writedata(dev, (s == &dev->subdevices[3]) ? 1 : 0);
+ /* 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 insn->n;
+ return 1;
}
/*
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;
-
- ret = comedi_dio_insn_config(dev, s, insn, data, mask);
- if (ret)
- return ret;
-
- dt3k_dio_config(dev, (s->io_bits & 0x01) | ((s->io_bits & 0x10) >> 3));
+ int mask;
+
+ mask = (CR_CHAN(insn->chanspec) < 4) ? 0x0f : 0xf0;
+
+ 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;
}
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)
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);
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);
struct comedi_insn *insn,
unsigned int *data)
{
- unsigned int chan = CR_CHAN(insn->chanspec);
- unsigned int mask;
- int ret;
-
- if (chan < 8)
- mask = 0x000000ff;
- else if (chan < 16)
- mask = 0x0000ff00;
- else if (chan < 24)
- mask = 0x00ff0000;
+ unsigned int mask = 1 << CR_CHAN(insn->chanspec);
+ unsigned int bits;
+
+ 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);
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;
+ unsigned long tmp;
+ int chan = CR_CHAN(insn->chanspec);
- if (chan < 8)
- mask = 0x000000ff;
- else if (chan < 16)
- mask = 0x0000ff00;
- else if (chan < 24)
- mask = 0x00ff0000;
- else
- mask = 0xff000000;
+ 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)
- tmp |= ME4000_DIO_CTRL_BIT_MODE_0;
- if (s->io_bits & 0x0000ff00)
- tmp |= ME4000_DIO_CTRL_BIT_MODE_2;
- if (s->io_bits & 0x00ff0000)
- tmp |= ME4000_DIO_CTRL_BIT_MODE_4;
- if (s->io_bits & 0xff000000)
- tmp |= ME4000_DIO_CTRL_BIT_MODE_6;
- /*
- * Check 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;
- tmp &= ~(ME4000_DIO_CTRL_BIT_MODE_2 |
- ME4000_DIO_CTRL_BIT_MODE_3);
+ 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;
+ } 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;
+ } 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;
+ } 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) {
+ /*
+ * 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 &= ~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;
}
/*=============================================================================
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;
}
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;
}
/*
/* 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,
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;
-
- /* 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);
+ 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 */
+ 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)