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: imu: bmi270: Add triggered buffer for Bosch BMI270 IMU

Set up a triggered buffer for the accel and angl_vel values.

Signed-off-by: Justin Weiss <justin@justinweiss.com>
Link: https://patch.msgid.link/20241027172029.160134-2-justin@justinweiss.com
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>

authored by

Justin Weiss and committed by
Jonathan Cameron
eaba902d 27f8b05b

+66
+1
drivers/iio/imu/bmi270/Kconfig
··· 6 6 config BMI270 7 7 tristate 8 8 select IIO_BUFFER 9 + select IIO_TRIGGERED_BUFFER 9 10 10 11 config BMI270_I2C 11 12 tristate "Bosch BMI270 I2C driver"
+9
drivers/iio/imu/bmi270/bmi270.h
··· 11 11 struct device *dev; 12 12 struct regmap *regmap; 13 13 const struct bmi270_chip_info *chip_info; 14 + 15 + /* 16 + * Where IIO_DMA_MINALIGN may be larger than 8 bytes, align to 17 + * that to ensure a DMA safe buffer. 18 + */ 19 + struct { 20 + __le16 channels[6]; 21 + aligned_s64 timestamp; 22 + } data __aligned(IIO_DMA_MINALIGN); 14 23 }; 15 24 16 25 struct bmi270_chip_info {
+56
drivers/iio/imu/bmi270/bmi270_core.c
··· 7 7 #include <linux/regmap.h> 8 8 9 9 #include <linux/iio/iio.h> 10 + #include <linux/iio/triggered_buffer.h> 11 + #include <linux/iio/trigger_consumer.h> 10 12 11 13 #include "bmi270.h" 12 14 ··· 66 64 BMI270_SCAN_GYRO_X, 67 65 BMI270_SCAN_GYRO_Y, 68 66 BMI270_SCAN_GYRO_Z, 67 + BMI270_SCAN_TIMESTAMP, 68 + }; 69 + 70 + static const unsigned long bmi270_avail_scan_masks[] = { 71 + (BIT(BMI270_SCAN_ACCEL_X) | 72 + BIT(BMI270_SCAN_ACCEL_Y) | 73 + BIT(BMI270_SCAN_ACCEL_Z) | 74 + BIT(BMI270_SCAN_GYRO_X) | 75 + BIT(BMI270_SCAN_GYRO_Y) | 76 + BIT(BMI270_SCAN_GYRO_Z)), 77 + 0 69 78 }; 70 79 71 80 const struct bmi270_chip_info bmi270_chip_info = { ··· 85 72 .fw_name = BMI270_INIT_DATA_FILE, 86 73 }; 87 74 EXPORT_SYMBOL_NS_GPL(bmi270_chip_info, IIO_BMI270); 75 + 76 + static irqreturn_t bmi270_trigger_handler(int irq, void *p) 77 + { 78 + struct iio_poll_func *pf = p; 79 + struct iio_dev *indio_dev = pf->indio_dev; 80 + struct bmi270_data *bmi270_device = iio_priv(indio_dev); 81 + int ret; 82 + 83 + ret = regmap_bulk_read(bmi270_device->regmap, BMI270_ACCEL_X_REG, 84 + &bmi270_device->data.channels, 85 + sizeof(bmi270_device->data.channels)); 86 + 87 + if (ret) 88 + goto done; 89 + 90 + iio_push_to_buffers_with_timestamp(indio_dev, &bmi270_device->data, 91 + pf->timestamp); 92 + done: 93 + iio_trigger_notify_done(indio_dev->trig); 94 + return IRQ_HANDLED; 95 + } 88 96 89 97 static int bmi270_get_data(struct bmi270_data *bmi270_device, 90 98 int chan_type, int axis, int *val) ··· 162 128 .modified = 1, \ 163 129 .channel2 = IIO_MOD_##_axis, \ 164 130 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \ 131 + .scan_index = BMI270_SCAN_ACCEL_##_axis, \ 132 + .scan_type = { \ 133 + .sign = 's', \ 134 + .realbits = 16, \ 135 + .storagebits = 16, \ 136 + .endianness = IIO_LE, \ 137 + }, \ 165 138 } 166 139 167 140 #define BMI270_ANG_VEL_CHANNEL(_axis) { \ ··· 176 135 .modified = 1, \ 177 136 .channel2 = IIO_MOD_##_axis, \ 178 137 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \ 138 + .scan_index = BMI270_SCAN_GYRO_##_axis, \ 139 + .scan_type = { \ 140 + .sign = 's', \ 141 + .realbits = 16, \ 142 + .storagebits = 16, \ 143 + .endianness = IIO_LE, \ 144 + }, \ 179 145 } 180 146 181 147 static const struct iio_chan_spec bmi270_channels[] = { ··· 192 144 BMI270_ANG_VEL_CHANNEL(X), 193 145 BMI270_ANG_VEL_CHANNEL(Y), 194 146 BMI270_ANG_VEL_CHANNEL(Z), 147 + IIO_CHAN_SOFT_TIMESTAMP(BMI270_SCAN_TIMESTAMP), 195 148 }; 196 149 197 150 static int bmi270_validate_chip_id(struct bmi270_data *bmi270_device) ··· 350 301 indio_dev->channels = bmi270_channels; 351 302 indio_dev->num_channels = ARRAY_SIZE(bmi270_channels); 352 303 indio_dev->name = chip_info->name; 304 + indio_dev->available_scan_masks = bmi270_avail_scan_masks; 353 305 indio_dev->modes = INDIO_DIRECT_MODE; 354 306 indio_dev->info = &bmi270_info; 307 + 308 + ret = devm_iio_triggered_buffer_setup(dev, indio_dev, 309 + iio_pollfunc_store_time, 310 + bmi270_trigger_handler, NULL); 311 + if (ret) 312 + return ret; 355 313 356 314 return devm_iio_device_register(dev, indio_dev); 357 315 }