Commit e1c0ea8f authored by Miquel Raynal's avatar Miquel Raynal Committed by Jonathan Cameron

iio: adc: max1027: Minimize the number of converted channels

Provide a list of ->available_scan_masks which match the device's
capabilities. Basically, these devices are 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.

Provide a comment in the code explaining this logic.
Signed-off-by: default avatarMiquel Raynal <miquel.raynal@bootlin.com>
Link: https://lore.kernel.org/r/20210921115408.66711-5-miquel.raynal@bootlin.comSigned-off-by: default avatarJonathan Cameron <Jonathan.Cameron@huawei.com>
parent 6f1bc6d8
......@@ -173,18 +173,53 @@ static const struct iio_chan_spec max1231_channels[] = {
MAX1X31_CHANNELS(12),
};
/*
* These devices are 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. Based on the below
* ->available_scan_masks, the core will select the most appropriate
* ->active_scan_mask and the "minimum" number of channels will be
* scanned and pushed to the buffers.
*
* 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.
*/
#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,
};
......@@ -369,9 +404,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;
......@@ -392,9 +433,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);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment