On Thu, 2 Sep 2021 23:14:26 +0200 Miquel Raynal <miquel.raynal@xxxxxxxxxxx> wrote: > Provide a list of ->available_scan_masks which match the device's > capabilities. Basically, the devices is able to scan from 0 to N, N > being the highest voltage channel requested by the user. The temperature > can be included or not, but cannot be retrieved alone. > > The consequence is, instead of reading and pushing to the IIO buffers > all channels each time, the "minimum" number of channels will be scanned > and pushed based on the ->active_scan_mask. > > For example, if the user wants channels 1, 4 and 5, all channels from > 0 to 5 will be scanned and pushed to the IIO buffers. The core will then > filter out the unneeded samples based on the ->active_scan_mask that has > been selected and only channels 1, 4 and 5 will be available to the user > in the shared buffer. This explanation is excellent. If you are respinning it would be great to have the essence of it as a comment alongside the code. The bit about temp in particular was something I'd missed. Nice optimization in general. Jonathan > > Signed-off-by: Miquel Raynal <miquel.raynal@xxxxxxxxxxx> > --- > drivers/iio/adc/max1027.c | 46 +++++++++++++++++++++++++++++++++------ > 1 file changed, 39 insertions(+), 7 deletions(-) > > diff --git a/drivers/iio/adc/max1027.c b/drivers/iio/adc/max1027.c > index 1167d50c1d67..3c41d2c0ed2a 100644 > --- a/drivers/iio/adc/max1027.c > +++ b/drivers/iio/adc/max1027.c > @@ -172,18 +172,39 @@ static const struct iio_chan_spec max1231_channels[] = { > MAX1X31_CHANNELS(12), > }; > > +#define MAX1X27_SCAN_MASK_TEMP BIT(0) > + > +#define MAX1X27_SCAN_MASKS(temp) \ > + GENMASK(1, 1 - (temp)), GENMASK(2, 1 - (temp)), \ > + GENMASK(3, 1 - (temp)), GENMASK(4, 1 - (temp)), \ > + GENMASK(5, 1 - (temp)), GENMASK(6, 1 - (temp)), \ > + GENMASK(7, 1 - (temp)), GENMASK(8, 1 - (temp)) > + > +#define MAX1X29_SCAN_MASKS(temp) \ > + MAX1X27_SCAN_MASKS(temp), \ > + GENMASK(9, 1 - (temp)), GENMASK(10, 1 - (temp)), \ > + GENMASK(11, 1 - (temp)), GENMASK(12, 1 - (temp)) > + > +#define MAX1X31_SCAN_MASKS(temp) \ > + MAX1X29_SCAN_MASKS(temp), \ > + GENMASK(13, 1 - (temp)), GENMASK(14, 1 - (temp)), \ > + GENMASK(15, 1 - (temp)), GENMASK(16, 1 - (temp)) > + > static const unsigned long max1027_available_scan_masks[] = { > - 0x000001ff, > + MAX1X27_SCAN_MASKS(0), > + MAX1X27_SCAN_MASKS(1), > 0x00000000, > }; > > static const unsigned long max1029_available_scan_masks[] = { > - 0x00001fff, > + MAX1X29_SCAN_MASKS(0), > + MAX1X29_SCAN_MASKS(1), > 0x00000000, > }; > > static const unsigned long max1031_available_scan_masks[] = { > - 0x0001ffff, > + MAX1X31_SCAN_MASKS(0), > + MAX1X31_SCAN_MASKS(1), > 0x00000000, > }; > > @@ -368,9 +389,15 @@ static int max1027_set_trigger_state(struct iio_trigger *trig, bool state) > if (ret < 0) > return ret; > > - /* Scan from 0 to max */ > - st->reg = MAX1027_CONV_REG | MAX1027_CHAN(0) | > - MAX1027_SCAN_N_M | MAX1027_TEMP; > + /* > + * Scan from chan 0 to the highest requested channel. > + * Include temperature on demand. > + */ > + st->reg = MAX1027_CONV_REG | MAX1027_SCAN_0_N; > + st->reg |= MAX1027_CHAN(fls(*indio_dev->active_scan_mask) - 2); > + if (*indio_dev->active_scan_mask & MAX1X27_SCAN_MASK_TEMP) > + st->reg |= MAX1027_TEMP; > + > ret = spi_write(st->spi, &st->reg, 1); > if (ret < 0) > return ret; > @@ -391,9 +418,14 @@ static irqreturn_t max1027_trigger_handler(int irq, void *private) > struct iio_poll_func *pf = private; > struct iio_dev *indio_dev = pf->indio_dev; > struct max1027_state *st = iio_priv(indio_dev); > + unsigned int scanned_chans; > + > + scanned_chans = fls(*indio_dev->active_scan_mask) - 1; > + if (*indio_dev->active_scan_mask & MAX1X27_SCAN_MASK_TEMP) > + scanned_chans++; > > /* fill buffer with all channel */ > - spi_read(st->spi, st->buffer, indio_dev->masklength * 2); > + spi_read(st->spi, st->buffer, scanned_chans * 2); > > iio_push_to_buffers(indio_dev, st->buffer); >