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

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

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



Convert the drivers with complex, port programmable i/o, to use the
comedi_dio_insn_config() helper function.

All of these drivers have some sort of 'port' programmable i/o where multiple
i/o channels are configured as a group. The 'mask' associated with the group
is passed to comedi_dio_insn_config() so that all the channels are configured.

Signed-off-by: default avatarH Hartley Sweeten <hsweeten@visionengravers.com>
Reviewed-by: default avatarIan Abbott <abbotti@mev.co.uk>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent e495dd83
Loading
Loading
Loading
Loading
+16 −26
Original line number Diff line number Diff line
@@ -184,39 +184,29 @@ 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;
	unsigned int bits;
	int ret;

	mask = 1 << CR_CHAN(insn->chanspec);
	if (mask & 0x0000ff)
		bits = 0x0000ff;
	else if (mask & 0x00ff00)
		bits = 0x00ff00;
	else if (mask & 0x0f0000)
		bits = 0x0f0000;
	if (chan < 8)
		mask = 0x0000ff;
	else if (chan < 16)
		mask = 0x00ff00;
	else if (chan < 20)
		mask = 0x0f0000;
	else
		bits = 0xf00000;
		mask = 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;
	}
	ret = comedi_dio_insn_config(dev, s, insn, data, mask);
	if (ret)
		return ret;

	subdev_8255_do_config(dev, s);

	return 1;
	return insn->n;
}

static int subdev_8255_cmdtest(struct comedi_device *dev,
+14 −28
Original line number Diff line number Diff line
@@ -60,36 +60,22 @@ static int apci16xx_insn_config(struct comedi_device *dev,
				struct comedi_insn *insn,
				unsigned int *data)
{
	unsigned int chan_mask = 1 << CR_CHAN(insn->chanspec);
	unsigned int bits;
	unsigned int chan = CR_CHAN(insn->chanspec);
	unsigned int mask;
	int ret;

	/*
	 * 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;
	if (chan < 8)
		mask = 0x000000ff;
	else if (chan < 16)
		mask = 0x0000ff00;
	else if (chan < 24)
		mask = 0x00ff0000;
	else
		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;
	}
		mask = 0xff000000;

	ret = comedi_dio_insn_config(dev, s, insn, data, mask);
	if (ret)
		return ret;

	outl(s->io_bits, dev->iobase + APCI16XX_DIR_REG(s->index));

+13 −23
Original line number Diff line number Diff line
@@ -686,37 +686,27 @@ static int apci3xxx_dio_insn_config(struct comedi_device *dev,
				    unsigned int *data)
{
	unsigned int chan = CR_CHAN(insn->chanspec);
	unsigned int mask = 1 << chan;
	unsigned int bits;
	unsigned int mask;
	int ret;

	/*
	 * 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 (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:
	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;
	}

	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;
+17 −26
Original line number Diff line number Diff line
@@ -180,38 +180,29 @@ 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 int bits;
	unsigned short dio_mode;
	unsigned short mode;
	int ret;

	mask = 1 << CR_CHAN(insn->chanspec);
	if (mask & 0x00FF)
		bits = 0x00FF;
	if (chan < 8)
		mask = 0x00ff;
	else
		bits = 0xFF00;
		mask = 0xff00;

	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 hardware DIO mode */
	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;
	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;
}

/*
+17 −25
Original line number Diff line number Diff line
@@ -976,34 +976,26 @@ 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;
	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;
	int ret;

	if (chan < 8)
		mask = 0x0000ff;
	else if (chan < 16)
		mask = 0x00ff00;
	else if (chan < 20)
		mask = 0x0f0000;
	else
		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;
	}
		mask = 0xf00000;

	ret = comedi_dio_insn_config(dev, s, insn, data, mask);
	if (ret)
		return ret;

	dio200_subdev_8255_set_dir(dev, s);
	return 1;

	return insn->n;
}

/*
Loading