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>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <4e2b2d07a255bb249a1dc40a4470c7e123d4213f.1756511030.git.marcelo.schmitt@analog.com>
Date: Fri, 29 Aug 2025 21:43:30 -0300
From: Marcelo Schmitt <marcelo.schmitt@...log.com>
To: <linux-iio@...r.kernel.org>, <linux-kernel@...r.kernel.org>,
        <linux-doc@...r.kernel.org>, <devicetree@...r.kernel.org>,
        <linux-spi@...r.kernel.org>
CC: <jic23@...nel.org>, <Michael.Hennerich@...log.com>, <nuno.sa@...log.com>,
        <eblanc@...libre.com>, <dlechner@...libre.com>, <andy@...nel.org>,
        <corbet@....net>, <robh@...nel.org>, <krzk+dt@...nel.org>,
        <conor+dt@...nel.org>, <broonie@...nel.org>,
        <Jonathan.Cameron@...wei.com>, <andriy.shevchenko@...ux.intel.com>,
        <ahaslam@...libre.com>, <sergiu.cuciurean@...log.com>,
        <marcelo.schmitt1@...il.com>
Subject: [PATCH 09/15] iio: adc: ad4030: Support multiple data lanes per channel

AD4030 and similar chips can output ADC sample data through 1, 2, or 4
lines per channel. The number of SPI lines the device uses to output data
is specified in firmware. Parse SPI read bus width setting from firmware
and configure the device to use that amount of lines to output data.

Co-developed-by: Sergiu Cuciurean <sergiu.cuciurean@...log.com>
Signed-off-by: Sergiu Cuciurean <sergiu.cuciurean@...log.com>
Signed-off-by: Marcelo Schmitt <marcelo.schmitt@...log.com>
---
 drivers/iio/adc/ad4030.c | 33 ++++++++++++++++++++++++++++++---
 1 file changed, 30 insertions(+), 3 deletions(-)

diff --git a/drivers/iio/adc/ad4030.c b/drivers/iio/adc/ad4030.c
index 68f76432dbfd..e6c1c9be1632 100644
--- a/drivers/iio/adc/ad4030.c
+++ b/drivers/iio/adc/ad4030.c
@@ -20,6 +20,7 @@
 #include <linux/iio/iio.h>
 #include <linux/iio/trigger_consumer.h>
 #include <linux/iio/triggered_buffer.h>
+#include <linux/log2.h>
 #include <linux/pwm.h>
 #include <linux/regmap.h>
 #include <linux/regulator/consumer.h>
@@ -258,6 +259,10 @@ struct ad4030_state {
 #define AD4030_OFFLOAD_CHAN_DIFF(_idx, _scan_type)			\
 	__AD4030_CHAN_DIFF(_idx, _scan_type, 1)
 
+static const int ad4030_rx_bus_width[] = {
+	1, 2, 4, 8,
+};
+
 static const int ad4030_average_modes[] = {
 	1, 2, 4, 8, 16, 32, 64, 128,
 	256, 512, 1024, 2048, 4096, 8192, 16384, 32768,
@@ -1197,7 +1202,7 @@ static void ad4030_prepare_offload_msg(struct ad4030_state *st)
 		 */
 		offload_bpw = data_width * st->chip->num_voltage_inputs;
 	else
-		offload_bpw  = data_width;
+		offload_bpw  = data_width / (1 << st->lane_mode);
 
 	st->offload_xfer.speed_hz = AD4030_SPI_MAX_REG_XFER_SPEED;
 	st->offload_xfer.bits_per_word = offload_bpw;
@@ -1208,6 +1213,10 @@ static void ad4030_prepare_offload_msg(struct ad4030_state *st)
 
 static int ad4030_config(struct ad4030_state *st)
 {
+	struct device *dev = &st->spi->dev;
+	const char *propname;
+	u32 rx_bus_width;
+	unsigned int i;
 	int ret;
 	u8 reg_modes;
 
@@ -1215,10 +1224,28 @@ static int ad4030_config(struct ad4030_state *st)
 	st->offset_avail[1] = 1;
 	st->offset_avail[2] = BIT(st->chip->precision_bits - 1) - 1;
 
-	if (st->chip->num_voltage_inputs > 1)
+	/* Optional property specifying the number of lanes to read ADC data */
+	propname = "spi-rx-bus-width";
+	rx_bus_width = ad4030_rx_bus_width[0]; /* Default to 1 rx lane. */
+	device_property_read_u32(dev, propname, &rx_bus_width);
+	/* Check the rx bus width is valid */
+	for (i = 0; i < ARRAY_SIZE(ad4030_rx_bus_width); i++)
+		if (ad4030_rx_bus_width[i] == rx_bus_width)
+			break;
+
+	if (i >= ARRAY_SIZE(ad4030_rx_bus_width))
+		return dev_err_probe(dev, -EINVAL, "Invalid %s: %u\n",
+				     propname, rx_bus_width);
+
+	rx_bus_width = ad4030_rx_bus_width[i];
+
+	if (rx_bus_width == 8 && st->chip->num_voltage_inputs == 1)
+		return dev_err_probe(dev, -EINVAL, "1 channel with 8 lanes?\n");
+
+	if (rx_bus_width == 1 && st->chip->num_voltage_inputs > 1)
 		st->lane_mode = AD4030_LANE_MD_INTERLEAVED;
 	else
-		st->lane_mode = AD4030_LANE_MD_1_PER_CH;
+		st->lane_mode = ilog2(rx_bus_width / st->chip->num_voltage_inputs);
 
 	reg_modes = FIELD_PREP(AD4030_REG_MODES_MASK_LANE_MODE, st->lane_mode);
 
-- 
2.39.2


Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ