From nobody Mon Dec 15 00:32:44 2025 Received: from smtp127.ord1d.emailsrvr.com (smtp127.ord1d.emailsrvr.com [184.106.54.127]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 287F781AA8 for ; Wed, 10 Dec 2025 14:01:45 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=184.106.54.127 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1765375308; cv=none; b=ulsjbIVSz/0LpdftRNlSO6vR7DykYVRHLYTE+Ulr1ldUUvmFUAWw00wP+Cs9Hvb++R7oCPtQHku4rt99KhxC3LjCbnhpK3NF4HFJm0SGcSrGpe+DzBcsrGxBCG7MaWbCmMINq15RgO4wRNLQHgW5JcoaGJZbuaCSpTkHYWHknNM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1765375308; c=relaxed/simple; bh=JHCTv6Fb69LJ9FBu24lh2q7LWTC2hUVeJEJaU54POTk=; h=From:To:Cc:Subject:Date:Message-ID:MIME-Version; b=Fzfb9LndW3exaRniiy3P5Jzqmsr1rEoweL2Fg9kIXheavvjKmLuTCirabmgyClQmPcZ96NSIK5HODTu3XCLbs8KaTxCXrepHfvvrkdiOIMmPhFqvPTV6PhdTXnVLxyS3/bJfT4FWbxYFQObif9wtKJzXcoTEbVEn3KnStRwLPWU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=mev.co.uk; spf=pass smtp.mailfrom=mev.co.uk; dkim=pass (1024-bit key) header.d=mev.co.uk header.i=@mev.co.uk header.b=bDWka4+I; arc=none smtp.client-ip=184.106.54.127 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=mev.co.uk Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=mev.co.uk Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=mev.co.uk header.i=@mev.co.uk header.b="bDWka4+I" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=mev.co.uk; s=20221208-6x11dpa4; t=1765370704; bh=JHCTv6Fb69LJ9FBu24lh2q7LWTC2hUVeJEJaU54POTk=; h=From:To:Subject:Date:From; b=bDWka4+I8Nckp0JtRrIsRt76flpRVfra6kWRUNKeYL+yCkkkcN/zC2x0pfR6Jbm7J 9BYZsaKMMx/YERIFajX5xKY/8CcIeO8za4It5sniYUVa1MjitUsTxb58D7F9/4bkf+ d0eT1peDU9uvDZHOUzaUOwWIKDsd/ByHN+Bpyb74= X-Auth-ID: abbotti@mev.co.uk Received: by smtp16.relay.ord1d.emailsrvr.com (Authenticated sender: abbotti-AT-mev.co.uk) with ESMTPSA id 7513E4029A; Wed, 10 Dec 2025 07:45:03 -0500 (EST) From: Ian Abbott To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , Ian Abbott , H Hartley Sweeten Subject: [PATCH] comedi: comedi_test: add a DIO subdevice Date: Wed, 10 Dec 2025 12:44:55 +0000 Message-ID: <20251210124455.69131-1-abbotti@mev.co.uk> X-Mailer: git-send-email 2.51.0 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Classification-ID: 0c694bc3-a244-457f-870e-2fef228df095-1-1 Content-Type: text/plain; charset="utf-8" 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 --- 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_devic= e *dev, return -EINVAL; } =20 +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 =3D driven low, + * 1 =3D 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 =3D s->io_bits & ~s->state; + wires =3D 0xFFFF & ~driven_low & ~(driven_low >> 16); + /* Read back the state of the wires for each pair of channels. */ + data[1] =3D 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 =3D amplitude; devpriv->wf_period =3D period; =20 - ret =3D comedi_alloc_subdevices(dev, 2); + ret =3D comedi_alloc_subdevices(dev, 3); if (ret) return ret; =20 @@ -746,6 +784,16 @@ static int waveform_common_attach(struct comedi_device= *dev, for (i =3D 0; i < s->n_chan; i++) devpriv->ao_loopbacks[i] =3D s->maxdata / 2; =20 + s =3D &dev->subdevices[2]; + /* digital input/output subdevice */ + s->type =3D COMEDI_SUBD_DIO; + s->subdev_flags =3D SDF_READABLE | SDF_WRITABLE; + s->n_chan =3D 32; + s->maxdata =3D 1; + s->range_table =3D &range_digital; + s->insn_bits =3D waveform_dio_insn_bits; + s->insn_config =3D waveform_dio_insn_config; + devpriv->dev =3D dev; timer_setup(&devpriv->ai_timer, waveform_ai_timer, 0); timer_setup(&devpriv->ao_timer, waveform_ao_timer, 0); --=20 2.51.0