staging: comedi: drivers: use comedi_dio_insn_config() for simple cases
Convert the drivers with simple, per channel programmable i/o, to use the comedi_dio_insn_config() helper function. All of these pass a 'mask' of '0' to comedi_dio_insn_config() this causes the per channel mask to be used to configure the i/o direction. 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:
parent
f3508b2294
commit
ddf62f2c7b
@ -3510,31 +3510,20 @@ static int do_wbits(struct comedi_device *dev, struct comedi_subdevice *s,
|
|||||||
|
|
||||||
static int dio_60xx_config_insn(struct comedi_device *dev,
|
static int dio_60xx_config_insn(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)
|
||||||
{
|
{
|
||||||
struct pcidas64_private *devpriv = dev->private;
|
struct pcidas64_private *devpriv = dev->private;
|
||||||
unsigned int mask;
|
int ret;
|
||||||
|
|
||||||
mask = 1 << CR_CHAN(insn->chanspec);
|
ret = comedi_dio_insn_config(dev, s, insn, data, 0);
|
||||||
|
if (ret)
|
||||||
switch (data[0]) {
|
return ret;
|
||||||
case INSN_CONFIG_DIO_INPUT:
|
|
||||||
s->io_bits &= ~mask;
|
|
||||||
break;
|
|
||||||
case INSN_CONFIG_DIO_OUTPUT:
|
|
||||||
s->io_bits |= mask;
|
|
||||||
break;
|
|
||||||
case INSN_CONFIG_DIO_QUERY:
|
|
||||||
data[1] = (s->io_bits & mask) ? COMEDI_OUTPUT : COMEDI_INPUT;
|
|
||||||
return 2;
|
|
||||||
default:
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
writeb(s->io_bits,
|
writeb(s->io_bits,
|
||||||
devpriv->dio_counter_iobase + DIO_DIRECTION_60XX_REG);
|
devpriv->dio_counter_iobase + DIO_DIRECTION_60XX_REG);
|
||||||
|
|
||||||
return 1;
|
return insn->n;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int dio_60xx_wbits(struct comedi_device *dev, struct comedi_subdevice *s,
|
static int dio_60xx_wbits(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||||
|
@ -158,27 +158,16 @@ static int ni_670x_dio_insn_bits(struct comedi_device *dev,
|
|||||||
|
|
||||||
static int ni_670x_dio_insn_config(struct comedi_device *dev,
|
static int ni_670x_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)
|
||||||
{
|
{
|
||||||
struct ni_670x_private *devpriv = dev->private;
|
struct ni_670x_private *devpriv = dev->private;
|
||||||
int chan = CR_CHAN(insn->chanspec);
|
int ret;
|
||||||
|
|
||||||
|
ret = comedi_dio_insn_config(dev, s, insn, data, 0);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
switch (data[0]) {
|
|
||||||
case INSN_CONFIG_DIO_OUTPUT:
|
|
||||||
s->io_bits |= 1 << chan;
|
|
||||||
break;
|
|
||||||
case INSN_CONFIG_DIO_INPUT:
|
|
||||||
s->io_bits &= ~(1 << chan);
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
writel(s->io_bits, devpriv->mite->daq_io_addr + DIO_PORT0_DIR_OFFSET);
|
writel(s->io_bits, devpriv->mite->daq_io_addr + DIO_PORT0_DIR_OFFSET);
|
||||||
|
|
||||||
return insn->n;
|
return insn->n;
|
||||||
|
@ -90,21 +90,17 @@ static int daq700_dio_insn_bits(struct comedi_device *dev,
|
|||||||
|
|
||||||
static int daq700_dio_insn_config(struct comedi_device *dev,
|
static int daq700_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 = 1 << CR_CHAN(insn->chanspec);
|
int ret;
|
||||||
|
|
||||||
switch (data[0]) {
|
ret = comedi_dio_insn_config(dev, s, insn, data, 0);
|
||||||
case INSN_CONFIG_DIO_INPUT:
|
if (ret)
|
||||||
break;
|
return ret;
|
||||||
case INSN_CONFIG_DIO_OUTPUT:
|
|
||||||
break;
|
/* The DIO channels are not configurable, fix the io_bits */
|
||||||
case INSN_CONFIG_DIO_QUERY:
|
s->io_bits = 0x00ff;
|
||||||
data[1] = (s->io_bits & chan) ? COMEDI_OUTPUT : COMEDI_INPUT;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return insn->n;
|
return insn->n;
|
||||||
}
|
}
|
||||||
|
@ -3528,37 +3528,21 @@ static int ni_ao_reset(struct comedi_device *dev, struct comedi_subdevice *s)
|
|||||||
|
|
||||||
static int ni_dio_insn_config(struct comedi_device *dev,
|
static int ni_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)
|
||||||
{
|
{
|
||||||
struct ni_private *devpriv = dev->private;
|
struct ni_private *devpriv = dev->private;
|
||||||
|
int ret;
|
||||||
|
|
||||||
#ifdef DEBUG_DIO
|
ret = comedi_dio_insn_config(dev, s, insn, data, 0);
|
||||||
printk("ni_dio_insn_config() chan=%d io=%d\n",
|
if (ret)
|
||||||
CR_CHAN(insn->chanspec), data[0]);
|
return ret;
|
||||||
#endif
|
|
||||||
switch (data[0]) {
|
|
||||||
case INSN_CONFIG_DIO_OUTPUT:
|
|
||||||
s->io_bits |= 1 << CR_CHAN(insn->chanspec);
|
|
||||||
break;
|
|
||||||
case INSN_CONFIG_DIO_INPUT:
|
|
||||||
s->io_bits &= ~(1 << CR_CHAN(insn->chanspec));
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
devpriv->dio_control &= ~DIO_Pins_Dir_Mask;
|
devpriv->dio_control &= ~DIO_Pins_Dir_Mask;
|
||||||
devpriv->dio_control |= DIO_Pins_Dir(s->io_bits);
|
devpriv->dio_control |= DIO_Pins_Dir(s->io_bits);
|
||||||
devpriv->stc_writew(dev, devpriv->dio_control, DIO_Control_Register);
|
devpriv->stc_writew(dev, devpriv->dio_control, DIO_Control_Register);
|
||||||
|
|
||||||
return 1;
|
return insn->n;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ni_dio_insn_bits(struct comedi_device *dev,
|
static int ni_dio_insn_bits(struct comedi_device *dev,
|
||||||
@ -3596,32 +3580,15 @@ static int ni_m_series_dio_insn_config(struct comedi_device *dev,
|
|||||||
unsigned int *data)
|
unsigned int *data)
|
||||||
{
|
{
|
||||||
struct ni_private *devpriv __maybe_unused = dev->private;
|
struct ni_private *devpriv __maybe_unused = dev->private;
|
||||||
|
int ret;
|
||||||
|
|
||||||
#ifdef DEBUG_DIO
|
ret = comedi_dio_insn_config(dev, s, insn, data, 0);
|
||||||
printk("ni_m_series_dio_insn_config() chan=%d io=%d\n",
|
if (ret)
|
||||||
CR_CHAN(insn->chanspec), data[0]);
|
return ret;
|
||||||
#endif
|
|
||||||
switch (data[0]) {
|
|
||||||
case INSN_CONFIG_DIO_OUTPUT:
|
|
||||||
s->io_bits |= 1 << CR_CHAN(insn->chanspec);
|
|
||||||
break;
|
|
||||||
case INSN_CONFIG_DIO_INPUT:
|
|
||||||
s->io_bits &= ~(1 << CR_CHAN(insn->chanspec));
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
ni_writel(s->io_bits, M_Offset_DIO_Direction);
|
ni_writel(s->io_bits, M_Offset_DIO_Direction);
|
||||||
|
|
||||||
return 1;
|
return insn->n;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ni_m_series_dio_insn_bits(struct comedi_device *dev,
|
static int ni_m_series_dio_insn_bits(struct comedi_device *dev,
|
||||||
|
@ -640,32 +640,19 @@ static void debug_int(struct comedi_device *dev)
|
|||||||
|
|
||||||
static int ni_pcidio_insn_config(struct comedi_device *dev,
|
static int ni_pcidio_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)
|
||||||
{
|
{
|
||||||
struct nidio96_private *devpriv = dev->private;
|
struct nidio96_private *devpriv = dev->private;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = comedi_dio_insn_config(dev, s, insn, data, 0);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
if (insn->n != 1)
|
|
||||||
return -EINVAL;
|
|
||||||
switch (data[0]) {
|
|
||||||
case INSN_CONFIG_DIO_OUTPUT:
|
|
||||||
s->io_bits |= 1 << CR_CHAN(insn->chanspec);
|
|
||||||
break;
|
|
||||||
case INSN_CONFIG_DIO_INPUT:
|
|
||||||
s->io_bits &= ~(1 << CR_CHAN(insn->chanspec));
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
writel(s->io_bits, devpriv->mite->daq_io_addr + Port_Pin_Directions(0));
|
writel(s->io_bits, devpriv->mite->daq_io_addr + Port_Pin_Directions(0));
|
||||||
|
|
||||||
return 1;
|
return insn->n;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ni_pcidio_insn_bits(struct comedi_device *dev,
|
static int ni_pcidio_insn_bits(struct comedi_device *dev,
|
||||||
|
@ -310,68 +310,27 @@ static int pcmmio_dio_insn_bits(struct comedi_device *dev,
|
|||||||
return insn->n;
|
return insn->n;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 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. */
|
|
||||||
static int pcmmio_dio_insn_config(struct comedi_device *dev,
|
static int pcmmio_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)
|
||||||
{
|
{
|
||||||
int chan = CR_CHAN(insn->chanspec), byte_no = chan / 8, bit_no =
|
unsigned int chan = CR_CHAN(insn->chanspec);
|
||||||
chan % 8;
|
int byte_no = chan / 8;
|
||||||
unsigned long ioaddr;
|
int bit_no = chan % 8;
|
||||||
unsigned char byte;
|
int ret;
|
||||||
|
|
||||||
/* Compute ioaddr for this channel */
|
ret = comedi_dio_insn_config(dev, s, insn, data, 0);
|
||||||
ioaddr = subpriv->iobases[byte_no];
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
/* NOTE:
|
if (data[0] == INSN_CONFIG_DIO_INPUT) {
|
||||||
writing a 0 an IO channel's bit sets the channel to INPUT
|
unsigned long ioaddr = subpriv->iobases[byte_no];
|
||||||
and pulls the line high as well
|
unsigned char val;
|
||||||
|
|
||||||
writing a 1 to an IO channel's bit pulls the line low
|
val = inb(ioaddr);
|
||||||
|
val &= ~(1 << bit_no);
|
||||||
All channels are implicitly always in OUTPUT mode -- but when
|
outb(val, ioaddr);
|
||||||
they are high they can be considered to be in INPUT mode..
|
|
||||||
|
|
||||||
Thus, we only force channels low if the config request was INPUT,
|
|
||||||
otherwise we do nothing to the hardware. */
|
|
||||||
|
|
||||||
switch (data[0]) {
|
|
||||||
case INSN_CONFIG_DIO_OUTPUT:
|
|
||||||
/* save to io_bits -- don't actually do anything since
|
|
||||||
all input channels are also output channels... */
|
|
||||||
s->io_bits |= 1 << chan;
|
|
||||||
break;
|
|
||||||
case INSN_CONFIG_DIO_INPUT:
|
|
||||||
/* write a 0 to the actual register representing the channel
|
|
||||||
to set it to 'input'. 0 means "float high". */
|
|
||||||
byte = inb(ioaddr);
|
|
||||||
byte &= ~(1 << bit_no);
|
|
||||||
/**< set input channel to '0' */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* write out byte -- this is the only time we actually affect
|
|
||||||
* the hardware as all channels are implicitly output
|
|
||||||
* -- but input channels are set to float-high
|
|
||||||
*/
|
|
||||||
outb(byte, ioaddr);
|
|
||||||
|
|
||||||
/* save to io_bits */
|
|
||||||
s->io_bits &= ~(1 << chan);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case INSN_CONFIG_DIO_QUERY:
|
|
||||||
/* retrieve from shadow register */
|
|
||||||
data[1] =
|
|
||||||
(s->io_bits & (1 << chan)) ? COMEDI_OUTPUT : COMEDI_INPUT;
|
|
||||||
return insn->n;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
return -EINVAL;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return insn->n;
|
return insn->n;
|
||||||
|
@ -233,27 +233,19 @@ static int pcmuio_dio_insn_bits(struct comedi_device *dev,
|
|||||||
|
|
||||||
static int pcmuio_dio_insn_config(struct comedi_device *dev,
|
static int pcmuio_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_mask = 1 << CR_CHAN(insn->chanspec);
|
|
||||||
int asic = s->index / 2;
|
int asic = s->index / 2;
|
||||||
int port = (s->index % 2) ? 3 : 0;
|
int port = (s->index % 2) ? 3 : 0;
|
||||||
|
int ret;
|
||||||
|
|
||||||
switch (data[0]) {
|
ret = comedi_dio_insn_config(dev, s, insn, data, 0);
|
||||||
case INSN_CONFIG_DIO_OUTPUT:
|
if (ret)
|
||||||
s->io_bits |= chan_mask;
|
return ret;
|
||||||
break;
|
|
||||||
case INSN_CONFIG_DIO_INPUT:
|
if (data[0] == INSN_CONFIG_DIO_INPUT)
|
||||||
s->io_bits &= ~chan_mask;
|
|
||||||
pcmuio_write(dev, s->io_bits, asic, 0, port);
|
pcmuio_write(dev, s->io_bits, asic, 0, port);
|
||||||
break;
|
|
||||||
case INSN_CONFIG_DIO_QUERY:
|
|
||||||
data[1] = (s->io_bits & chan_mask) ? COMEDI_OUTPUT : COMEDI_INPUT;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return -EINVAL;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return insn->n;
|
return insn->n;
|
||||||
}
|
}
|
||||||
|
@ -1238,23 +1238,11 @@ static int rtd_dio_insn_config(struct comedi_device *dev,
|
|||||||
unsigned int *data)
|
unsigned int *data)
|
||||||
{
|
{
|
||||||
struct rtd_private *devpriv = dev->private;
|
struct rtd_private *devpriv = dev->private;
|
||||||
unsigned int chan = CR_CHAN(insn->chanspec);
|
int ret;
|
||||||
unsigned int mask = 1 << chan;
|
|
||||||
|
|
||||||
switch (data[0]) {
|
ret = comedi_dio_insn_config(dev, s, insn, data, 0);
|
||||||
case INSN_CONFIG_DIO_OUTPUT:
|
if (ret)
|
||||||
s->io_bits |= mask;
|
return ret;
|
||||||
break;
|
|
||||||
case INSN_CONFIG_DIO_INPUT:
|
|
||||||
s->io_bits &= ~mask;
|
|
||||||
break;
|
|
||||||
case INSN_CONFIG_DIO_QUERY:
|
|
||||||
data[1] = (s->io_bits & mask) ? COMEDI_OUTPUT : COMEDI_INPUT;
|
|
||||||
return insn->n;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* TODO support digital match interrupts and strobes */
|
/* TODO support digital match interrupts and strobes */
|
||||||
|
|
||||||
|
@ -1662,24 +1662,12 @@ static int s626_dio_insn_config(struct comedi_device *dev,
|
|||||||
unsigned int *data)
|
unsigned int *data)
|
||||||
{
|
{
|
||||||
unsigned long group = (unsigned long)s->private;
|
unsigned long group = (unsigned long)s->private;
|
||||||
unsigned int chan = CR_CHAN(insn->chanspec);
|
int ret;
|
||||||
unsigned int mask = 1 << chan;
|
|
||||||
|
ret = comedi_dio_insn_config(dev, s, insn, data, 0);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
switch (data[0]) {
|
|
||||||
case INSN_CONFIG_DIO_QUERY:
|
|
||||||
data[1] = (s->io_bits & mask) ? COMEDI_OUTPUT : COMEDI_INPUT;
|
|
||||||
return insn->n;
|
|
||||||
break;
|
|
||||||
case COMEDI_INPUT:
|
|
||||||
s->io_bits &= ~mask;
|
|
||||||
break;
|
|
||||||
case COMEDI_OUTPUT:
|
|
||||||
s->io_bits |= mask;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return -EINVAL;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
DEBIwrite(dev, LP_WRDOUT(group), s->io_bits);
|
DEBIwrite(dev, LP_WRDOUT(group), s->io_bits);
|
||||||
|
|
||||||
return insn->n;
|
return insn->n;
|
||||||
|
@ -93,68 +93,48 @@ static int dnp_dio_insn_bits(struct comedi_device *dev,
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ------------------------------------------------------------------------- */
|
|
||||||
/* Configure the direction of the bidirectional digital i/o pins. chanspec */
|
|
||||||
/* contains the channel to be changed and data[0] contains either */
|
|
||||||
/* COMEDI_INPUT or COMEDI_OUTPUT. */
|
|
||||||
/* ------------------------------------------------------------------------- */
|
|
||||||
|
|
||||||
static int dnp_dio_insn_config(struct comedi_device *dev,
|
static int dnp_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 val;
|
||||||
|
int ret;
|
||||||
|
|
||||||
u8 register_buffer;
|
ret = comedi_dio_insn_config(dev, s, insn, data, 0);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
/* reduces chanspec to lower 16 bits */
|
if (chan < 8) { /* Port A */
|
||||||
int chan = CR_CHAN(insn->chanspec);
|
mask = 1 << chan;
|
||||||
|
|
||||||
switch (data[0]) {
|
|
||||||
case INSN_CONFIG_DIO_OUTPUT:
|
|
||||||
case INSN_CONFIG_DIO_INPUT:
|
|
||||||
break;
|
|
||||||
case INSN_CONFIG_DIO_QUERY:
|
|
||||||
data[1] =
|
|
||||||
(inb(CSCDR) & (1 << chan)) ? COMEDI_OUTPUT : COMEDI_INPUT;
|
|
||||||
return insn->n;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return -EINVAL;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
/* Test: which port does the channel belong to? */
|
|
||||||
|
|
||||||
/* We have to pay attention with port C: this is the meaning of PCMR: */
|
|
||||||
/* Bit in PCMR: 7 6 5 4 3 2 1 0 */
|
|
||||||
/* Corresponding port C pin: d 3 d 2 d 1 d 0 d= don't touch */
|
|
||||||
|
|
||||||
if ((chan >= 0) && (chan <= 7)) {
|
|
||||||
/* this is port A */
|
|
||||||
outb(PAMR, CSCIR);
|
outb(PAMR, CSCIR);
|
||||||
} else if ((chan >= 8) && (chan <= 15)) {
|
} else if (chan < 16) { /* Port B */
|
||||||
/* this is port B */
|
mask = 1 << (chan - 8);
|
||||||
chan -= 8;
|
|
||||||
outb(PBMR, CSCIR);
|
outb(PBMR, CSCIR);
|
||||||
} else if ((chan >= 16) && (chan <= 19)) {
|
} else { /* Port C */
|
||||||
/* this is port C; multiplication with 2 brings bits into */
|
/*
|
||||||
/* correct position for PCMR! */
|
* We have to pay attention with port C.
|
||||||
chan -= 16;
|
* This is the meaning of PCMR:
|
||||||
chan *= 2;
|
* Bit in PCMR: 7 6 5 4 3 2 1 0
|
||||||
|
* Corresponding port C pin: d 3 d 2 d 1 d 0 d= don't touch
|
||||||
|
*
|
||||||
|
* Multiplication by 2 brings bits into correct position
|
||||||
|
* for PCMR!
|
||||||
|
*/
|
||||||
|
mask = 1 << ((chan - 16) * 2);
|
||||||
outb(PCMR, CSCIR);
|
outb(PCMR, CSCIR);
|
||||||
} else {
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* read 'old' direction of the port and set bits (out=1, in=0) */
|
val = inb(CSCDR);
|
||||||
register_buffer = inb(CSCDR);
|
|
||||||
if (data[0] == COMEDI_OUTPUT)
|
if (data[0] == COMEDI_OUTPUT)
|
||||||
register_buffer |= (1 << chan);
|
val |= mask;
|
||||||
else
|
else
|
||||||
register_buffer &= ~(1 << chan);
|
val &= ~mask;
|
||||||
|
outb(val, CSCDR);
|
||||||
|
|
||||||
outb(register_buffer, CSCDR);
|
return insn->n;
|
||||||
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1113,22 +1113,11 @@ static int usbdux_dio_insn_config(struct comedi_device *dev,
|
|||||||
struct comedi_insn *insn,
|
struct comedi_insn *insn,
|
||||||
unsigned int *data)
|
unsigned int *data)
|
||||||
{
|
{
|
||||||
unsigned int mask = 1 << CR_CHAN(insn->chanspec);
|
int ret;
|
||||||
|
|
||||||
switch (data[0]) {
|
ret = comedi_dio_insn_config(dev, s, insn, data, 0);
|
||||||
case INSN_CONFIG_DIO_OUTPUT:
|
if (ret)
|
||||||
s->io_bits |= mask;
|
return ret;
|
||||||
break;
|
|
||||||
case INSN_CONFIG_DIO_INPUT:
|
|
||||||
s->io_bits &= ~mask;
|
|
||||||
break;
|
|
||||||
case INSN_CONFIG_DIO_QUERY:
|
|
||||||
data[1] = (s->io_bits & mask) ? COMEDI_OUTPUT : COMEDI_INPUT;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return -EINVAL;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We don't tell the firmware here as it would take 8 frames
|
* We don't tell the firmware here as it would take 8 frames
|
||||||
|
@ -1040,23 +1040,11 @@ static int usbduxsigma_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);
|
int ret;
|
||||||
unsigned int mask = 1 << chan;
|
|
||||||
|
|
||||||
switch (data[0]) {
|
ret = comedi_dio_insn_config(dev, s, insn, data, 0);
|
||||||
case INSN_CONFIG_DIO_OUTPUT:
|
if (ret)
|
||||||
s->io_bits |= mask;
|
return ret;
|
||||||
break;
|
|
||||||
case INSN_CONFIG_DIO_INPUT:
|
|
||||||
s->io_bits &= ~mask;
|
|
||||||
break;
|
|
||||||
case INSN_CONFIG_DIO_QUERY:
|
|
||||||
data[1] = (s->io_bits & mask) ? COMEDI_OUTPUT : COMEDI_INPUT;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return -EINVAL;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We don't tell the firmware here as it would take 8 frames
|
* We don't tell the firmware here as it would take 8 frames
|
||||||
|
Loading…
x
Reference in New Issue
Block a user