On 8/29/25 7:43 PM, Marcelo Schmitt wrote: > 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@xxxxxxxxxx> > Signed-off-by: Sergiu Cuciurean <sergiu.cuciurean@xxxxxxxxxx> > Signed-off-by: Marcelo Schmitt <marcelo.schmitt@xxxxxxxxxx> > --- > 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); To make proper use of 2 or 4 lines for a single channel, we should be using the SPI APIs correctly and set rx_nbits in struct spi_transfer instead of providing an inaccurate bits per word. > > 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"; This property is already handled by the core SPI code and will set spi->mode flags SPI_RX_DUAL, SPI_RX_QUAD or SPI_RX_OCTAL. So we don't need to read the property again. > + 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"); As mentioned in the dt-bindings patch review, we really should consider the 2 channel case separate as 2 SPI buses rather than 8 lines on a single bus. Only using "spi-rx-bus-width" also has the shortcoming that if we specify 4, we don't know if is it 4 lines on 1 channel or is it 2 lines each on 2 channels? There is no way to tell from just that information. > + > + 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); >