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: Miquel Raynal <miquel.raynal@bootlin.com> Link: https://lore.kernel.org/r/20210921115408.66711-5-miquel.raynal@bootlin.com Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
This commit is contained in:
Родитель
6f1bc6d8fb
Коммит
e1c0ea8f6e
|
@ -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);
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче