On Tue, 4 Feb 2025 16:36:09 +0200 Robert Budai <robert.budai@xxxxxxxxxx> wrote: > The ADIS16550 is a complete inertial system that includes a triaxis > gyroscope and a triaxis accelerometer. Each inertial sensor in the > ADIS16550 combines industry leading MEMS only technology with signal > conditioning that optimizes dynamic performance. The factory calibration > characterizes each sensor for sensitivity, bias, and alignment. As a > result, each sensor has its own dynamic compensation formulas that > provide accurate sensor measurements. > > Co-developed-by: Ramona Gradinariu <ramona.gradinariu@xxxxxxxxxx> > Signed-off-by: Ramona Gradinariu <ramona.gradinariu@xxxxxxxxxx> > Co-developed-by: Antoniu Miclaus <antoniu.miclaus@xxxxxxxxxx> > Signed-off-by: Antoniu Miclaus <antoniu.miclaus@xxxxxxxxxx> > Signed-off-by: Nuno Sá <nuno.sa@xxxxxxxxxx> > Signed-off-by: Robert Budai <robert.budai@xxxxxxxxxx> A few minor comments inline given you will need to do a v7 for the DT feedback. Otherwise I might just have tweaked these whilst applying. > diff --git a/drivers/iio/imu/adis16550.c b/drivers/iio/imu/adis16550.c > new file mode 100644 > index 000000000000..b20dc850346f > --- /dev/null > +++ b/drivers/iio/imu/adis16550.c > @@ -0,0 +1,1156 @@ > + > +struct adis16550 { > + const struct adis16550_chip_info *info; > + struct adis adis; > + unsigned long clk_freq_hz; > + u32 sync_mode; > + struct spi_transfer xfer[2]; > + u8 buffer[ADIS16550_BURST_DATA_LEN + sizeof(u32)] __aligned(IIO_DMA_MINALIGN); > + __be32 din[2] __aligned(IIO_DMA_MINALIGN); > + __be32 dout[2] __aligned(IIO_DMA_MINALIGN); In most cases only one such marking is needed. Devices tend not to interfere with themselves and we tend not to be changing values from software in one of the buffer DMA is targetting whilst the device is using the others. So we normally just mark the first one of a set like this. That avoids adding a lot of padding when it is not needed. > +}; > + > +static int adis16550_set_gyro_filter_freq(struct adis16550 *st, int freq_hz) > +{ > + u8 en = 0; > + > + if (freq_hz) > + en = 1; Could save a line or two without greatly affecting readability. Same thing applies in at least one other place. u8 en = freq_hz ? 1 : 0; > + > + return __adis_update_bits(&st->adis, ADIS16550_REG_CONFIG, > + ADIS16550_GYRO_FIR_EN_MASK, > + FIELD_PREP(ADIS16550_GYRO_FIR_EN_MASK, en)); > +} > + > +static irqreturn_t adis16550_trigger_handler(int irq, void *p) > +{ > + memcpy(data, &buffer[3], (ADIS16550_SCAN_ACCEL_Z - > + ADIS16550_SCAN_GYRO_X + 2) * > + sizeof(__be32)); Strange alignment. memcpy(data, &buffer[3], (ADIS16550_SCAN_ACCEL_Z - ADIS16550_SCAN_GYRO_X + 2) * sizeof(__be32)); Is about the best I could come up with. Good to add a comment on why the + 2 as well. > + iio_push_to_buffers_with_timestamp(indio_dev, data, pf->timestamp); > +done: > + iio_trigger_notify_done(indio_dev->trig); > + return IRQ_HANDLED; > +} > +static int adis16550_probe(struct spi_device *spi) > +{ > + u16 burst_length = ADIS16550_BURST_DATA_LEN; > + struct device *dev = &spi->dev; > + struct iio_dev *indio_dev; > + struct adis16550 *st; > + struct adis *adis; > + int ret; > + > + indio_dev = devm_iio_device_alloc(dev, sizeof(*st)); > + if (!indio_dev) > + return -ENOMEM; > + > + st = iio_priv(indio_dev); > + st->info = spi_get_device_match_data(spi); > + if (!st->info) > + return -EINVAL; > + adis = &st->adis; > + indio_dev->name = st->info->name; > + indio_dev->channels = st->info->channels; > + indio_dev->num_channels = st->info->num_channels; > + indio_dev->available_scan_masks = adis16550_channel_masks; > + indio_dev->info = &adis16550_info; > + indio_dev->modes = INDIO_DIRECT_MODE; > + > + st->adis.ops = &adis16550_ops; > + st->xfer[0].tx_buf = st->buffer + burst_length; > + st->xfer[0].len = 4; > + st->xfer[0].cs_change = 1; > + st->xfer[0].delay.value = 8; > + st->xfer[0].delay.unit = SPI_DELAY_UNIT_USECS; > + st->xfer[1].rx_buf = st->buffer; > + st->xfer[1].len = burst_length; > + > + spi_message_init_with_transfers(&adis->msg, st->xfer, 2); > + > + ret = devm_regulator_get_enable(dev, "vdd"); > + if (ret) > + return dev_err_probe(dev, ret, > + "Failed to get vdd regulator\n"); Totally trivial but preference is to align after ( unless the line ends up too long. In those cases it is fine to indent just one tab more than the line above. Here it actually fits on one line anyway as it's exactly 80 chars. return dev_err_probe(dev, ret, "Failed to get vdd regulator\n"); > + > + ret = adis_init(&st->adis, indio_dev, spi, &adis16550_data); > + if (ret) > + return ret; > + > + ret = __adis_initial_startup(&st->adis); > + if (ret) > + return ret; > + > + ret = adis16550_config_sync(st); > + if (ret) > + return ret; > + > + ret = devm_adis_setup_buffer_and_trigger(&st->adis, indio_dev, > + adis16550_trigger_handler); > + if (ret) > + return ret; > + > + ret = devm_iio_device_register(dev, indio_dev); > + if (ret) > + return ret; > + > + adis16550_debugfs_init(indio_dev); > + > + return 0; > +}