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 temperature channel

The BMI270 IMU includes a temperature sensor. Add a channel for reading
the temperature.

Signed-off-by: Gustavo Silva <gustavograzs@gmail.com>
Link: https://patch.msgid.link/20250118-bmi270-temp-v2-1-50bc85f36ab2@gmail.com
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>

authored by

Gustavo Silva and committed by
Jonathan Cameron
7ecbbb5b d438fc93

+43 -5
+43 -5
drivers/iio/imu/bmi270/bmi270_core.c
··· 5 5 #include <linux/i2c.h> 6 6 #include <linux/module.h> 7 7 #include <linux/regmap.h> 8 + #include <linux/units.h> 8 9 9 10 #include <linux/iio/iio.h> 10 11 #include <linux/iio/sysfs.h> ··· 29 28 #define BMI270_INTERNAL_STATUS_REG 0x21 30 29 #define BMI270_INTERNAL_STATUS_MSG_MSK GENMASK(3, 0) 31 30 #define BMI270_INTERNAL_STATUS_MSG_INIT_OK 0x01 32 - 33 31 #define BMI270_INTERNAL_STATUS_AXES_REMAP_ERR_MSK BIT(5) 34 32 #define BMI270_INTERNAL_STATUS_ODR_50HZ_ERR_MSK BIT(6) 33 + 34 + #define BMI270_TEMPERATURE_0_REG 0x22 35 35 36 36 #define BMI270_ACC_CONF_REG 0x40 37 37 #define BMI270_ACC_CONF_ODR_MSK GENMASK(3, 0) ··· 70 68 #define BMI270_PWR_CTRL_GYR_EN_MSK BIT(1) 71 69 #define BMI270_PWR_CTRL_ACCEL_EN_MSK BIT(2) 72 70 #define BMI270_PWR_CTRL_TEMP_EN_MSK BIT(3) 71 + 72 + /* See datasheet section 4.6.14, Temperature Sensor */ 73 + #define BMI270_TEMP_OFFSET 11776 74 + #define BMI270_TEMP_SCALE 1953125 73 75 74 76 #define BMI260_INIT_DATA_FILE "bmi260-init-data.fw" 75 77 #define BMI270_INIT_DATA_FILE "bmi270-init-data.fw" ··· 115 109 enum bmi270_sensor_type { 116 110 BMI270_ACCEL = 0, 117 111 BMI270_GYRO, 112 + BMI270_TEMP, 118 113 }; 119 114 120 115 struct bmi270_scale { ··· 143 136 { 0, 66 }, 144 137 }; 145 138 139 + static const struct bmi270_scale bmi270_temp_scale[] = { 140 + { BMI270_TEMP_SCALE / MICRO, BMI270_TEMP_SCALE % MICRO }, 141 + }; 142 + 146 143 struct bmi270_scale_item { 147 144 const struct bmi270_scale *tbl; 148 145 int num; ··· 160 149 [BMI270_GYRO] = { 161 150 .tbl = bmi270_gyro_scale, 162 151 .num = ARRAY_SIZE(bmi270_gyro_scale), 152 + }, 153 + [BMI270_TEMP] = { 154 + .tbl = bmi270_temp_scale, 155 + .num = ARRAY_SIZE(bmi270_temp_scale), 163 156 }, 164 157 }; 165 158 ··· 270 255 } 271 256 272 257 static int bmi270_get_scale(struct bmi270_data *bmi270_device, int chan_type, 273 - int *uscale) 258 + int *scale, int *uscale) 274 259 { 275 260 int ret; 276 261 unsigned int val; ··· 295 280 val = FIELD_GET(BMI270_GYR_CONF_RANGE_MSK, val); 296 281 bmi270_scale_item = bmi270_scale_table[BMI270_GYRO]; 297 282 break; 283 + case IIO_TEMP: 284 + val = 0; 285 + bmi270_scale_item = bmi270_scale_table[BMI270_TEMP]; 286 + break; 298 287 default: 299 288 return -EINVAL; 300 289 } ··· 306 287 if (val >= bmi270_scale_item.num) 307 288 return -EINVAL; 308 289 290 + *scale = bmi270_scale_item.tbl[val].scale; 309 291 *uscale = bmi270_scale_item.tbl[val].uscale; 310 292 return 0; 311 293 } ··· 419 399 case IIO_ANGL_VEL: 420 400 reg = BMI270_ANG_VEL_X_REG + (axis - IIO_MOD_X) * 2; 421 401 break; 402 + case IIO_TEMP: 403 + reg = BMI270_TEMPERATURE_0_REG; 404 + break; 422 405 default: 423 406 return -EINVAL; 424 407 } ··· 450 427 451 428 return IIO_VAL_INT; 452 429 case IIO_CHAN_INFO_SCALE: 453 - *val = 0; 454 - ret = bmi270_get_scale(bmi270_device, chan->type, val2); 430 + ret = bmi270_get_scale(bmi270_device, chan->type, val, val2); 455 431 return ret ? ret : IIO_VAL_INT_PLUS_MICRO; 432 + case IIO_CHAN_INFO_OFFSET: 433 + switch (chan->type) { 434 + case IIO_TEMP: 435 + *val = BMI270_TEMP_OFFSET; 436 + return IIO_VAL_INT; 437 + default: 438 + return -EINVAL; 439 + } 456 440 case IIO_CHAN_INFO_SAMP_FREQ: 457 441 ret = bmi270_get_odr(bmi270_device, chan->type, val, val2); 458 442 return ret ? ret : IIO_VAL_INT_PLUS_MICRO; ··· 574 544 BMI270_ANG_VEL_CHANNEL(X), 575 545 BMI270_ANG_VEL_CHANNEL(Y), 576 546 BMI270_ANG_VEL_CHANNEL(Z), 547 + { 548 + .type = IIO_TEMP, 549 + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | 550 + BIT(IIO_CHAN_INFO_SCALE) | 551 + BIT(IIO_CHAN_INFO_OFFSET), 552 + .scan_index = -1, /* No buffer support */ 553 + }, 577 554 IIO_CHAN_SOFT_TIMESTAMP(BMI270_SCAN_TIMESTAMP), 578 555 }; 579 556 ··· 683 646 ret = regmap_set_bits(regmap, BMI270_PWR_CTRL_REG, 684 647 BMI270_PWR_CTRL_AUX_EN_MSK | 685 648 BMI270_PWR_CTRL_GYR_EN_MSK | 686 - BMI270_PWR_CTRL_ACCEL_EN_MSK); 649 + BMI270_PWR_CTRL_ACCEL_EN_MSK | 650 + BMI270_PWR_CTRL_TEMP_EN_MSK); 687 651 if (ret) 688 652 return dev_err_probe(dev, ret, "Failed to enable accelerometer and gyroscope"); 689 653