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

iio: adis: Support different burst sizes

Add burst_max_len to `adis_burst`. This is useful for devices which
support different burst modes with different sizes. The buffer to be
used in the spi transfer is allocated with this variable making sure
that has space for all burst modes. The spi transfer length should hold
the "real" burst length depending on the current burst mode configured
in the device.

Moreover, `extra_len` in `adis_burst` is made const and it should
contain the smallest extra length necessary for a burst transfer. In
`struct adis` was added a new `burst_extra_len` that should hold the
extra bytes needed depending on the device instance being used.

Signed-off-by: Nuno Sá <nuno.sa@analog.com>
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>

authored by

Nuno Sá and committed by
Jonathan Cameron
3e04cb60 b9c5eec7

+17 -7
+1 -1
drivers/iio/imu/adis16400.c
··· 1195 1195 indio_dev->available_scan_masks = st->avail_scan_mask; 1196 1196 st->adis.burst = &adis16400_burst; 1197 1197 if (st->variant->flags & ADIS16400_BURST_DIAG_STAT) 1198 - st->adis.burst->extra_len = sizeof(u16); 1198 + st->adis.burst_extra_len = sizeof(u16); 1199 1199 } 1200 1200 1201 1201 adis16400_data = &st->variant->adis_data;
+9 -4
drivers/iio/imu/adis_buffer.c
··· 23 23 const unsigned long *scan_mask) 24 24 { 25 25 struct adis *adis = iio_device_get_drvdata(indio_dev); 26 - unsigned int burst_length; 26 + unsigned int burst_length, burst_max_length; 27 27 u8 *tx; 28 28 29 29 /* All but the timestamp channel */ 30 30 burst_length = (indio_dev->num_channels - 1) * sizeof(u16); 31 - burst_length += adis->burst->extra_len; 31 + burst_length += adis->burst->extra_len + adis->burst_extra_len; 32 + 33 + if (adis->burst->burst_max_len) 34 + burst_max_length = adis->burst->burst_max_len; 35 + else 36 + burst_max_length = burst_length; 32 37 33 38 adis->xfer = kcalloc(2, sizeof(*adis->xfer), GFP_KERNEL); 34 39 if (!adis->xfer) 35 40 return -ENOMEM; 36 41 37 - adis->buffer = kzalloc(burst_length + sizeof(u16), GFP_KERNEL); 42 + adis->buffer = kzalloc(burst_max_length + sizeof(u16), GFP_KERNEL); 38 43 if (!adis->buffer) { 39 44 kfree(adis->xfer); 40 45 adis->xfer = NULL; 41 46 return -ENOMEM; 42 47 } 43 48 44 - tx = adis->buffer + burst_length; 49 + tx = adis->buffer + burst_max_length; 45 50 tx[0] = ADIS_READ_REG(adis->burst->reg_cmd); 46 51 tx[1] = 0; 47 52
+7 -2
include/linux/iio/imu/adis.h
··· 83 83 * @trig: IIO trigger object data 84 84 * @data: ADIS chip variant specific data 85 85 * @burst: ADIS burst transfer information 86 + * @burst_extra_len: Burst extra length. Should only be used by devices that can 87 + * dynamically change their burst mode length. 86 88 * @state_lock: Lock used by the device to protect state 87 89 * @msg: SPI message object 88 90 * @xfer: SPI transfer objects to be used for a @msg ··· 100 98 101 99 const struct adis_data *data; 102 100 struct adis_burst *burst; 103 - 101 + unsigned int burst_extra_len; 104 102 /** 105 103 * The state_lock is meant to be used during operations that require 106 104 * a sequence of SPI R/W in order to protect the SPI transfer ··· 504 502 * @en burst mode enabled 505 503 * @reg_cmd register command that triggers burst 506 504 * @extra_len extra length to account in the SPI RX buffer 505 + * @burst_max_len holds the maximum burst size when the device supports 506 + * more than one burst mode with different sizes 507 507 */ 508 508 struct adis_burst { 509 509 bool en; 510 510 unsigned int reg_cmd; 511 - unsigned int extra_len; 511 + const u32 extra_len; 512 + const u32 burst_max_len; 512 513 }; 513 514 514 515 int