Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

iio: adc: ad7606_spi: add offload scan mask check

Validate the scan mask when SPI offloading is being used.

Since this family of ADCs is simultaneous sampling, there isn't a way
to selectively disable channels when reading sample data. (Technically,
AD7616 has a sequencer so the driver could have some control, but that
is for another day).

For "regular" IIO triggered buffer reads, this isn't a problem and the
IIO core will demux the data and ignore data from disabled channels.
However, since SPI offloading is done completely in hardware, we don't
have a way to do the same. So before this patch, if less than all
channels were enabled, the data would be misplaced in the buffer.

By adding a check in update_scan_mode, we can fail to enable the buffer
instead of having bad data returned to userspace.

Fixes: e96d35faf357 ("iio: adc: ad7606: add SPI offload support")
Signed-off-by: David Lechner <dlechner@baylibre.com>
Reviewed-by: Andy Shevchenko <andy@kernel.org>
Reviewed-by: Nuno Sá <nuno.sa@analog.com>
Link: https://patch.msgid.link/20250502-iio-adc-ad7606_spi-fix-offload-scan-mask-check-v2-1-e70c6d71baa3@baylibre.com
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>

authored by

David Lechner and committed by
Jonathan Cameron
017294e5 6eb97496

+29
+29
drivers/iio/adc/ad7606_spi.c
··· 5 5 * Copyright 2011 Analog Devices Inc. 6 6 */ 7 7 8 + #include <linux/bitmap.h> 8 9 #include <linux/err.h> 9 10 #include <linux/math.h> 10 11 #include <linux/module.h> ··· 330 329 return 0; 331 330 } 332 331 332 + static int ad7606_spi_update_scan_mode(struct iio_dev *indio_dev, 333 + const unsigned long *scan_mask) 334 + { 335 + struct ad7606_state *st = iio_priv(indio_dev); 336 + 337 + if (st->offload_en) { 338 + unsigned int num_adc_ch = st->chip_info->num_adc_channels; 339 + 340 + /* 341 + * SPI offload requires that all channels are enabled since 342 + * there isn't a way to selectively disable channels that get 343 + * read (this is simultaneous sampling ADC) and the DMA buffer 344 + * has no way of demuxing the data to filter out unwanted 345 + * channels. 346 + */ 347 + if (bitmap_weight(scan_mask, num_adc_ch) != num_adc_ch) 348 + return -EINVAL; 349 + } 350 + 351 + return 0; 352 + } 353 + 333 354 static const struct ad7606_bus_ops ad7606_spi_bops = { 334 355 .offload_config = ad7606_spi_offload_probe, 335 356 .read_block = ad7606_spi_read_block, 357 + .update_scan_mode = ad7606_spi_update_scan_mode, 336 358 }; 337 359 338 360 static const struct ad7606_bus_ops ad7607_spi_bops = { 339 361 .offload_config = ad7606_spi_offload_probe, 340 362 .read_block = ad7606_spi_read_block14to16, 363 + .update_scan_mode = ad7606_spi_update_scan_mode, 341 364 }; 342 365 343 366 static const struct ad7606_bus_ops ad7608_spi_bops = { 344 367 .offload_config = ad7606_spi_offload_probe, 345 368 .read_block = ad7606_spi_read_block18to32, 369 + .update_scan_mode = ad7606_spi_update_scan_mode, 346 370 }; 347 371 348 372 static const struct ad7606_bus_ops ad7616_spi_bops = { ··· 376 350 .reg_read = ad7606_spi_reg_read, 377 351 .reg_write = ad7606_spi_reg_write, 378 352 .rd_wr_cmd = ad7616_spi_rd_wr_cmd, 353 + .update_scan_mode = ad7606_spi_update_scan_mode, 379 354 }; 380 355 381 356 static const struct ad7606_bus_ops ad7606b_spi_bops = { ··· 386 359 .reg_write = ad7606_spi_reg_write, 387 360 .rd_wr_cmd = ad7606b_spi_rd_wr_cmd, 388 361 .sw_mode_config = ad7606b_sw_mode_config, 362 + .update_scan_mode = ad7606_spi_update_scan_mode, 389 363 }; 390 364 391 365 static const struct ad7606_bus_ops ad7606c_18_spi_bops = { ··· 396 368 .reg_write = ad7606_spi_reg_write, 397 369 .rd_wr_cmd = ad7606b_spi_rd_wr_cmd, 398 370 .sw_mode_config = ad7606b_sw_mode_config, 371 + .update_scan_mode = ad7606_spi_update_scan_mode, 399 372 }; 400 373 401 374 static const struct ad7606_bus_info ad7605_4_bus_info = {