1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * Copyright (C) 2020 Invensense, Inc. 4 */ 5 6 #include <linux/kernel.h> 7 #include <linux/device.h> 8 #include <linux/mutex.h> 9 #include <linux/pm_runtime.h> 10 #include <linux/regmap.h> 11 #include <linux/delay.h> 12 13 #include <linux/iio/buffer.h> 14 #include <linux/iio/common/inv_sensors_timestamp.h> 15 #include <linux/iio/iio.h> 16 17 #include "inv_icm42600.h" 18 #include "inv_icm42600_buffer.h" 19 20 /* FIFO header: 1 byte */ 21 #define INV_ICM42600_FIFO_HEADER_MSG BIT(7) 22 #define INV_ICM42600_FIFO_HEADER_ACCEL BIT(6) 23 #define INV_ICM42600_FIFO_HEADER_GYRO BIT(5) 24 #define INV_ICM42600_FIFO_HEADER_TMST_FSYNC GENMASK(3, 2) 25 #define INV_ICM42600_FIFO_HEADER_ODR_ACCEL BIT(1) 26 #define INV_ICM42600_FIFO_HEADER_ODR_GYRO BIT(0) 27 28 struct inv_icm42600_fifo_1sensor_packet { 29 uint8_t header; 30 struct inv_icm42600_fifo_sensor_data data; 31 int8_t temp; 32 } __packed; 33 #define INV_ICM42600_FIFO_1SENSOR_PACKET_SIZE 8 34 35 struct inv_icm42600_fifo_2sensors_packet { 36 uint8_t header; 37 struct inv_icm42600_fifo_sensor_data accel; 38 struct inv_icm42600_fifo_sensor_data gyro; 39 int8_t temp; 40 __be16 timestamp; 41 } __packed; 42 #define INV_ICM42600_FIFO_2SENSORS_PACKET_SIZE 16 43 44 ssize_t inv_icm42600_fifo_decode_packet(const void *packet, const void **accel, 45 const void **gyro, const int8_t **temp, 46 const void **timestamp, unsigned int *odr) 47 { 48 const struct inv_icm42600_fifo_1sensor_packet *pack1 = packet; 49 const struct inv_icm42600_fifo_2sensors_packet *pack2 = packet; 50 uint8_t header = *((const uint8_t *)packet); 51 52 /* FIFO empty */ 53 if (header & INV_ICM42600_FIFO_HEADER_MSG) { 54 *accel = NULL; 55 *gyro = NULL; 56 *temp = NULL; 57 *timestamp = NULL; 58 *odr = 0; 59 return 0; 60 } 61 62 /* handle odr flags */ 63 *odr = 0; 64 if (header & INV_ICM42600_FIFO_HEADER_ODR_GYRO) 65 *odr |= INV_ICM42600_SENSOR_GYRO; 66 if (header & INV_ICM42600_FIFO_HEADER_ODR_ACCEL) 67 *odr |= INV_ICM42600_SENSOR_ACCEL; 68 69 /* accel + gyro */ 70 if ((header & INV_ICM42600_FIFO_HEADER_ACCEL) && 71 (header & INV_ICM42600_FIFO_HEADER_GYRO)) { 72 *accel = &pack2->accel; 73 *gyro = &pack2->gyro; 74 *temp = &pack2->temp; 75 *timestamp = &pack2->timestamp; 76 return INV_ICM42600_FIFO_2SENSORS_PACKET_SIZE; 77 } 78 79 /* accel only */ 80 if (header & INV_ICM42600_FIFO_HEADER_ACCEL) { 81 *accel = &pack1->data; 82 *gyro = NULL; 83 *temp = &pack1->temp; 84 *timestamp = NULL; 85 return INV_ICM42600_FIFO_1SENSOR_PACKET_SIZE; 86 } 87 88 /* gyro only */ 89 if (header & INV_ICM42600_FIFO_HEADER_GYRO) { 90 *accel = NULL; 91 *gyro = &pack1->data; 92 *temp = &pack1->temp; 93 *timestamp = NULL; 94 return INV_ICM42600_FIFO_1SENSOR_PACKET_SIZE; 95 } 96 97 /* invalid packet if here */ 98 return -EINVAL; 99 } 100 101 void inv_icm42600_buffer_update_fifo_period(struct inv_icm42600_state *st) 102 { 103 uint32_t period_gyro, period_accel, period; 104 105 if (st->fifo.en & INV_ICM42600_SENSOR_GYRO) 106 period_gyro = inv_icm42600_odr_to_period(st->conf.gyro.odr); 107 else 108 period_gyro = U32_MAX; 109 110 if (st->fifo.en & INV_ICM42600_SENSOR_ACCEL) 111 period_accel = inv_icm42600_odr_to_period(st->conf.accel.odr); 112 else 113 period_accel = U32_MAX; 114 115 if (period_gyro <= period_accel) 116 period = period_gyro; 117 else 118 period = period_accel; 119 120 st->fifo.period = period; 121 } 122 123 int inv_icm42600_buffer_set_fifo_en(struct inv_icm42600_state *st, 124 unsigned int fifo_en) 125 { 126 unsigned int mask, val; 127 int ret; 128 129 /* update only FIFO EN bits */ 130 mask = INV_ICM42600_FIFO_CONFIG1_TMST_FSYNC_EN | 131 INV_ICM42600_FIFO_CONFIG1_TEMP_EN | 132 INV_ICM42600_FIFO_CONFIG1_GYRO_EN | 133 INV_ICM42600_FIFO_CONFIG1_ACCEL_EN; 134 135 val = 0; 136 if (fifo_en & INV_ICM42600_SENSOR_GYRO) 137 val |= INV_ICM42600_FIFO_CONFIG1_GYRO_EN; 138 if (fifo_en & INV_ICM42600_SENSOR_ACCEL) 139 val |= INV_ICM42600_FIFO_CONFIG1_ACCEL_EN; 140 if (fifo_en & INV_ICM42600_SENSOR_TEMP) 141 val |= INV_ICM42600_FIFO_CONFIG1_TEMP_EN; 142 143 ret = regmap_update_bits(st->map, INV_ICM42600_REG_FIFO_CONFIG1, mask, val); 144 if (ret) 145 return ret; 146 147 st->fifo.en = fifo_en; 148 inv_icm42600_buffer_update_fifo_period(st); 149 150 return 0; 151 } 152 153 static size_t inv_icm42600_get_packet_size(unsigned int fifo_en) 154 { 155 size_t packet_size; 156 157 if ((fifo_en & INV_ICM42600_SENSOR_GYRO) && 158 (fifo_en & INV_ICM42600_SENSOR_ACCEL)) 159 packet_size = INV_ICM42600_FIFO_2SENSORS_PACKET_SIZE; 160 else 161 packet_size = INV_ICM42600_FIFO_1SENSOR_PACKET_SIZE; 162 163 return packet_size; 164 } 165 166 static unsigned int inv_icm42600_wm_truncate(unsigned int watermark, 167 size_t packet_size) 168 { 169 size_t wm_size; 170 unsigned int wm; 171 172 wm_size = watermark * packet_size; 173 if (wm_size > INV_ICM42600_FIFO_WATERMARK_MAX) 174 wm_size = INV_ICM42600_FIFO_WATERMARK_MAX; 175 176 wm = wm_size / packet_size; 177 178 return wm; 179 } 180 181 /** 182 * inv_icm42600_buffer_update_watermark - update watermark FIFO threshold 183 * @st: driver internal state 184 * 185 * Returns 0 on success, a negative error code otherwise. 186 * 187 * FIFO watermark threshold is computed based on the required watermark values 188 * set for gyro and accel sensors. Since watermark is all about acceptable data 189 * latency, use the smallest setting between the 2. It means choosing the 190 * smallest latency but this is not as simple as choosing the smallest watermark 191 * value. Latency depends on watermark and ODR. It requires several steps: 192 * 1) compute gyro and accel latencies and choose the smallest value. 193 * 2) adapt the choosen latency so that it is a multiple of both gyro and accel 194 * ones. Otherwise it is possible that you don't meet a requirement. (for 195 * example with gyro @100Hz wm 4 and accel @100Hz with wm 6, choosing the 196 * value of 4 will not meet accel latency requirement because 6 is not a 197 * multiple of 4. You need to use the value 2.) 198 * 3) Since all periods are multiple of each others, watermark is computed by 199 * dividing this computed latency by the smallest period, which corresponds 200 * to the FIFO frequency. Beware that this is only true because we are not 201 * using 500Hz frequency which is not a multiple of the others. 202 */ 203 int inv_icm42600_buffer_update_watermark(struct inv_icm42600_state *st) 204 { 205 size_t packet_size, wm_size; 206 unsigned int wm_gyro, wm_accel, watermark; 207 uint32_t period_gyro, period_accel, period; 208 uint32_t latency_gyro, latency_accel, latency; 209 bool restore; 210 __le16 raw_wm; 211 int ret; 212 213 packet_size = inv_icm42600_get_packet_size(st->fifo.en); 214 215 /* compute sensors latency, depending on sensor watermark and odr */ 216 wm_gyro = inv_icm42600_wm_truncate(st->fifo.watermark.gyro, packet_size); 217 wm_accel = inv_icm42600_wm_truncate(st->fifo.watermark.accel, packet_size); 218 /* use us for odr to avoid overflow using 32 bits values */ 219 period_gyro = inv_icm42600_odr_to_period(st->conf.gyro.odr) / 1000UL; 220 period_accel = inv_icm42600_odr_to_period(st->conf.accel.odr) / 1000UL; 221 latency_gyro = period_gyro * wm_gyro; 222 latency_accel = period_accel * wm_accel; 223 224 /* 0 value for watermark means that the sensor is turned off */ 225 if (wm_gyro == 0 && wm_accel == 0) 226 return 0; 227 228 if (latency_gyro == 0) { 229 watermark = wm_accel; 230 st->fifo.watermark.eff_accel = wm_accel; 231 } else if (latency_accel == 0) { 232 watermark = wm_gyro; 233 st->fifo.watermark.eff_gyro = wm_gyro; 234 } else { 235 /* compute the smallest latency that is a multiple of both */ 236 if (latency_gyro <= latency_accel) 237 latency = latency_gyro - (latency_accel % latency_gyro); 238 else 239 latency = latency_accel - (latency_gyro % latency_accel); 240 /* use the shortest period */ 241 if (period_gyro <= period_accel) 242 period = period_gyro; 243 else 244 period = period_accel; 245 /* all this works because periods are multiple of each others */ 246 watermark = latency / period; 247 if (watermark < 1) 248 watermark = 1; 249 /* update effective watermark */ 250 st->fifo.watermark.eff_gyro = latency / period_gyro; 251 if (st->fifo.watermark.eff_gyro < 1) 252 st->fifo.watermark.eff_gyro = 1; 253 st->fifo.watermark.eff_accel = latency / period_accel; 254 if (st->fifo.watermark.eff_accel < 1) 255 st->fifo.watermark.eff_accel = 1; 256 } 257 258 /* compute watermark value in bytes */ 259 wm_size = watermark * packet_size; 260 261 /* changing FIFO watermark requires to turn off watermark interrupt */ 262 ret = regmap_update_bits_check(st->map, INV_ICM42600_REG_INT_SOURCE0, 263 INV_ICM42600_INT_SOURCE0_FIFO_THS_INT1_EN, 264 0, &restore); 265 if (ret) 266 return ret; 267 268 raw_wm = INV_ICM42600_FIFO_WATERMARK_VAL(wm_size); 269 memcpy(st->buffer, &raw_wm, sizeof(raw_wm)); 270 ret = regmap_bulk_write(st->map, INV_ICM42600_REG_FIFO_WATERMARK, 271 st->buffer, sizeof(raw_wm)); 272 if (ret) 273 return ret; 274 275 /* restore watermark interrupt */ 276 if (restore) { 277 ret = regmap_update_bits(st->map, INV_ICM42600_REG_INT_SOURCE0, 278 INV_ICM42600_INT_SOURCE0_FIFO_THS_INT1_EN, 279 INV_ICM42600_INT_SOURCE0_FIFO_THS_INT1_EN); 280 if (ret) 281 return ret; 282 } 283 284 return 0; 285 } 286 287 static int inv_icm42600_buffer_preenable(struct iio_dev *indio_dev) 288 { 289 struct inv_icm42600_state *st = iio_device_get_drvdata(indio_dev); 290 struct device *dev = regmap_get_device(st->map); 291 struct inv_icm42600_sensor_state *sensor_st = iio_priv(indio_dev); 292 struct inv_sensors_timestamp *ts = &sensor_st->ts; 293 294 pm_runtime_get_sync(dev); 295 296 mutex_lock(&st->lock); 297 inv_sensors_timestamp_reset(ts); 298 mutex_unlock(&st->lock); 299 300 return 0; 301 } 302 303 /* 304 * update_scan_mode callback is turning sensors on and setting data FIFO enable 305 * bits. 306 */ 307 static int inv_icm42600_buffer_postenable(struct iio_dev *indio_dev) 308 { 309 struct inv_icm42600_state *st = iio_device_get_drvdata(indio_dev); 310 int ret; 311 312 mutex_lock(&st->lock); 313 314 /* exit if FIFO is already on */ 315 if (st->fifo.on) { 316 ret = 0; 317 goto out_on; 318 } 319 320 /* set FIFO threshold interrupt */ 321 ret = regmap_update_bits(st->map, INV_ICM42600_REG_INT_SOURCE0, 322 INV_ICM42600_INT_SOURCE0_FIFO_THS_INT1_EN, 323 INV_ICM42600_INT_SOURCE0_FIFO_THS_INT1_EN); 324 if (ret) 325 goto out_unlock; 326 327 /* flush FIFO data */ 328 ret = regmap_write(st->map, INV_ICM42600_REG_SIGNAL_PATH_RESET, 329 INV_ICM42600_SIGNAL_PATH_RESET_FIFO_FLUSH); 330 if (ret) 331 goto out_unlock; 332 333 /* set FIFO in streaming mode */ 334 ret = regmap_write(st->map, INV_ICM42600_REG_FIFO_CONFIG, 335 INV_ICM42600_FIFO_CONFIG_STREAM); 336 if (ret) 337 goto out_unlock; 338 339 /* workaround: first read of FIFO count after reset is always 0 */ 340 ret = regmap_bulk_read(st->map, INV_ICM42600_REG_FIFO_COUNT, st->buffer, 2); 341 if (ret) 342 goto out_unlock; 343 344 out_on: 345 /* increase FIFO on counter */ 346 st->fifo.on++; 347 out_unlock: 348 mutex_unlock(&st->lock); 349 return ret; 350 } 351 352 static int inv_icm42600_buffer_predisable(struct iio_dev *indio_dev) 353 { 354 struct inv_icm42600_state *st = iio_device_get_drvdata(indio_dev); 355 int ret; 356 357 mutex_lock(&st->lock); 358 359 /* exit if there are several sensors using the FIFO */ 360 if (st->fifo.on > 1) { 361 ret = 0; 362 goto out_off; 363 } 364 365 /* set FIFO in bypass mode */ 366 ret = regmap_write(st->map, INV_ICM42600_REG_FIFO_CONFIG, 367 INV_ICM42600_FIFO_CONFIG_BYPASS); 368 if (ret) 369 goto out_unlock; 370 371 /* flush FIFO data */ 372 ret = regmap_write(st->map, INV_ICM42600_REG_SIGNAL_PATH_RESET, 373 INV_ICM42600_SIGNAL_PATH_RESET_FIFO_FLUSH); 374 if (ret) 375 goto out_unlock; 376 377 /* disable FIFO threshold interrupt */ 378 ret = regmap_update_bits(st->map, INV_ICM42600_REG_INT_SOURCE0, 379 INV_ICM42600_INT_SOURCE0_FIFO_THS_INT1_EN, 0); 380 if (ret) 381 goto out_unlock; 382 383 out_off: 384 /* decrease FIFO on counter */ 385 st->fifo.on--; 386 out_unlock: 387 mutex_unlock(&st->lock); 388 return ret; 389 } 390 391 static int inv_icm42600_buffer_postdisable(struct iio_dev *indio_dev) 392 { 393 struct inv_icm42600_state *st = iio_device_get_drvdata(indio_dev); 394 struct device *dev = regmap_get_device(st->map); 395 unsigned int sensor; 396 unsigned int *watermark; 397 struct inv_icm42600_sensor_conf conf = INV_ICM42600_SENSOR_CONF_INIT; 398 unsigned int sleep_temp = 0; 399 unsigned int sleep_sensor = 0; 400 unsigned int sleep; 401 int ret; 402 403 if (indio_dev == st->indio_gyro) { 404 sensor = INV_ICM42600_SENSOR_GYRO; 405 watermark = &st->fifo.watermark.gyro; 406 } else if (indio_dev == st->indio_accel) { 407 sensor = INV_ICM42600_SENSOR_ACCEL; 408 watermark = &st->fifo.watermark.accel; 409 } else { 410 return -EINVAL; 411 } 412 413 mutex_lock(&st->lock); 414 415 ret = inv_icm42600_buffer_set_fifo_en(st, st->fifo.en & ~sensor); 416 if (ret) 417 goto out_unlock; 418 419 *watermark = 0; 420 ret = inv_icm42600_buffer_update_watermark(st); 421 if (ret) 422 goto out_unlock; 423 424 conf.mode = INV_ICM42600_SENSOR_MODE_OFF; 425 if (sensor == INV_ICM42600_SENSOR_GYRO) 426 ret = inv_icm42600_set_gyro_conf(st, &conf, &sleep_sensor); 427 else 428 ret = inv_icm42600_set_accel_conf(st, &conf, &sleep_sensor); 429 if (ret) 430 goto out_unlock; 431 432 /* if FIFO is off, turn temperature off */ 433 if (!st->fifo.on) 434 ret = inv_icm42600_set_temp_conf(st, false, &sleep_temp); 435 436 out_unlock: 437 mutex_unlock(&st->lock); 438 439 /* sleep maximum required time */ 440 sleep = max(sleep_sensor, sleep_temp); 441 if (sleep) 442 msleep(sleep); 443 444 pm_runtime_mark_last_busy(dev); 445 pm_runtime_put_autosuspend(dev); 446 447 return ret; 448 } 449 450 const struct iio_buffer_setup_ops inv_icm42600_buffer_ops = { 451 .preenable = inv_icm42600_buffer_preenable, 452 .postenable = inv_icm42600_buffer_postenable, 453 .predisable = inv_icm42600_buffer_predisable, 454 .postdisable = inv_icm42600_buffer_postdisable, 455 }; 456 457 int inv_icm42600_buffer_fifo_read(struct inv_icm42600_state *st, 458 unsigned int max) 459 { 460 size_t max_count; 461 __be16 *raw_fifo_count; 462 ssize_t i, size; 463 const void *accel, *gyro, *timestamp; 464 const int8_t *temp; 465 unsigned int odr; 466 int ret; 467 468 /* reset all samples counters */ 469 st->fifo.count = 0; 470 st->fifo.nb.gyro = 0; 471 st->fifo.nb.accel = 0; 472 st->fifo.nb.total = 0; 473 474 /* compute maximum FIFO read size */ 475 if (max == 0) 476 max_count = sizeof(st->fifo.data); 477 else 478 max_count = max * inv_icm42600_get_packet_size(st->fifo.en); 479 480 /* read FIFO count value */ 481 raw_fifo_count = (__be16 *)st->buffer; 482 ret = regmap_bulk_read(st->map, INV_ICM42600_REG_FIFO_COUNT, 483 raw_fifo_count, sizeof(*raw_fifo_count)); 484 if (ret) 485 return ret; 486 st->fifo.count = be16_to_cpup(raw_fifo_count); 487 488 /* check and clamp FIFO count value */ 489 if (st->fifo.count == 0) 490 return 0; 491 if (st->fifo.count > max_count) 492 st->fifo.count = max_count; 493 494 /* read all FIFO data in internal buffer */ 495 ret = regmap_noinc_read(st->map, INV_ICM42600_REG_FIFO_DATA, 496 st->fifo.data, st->fifo.count); 497 if (ret) 498 return ret; 499 500 /* compute number of samples for each sensor */ 501 for (i = 0; i < st->fifo.count; i += size) { 502 size = inv_icm42600_fifo_decode_packet(&st->fifo.data[i], 503 &accel, &gyro, &temp, ×tamp, &odr); 504 if (size <= 0) 505 break; 506 if (gyro != NULL && inv_icm42600_fifo_is_data_valid(gyro)) 507 st->fifo.nb.gyro++; 508 if (accel != NULL && inv_icm42600_fifo_is_data_valid(accel)) 509 st->fifo.nb.accel++; 510 st->fifo.nb.total++; 511 } 512 513 return 0; 514 } 515 516 int inv_icm42600_buffer_fifo_parse(struct inv_icm42600_state *st) 517 { 518 struct inv_icm42600_sensor_state *gyro_st = iio_priv(st->indio_gyro); 519 struct inv_icm42600_sensor_state *accel_st = iio_priv(st->indio_accel); 520 struct inv_sensors_timestamp *ts; 521 int ret; 522 523 if (st->fifo.nb.total == 0) 524 return 0; 525 526 /* handle gyroscope timestamp and FIFO data parsing */ 527 if (st->fifo.nb.gyro > 0) { 528 ts = &gyro_st->ts; 529 inv_sensors_timestamp_interrupt(ts, st->fifo.watermark.eff_gyro, 530 st->timestamp.gyro); 531 ret = inv_icm42600_gyro_parse_fifo(st->indio_gyro); 532 if (ret) 533 return ret; 534 } 535 536 /* handle accelerometer timestamp and FIFO data parsing */ 537 if (st->fifo.nb.accel > 0) { 538 ts = &accel_st->ts; 539 inv_sensors_timestamp_interrupt(ts, st->fifo.watermark.eff_accel, 540 st->timestamp.accel); 541 ret = inv_icm42600_accel_parse_fifo(st->indio_accel); 542 if (ret) 543 return ret; 544 } 545 546 return 0; 547 } 548 549 int inv_icm42600_buffer_hwfifo_flush(struct inv_icm42600_state *st, 550 unsigned int count) 551 { 552 struct inv_icm42600_sensor_state *gyro_st = iio_priv(st->indio_gyro); 553 struct inv_icm42600_sensor_state *accel_st = iio_priv(st->indio_accel); 554 struct inv_sensors_timestamp *ts; 555 int64_t gyro_ts, accel_ts; 556 int ret; 557 558 gyro_ts = iio_get_time_ns(st->indio_gyro); 559 accel_ts = iio_get_time_ns(st->indio_accel); 560 561 ret = inv_icm42600_buffer_fifo_read(st, count); 562 if (ret) 563 return ret; 564 565 if (st->fifo.nb.total == 0) 566 return 0; 567 568 if (st->fifo.nb.gyro > 0) { 569 ts = &gyro_st->ts; 570 inv_sensors_timestamp_interrupt(ts, st->fifo.nb.gyro, gyro_ts); 571 ret = inv_icm42600_gyro_parse_fifo(st->indio_gyro); 572 if (ret) 573 return ret; 574 } 575 576 if (st->fifo.nb.accel > 0) { 577 ts = &accel_st->ts; 578 inv_sensors_timestamp_interrupt(ts, st->fifo.nb.accel, accel_ts); 579 ret = inv_icm42600_accel_parse_fifo(st->indio_accel); 580 if (ret) 581 return ret; 582 } 583 584 return 0; 585 } 586 587 int inv_icm42600_buffer_init(struct inv_icm42600_state *st) 588 { 589 unsigned int val; 590 int ret; 591 592 st->fifo.watermark.eff_gyro = 1; 593 st->fifo.watermark.eff_accel = 1; 594 595 /* 596 * Default FIFO configuration (bits 7 to 5) 597 * - use invalid value 598 * - FIFO count in bytes 599 * - FIFO count in big endian 600 */ 601 val = INV_ICM42600_INTF_CONFIG0_FIFO_COUNT_ENDIAN; 602 ret = regmap_update_bits(st->map, INV_ICM42600_REG_INTF_CONFIG0, 603 GENMASK(7, 5), val); 604 if (ret) 605 return ret; 606 607 /* 608 * Enable FIFO partial read and continuous watermark interrupt. 609 * Disable all FIFO EN bits. 610 */ 611 val = INV_ICM42600_FIFO_CONFIG1_RESUME_PARTIAL_RD | 612 INV_ICM42600_FIFO_CONFIG1_WM_GT_TH; 613 return regmap_update_bits(st->map, INV_ICM42600_REG_FIFO_CONFIG1, 614 GENMASK(6, 5) | GENMASK(3, 0), val); 615 } 616