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