On Fri, 22 Mar 2019 22:44:39 +0200 Alexandru Ardelean <ardeleanalex@xxxxxxxxx> wrote: > From: Alexandru Ardelean <alexandru.ardelean@xxxxxxxxxx> > > Some variants in the ADIS16400 family support burst mode. This mechanism is > implemented in the `adis16400_buffer.c` file. > > Some variants in ADIS16480 are also adding burst mode, which is > functionally similar to ADIS16400, but with different parameters. To get > there, a `adis_burst` struct is added to parametrize certain bits of the > SPI communication to setup: the register that triggers burst-mode, and the > extra-data-length that needs be accounted for when building the bust-length > buffer. > > The trigger handler cannot be made generic, since it's very specific to > each ADIS164XX family. > > A future enhancement of this `adis_burst` mode will be the possibility to > enable/disable burst-mode. For the ADIS16400 family it's hard-coded to on > by default. But for ADIS16480 there will be a need to disable this. This sounds interesting. I'll wait to see why you need to disable it :) >From what I recall there are definitely advantages to turning it off if you have a disconnected set of channels to read. Been a long time since I fired one of these up, though I think the one I have still works so I might move it into a more regular test set. > > When that will be implemented, both ADIS16400 & ADIS16480 will have the > burst-mode enable-able/disable-able. > > Signed-off-by: Alexandru Ardelean <alexandru.ardelean@xxxxxxxxxx> Applied to the togreg branch of iio.git and pushed out as testing for the autobuilders to play with it. Thanks, Jonathan > --- > drivers/iio/imu/adis16400_buffer.c | 7 +++---- > drivers/iio/imu/adis16400_core.c | 8 ++++++++ > include/linux/iio/imu/adis.h | 14 ++++++++++++++ > 3 files changed, 25 insertions(+), 4 deletions(-) > > diff --git a/drivers/iio/imu/adis16400_buffer.c b/drivers/iio/imu/adis16400_buffer.c > index 268349eb51c7..199bd72348eb 100644 > --- a/drivers/iio/imu/adis16400_buffer.c > +++ b/drivers/iio/imu/adis16400_buffer.c > @@ -22,7 +22,7 @@ int adis16400_update_scan_mode(struct iio_dev *indio_dev, > unsigned int burst_length; > u8 *tx; > > - if (st->variant->flags & ADIS16400_NO_BURST) > + if (!adis->burst || !adis->burst->en) > return adis_update_scan_mode(indio_dev, scan_mask); > > kfree(adis->xfer); > @@ -30,8 +30,7 @@ int adis16400_update_scan_mode(struct iio_dev *indio_dev, > > /* All but the timestamp channel */ > burst_length = (indio_dev->num_channels - 1) * sizeof(u16); > - if (st->variant->flags & ADIS16400_BURST_DIAG_STAT) > - burst_length += sizeof(u16); > + burst_length += adis->burst->extra_len; > > adis->xfer = kcalloc(2, sizeof(*adis->xfer), GFP_KERNEL); > if (!adis->xfer) > @@ -42,7 +41,7 @@ int adis16400_update_scan_mode(struct iio_dev *indio_dev, > return -ENOMEM; > > tx = adis->buffer + burst_length; > - tx[0] = ADIS_READ_REG(ADIS16400_GLOB_CMD); > + tx[0] = ADIS_READ_REG(adis->burst->reg_cmd); > tx[1] = 0; > > adis->xfer[0].tx_buf = tx; > diff --git a/drivers/iio/imu/adis16400_core.c b/drivers/iio/imu/adis16400_core.c > index 34d52863377a..0d799e983d74 100644 > --- a/drivers/iio/imu/adis16400_core.c > +++ b/drivers/iio/imu/adis16400_core.c > @@ -146,6 +146,11 @@ enum adis16400_chip_variant { > ADIS16448, > }; > > +static struct adis_burst adis16400_burst = { > + .en = true, > + .reg_cmd = ADIS16400_GLOB_CMD, > +}; > + > static int adis16334_get_freq(struct adis16400_state *st) > { > int ret; > @@ -973,6 +978,9 @@ static int adis16400_probe(struct spi_device *spi) > if (!(st->variant->flags & ADIS16400_NO_BURST)) { > adis16400_setup_chan_mask(st); > indio_dev->available_scan_masks = st->avail_scan_mask; > + st->adis.burst = &adis16400_burst; > + if (st->variant->flags & ADIS16400_BURST_DIAG_STAT) > + st->adis.burst->extra_len = sizeof(u16); > } > > ret = adis_init(&st->adis, indio_dev, spi, &adis16400_data); > diff --git a/include/linux/iio/imu/adis.h b/include/linux/iio/imu/adis.h > index cb6c3ed13459..26141ee87cfb 100644 > --- a/include/linux/iio/imu/adis.h > +++ b/include/linux/iio/imu/adis.h > @@ -21,6 +21,7 @@ > #define ADIS_REG_PAGE_ID 0x00 > > struct adis; > +struct adis_burst; > > /** > * struct adis_data - ADIS chip variant specific data > @@ -59,6 +60,7 @@ struct adis { > struct iio_trigger *trig; > > const struct adis_data *data; > + struct adis_burst *burst; > > struct mutex txrx_lock; > struct spi_message msg; > @@ -234,6 +236,18 @@ int adis_single_conversion(struct iio_dev *indio_dev, > > #ifdef CONFIG_IIO_ADIS_LIB_BUFFER > > +/** > + * struct adis_burst - ADIS data for burst transfers > + * @en burst mode enabled > + * @reg_cmd register command that triggers burst > + * @extra_len extra length to account in the SPI RX buffer > + */ > +struct adis_burst { > + bool en; > + unsigned int reg_cmd; > + unsigned int extra_len; > +}; > + > int adis_setup_buffer_and_trigger(struct adis *adis, > struct iio_dev *indio_dev, irqreturn_t (*trigger_handler)(int, void *)); > void adis_cleanup_buffer_and_trigger(struct adis *adis,