1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * 3-axis accelerometer driver supporting following Bosch-Sensortec chips: 4 * - BMI088 5 * 6 * Copyright (c) 2018-2021, Topic Embedded Products 7 */ 8 9 #include <linux/delay.h> 10 #include <linux/iio/iio.h> 11 #include <linux/iio/sysfs.h> 12 #include <linux/interrupt.h> 13 #include <linux/module.h> 14 #include <linux/pm.h> 15 #include <linux/pm_runtime.h> 16 #include <linux/regmap.h> 17 #include <linux/slab.h> 18 #include <asm/unaligned.h> 19 20 #include "bmi088-accel.h" 21 22 #define BMI088_ACCEL_REG_CHIP_ID 0x00 23 #define BMI088_ACCEL_REG_ERROR 0x02 24 25 #define BMI088_ACCEL_REG_INT_STATUS 0x1D 26 #define BMI088_ACCEL_INT_STATUS_BIT_DRDY BIT(7) 27 28 #define BMI088_ACCEL_REG_RESET 0x7E 29 #define BMI088_ACCEL_RESET_VAL 0xB6 30 31 #define BMI088_ACCEL_REG_PWR_CTRL 0x7D 32 #define BMI088_ACCEL_REG_PWR_CONF 0x7C 33 34 #define BMI088_ACCEL_REG_INT_MAP_DATA 0x58 35 #define BMI088_ACCEL_INT_MAP_DATA_BIT_INT1_DRDY BIT(2) 36 #define BMI088_ACCEL_INT_MAP_DATA_BIT_INT2_FWM BIT(5) 37 38 #define BMI088_ACCEL_REG_INT1_IO_CONF 0x53 39 #define BMI088_ACCEL_INT1_IO_CONF_BIT_ENABLE_OUT BIT(3) 40 #define BMI088_ACCEL_INT1_IO_CONF_BIT_LVL BIT(1) 41 42 #define BMI088_ACCEL_REG_INT2_IO_CONF 0x54 43 #define BMI088_ACCEL_INT2_IO_CONF_BIT_ENABLE_OUT BIT(3) 44 #define BMI088_ACCEL_INT2_IO_CONF_BIT_LVL BIT(1) 45 46 #define BMI088_ACCEL_REG_ACC_CONF 0x40 47 #define BMI088_ACCEL_MODE_ODR_MASK 0x0f 48 49 #define BMI088_ACCEL_REG_ACC_RANGE 0x41 50 #define BMI088_ACCEL_RANGE_3G 0x00 51 #define BMI088_ACCEL_RANGE_6G 0x01 52 #define BMI088_ACCEL_RANGE_12G 0x02 53 #define BMI088_ACCEL_RANGE_24G 0x03 54 55 #define BMI088_ACCEL_REG_TEMP 0x22 56 #define BMI088_ACCEL_REG_TEMP_SHIFT 5 57 #define BMI088_ACCEL_TEMP_UNIT 125 58 #define BMI088_ACCEL_TEMP_OFFSET 23000 59 60 #define BMI088_ACCEL_REG_XOUT_L 0x12 61 #define BMI088_ACCEL_AXIS_TO_REG(axis) \ 62 (BMI088_ACCEL_REG_XOUT_L + (axis * 2)) 63 64 #define BMI088_ACCEL_MAX_STARTUP_TIME_US 1000 65 #define BMI088_AUTO_SUSPEND_DELAY_MS 2000 66 67 #define BMI088_ACCEL_REG_FIFO_STATUS 0x0E 68 #define BMI088_ACCEL_REG_FIFO_CONFIG0 0x48 69 #define BMI088_ACCEL_REG_FIFO_CONFIG1 0x49 70 #define BMI088_ACCEL_REG_FIFO_DATA 0x3F 71 #define BMI088_ACCEL_FIFO_LENGTH 100 72 73 #define BMI088_ACCEL_FIFO_MODE_FIFO 0x40 74 #define BMI088_ACCEL_FIFO_MODE_STREAM 0x80 75 76 enum bmi088_accel_axis { 77 AXIS_X, 78 AXIS_Y, 79 AXIS_Z, 80 }; 81 82 static const int bmi088_sample_freqs[] = { 83 12, 500000, 84 25, 0, 85 50, 0, 86 100, 0, 87 200, 0, 88 400, 0, 89 800, 0, 90 1600, 0, 91 }; 92 93 /* Available OSR (over sampling rate) sets the 3dB cut-off frequency */ 94 enum bmi088_osr_modes { 95 BMI088_ACCEL_MODE_OSR_NORMAL = 0xA, 96 BMI088_ACCEL_MODE_OSR_2 = 0x9, 97 BMI088_ACCEL_MODE_OSR_4 = 0x8, 98 }; 99 100 /* Available ODR (output data rates) in Hz */ 101 enum bmi088_odr_modes { 102 BMI088_ACCEL_MODE_ODR_12_5 = 0x5, 103 BMI088_ACCEL_MODE_ODR_25 = 0x6, 104 BMI088_ACCEL_MODE_ODR_50 = 0x7, 105 BMI088_ACCEL_MODE_ODR_100 = 0x8, 106 BMI088_ACCEL_MODE_ODR_200 = 0x9, 107 BMI088_ACCEL_MODE_ODR_400 = 0xa, 108 BMI088_ACCEL_MODE_ODR_800 = 0xb, 109 BMI088_ACCEL_MODE_ODR_1600 = 0xc, 110 }; 111 112 struct bmi088_scale_info { 113 int scale; 114 u8 reg_range; 115 }; 116 117 struct bmi088_accel_chip_info { 118 const char *name; 119 u8 chip_id; 120 const struct iio_chan_spec *channels; 121 int num_channels; 122 }; 123 124 struct bmi088_accel_data { 125 struct regmap *regmap; 126 const struct bmi088_accel_chip_info *chip_info; 127 u8 buffer[2] ____cacheline_aligned; /* shared DMA safe buffer */ 128 }; 129 130 static const struct regmap_range bmi088_volatile_ranges[] = { 131 /* All registers below 0x40 are volatile, except the CHIP ID. */ 132 regmap_reg_range(BMI088_ACCEL_REG_ERROR, 0x3f), 133 /* Mark the RESET as volatile too, it is self-clearing */ 134 regmap_reg_range(BMI088_ACCEL_REG_RESET, BMI088_ACCEL_REG_RESET), 135 }; 136 137 static const struct regmap_access_table bmi088_volatile_table = { 138 .yes_ranges = bmi088_volatile_ranges, 139 .n_yes_ranges = ARRAY_SIZE(bmi088_volatile_ranges), 140 }; 141 142 const struct regmap_config bmi088_regmap_conf = { 143 .reg_bits = 8, 144 .val_bits = 8, 145 .max_register = 0x7E, 146 .volatile_table = &bmi088_volatile_table, 147 .cache_type = REGCACHE_RBTREE, 148 }; 149 EXPORT_SYMBOL_GPL(bmi088_regmap_conf); 150 151 static int bmi088_accel_power_up(struct bmi088_accel_data *data) 152 { 153 int ret; 154 155 /* Enable accelerometer and temperature sensor */ 156 ret = regmap_write(data->regmap, BMI088_ACCEL_REG_PWR_CTRL, 0x4); 157 if (ret) 158 return ret; 159 160 /* Datasheet recommends to wait at least 5ms before communication */ 161 usleep_range(5000, 6000); 162 163 /* Disable suspend mode */ 164 ret = regmap_write(data->regmap, BMI088_ACCEL_REG_PWR_CONF, 0x0); 165 if (ret) 166 return ret; 167 168 /* Recommended at least 1ms before further communication */ 169 usleep_range(1000, 1200); 170 171 return 0; 172 } 173 174 static int bmi088_accel_power_down(struct bmi088_accel_data *data) 175 { 176 int ret; 177 178 /* Enable suspend mode */ 179 ret = regmap_write(data->regmap, BMI088_ACCEL_REG_PWR_CONF, 0x3); 180 if (ret) 181 return ret; 182 183 /* Recommended at least 1ms before further communication */ 184 usleep_range(1000, 1200); 185 186 /* Disable accelerometer and temperature sensor */ 187 ret = regmap_write(data->regmap, BMI088_ACCEL_REG_PWR_CTRL, 0x0); 188 if (ret) 189 return ret; 190 191 /* Datasheet recommends to wait at least 5ms before communication */ 192 usleep_range(5000, 6000); 193 194 return 0; 195 } 196 197 static int bmi088_accel_get_sample_freq(struct bmi088_accel_data *data, 198 int *val, int *val2) 199 { 200 unsigned int value; 201 int ret; 202 203 ret = regmap_read(data->regmap, BMI088_ACCEL_REG_ACC_CONF, 204 &value); 205 if (ret) 206 return ret; 207 208 value &= BMI088_ACCEL_MODE_ODR_MASK; 209 value -= BMI088_ACCEL_MODE_ODR_12_5; 210 value <<= 1; 211 212 if (value >= ARRAY_SIZE(bmi088_sample_freqs) - 1) 213 return -EINVAL; 214 215 *val = bmi088_sample_freqs[value]; 216 *val2 = bmi088_sample_freqs[value + 1]; 217 218 return IIO_VAL_INT_PLUS_MICRO; 219 } 220 221 static int bmi088_accel_set_sample_freq(struct bmi088_accel_data *data, int val) 222 { 223 unsigned int regval; 224 int index = 0; 225 226 while (index < ARRAY_SIZE(bmi088_sample_freqs) && 227 bmi088_sample_freqs[index] != val) 228 index += 2; 229 230 if (index >= ARRAY_SIZE(bmi088_sample_freqs)) 231 return -EINVAL; 232 233 regval = (index >> 1) + BMI088_ACCEL_MODE_ODR_12_5; 234 235 return regmap_update_bits(data->regmap, BMI088_ACCEL_REG_ACC_CONF, 236 BMI088_ACCEL_MODE_ODR_MASK, regval); 237 } 238 239 static int bmi088_accel_get_temp(struct bmi088_accel_data *data, int *val) 240 { 241 int ret; 242 s16 temp; 243 244 ret = regmap_bulk_read(data->regmap, BMI088_ACCEL_REG_TEMP, 245 &data->buffer, sizeof(__be16)); 246 if (ret) 247 return ret; 248 249 /* data->buffer is cacheline aligned */ 250 temp = be16_to_cpu(*(__be16 *)data->buffer); 251 252 *val = temp >> BMI088_ACCEL_REG_TEMP_SHIFT; 253 254 return IIO_VAL_INT; 255 } 256 257 static int bmi088_accel_get_axis(struct bmi088_accel_data *data, 258 struct iio_chan_spec const *chan, 259 int *val) 260 { 261 int ret; 262 s16 raw_val; 263 264 ret = regmap_bulk_read(data->regmap, 265 BMI088_ACCEL_AXIS_TO_REG(chan->scan_index), 266 data->buffer, sizeof(__le16)); 267 if (ret) 268 return ret; 269 270 raw_val = le16_to_cpu(*(__le16 *)data->buffer); 271 *val = raw_val; 272 273 return IIO_VAL_INT; 274 } 275 276 static int bmi088_accel_read_raw(struct iio_dev *indio_dev, 277 struct iio_chan_spec const *chan, 278 int *val, int *val2, long mask) 279 { 280 struct bmi088_accel_data *data = iio_priv(indio_dev); 281 struct device *dev = regmap_get_device(data->regmap); 282 int ret; 283 284 switch (mask) { 285 case IIO_CHAN_INFO_RAW: 286 switch (chan->type) { 287 case IIO_TEMP: 288 pm_runtime_get_sync(dev); 289 ret = bmi088_accel_get_temp(data, val); 290 goto out_read_raw_pm_put; 291 case IIO_ACCEL: 292 pm_runtime_get_sync(dev); 293 ret = iio_device_claim_direct_mode(indio_dev); 294 if (ret) 295 goto out_read_raw_pm_put; 296 297 ret = bmi088_accel_get_axis(data, chan, val); 298 iio_device_release_direct_mode(indio_dev); 299 if (!ret) 300 ret = IIO_VAL_INT; 301 302 goto out_read_raw_pm_put; 303 default: 304 return -EINVAL; 305 } 306 case IIO_CHAN_INFO_OFFSET: 307 switch (chan->type) { 308 case IIO_TEMP: 309 /* Offset applies before scale */ 310 *val = BMI088_ACCEL_TEMP_OFFSET/BMI088_ACCEL_TEMP_UNIT; 311 return IIO_VAL_INT; 312 default: 313 return -EINVAL; 314 } 315 case IIO_CHAN_INFO_SCALE: 316 switch (chan->type) { 317 case IIO_TEMP: 318 /* 0.125 degrees per LSB */ 319 *val = BMI088_ACCEL_TEMP_UNIT; 320 return IIO_VAL_INT; 321 case IIO_ACCEL: 322 pm_runtime_get_sync(dev); 323 ret = regmap_read(data->regmap, 324 BMI088_ACCEL_REG_ACC_RANGE, val); 325 if (ret) 326 goto out_read_raw_pm_put; 327 328 *val2 = 15 - (*val & 0x3); 329 *val = 3 * 980; 330 ret = IIO_VAL_FRACTIONAL_LOG2; 331 332 goto out_read_raw_pm_put; 333 default: 334 return -EINVAL; 335 } 336 case IIO_CHAN_INFO_SAMP_FREQ: 337 pm_runtime_get_sync(dev); 338 ret = bmi088_accel_get_sample_freq(data, val, val2); 339 goto out_read_raw_pm_put; 340 default: 341 break; 342 } 343 344 return -EINVAL; 345 346 out_read_raw_pm_put: 347 pm_runtime_mark_last_busy(dev); 348 pm_runtime_put_autosuspend(dev); 349 350 return ret; 351 } 352 353 static int bmi088_accel_read_avail(struct iio_dev *indio_dev, 354 struct iio_chan_spec const *chan, 355 const int **vals, int *type, int *length, 356 long mask) 357 { 358 switch (mask) { 359 case IIO_CHAN_INFO_SAMP_FREQ: 360 *type = IIO_VAL_INT_PLUS_MICRO; 361 *vals = bmi088_sample_freqs; 362 *length = ARRAY_SIZE(bmi088_sample_freqs); 363 return IIO_AVAIL_LIST; 364 default: 365 return -EINVAL; 366 } 367 } 368 369 static int bmi088_accel_write_raw(struct iio_dev *indio_dev, 370 struct iio_chan_spec const *chan, 371 int val, int val2, long mask) 372 { 373 struct bmi088_accel_data *data = iio_priv(indio_dev); 374 struct device *dev = regmap_get_device(data->regmap); 375 int ret; 376 377 switch (mask) { 378 case IIO_CHAN_INFO_SAMP_FREQ: 379 pm_runtime_get_sync(dev); 380 ret = bmi088_accel_set_sample_freq(data, val); 381 pm_runtime_mark_last_busy(dev); 382 pm_runtime_put_autosuspend(dev); 383 return ret; 384 default: 385 return -EINVAL; 386 } 387 } 388 389 #define BMI088_ACCEL_CHANNEL(_axis) { \ 390 .type = IIO_ACCEL, \ 391 .modified = 1, \ 392 .channel2 = IIO_MOD_##_axis, \ 393 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \ 394 .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) | \ 395 BIT(IIO_CHAN_INFO_SAMP_FREQ), \ 396 .info_mask_shared_by_type_available = BIT(IIO_CHAN_INFO_SAMP_FREQ), \ 397 .scan_index = AXIS_##_axis, \ 398 } 399 400 static const struct iio_chan_spec bmi088_accel_channels[] = { 401 { 402 .type = IIO_TEMP, 403 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | 404 BIT(IIO_CHAN_INFO_SCALE) | 405 BIT(IIO_CHAN_INFO_OFFSET), 406 .scan_index = -1, 407 }, 408 BMI088_ACCEL_CHANNEL(X), 409 BMI088_ACCEL_CHANNEL(Y), 410 BMI088_ACCEL_CHANNEL(Z), 411 IIO_CHAN_SOFT_TIMESTAMP(3), 412 }; 413 414 static const struct bmi088_accel_chip_info bmi088_accel_chip_info_tbl[] = { 415 [0] = { 416 .name = "bmi088a", 417 .chip_id = 0x1E, 418 .channels = bmi088_accel_channels, 419 .num_channels = ARRAY_SIZE(bmi088_accel_channels), 420 }, 421 }; 422 423 static const struct iio_info bmi088_accel_info = { 424 .read_raw = bmi088_accel_read_raw, 425 .write_raw = bmi088_accel_write_raw, 426 .read_avail = bmi088_accel_read_avail, 427 }; 428 429 static const unsigned long bmi088_accel_scan_masks[] = { 430 BIT(AXIS_X) | BIT(AXIS_Y) | BIT(AXIS_Z), 431 0 432 }; 433 434 static int bmi088_accel_chip_init(struct bmi088_accel_data *data) 435 { 436 struct device *dev = regmap_get_device(data->regmap); 437 int ret, i; 438 unsigned int val; 439 440 /* Do a dummy read to enable SPI interface, won't harm I2C */ 441 regmap_read(data->regmap, BMI088_ACCEL_REG_INT_STATUS, &val); 442 443 /* 444 * Reset chip to get it in a known good state. A delay of 1ms after 445 * reset is required according to the data sheet 446 */ 447 ret = regmap_write(data->regmap, BMI088_ACCEL_REG_RESET, 448 BMI088_ACCEL_RESET_VAL); 449 if (ret) 450 return ret; 451 452 usleep_range(1000, 2000); 453 454 /* Do a dummy read again after a reset to enable the SPI interface */ 455 regmap_read(data->regmap, BMI088_ACCEL_REG_INT_STATUS, &val); 456 457 /* Read chip ID */ 458 ret = regmap_read(data->regmap, BMI088_ACCEL_REG_CHIP_ID, &val); 459 if (ret) { 460 dev_err(dev, "Error: Reading chip id\n"); 461 return ret; 462 } 463 464 /* Validate chip ID */ 465 for (i = 0; i < ARRAY_SIZE(bmi088_accel_chip_info_tbl); i++) { 466 if (bmi088_accel_chip_info_tbl[i].chip_id == val) { 467 data->chip_info = &bmi088_accel_chip_info_tbl[i]; 468 break; 469 } 470 } 471 if (i == ARRAY_SIZE(bmi088_accel_chip_info_tbl)) { 472 dev_err(dev, "Invalid chip %x\n", val); 473 return -ENODEV; 474 } 475 476 return 0; 477 } 478 479 int bmi088_accel_core_probe(struct device *dev, struct regmap *regmap, 480 int irq, const char *name, bool block_supported) 481 { 482 struct bmi088_accel_data *data; 483 struct iio_dev *indio_dev; 484 int ret; 485 486 indio_dev = devm_iio_device_alloc(dev, sizeof(*data)); 487 if (!indio_dev) 488 return -ENOMEM; 489 490 data = iio_priv(indio_dev); 491 dev_set_drvdata(dev, indio_dev); 492 493 data->regmap = regmap; 494 495 ret = bmi088_accel_chip_init(data); 496 if (ret) 497 return ret; 498 499 indio_dev->dev.parent = dev; 500 indio_dev->channels = data->chip_info->channels; 501 indio_dev->num_channels = data->chip_info->num_channels; 502 indio_dev->name = name ? name : data->chip_info->name; 503 indio_dev->available_scan_masks = bmi088_accel_scan_masks; 504 indio_dev->modes = INDIO_DIRECT_MODE; 505 indio_dev->info = &bmi088_accel_info; 506 507 /* Enable runtime PM */ 508 pm_runtime_get_noresume(dev); 509 pm_runtime_set_suspended(dev); 510 pm_runtime_enable(dev); 511 /* We need ~6ms to startup, so set the delay to 6 seconds */ 512 pm_runtime_set_autosuspend_delay(dev, 6000); 513 pm_runtime_use_autosuspend(dev); 514 pm_runtime_put(dev); 515 516 ret = iio_device_register(indio_dev); 517 if (ret) 518 dev_err(dev, "Unable to register iio device\n"); 519 520 return ret; 521 } 522 EXPORT_SYMBOL_GPL(bmi088_accel_core_probe); 523 524 525 int bmi088_accel_core_remove(struct device *dev) 526 { 527 struct iio_dev *indio_dev = dev_get_drvdata(dev); 528 struct bmi088_accel_data *data = iio_priv(indio_dev); 529 530 iio_device_unregister(indio_dev); 531 532 pm_runtime_disable(dev); 533 pm_runtime_set_suspended(dev); 534 pm_runtime_put_noidle(dev); 535 bmi088_accel_power_down(data); 536 537 return 0; 538 } 539 EXPORT_SYMBOL_GPL(bmi088_accel_core_remove); 540 541 static int __maybe_unused bmi088_accel_runtime_suspend(struct device *dev) 542 { 543 struct iio_dev *indio_dev = dev_get_drvdata(dev); 544 struct bmi088_accel_data *data = iio_priv(indio_dev); 545 546 return bmi088_accel_power_down(data); 547 } 548 549 static int __maybe_unused bmi088_accel_runtime_resume(struct device *dev) 550 { 551 struct iio_dev *indio_dev = dev_get_drvdata(dev); 552 struct bmi088_accel_data *data = iio_priv(indio_dev); 553 554 return bmi088_accel_power_up(data); 555 } 556 557 const struct dev_pm_ops bmi088_accel_pm_ops = { 558 SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, 559 pm_runtime_force_resume) 560 SET_RUNTIME_PM_OPS(bmi088_accel_runtime_suspend, 561 bmi088_accel_runtime_resume, NULL) 562 }; 563 EXPORT_SYMBOL_GPL(bmi088_accel_pm_ops); 564 565 MODULE_AUTHOR("Niek van Agt <niek.van.agt@topicproducts.com>"); 566 MODULE_LICENSE("GPL v2"); 567 MODULE_DESCRIPTION("BMI088 accelerometer driver (core)"); 568