Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b3ff824a authored by H Hartley Sweeten's avatar H Hartley Sweeten Committed by Greg Kroah-Hartman
Browse files

staging: comedi: drivers: use comedi_dio_update_state() for complex cases



Use comedi_dio_update_state() to handle the boilerplate code to update
the subdevice s->state for more complex cases where the hardware is only
updated based on the 'mask' of the channels that are modified.

Signed-off-by: default avatarH Hartley Sweeten <hsweeten@visionengravers.com>
Reviewed-by: default avatarIan Abbott <abbotti@mev.co.uk>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 97f4289a
Loading
Loading
Loading
Loading
+8 −14
Original line number Original line Diff line number Diff line
@@ -126,30 +126,24 @@ EXPORT_SYMBOL_GPL(subdev_8255_interrupt);


static int subdev_8255_insn(struct comedi_device *dev,
static int subdev_8255_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 subdev_8255_private *spriv = s->private;
	struct subdev_8255_private *spriv = s->private;
	unsigned long iobase = spriv->iobase;
	unsigned long iobase = spriv->iobase;
	unsigned int mask;
	unsigned int mask;
	unsigned int bits;
	unsigned int v;
	unsigned int v;


	mask = data[0];
	mask = comedi_dio_update_state(s, data);
	bits = data[1];

	if (mask) {
	if (mask) {
		v = s->state;
		v &= ~mask;
		v |= (bits & mask);

		if (mask & 0xff)
		if (mask & 0xff)
			spriv->io(1, _8255_DATA, v & 0xff, iobase);
			spriv->io(1, _8255_DATA, s->state & 0xff, iobase);
		if (mask & 0xff00)
		if (mask & 0xff00)
			spriv->io(1, _8255_DATA + 1, (v >> 8) & 0xff, iobase);
			spriv->io(1, _8255_DATA + 1, (s->state >> 8) & 0xff,
				  iobase);
		if (mask & 0xff0000)
		if (mask & 0xff0000)
			spriv->io(1, _8255_DATA + 2, (v >> 16) & 0xff, iobase);
			spriv->io(1, _8255_DATA + 2, (s->state >> 16) & 0xff,

				  iobase);
		s->state = v;
	}
	}


	v = spriv->io(0, _8255_DATA, 0, iobase);
	v = spriv->io(0, _8255_DATA, 0, iobase);
+17 −14
Original line number Original line Diff line number Diff line
@@ -941,31 +941,34 @@ static void dio200_subdev_8255_set_dir(struct comedi_device *dev,
	dio200_write8(dev, subpriv->ofs + 3, config);
	dio200_write8(dev, subpriv->ofs + 3, config);
}
}


/*
 * Handle 'insn_bits' for an '8255' DIO subdevice.
 */
static int dio200_subdev_8255_bits(struct comedi_device *dev,
static int dio200_subdev_8255_bits(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 dio200_subdev_8255 *subpriv = s->private;
	struct dio200_subdev_8255 *subpriv = s->private;
	unsigned int mask;
	unsigned int val;


	if (data[0]) {
	mask = comedi_dio_update_state(s, data);
		s->state &= ~data[0];
	if (mask) {
		s->state |= (data[0] & data[1]);
		if (mask & 0xff)
		if (data[0] & 0xff)
			dio200_write8(dev, subpriv->ofs, s->state & 0xff);
			dio200_write8(dev, subpriv->ofs, s->state & 0xff);
		if (data[0] & 0xff00)
		if (mask & 0xff00)
			dio200_write8(dev, subpriv->ofs + 1,
			dio200_write8(dev, subpriv->ofs + 1,
				      (s->state >> 8) & 0xff);
				      (s->state >> 8) & 0xff);
		if (data[0] & 0xff0000)
		if (mask & 0xff0000)
			dio200_write8(dev, subpriv->ofs + 2,
			dio200_write8(dev, subpriv->ofs + 2,
				      (s->state >> 16) & 0xff);
				      (s->state >> 16) & 0xff);
	}
	}
	data[1] = dio200_read8(dev, subpriv->ofs);

	data[1] |= dio200_read8(dev, subpriv->ofs + 1) << 8;
	val = dio200_read8(dev, subpriv->ofs);
	data[1] |= dio200_read8(dev, subpriv->ofs + 2) << 16;
	val |= dio200_read8(dev, subpriv->ofs + 1) << 8;
	return 2;
	val |= dio200_read8(dev, subpriv->ofs + 2) << 16;

	data[1] = val;

	return insn->n;
}
}


/*
/*
+29 −41
Original line number Original line Diff line number Diff line
@@ -596,52 +596,40 @@ static int dmm32at_ao_rinsn(struct comedi_device *dev,


static int dmm32at_dio_insn_bits(struct comedi_device *dev,
static int dmm32at_dio_insn_bits(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 dmm32at_private *devpriv = dev->private;
	struct dmm32at_private *devpriv = dev->private;
	unsigned char diobits;
	unsigned int mask;

	unsigned int val;
	/* The insn data is a mask in data[0] and the new data
	 * in data[1], each channel cooresponding to a bit. */
	if (data[0]) {
		s->state &= ~data[0];
		s->state |= data[0] & data[1];
		/* Write out the new digital output lines */
		/* outw(s->state,dev->iobase + DMM32AT_DIO); */
	}


	mask = comedi_dio_update_state(s, data);
	if (mask) {
		/* get access to the DIO regs */
		/* get access to the DIO regs */
		outb(DMM32AT_DIOACC, dev->iobase + DMM32AT_CNTRL);
		outb(DMM32AT_DIOACC, dev->iobase + DMM32AT_CNTRL);


		/* if either part of dio is set for output */
		/* if either part of dio is set for output */
		if (((devpriv->dio_config & DMM32AT_DIRCL) == 0) ||
		if (((devpriv->dio_config & DMM32AT_DIRCL) == 0) ||
		    ((devpriv->dio_config & DMM32AT_DIRCH) == 0)) {
		    ((devpriv->dio_config & DMM32AT_DIRCH) == 0)) {
		diobits = (s->state & 0x00ff0000) >> 16;
			val = (s->state & 0x00ff0000) >> 16;
		outb(diobits, dev->iobase + DMM32AT_DIOC);
			outb(val, dev->iobase + DMM32AT_DIOC);
		}
		}
		if ((devpriv->dio_config & DMM32AT_DIRB) == 0) {
		if ((devpriv->dio_config & DMM32AT_DIRB) == 0) {
		diobits = (s->state & 0x0000ff00) >> 8;
			val = (s->state & 0x0000ff00) >> 8;
		outb(diobits, dev->iobase + DMM32AT_DIOB);
			outb(val, dev->iobase + DMM32AT_DIOB);
		}
		}
		if ((devpriv->dio_config & DMM32AT_DIRA) == 0) {
		if ((devpriv->dio_config & DMM32AT_DIRA) == 0) {
		diobits = (s->state & 0x000000ff);
			val = (s->state & 0x000000ff);
		outb(diobits, dev->iobase + DMM32AT_DIOA);
			outb(val, dev->iobase + DMM32AT_DIOA);
	}
		}

	}
	/* now read the state back in */

	s->state = inb(dev->iobase + DMM32AT_DIOC);
	val = inb(dev->iobase + DMM32AT_DIOA);
	s->state <<= 8;
	val |= inb(dev->iobase + DMM32AT_DIOB) << 8;
	s->state |= inb(dev->iobase + DMM32AT_DIOB);
	val |= inb(dev->iobase + DMM32AT_DIOC) << 16;
	s->state <<= 8;
	s->state = val;
	s->state |= inb(dev->iobase + DMM32AT_DIOA);

	data[1] = s->state;
	data[1] = val;

	/* on return, data[1] contains the value of the digital
	 * input and output lines. */
	/* data[1]=inw(dev->iobase + DMM32AT_DIO); */
	/* or we could just return the software copy of the output values if
	 * it was a purely digital output subdevice */
	/* data[1]=s->state; */


	return insn->n;
	return insn->n;
}
}
+23 −28
Original line number Original line Diff line number Diff line
@@ -80,36 +80,31 @@ static int dt2817_dio_insn_config(struct comedi_device *dev,


static int dt2817_dio_insn_bits(struct comedi_device *dev,
static int dt2817_dio_insn_bits(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 changed;
	unsigned long iobase = dev->iobase + DT2817_DATA;

	unsigned int mask;
	/* It's questionable whether it is more important in
	unsigned int val;
	 * a driver like this to be deterministic or fast.

	 * We choose fast. */
	mask = comedi_dio_update_state(s, data);

	if (mask) {
	if (data[0]) {
		if (mask & 0x000000ff)
		changed = s->state;
			outb(s->state & 0xff, iobase + 0);
		s->state &= ~data[0];
		if (mask & 0x0000ff00)
		s->state |= (data[0] & data[1]);
			outb((s->state >> 8) & 0xff, iobase + 1);
		changed ^= s->state;
		if (mask & 0x00ff0000)
		changed &= s->io_bits;
			outb((s->state >> 16) & 0xff, iobase + 2);
		if (changed & 0x000000ff)
		if (mask & 0xff000000)
			outb(s->state & 0xff, dev->iobase + DT2817_DATA + 0);
			outb((s->state >> 24) & 0xff, iobase + 3);
		if (changed & 0x0000ff00)
			outb((s->state >> 8) & 0xff,
			     dev->iobase + DT2817_DATA + 1);
		if (changed & 0x00ff0000)
			outb((s->state >> 16) & 0xff,
			     dev->iobase + DT2817_DATA + 2);
		if (changed & 0xff000000)
			outb((s->state >> 24) & 0xff,
			     dev->iobase + DT2817_DATA + 3);
	}
	}
	data[1] = inb(dev->iobase + DT2817_DATA + 0);

	data[1] |= (inb(dev->iobase + DT2817_DATA + 1) << 8);
	val = inb(iobase + 0);
	data[1] |= (inb(dev->iobase + DT2817_DATA + 2) << 16);
	val |= (inb(iobase + 1) << 8);
	data[1] |= (inb(dev->iobase + DT2817_DATA + 3) << 24);
	val |= (inb(iobase + 2) << 16);
	val |= (inb(iobase + 3) << 24);

	data[1] = val;


	return insn->n;
	return insn->n;
}
}
+11 −11
Original line number Original line Diff line number Diff line
@@ -163,29 +163,29 @@ static int ni6527_di_insn_bits(struct comedi_device *dev,


static int ni6527_do_insn_bits(struct comedi_device *dev,
static int ni6527_do_insn_bits(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 ni6527_private *devpriv = dev->private;
	struct ni6527_private *devpriv = dev->private;
	unsigned int mask;


	if (data[0]) {
	mask = comedi_dio_update_state(s, data);
		s->state &= ~data[0];
	if (mask) {
		s->state |= (data[0] & data[1]);
		/* Outputs are inverted */

		if (mask & 0x0000ff) {
		/* The open relay state on the board cooresponds to 1,
			writeb(s->state ^ 0xff,
		 * but in Comedi, it is represented by 0. */
		if (data[0] & 0x0000ff) {
			writeb((s->state ^ 0xff),
			       devpriv->mite->daq_io_addr + Port_Register(3));
			       devpriv->mite->daq_io_addr + Port_Register(3));
		}
		}
		if (data[0] & 0x00ff00) {
		if (mask & 0x00ff00) {
			writeb((s->state >> 8) ^ 0xff,
			writeb((s->state >> 8) ^ 0xff,
			       devpriv->mite->daq_io_addr + Port_Register(4));
			       devpriv->mite->daq_io_addr + Port_Register(4));
		}
		}
		if (data[0] & 0xff0000) {
		if (mask & 0xff0000) {
			writeb((s->state >> 16) ^ 0xff,
			writeb((s->state >> 16) ^ 0xff,
			       devpriv->mite->daq_io_addr + Port_Register(5));
			       devpriv->mite->daq_io_addr + Port_Register(5));
		}
		}
	}
	}

	data[1] = s->state;
	data[1] = s->state;


	return insn->n;
	return insn->n;
Loading