lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [day] [month] [year] [list]
Message-ID: <20251210124455.69131-1-abbotti@mev.co.uk>
Date: Wed, 10 Dec 2025 12:44:55 +0000
From: Ian Abbott <abbotti@....co.uk>
To: linux-kernel@...r.kernel.org
Cc: Greg Kroah-Hartman <gregkh@...uxfoundation.org>,
	Ian Abbott <abbotti@....co.uk>,
	H Hartley Sweeten <hsweeten@...ionengravers.com>
Subject: [PATCH] comedi: comedi_test: add a DIO subdevice

The fake "comedi_test" device currently has two subdevices: an analog
input subdevice, and an analog output subdevice.  To make it a bit more
useful for testing, add a third subdevice for digital I/O.

The new DIO subdevice has 32 channels with each channel individually
programmable as an input or an output.  To add a bit of interaction,
channels 0 to 15 are wired to channels 16 to 31 (0 to 16, 1 to 17,
etc.), and the state of each wire can be read back on both of the
channels connected to it.  The outputs are modelled as NPN open
collector outputs with a pull-up resistor on the wire, so the state of
each wire (and the value read back from each channel connected to it)
will be logic level 1 unless either channel is configured as an output
at logic level 0.

Signed-off-by: Ian Abbott <abbotti@....co.uk>
---
 drivers/comedi/drivers/comedi_test.c | 50 +++++++++++++++++++++++++++-
 1 file changed, 49 insertions(+), 1 deletion(-)

diff --git a/drivers/comedi/drivers/comedi_test.c b/drivers/comedi/drivers/comedi_test.c
index 7984950f0f99..01aafce20ef8 100644
--- a/drivers/comedi/drivers/comedi_test.c
+++ b/drivers/comedi/drivers/comedi_test.c
@@ -692,6 +692,44 @@ static int waveform_ao_insn_config(struct comedi_device *dev,
 	return -EINVAL;
 }
 
+static int waveform_dio_insn_bits(struct comedi_device *dev,
+				  struct comedi_subdevice *s,
+				  struct comedi_insn *insn,
+				  unsigned int *data)
+{
+	u32 driven_low;
+	u16 wires;
+
+	/* Update the channel outputs. */
+	comedi_dio_update_state(s, data);
+	/*
+	 * We are modelling the outputs as NPN open collector (0 = driven low,
+	 * 1 = high impedance), with the lower 16 channels wired to the upper
+	 * 16 channels in pairs (0 to 16, 1 to 17, ..., 15 to 31), with a
+	 * pull-up resistor on each wire.  When reading back each channel, we
+	 * read back the state of the wire to which it is connected.
+	 *
+	 * The state of each wire and the value read back from both channels
+	 * connected to it will be logic 1 unless either channel connected to
+	 * the wire is configured as an output in the logic 0 state.
+	 */
+	driven_low = s->io_bits & ~s->state;
+	wires = 0xFFFF & ~driven_low & ~(driven_low >> 16);
+	/* Read back the state of the wires for each pair of channels. */
+	data[1] = wires | (wires << 16);
+
+	return insn->n;
+}
+
+static int waveform_dio_insn_config(struct comedi_device *dev,
+				    struct comedi_subdevice *s,
+				    struct comedi_insn *insn,
+				    unsigned int *data)
+{
+	/* configure each channel as input or output individually */
+	return comedi_dio_insn_config(dev, s, insn, data, 0);
+}
+
 static int waveform_common_attach(struct comedi_device *dev,
 				  int amplitude, int period)
 {
@@ -707,7 +745,7 @@ static int waveform_common_attach(struct comedi_device *dev,
 	devpriv->wf_amplitude = amplitude;
 	devpriv->wf_period = period;
 
-	ret = comedi_alloc_subdevices(dev, 2);
+	ret = comedi_alloc_subdevices(dev, 3);
 	if (ret)
 		return ret;
 
@@ -746,6 +784,16 @@ static int waveform_common_attach(struct comedi_device *dev,
 	for (i = 0; i < s->n_chan; i++)
 		devpriv->ao_loopbacks[i] = s->maxdata / 2;
 
+	s = &dev->subdevices[2];
+	/* digital input/output subdevice */
+	s->type = COMEDI_SUBD_DIO;
+	s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
+	s->n_chan = 32;
+	s->maxdata = 1;
+	s->range_table = &range_digital;
+	s->insn_bits = waveform_dio_insn_bits;
+	s->insn_config = waveform_dio_insn_config;
+
 	devpriv->dev = dev;
 	timer_setup(&devpriv->ai_timer, waveform_ai_timer, 0);
 	timer_setup(&devpriv->ao_timer, waveform_ao_timer, 0);
-- 
2.51.0


Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ