static int dio_60xx_config_insn(struct comedi_device *dev,
struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data)
+ struct comedi_insn *insn,
+ unsigned int *data)
{
struct pcidas64_private *devpriv = dev->private;
- unsigned int mask;
-
- mask = 1 << CR_CHAN(insn->chanspec);
+ int ret;
- switch (data[0]) {
- 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;
- }
+ ret = comedi_dio_insn_config(dev, s, insn, data, 0);
+ if (ret)
+ return ret;
writeb(s->io_bits,
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 ni_670x_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 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);
return insn->n;
static int daq700_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 = 1 << CR_CHAN(insn->chanspec);
-
- switch (data[0]) {
- case INSN_CONFIG_DIO_INPUT:
- break;
- case INSN_CONFIG_DIO_OUTPUT:
- break;
- case INSN_CONFIG_DIO_QUERY:
- data[1] = (s->io_bits & chan) ? COMEDI_OUTPUT : COMEDI_INPUT;
- break;
- default:
- return -EINVAL;
- }
+ int ret;
+
+ ret = comedi_dio_insn_config(dev, s, insn, data, 0);
+ if (ret)
+ return ret;
+
+ /* The DIO channels are not configurable, fix the io_bits */
+ s->io_bits = 0x00ff;
return insn->n;
}
static int ni_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 ni_private *devpriv = dev->private;
+ int ret;
-#ifdef DEBUG_DIO
- printk("ni_dio_insn_config() chan=%d io=%d\n",
- CR_CHAN(insn->chanspec), data[0]);
-#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;
- }
+ ret = comedi_dio_insn_config(dev, s, insn, data, 0);
+ if (ret)
+ return ret;
devpriv->dio_control &= ~DIO_Pins_Dir_Mask;
devpriv->dio_control |= DIO_Pins_Dir(s->io_bits);
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,
unsigned int *data)
{
struct ni_private *devpriv __maybe_unused = dev->private;
+ int ret;
-#ifdef DEBUG_DIO
- printk("ni_m_series_dio_insn_config() chan=%d io=%d\n",
- CR_CHAN(insn->chanspec), data[0]);
-#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;
- }
+ ret = comedi_dio_insn_config(dev, s, insn, data, 0);
+ if (ret)
+ return ret;
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_pcidio_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 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));
- return 1;
+ return insn->n;
}
static int ni_pcidio_insn_bits(struct comedi_device *dev,
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,
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 =
- chan % 8;
- unsigned long ioaddr;
- unsigned char byte;
-
- /* Compute ioaddr for this channel */
- ioaddr = subpriv->iobases[byte_no];
-
- /* NOTE:
- writing a 0 an IO channel's bit sets the channel to INPUT
- and pulls the line high as well
-
- writing a 1 to an IO channel's bit pulls the line low
-
- All channels are implicitly always in OUTPUT mode -- but when
- 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);
+ unsigned int chan = CR_CHAN(insn->chanspec);
+ int byte_no = chan / 8;
+ int bit_no = chan % 8;
+ int ret;
- /* save to io_bits */
- s->io_bits &= ~(1 << chan);
- break;
+ ret = comedi_dio_insn_config(dev, s, insn, data, 0);
+ if (ret)
+ return ret;
- case INSN_CONFIG_DIO_QUERY:
- /* retrieve from shadow register */
- data[1] =
- (s->io_bits & (1 << chan)) ? COMEDI_OUTPUT : COMEDI_INPUT;
- return insn->n;
- break;
+ if (data[0] == INSN_CONFIG_DIO_INPUT) {
+ unsigned long ioaddr = subpriv->iobases[byte_no];
+ unsigned char val;
- default:
- return -EINVAL;
- break;
+ val = inb(ioaddr);
+ val &= ~(1 << bit_no);
+ outb(val, ioaddr);
}
return insn->n;
static int pcmuio_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_mask = 1 << CR_CHAN(insn->chanspec);
int asic = s->index / 2;
int port = (s->index % 2) ? 3 : 0;
+ int ret;
- switch (data[0]) {
- case INSN_CONFIG_DIO_OUTPUT:
- s->io_bits |= chan_mask;
- break;
- case INSN_CONFIG_DIO_INPUT:
- s->io_bits &= ~chan_mask;
+ ret = comedi_dio_insn_config(dev, s, insn, data, 0);
+ if (ret)
+ return ret;
+
+ if (data[0] == INSN_CONFIG_DIO_INPUT)
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;
}
unsigned int *data)
{
struct rtd_private *devpriv = dev->private;
- unsigned int chan = CR_CHAN(insn->chanspec);
- unsigned int mask = 1 << chan;
+ int ret;
- 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 & mask) ? COMEDI_OUTPUT : COMEDI_INPUT;
- return insn->n;
- break;
- default:
- return -EINVAL;
- }
+ ret = comedi_dio_insn_config(dev, s, insn, data, 0);
+ if (ret)
+ return ret;
/* TODO support digital match interrupts and strobes */
unsigned int *data)
{
unsigned long group = (unsigned long)s->private;
- unsigned int chan = CR_CHAN(insn->chanspec);
- unsigned int mask = 1 << chan;
+ int ret;
+
+ 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);
return insn->n;
}
-/* ------------------------------------------------------------------------- */
-/* 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,
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;
-
- /* reduces chanspec to lower 16 bits */
- int chan = CR_CHAN(insn->chanspec);
-
- 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 */
+ ret = comedi_dio_insn_config(dev, s, insn, data, 0);
+ if (ret)
+ return ret;
- if ((chan >= 0) && (chan <= 7)) {
- /* this is port A */
+ if (chan < 8) { /* Port A */
+ mask = 1 << chan;
outb(PAMR, CSCIR);
- } else if ((chan >= 8) && (chan <= 15)) {
- /* this is port B */
- chan -= 8;
+ } else if (chan < 16) { /* Port B */
+ mask = 1 << (chan - 8);
outb(PBMR, CSCIR);
- } else if ((chan >= 16) && (chan <= 19)) {
- /* this is port C; multiplication with 2 brings bits into */
- /* correct position for PCMR! */
- chan -= 16;
- chan *= 2;
+ } else { /* Port C */
+ /*
+ * 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
+ *
+ * Multiplication by 2 brings bits into correct position
+ * for PCMR!
+ */
+ mask = 1 << ((chan - 16) * 2);
outb(PCMR, CSCIR);
- } else {
- return -EINVAL;
}
- /* read 'old' direction of the port and set bits (out=1, in=0) */
- register_buffer = inb(CSCDR);
+ val = inb(CSCDR);
if (data[0] == COMEDI_OUTPUT)
- register_buffer |= (1 << chan);
+ val |= mask;
else
- register_buffer &= ~(1 << chan);
-
- outb(register_buffer, CSCDR);
+ val &= ~mask;
+ outb(val, CSCDR);
- return 1;
+ return insn->n;
}
struct comedi_insn *insn,
unsigned int *data)
{
- unsigned int mask = 1 << CR_CHAN(insn->chanspec);
+ int ret;
- 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 & mask) ? COMEDI_OUTPUT : COMEDI_INPUT;
- break;
- default:
- return -EINVAL;
- break;
- }
+ ret = comedi_dio_insn_config(dev, s, insn, data, 0);
+ if (ret)
+ return ret;
/*
* We don't tell the firmware here as it would take 8 frames
struct comedi_insn *insn,
unsigned int *data)
{
- unsigned int chan = CR_CHAN(insn->chanspec);
- unsigned int mask = 1 << chan;
+ int ret;
- 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 & mask) ? COMEDI_OUTPUT : COMEDI_INPUT;
- break;
- default:
- return -EINVAL;
- break;
- }
+ ret = comedi_dio_insn_config(dev, s, insn, data, 0);
+ if (ret)
+ return ret;
/*
* We don't tell the firmware here as it would take 8 frames