FILE
inv_icm45600_core.c
File preview with syntax highlighting.
linux-6.19.14/drivers/iio/imu/inv_icm45600/inv_icm45600_core.c
1// SPDX-License-Identifier: GPL-2.0-or-later 2/* Copyright (C) 2025 Invensense, Inc. */ 3 4#include <linux/bitfield.h> 5#include <linux/delay.h> 6#include <linux/device.h> 7#include <linux/err.h> 8#include <linux/interrupt.h> 9#include <linux/irq.h> 10#include <linux/limits.h> 11#include <linux/minmax.h> 12#include <linux/module.h> 13#include <linux/mutex.h> 14#include <linux/pm_runtime.h> 15#include <linux/property.h> 16#include <linux/regmap.h> 17#include <linux/regulator/consumer.h> 18#include <linux/time.h> 19#include <linux/types.h> 20 21#include <asm/byteorder.h> 22 23#include <linux/iio/iio.h> 24 25#include "inv_icm45600_buffer.h" 26#include "inv_icm45600.h" 27 28static int inv_icm45600_ireg_read(struct regmap *map, unsigned int reg, 29 u8 *data, size_t count) 30{ 31 const struct device *dev = regmap_get_device(map); 32 struct inv_icm45600_state *st = dev_get_drvdata(dev); 33 unsigned int d; 34 size_t i; 35 int ret; 36 37 st->buffer.ireg[0] = FIELD_GET(INV_ICM45600_REG_BANK_MASK, reg); 38 st->buffer.ireg[1] = FIELD_GET(INV_ICM45600_REG_ADDR_MASK, reg); 39 40 /* Burst write address. */ 41 ret = regmap_bulk_write(map, INV_ICM45600_REG_IREG_ADDR, st->buffer.ireg, 2); 42 /* 43 * Wait while the device is busy processing the address. 44 * Datasheet: 13.3 MINIMUM WAIT TIME-GAP 45 */ 46 fsleep(INV_ICM45600_IREG_DELAY_US); 47 if (ret) 48 return ret; 49 50 /* Read the data. */ 51 for (i = 0; i < count; i++) { 52 ret = regmap_read(map, INV_ICM45600_REG_IREG_DATA, &d); 53 /* 54 * Wait while the device is busy processing the address. 55 * Datasheet: 13.3 MINIMUM WAIT TIME-GAP 56 */ 57 fsleep(INV_ICM45600_IREG_DELAY_US); 58 if (ret) 59 return ret; 60 data[i] = d; 61 } 62 63 return 0; 64} 65 66static int inv_icm45600_ireg_write(struct regmap *map, unsigned int reg, 67 const u8 *data, size_t count) 68{ 69 const struct device *dev = regmap_get_device(map); 70 struct inv_icm45600_state *st = dev_get_drvdata(dev); 71 size_t i; 72 int ret; 73 74 st->buffer.ireg[0] = FIELD_GET(INV_ICM45600_REG_BANK_MASK, reg); 75 st->buffer.ireg[1] = FIELD_GET(INV_ICM45600_REG_ADDR_MASK, reg); 76 st->buffer.ireg[2] = data[0]; 77 78 /* Burst write address and first byte. */ 79 ret = regmap_bulk_write(map, INV_ICM45600_REG_IREG_ADDR, st->buffer.ireg, 3); 80 /* 81 * Wait while the device is busy processing the address. 82 * Datasheet: 13.3 MINIMUM WAIT TIME-GAP 83 */ 84 fsleep(INV_ICM45600_IREG_DELAY_US); 85 if (ret) 86 return ret; 87 88 /* Write the remaining bytes. */ 89 for (i = 1; i < count; i++) { 90 ret = regmap_write(map, INV_ICM45600_REG_IREG_DATA, data[i]); 91 /* 92 * Wait while the device is busy processing the address. 93 * Datasheet: 13.3 MINIMUM WAIT TIME-GAP 94 */ 95 fsleep(INV_ICM45600_IREG_DELAY_US); 96 if (ret) 97 return ret; 98 } 99 100 return 0; 101} 102 103static int inv_icm45600_read(void *context, const void *reg_buf, size_t reg_size, 104 void *val_buf, size_t val_size) 105{ 106 unsigned int reg = be16_to_cpup(reg_buf); 107 struct regmap *map = context; 108 109 if (FIELD_GET(INV_ICM45600_REG_BANK_MASK, reg)) 110 return inv_icm45600_ireg_read(map, reg, val_buf, val_size); 111 112 return regmap_bulk_read(map, FIELD_GET(INV_ICM45600_REG_ADDR_MASK, reg), 113 val_buf, val_size); 114} 115 116static int inv_icm45600_write(void *context, const void *data, size_t count) 117{ 118 const u8 *d = data; 119 unsigned int reg = be16_to_cpup(data); 120 struct regmap *map = context; 121 122 if (FIELD_GET(INV_ICM45600_REG_BANK_MASK, reg)) 123 return inv_icm45600_ireg_write(map, reg, d + 2, count - 2); 124 125 return regmap_bulk_write(map, FIELD_GET(INV_ICM45600_REG_ADDR_MASK, reg), 126 d + 2, count - 2); 127} 128 129static const struct regmap_bus inv_icm45600_regmap_bus = { 130 .read = inv_icm45600_read, 131 .write = inv_icm45600_write, 132}; 133 134static const struct regmap_config inv_icm45600_regmap_config = { 135 .reg_bits = 16, 136 .val_bits = 8, 137}; 138 139/* These are the chip initial default configurations (default FS value is based on icm45686) */ 140static const struct inv_icm45600_conf inv_icm45600_default_conf = { 141 .gyro = { 142 .mode = INV_ICM45600_SENSOR_MODE_OFF, 143 .fs = INV_ICM45686_GYRO_FS_2000DPS, 144 .odr = INV_ICM45600_ODR_800HZ_LN, 145 .filter = INV_ICM45600_GYRO_LP_AVG_SEL_8X, 146 }, 147 .accel = { 148 .mode = INV_ICM45600_SENSOR_MODE_OFF, 149 .fs = INV_ICM45686_ACCEL_FS_16G, 150 .odr = INV_ICM45600_ODR_800HZ_LN, 151 .filter = INV_ICM45600_ACCEL_LP_AVG_SEL_4X, 152 }, 153}; 154 155static const struct inv_icm45600_conf inv_icm45686_default_conf = { 156 .gyro = { 157 .mode = INV_ICM45600_SENSOR_MODE_OFF, 158 .fs = INV_ICM45686_GYRO_FS_4000DPS, 159 .odr = INV_ICM45600_ODR_800HZ_LN, 160 .filter = INV_ICM45600_GYRO_LP_AVG_SEL_8X, 161 }, 162 .accel = { 163 .mode = INV_ICM45600_SENSOR_MODE_OFF, 164 .fs = INV_ICM45686_ACCEL_FS_32G, 165 .odr = INV_ICM45600_ODR_800HZ_LN, 166 .filter = INV_ICM45600_ACCEL_LP_AVG_SEL_4X, 167 }, 168}; 169 170const struct inv_icm45600_chip_info inv_icm45605_chip_info = { 171 .whoami = INV_ICM45600_WHOAMI_ICM45605, 172 .name = "icm45605", 173 .conf = &inv_icm45600_default_conf, 174 .accel_scales = (const int *)inv_icm45600_accel_scale, 175 .accel_scales_len = INV_ICM45600_ACCEL_FS_MAX, 176 .gyro_scales = (const int *)inv_icm45600_gyro_scale, 177 .gyro_scales_len = INV_ICM45600_GYRO_FS_MAX, 178}; 179EXPORT_SYMBOL_NS_GPL(inv_icm45605_chip_info, "IIO_ICM45600"); 180 181const struct inv_icm45600_chip_info inv_icm45606_chip_info = { 182 .whoami = INV_ICM45600_WHOAMI_ICM45606, 183 .name = "icm45606", 184 .conf = &inv_icm45600_default_conf, 185 .accel_scales = (const int *)inv_icm45600_accel_scale, 186 .accel_scales_len = INV_ICM45600_ACCEL_FS_MAX, 187 .gyro_scales = (const int *)inv_icm45600_gyro_scale, 188 .gyro_scales_len = INV_ICM45600_GYRO_FS_MAX, 189}; 190EXPORT_SYMBOL_NS_GPL(inv_icm45606_chip_info, "IIO_ICM45600"); 191 192const struct inv_icm45600_chip_info inv_icm45608_chip_info = { 193 .whoami = INV_ICM45600_WHOAMI_ICM45608, 194 .name = "icm45608", 195 .conf = &inv_icm45600_default_conf, 196 .accel_scales = (const int *)inv_icm45600_accel_scale, 197 .accel_scales_len = INV_ICM45600_ACCEL_FS_MAX, 198 .gyro_scales = (const int *)inv_icm45600_gyro_scale, 199 .gyro_scales_len = INV_ICM45600_GYRO_FS_MAX, 200}; 201EXPORT_SYMBOL_NS_GPL(inv_icm45608_chip_info, "IIO_ICM45600"); 202 203const struct inv_icm45600_chip_info inv_icm45634_chip_info = { 204 .whoami = INV_ICM45600_WHOAMI_ICM45634, 205 .name = "icm45634", 206 .conf = &inv_icm45600_default_conf, 207 .accel_scales = (const int *)inv_icm45600_accel_scale, 208 .accel_scales_len = INV_ICM45600_ACCEL_FS_MAX, 209 .gyro_scales = (const int *)inv_icm45600_gyro_scale, 210 .gyro_scales_len = INV_ICM45600_GYRO_FS_MAX, 211}; 212EXPORT_SYMBOL_NS_GPL(inv_icm45634_chip_info, "IIO_ICM45600"); 213 214const struct inv_icm45600_chip_info inv_icm45686_chip_info = { 215 .whoami = INV_ICM45600_WHOAMI_ICM45686, 216 .name = "icm45686", 217 .conf = &inv_icm45686_default_conf, 218 .accel_scales = (const int *)inv_icm45686_accel_scale, 219 .accel_scales_len = INV_ICM45686_ACCEL_FS_MAX, 220 .gyro_scales = (const int *)inv_icm45686_gyro_scale, 221 .gyro_scales_len = INV_ICM45686_GYRO_FS_MAX, 222}; 223EXPORT_SYMBOL_NS_GPL(inv_icm45686_chip_info, "IIO_ICM45600"); 224 225const struct inv_icm45600_chip_info inv_icm45687_chip_info = { 226 .whoami = INV_ICM45600_WHOAMI_ICM45687, 227 .name = "icm45687", 228 .conf = &inv_icm45686_default_conf, 229 .accel_scales = (const int *)inv_icm45686_accel_scale, 230 .accel_scales_len = INV_ICM45686_ACCEL_FS_MAX, 231 .gyro_scales = (const int *)inv_icm45686_gyro_scale, 232 .gyro_scales_len = INV_ICM45686_GYRO_FS_MAX, 233}; 234EXPORT_SYMBOL_NS_GPL(inv_icm45687_chip_info, "IIO_ICM45600"); 235 236const struct inv_icm45600_chip_info inv_icm45688p_chip_info = { 237 .whoami = INV_ICM45600_WHOAMI_ICM45688P, 238 .name = "icm45688p", 239 .conf = &inv_icm45686_default_conf, 240 .accel_scales = (const int *)inv_icm45686_accel_scale, 241 .accel_scales_len = INV_ICM45686_ACCEL_FS_MAX, 242 .gyro_scales = (const int *)inv_icm45686_gyro_scale, 243 .gyro_scales_len = INV_ICM45686_GYRO_FS_MAX, 244}; 245EXPORT_SYMBOL_NS_GPL(inv_icm45688p_chip_info, "IIO_ICM45600"); 246 247const struct inv_icm45600_chip_info inv_icm45689_chip_info = { 248 .whoami = INV_ICM45600_WHOAMI_ICM45689, 249 .name = "icm45689", 250 .conf = &inv_icm45686_default_conf, 251 .accel_scales = (const int *)inv_icm45686_accel_scale, 252 .accel_scales_len = INV_ICM45686_ACCEL_FS_MAX, 253 .gyro_scales = (const int *)inv_icm45686_gyro_scale, 254 .gyro_scales_len = INV_ICM45686_GYRO_FS_MAX, 255}; 256EXPORT_SYMBOL_NS_GPL(inv_icm45689_chip_info, "IIO_ICM45600"); 257 258const struct iio_mount_matrix * 259inv_icm45600_get_mount_matrix(const struct iio_dev *indio_dev, 260 const struct iio_chan_spec *chan) 261{ 262 const struct inv_icm45600_state *st = iio_device_get_drvdata(indio_dev); 263 264 return &st->orientation; 265} 266 267u32 inv_icm45600_odr_to_period(enum inv_icm45600_odr odr) 268{ 269 static const u32 odr_periods[INV_ICM45600_ODR_MAX] = { 270 /* 3 first values are reserved, left to 0 */ 271 [INV_ICM45600_ODR_6400HZ_LN] = 156250, 272 [INV_ICM45600_ODR_3200HZ_LN] = 312500, 273 [INV_ICM45600_ODR_1600HZ_LN] = 625000, 274 [INV_ICM45600_ODR_800HZ_LN] = 1250000, 275 [INV_ICM45600_ODR_400HZ] = 2500000, 276 [INV_ICM45600_ODR_200HZ] = 5000000, 277 [INV_ICM45600_ODR_100HZ] = 10000000, 278 [INV_ICM45600_ODR_50HZ] = 20000000, 279 [INV_ICM45600_ODR_25HZ] = 40000000, 280 [INV_ICM45600_ODR_12_5HZ] = 80000000, 281 [INV_ICM45600_ODR_6_25HZ_LP] = 160000000, 282 [INV_ICM45600_ODR_3_125HZ_LP] = 320000000, 283 [INV_ICM45600_ODR_1_5625HZ_LP] = 640000000, 284 }; 285 286 return odr_periods[odr]; 287} 288 289static int inv_icm45600_set_pwr_mgmt0(struct inv_icm45600_state *st, 290 enum inv_icm45600_sensor_mode gyro, 291 enum inv_icm45600_sensor_mode accel, 292 unsigned int *sleep_ms) 293{ 294 enum inv_icm45600_sensor_mode oldgyro = st->conf.gyro.mode; 295 enum inv_icm45600_sensor_mode oldaccel = st->conf.accel.mode; 296 unsigned int sleepval; 297 unsigned int val; 298 int ret; 299 300 /* if nothing changed, exit */ 301 if (gyro == oldgyro && accel == oldaccel) 302 return 0; 303 304 val = FIELD_PREP(INV_ICM45600_PWR_MGMT0_GYRO_MODE_MASK, gyro) | 305 FIELD_PREP(INV_ICM45600_PWR_MGMT0_ACCEL_MODE_MASK, accel); 306 ret = regmap_write(st->map, INV_ICM45600_REG_PWR_MGMT0, val); 307 if (ret) 308 return ret; 309 310 st->conf.gyro.mode = gyro; 311 st->conf.accel.mode = accel; 312 313 /* Compute the required wait time for sensors to stabilize. */ 314 sleepval = 0; 315 if (accel != oldaccel && oldaccel == INV_ICM45600_SENSOR_MODE_OFF) 316 sleepval = max(sleepval, INV_ICM45600_ACCEL_STARTUP_TIME_MS); 317 318 if (gyro != oldgyro) { 319 if (oldgyro == INV_ICM45600_SENSOR_MODE_OFF) 320 sleepval = max(sleepval, INV_ICM45600_GYRO_STARTUP_TIME_MS); 321 else if (gyro == INV_ICM45600_SENSOR_MODE_OFF) 322 sleepval = max(sleepval, INV_ICM45600_GYRO_STOP_TIME_MS); 323 } 324 325 /* Deferred sleep value if sleep pointer is provided or direct sleep */ 326 if (sleep_ms) 327 *sleep_ms = sleepval; 328 else if (sleepval) 329 msleep(sleepval); 330 331 return 0; 332} 333 334static void inv_icm45600_set_default_conf(struct inv_icm45600_sensor_conf *conf, 335 struct inv_icm45600_sensor_conf *oldconf) 336{ 337 /* Sanitize missing values with current values. */ 338 if (conf->mode == U8_MAX) 339 conf->mode = oldconf->mode; 340 if (conf->fs == U8_MAX) 341 conf->fs = oldconf->fs; 342 if (conf->odr == U8_MAX) 343 conf->odr = oldconf->odr; 344 if (conf->filter == U8_MAX) 345 conf->filter = oldconf->filter; 346} 347 348int inv_icm45600_set_accel_conf(struct inv_icm45600_state *st, 349 struct inv_icm45600_sensor_conf *conf, 350 unsigned int *sleep_ms) 351{ 352 struct inv_icm45600_sensor_conf *oldconf = &st->conf.accel; 353 unsigned int val; 354 int ret; 355 356 inv_icm45600_set_default_conf(conf, oldconf); 357 358 /* Force the power mode against the ODR when sensor is on. */ 359 if (conf->mode > INV_ICM45600_SENSOR_MODE_STANDBY) { 360 if (conf->odr <= INV_ICM45600_ODR_800HZ_LN) { 361 conf->mode = INV_ICM45600_SENSOR_MODE_LOW_NOISE; 362 } else { 363 conf->mode = INV_ICM45600_SENSOR_MODE_LOW_POWER; 364 /* sanitize averaging value depending on ODR for low-power mode */ 365 /* maximum 1x @400Hz */ 366 if (conf->odr == INV_ICM45600_ODR_400HZ) 367 conf->filter = INV_ICM45600_ACCEL_LP_AVG_SEL_1X; 368 else 369 conf->filter = INV_ICM45600_ACCEL_LP_AVG_SEL_4X; 370 } 371 } 372 373 /* Set accel fullscale & odr. */ 374 if (conf->fs != oldconf->fs || conf->odr != oldconf->odr) { 375 val = FIELD_PREP(INV_ICM45600_ACCEL_CONFIG0_FS_MASK, conf->fs) | 376 FIELD_PREP(INV_ICM45600_ACCEL_CONFIG0_ODR_MASK, conf->odr); 377 ret = regmap_write(st->map, INV_ICM45600_REG_ACCEL_CONFIG0, val); 378 if (ret) 379 return ret; 380 oldconf->fs = conf->fs; 381 oldconf->odr = conf->odr; 382 } 383 384 /* Set accel low-power average filter. */ 385 if (conf->filter != oldconf->filter) { 386 ret = regmap_write(st->map, INV_ICM45600_IPREG_SYS2_REG_129, 387 conf->filter); 388 if (ret) 389 return ret; 390 oldconf->filter = conf->filter; 391 } 392 393 /* Update the sensor accel mode. */ 394 return inv_icm45600_set_pwr_mgmt0(st, st->conf.gyro.mode, conf->mode, 395 sleep_ms); 396} 397 398int inv_icm45600_set_gyro_conf(struct inv_icm45600_state *st, 399 struct inv_icm45600_sensor_conf *conf, 400 unsigned int *sleep_ms) 401{ 402 struct inv_icm45600_sensor_conf *oldconf = &st->conf.gyro; 403 unsigned int val; 404 int ret; 405 406 inv_icm45600_set_default_conf(conf, oldconf); 407 408 /* Force the power mode against ODR when sensor is on. */ 409 if (conf->mode > INV_ICM45600_SENSOR_MODE_STANDBY) { 410 if (conf->odr >= INV_ICM45600_ODR_6_25HZ_LP) { 411 conf->mode = INV_ICM45600_SENSOR_MODE_LOW_POWER; 412 conf->filter = INV_ICM45600_GYRO_LP_AVG_SEL_8X; 413 } else { 414 conf->mode = INV_ICM45600_SENSOR_MODE_LOW_NOISE; 415 } 416 } 417 418 /* Set gyro fullscale & odr. */ 419 if (conf->fs != oldconf->fs || conf->odr != oldconf->odr) { 420 val = FIELD_PREP(INV_ICM45600_GYRO_CONFIG0_FS_MASK, conf->fs) | 421 FIELD_PREP(INV_ICM45600_GYRO_CONFIG0_ODR_MASK, conf->odr); 422 ret = regmap_write(st->map, INV_ICM45600_REG_GYRO_CONFIG0, val); 423 if (ret) 424 return ret; 425 oldconf->fs = conf->fs; 426 oldconf->odr = conf->odr; 427 } 428 429 /* Set gyro low-power average filter. */ 430 if (conf->filter != oldconf->filter) { 431 val = FIELD_PREP(INV_ICM45600_IPREG_SYS1_170_GYRO_LP_AVG_MASK, conf->filter); 432 ret = regmap_update_bits(st->map, INV_ICM45600_IPREG_SYS1_REG_170, 433 INV_ICM45600_IPREG_SYS1_170_GYRO_LP_AVG_MASK, val); 434 if (ret) 435 return ret; 436 oldconf->filter = conf->filter; 437 } 438 439 /* Update the sensor gyro mode. */ 440 return inv_icm45600_set_pwr_mgmt0(st, conf->mode, st->conf.accel.mode, 441 sleep_ms); 442} 443 444int inv_icm45600_debugfs_reg(struct iio_dev *indio_dev, unsigned int reg, 445 unsigned int writeval, unsigned int *readval) 446{ 447 struct inv_icm45600_state *st = iio_device_get_drvdata(indio_dev); 448 449 guard(mutex)(&st->lock); 450 451 if (readval) 452 return regmap_read(st->map, reg, readval); 453 else 454 return regmap_write(st->map, reg, writeval); 455} 456 457static int inv_icm45600_set_conf(struct inv_icm45600_state *st, 458 const struct inv_icm45600_conf *conf) 459{ 460 unsigned int val; 461 int ret; 462 463 val = FIELD_PREP(INV_ICM45600_PWR_MGMT0_GYRO_MODE_MASK, conf->gyro.mode) | 464 FIELD_PREP(INV_ICM45600_PWR_MGMT0_ACCEL_MODE_MASK, conf->accel.mode); 465 ret = regmap_write(st->map, INV_ICM45600_REG_PWR_MGMT0, val); 466 if (ret) 467 return ret; 468 469 val = FIELD_PREP(INV_ICM45600_GYRO_CONFIG0_FS_MASK, conf->gyro.fs) | 470 FIELD_PREP(INV_ICM45600_GYRO_CONFIG0_ODR_MASK, conf->gyro.odr); 471 ret = regmap_write(st->map, INV_ICM45600_REG_GYRO_CONFIG0, val); 472 if (ret) 473 return ret; 474 475 val = FIELD_PREP(INV_ICM45600_ACCEL_CONFIG0_FS_MASK, conf->accel.fs) | 476 FIELD_PREP(INV_ICM45600_ACCEL_CONFIG0_ODR_MASK, conf->accel.odr); 477 ret = regmap_write(st->map, INV_ICM45600_REG_ACCEL_CONFIG0, val); 478 if (ret) 479 return ret; 480 481 /* Save configuration. */ 482 st->conf = *conf; 483 484 return 0; 485} 486 487/** 488 * inv_icm45600_setup() - check and setup chip 489 * @st: driver internal state 490 * @chip_info: detected chip description 491 * @reset: define whether a reset is required or not 492 * @bus_setup: callback for setting up bus specific registers 493 * 494 * Returns: 0 on success, a negative error code otherwise. 495 */ 496static int inv_icm45600_setup(struct inv_icm45600_state *st, 497 const struct inv_icm45600_chip_info *chip_info, 498 bool reset, inv_icm45600_bus_setup bus_setup) 499{ 500 const struct device *dev = regmap_get_device(st->map); 501 unsigned int val; 502 int ret; 503 504 /* Set chip bus configuration if specified. */ 505 if (bus_setup) { 506 ret = bus_setup(st); 507 if (ret) 508 return ret; 509 } 510 511 /* Check chip self-identification value. */ 512 ret = regmap_read(st->map, INV_ICM45600_REG_WHOAMI, &val); 513 if (ret) 514 return ret; 515 if (val != chip_info->whoami) { 516 /* 517 * SPI interface has no ack mechanism. 518 * 0xFF or 0x00 whoami means no response from the device. 519 */ 520 if (val == U8_MAX || val == 0) 521 return dev_err_probe(dev, -ENODEV, 522 "Invalid whoami %#02x expected %#02x (%s)\n", 523 val, chip_info->whoami, chip_info->name); 524 525 dev_warn(dev, "Unexpected whoami %#02x expected %#02x (%s)\n", 526 val, chip_info->whoami, chip_info->name); 527 } 528 529 st->chip_info = chip_info; 530 531 if (reset) { 532 /* Reset previous state. */ 533 ret = regmap_write(st->map, INV_ICM45600_REG_MISC2, 534 INV_ICM45600_MISC2_SOFT_RESET); 535 if (ret) 536 return ret; 537 /* 538 * IMU reset time. 539 * Datasheet: 16.84 REG_MISC2 540 */ 541 fsleep(USEC_PER_MSEC); 542 543 if (bus_setup) { 544 ret = bus_setup(st); 545 if (ret) 546 return ret; 547 } 548 549 ret = regmap_read(st->map, INV_ICM45600_REG_INT_STATUS, &val); 550 if (ret) 551 return ret; 552 if (!(val & INV_ICM45600_INT_STATUS_RESET_DONE)) { 553 dev_err(dev, "reset error, reset done bit not set\n"); 554 return -ENODEV; 555 } 556 } 557 558 return inv_icm45600_set_conf(st, chip_info->conf); 559} 560 561static irqreturn_t inv_icm45600_irq_timestamp(int irq, void *_data) 562{ 563 struct inv_icm45600_state *st = _data; 564 565 st->timestamp.gyro = iio_get_time_ns(st->indio_gyro); 566 st->timestamp.accel = iio_get_time_ns(st->indio_accel); 567 568 return IRQ_WAKE_THREAD; 569} 570 571static irqreturn_t inv_icm45600_irq_handler(int irq, void *_data) 572{ 573 struct inv_icm45600_state *st = _data; 574 struct device *dev = regmap_get_device(st->map); 575 unsigned int mask, status; 576 int ret; 577 578 guard(mutex)(&st->lock); 579 580 ret = regmap_read(st->map, INV_ICM45600_REG_INT_STATUS, &status); 581 if (ret) 582 return IRQ_HANDLED; 583 584 /* Read the FIFO data. */ 585 mask = INV_ICM45600_INT_STATUS_FIFO_THS | INV_ICM45600_INT_STATUS_FIFO_FULL; 586 if (status & mask) { 587 ret = inv_icm45600_buffer_fifo_read(st, 0); 588 if (ret) { 589 dev_err(dev, "FIFO read error %d\n", ret); 590 return IRQ_HANDLED; 591 } 592 ret = inv_icm45600_buffer_fifo_parse(st); 593 if (ret) 594 dev_err(dev, "FIFO parsing error %d\n", ret); 595 } 596 597 /* FIFO full warning. */ 598 if (status & INV_ICM45600_INT_STATUS_FIFO_FULL) 599 dev_warn(dev, "FIFO full possible data lost!\n"); 600 601 return IRQ_HANDLED; 602} 603 604/** 605 * inv_icm45600_irq_init() - initialize int pin and interrupt handler 606 * @st: driver internal state 607 * @irq: irq number 608 * @irq_type: irq trigger type 609 * @open_drain: true if irq is open drain, false for push-pull 610 * 611 * Returns: 0 on success, a negative error code otherwise. 612 */ 613static int inv_icm45600_irq_init(struct inv_icm45600_state *st, int irq, 614 int irq_type, bool open_drain) 615{ 616 struct device *dev = regmap_get_device(st->map); 617 unsigned int val; 618 int ret; 619 620 /* Configure INT1 interrupt: default is active low on edge. */ 621 switch (irq_type) { 622 case IRQF_TRIGGER_RISING: 623 case IRQF_TRIGGER_HIGH: 624 val = INV_ICM45600_INT1_CONFIG2_ACTIVE_HIGH; 625 break; 626 default: 627 val = INV_ICM45600_INT1_CONFIG2_ACTIVE_LOW; 628 break; 629 } 630 631 switch (irq_type) { 632 case IRQF_TRIGGER_LOW: 633 case IRQF_TRIGGER_HIGH: 634 val |= INV_ICM45600_INT1_CONFIG2_LATCHED; 635 break; 636 default: 637 break; 638 } 639 640 if (open_drain) 641 val |= INV_ICM45600_INT1_CONFIG2_OPEN_DRAIN; 642 643 ret = regmap_write(st->map, INV_ICM45600_REG_INT1_CONFIG2, val); 644 if (ret) 645 return ret; 646 647 return devm_request_threaded_irq(dev, irq, inv_icm45600_irq_timestamp, 648 inv_icm45600_irq_handler, irq_type | IRQF_ONESHOT, 649 "inv_icm45600", st); 650} 651 652static int inv_icm45600_timestamp_setup(struct inv_icm45600_state *st) 653{ 654 /* Enable timestamps. */ 655 return regmap_set_bits(st->map, INV_ICM45600_REG_SMC_CONTROL_0, 656 INV_ICM45600_SMC_CONTROL_0_TMST_EN); 657} 658 659static int inv_icm45600_enable_regulator_vddio(struct inv_icm45600_state *st) 660{ 661 int ret; 662 663 ret = regulator_enable(st->vddio_supply); 664 if (ret) 665 return ret; 666 667 /* 668 * Wait a little for supply ramp. 669 * Duration is empirically defined. 670 */ 671 fsleep(3 * USEC_PER_MSEC); 672 673 return 0; 674} 675 676static void inv_icm45600_disable_vddio_reg(void *_data) 677{ 678 struct inv_icm45600_state *st = _data; 679 struct device *dev = regmap_get_device(st->map); 680 681 if (pm_runtime_status_suspended(dev)) 682 return; 683 684 regulator_disable(st->vddio_supply); 685} 686 687int inv_icm45600_core_probe(struct regmap *regmap, const struct inv_icm45600_chip_info *chip_info, 688 bool reset, inv_icm45600_bus_setup bus_setup) 689{ 690 struct device *dev = regmap_get_device(regmap); 691 struct inv_icm45600_state *st; 692 struct regmap *regmap_custom; 693 struct fwnode_handle *fwnode; 694 int irq, irq_type; 695 bool open_drain; 696 int ret; 697 698 /* Get INT1 only supported interrupt. */ 699 fwnode = dev_fwnode(dev); 700 irq = fwnode_irq_get_byname(fwnode, "int1"); 701 if (irq < 0) 702 return dev_err_probe(dev, irq, "Missing int1 interrupt\n"); 703 704 irq_type = irq_get_trigger_type(irq); 705 706 open_drain = device_property_read_bool(dev, "drive-open-drain"); 707 708 regmap_custom = devm_regmap_init(dev, &inv_icm45600_regmap_bus, regmap, 709 &inv_icm45600_regmap_config); 710 if (IS_ERR(regmap_custom)) 711 return dev_err_probe(dev, PTR_ERR(regmap_custom), "Failed to register regmap\n"); 712 713 st = devm_kzalloc(dev, sizeof(*st), GFP_KERNEL); 714 if (!st) 715 return -ENOMEM; 716 717 dev_set_drvdata(dev, st); 718 719 st->fifo.data = devm_kzalloc(dev, 8192, GFP_KERNEL); 720 if (!st->fifo.data) 721 return -ENOMEM; 722 723 ret = devm_mutex_init(dev, &st->lock); 724 if (ret) 725 return ret; 726 727 st->map = regmap_custom; 728 729 ret = iio_read_mount_matrix(dev, &st->orientation); 730 if (ret) 731 return dev_err_probe(dev, ret, "Failed to retrieve mounting matrix\n"); 732 733 st->vddio_supply = devm_regulator_get(dev, "vddio"); 734 if (IS_ERR(st->vddio_supply)) 735 return PTR_ERR(st->vddio_supply); 736 737 ret = devm_regulator_get_enable(dev, "vdd"); 738 if (ret) 739 return dev_err_probe(dev, ret, "Failed to get vdd regulator\n"); 740 741 /* 742 * Supply ramp time + Start-up time. 743 * Datasheet: 3.3.2 A.C. Electrical Characteristics 744 */ 745 fsleep(5 * USEC_PER_MSEC); 746 747 /* set pm_runtime active early for disable vddio resource cleanup */ 748 ret = pm_runtime_set_active(dev); 749 if (ret) 750 return ret; 751 752 ret = inv_icm45600_enable_regulator_vddio(st); 753 if (ret) 754 return ret; 755 756 ret = devm_add_action_or_reset(dev, inv_icm45600_disable_vddio_reg, st); 757 if (ret) 758 return ret; 759 760 ret = inv_icm45600_setup(st, chip_info, reset, bus_setup); 761 if (ret) 762 return ret; 763 764 ret = inv_icm45600_timestamp_setup(st); 765 if (ret) 766 return ret; 767 768 ret = inv_icm45600_buffer_init(st); 769 if (ret) 770 return ret; 771 772 st->indio_gyro = inv_icm45600_gyro_init(st); 773 if (IS_ERR(st->indio_gyro)) 774 return PTR_ERR(st->indio_gyro); 775 776 st->indio_accel = inv_icm45600_accel_init(st); 777 if (IS_ERR(st->indio_accel)) 778 return PTR_ERR(st->indio_accel); 779 780 ret = inv_icm45600_irq_init(st, irq, irq_type, open_drain); 781 if (ret) 782 return ret; 783 784 ret = devm_pm_runtime_enable(dev); 785 if (ret) 786 return ret; 787 788 pm_runtime_get_noresume(dev); 789 pm_runtime_set_autosuspend_delay(dev, 2 * USEC_PER_MSEC); 790 pm_runtime_use_autosuspend(dev); 791 pm_runtime_put(dev); 792 793 return 0; 794} 795EXPORT_SYMBOL_NS_GPL(inv_icm45600_core_probe, "IIO_ICM45600"); 796 797/* 798 * Suspend saves sensors state and turns everything off. 799 */ 800static int inv_icm45600_suspend(struct device *dev) 801{ 802 struct inv_icm45600_state *st = dev_get_drvdata(dev); 803 int ret; 804 805 scoped_guard(mutex, &st->lock) { 806 /* Disable FIFO data streaming. */ 807 if (st->fifo.on) { 808 unsigned int val; 809 810 /* Clear FIFO_CONFIG3_IF_EN before changing the FIFO configuration */ 811 ret = regmap_clear_bits(st->map, INV_ICM45600_REG_FIFO_CONFIG3, 812 INV_ICM45600_FIFO_CONFIG3_IF_EN); 813 if (ret) 814 return ret; 815 val = FIELD_PREP(INV_ICM45600_FIFO_CONFIG0_MODE_MASK, 816 INV_ICM45600_FIFO_CONFIG0_MODE_BYPASS); 817 ret = regmap_update_bits(st->map, INV_ICM45600_REG_FIFO_CONFIG0, 818 INV_ICM45600_FIFO_CONFIG0_MODE_MASK, val); 819 if (ret) 820 return ret; 821 } 822 823 /* Save sensors states */ 824 st->suspended.gyro = st->conf.gyro.mode; 825 st->suspended.accel = st->conf.accel.mode; 826 } 827 828 return pm_runtime_force_suspend(dev); 829} 830 831/* 832 * System resume gets the system back on and restores the sensors state. 833 * Manually put runtime power management in system active state. 834 */ 835static int inv_icm45600_resume(struct device *dev) 836{ 837 struct inv_icm45600_state *st = dev_get_drvdata(dev); 838 int ret; 839 840 ret = pm_runtime_force_resume(dev); 841 if (ret) 842 return ret; 843 844 scoped_guard(mutex, &st->lock) { 845 /* Restore sensors state. */ 846 ret = inv_icm45600_set_pwr_mgmt0(st, st->suspended.gyro, 847 st->suspended.accel, NULL); 848 if (ret) 849 return ret; 850 851 /* Restore FIFO data streaming. */ 852 if (st->fifo.on) { 853 struct inv_icm45600_sensor_state *gyro_st = iio_priv(st->indio_gyro); 854 struct inv_icm45600_sensor_state *accel_st = iio_priv(st->indio_accel); 855 unsigned int val; 856 857 inv_sensors_timestamp_reset(&gyro_st->ts); 858 inv_sensors_timestamp_reset(&accel_st->ts); 859 val = FIELD_PREP(INV_ICM45600_FIFO_CONFIG0_MODE_MASK, 860 INV_ICM45600_FIFO_CONFIG0_MODE_STREAM); 861 ret = regmap_update_bits(st->map, INV_ICM45600_REG_FIFO_CONFIG0, 862 INV_ICM45600_FIFO_CONFIG0_MODE_MASK, val); 863 if (ret) 864 return ret; 865 /* FIFO_CONFIG3_IF_EN must only be set at end of FIFO the configuration */ 866 ret = regmap_set_bits(st->map, INV_ICM45600_REG_FIFO_CONFIG3, 867 INV_ICM45600_FIFO_CONFIG3_IF_EN); 868 if (ret) 869 return ret; 870 } 871 } 872 873 return ret; 874} 875 876/* Runtime suspend will turn off sensors that are enabled by iio devices. */ 877static int inv_icm45600_runtime_suspend(struct device *dev) 878{ 879 struct inv_icm45600_state *st = dev_get_drvdata(dev); 880 int ret; 881 882 guard(mutex)(&st->lock); 883 884 /* disable all sensors */ 885 ret = inv_icm45600_set_pwr_mgmt0(st, INV_ICM45600_SENSOR_MODE_OFF, 886 INV_ICM45600_SENSOR_MODE_OFF, NULL); 887 if (ret) 888 return ret; 889 890 regulator_disable(st->vddio_supply); 891 892 return 0; 893} 894 895/* Sensors are enabled by iio devices, no need to turn them back on here. */ 896static int inv_icm45600_runtime_resume(struct device *dev) 897{ 898 struct inv_icm45600_state *st = dev_get_drvdata(dev); 899 900 guard(mutex)(&st->lock); 901 902 return inv_icm45600_enable_regulator_vddio(st); 903} 904 905static int _inv_icm45600_temp_read(struct inv_icm45600_state *st, s16 *temp) 906{ 907 struct inv_icm45600_sensor_conf conf = INV_ICM45600_SENSOR_CONF_KEEP_VALUES; 908 int ret; 909 910 /* Make sure a sensor is on. */ 911 if (st->conf.gyro.mode == INV_ICM45600_SENSOR_MODE_OFF && 912 st->conf.accel.mode == INV_ICM45600_SENSOR_MODE_OFF) { 913 conf.mode = INV_ICM45600_SENSOR_MODE_LOW_POWER; 914 ret = inv_icm45600_set_accel_conf(st, &conf, NULL); 915 if (ret) 916 return ret; 917 } 918 919 ret = regmap_bulk_read(st->map, INV_ICM45600_REG_TEMP_DATA, 920 &st->buffer.u16, sizeof(st->buffer.u16)); 921 if (ret) 922 return ret; 923 924 *temp = (s16)le16_to_cpup(&st->buffer.u16); 925 if (*temp == INV_ICM45600_DATA_INVALID) 926 return -EINVAL; 927 928 return 0; 929} 930 931static int inv_icm45600_temp_read(struct inv_icm45600_state *st, s16 *temp) 932{ 933 struct device *dev = regmap_get_device(st->map); 934 int ret; 935 936 ret = pm_runtime_resume_and_get(dev); 937 if (ret) 938 return ret; 939 940 scoped_guard(mutex, &st->lock) 941 ret = _inv_icm45600_temp_read(st, temp); 942 943 pm_runtime_put_autosuspend(dev); 944 945 return ret; 946} 947 948int inv_icm45600_temp_read_raw(struct iio_dev *indio_dev, 949 struct iio_chan_spec const *chan, 950 int *val, int *val2, long mask) 951{ 952 struct inv_icm45600_state *st = iio_device_get_drvdata(indio_dev); 953 s16 temp; 954 int ret; 955 956 if (chan->type != IIO_TEMP) 957 return -EINVAL; 958 959 switch (mask) { 960 case IIO_CHAN_INFO_RAW: 961 ret = inv_icm45600_temp_read(st, &temp); 962 if (ret) 963 return ret; 964 *val = temp; 965 return IIO_VAL_INT; 966 /* 967 * T°C = (temp / 128) + 25 968 * Tm°C = ((temp + 25 * 128) / 128)) * 1000 969 * Tm°C = (temp + 3200) * (1000 / 128) 970 * scale: 1000 / 128 = 7.8125 971 * offset: 3200 972 */ 973 case IIO_CHAN_INFO_SCALE: 974 *val = 7; 975 *val2 = 812500; 976 return IIO_VAL_INT_PLUS_MICRO; 977 case IIO_CHAN_INFO_OFFSET: 978 *val = 3200; 979 return IIO_VAL_INT; 980 default: 981 return -EINVAL; 982 } 983} 984 985EXPORT_NS_GPL_DEV_PM_OPS(inv_icm45600_pm_ops, IIO_ICM45600) = { 986 SYSTEM_SLEEP_PM_OPS(inv_icm45600_suspend, inv_icm45600_resume) 987 RUNTIME_PM_OPS(inv_icm45600_runtime_suspend, 988 inv_icm45600_runtime_resume, NULL) 989}; 990 991MODULE_AUTHOR("InvenSense, Inc."); 992MODULE_DESCRIPTION("InvenSense ICM-456xx device driver"); 993MODULE_LICENSE("GPL"); 994MODULE_IMPORT_NS("IIO_INV_SENSORS_TIMESTAMP");
~/
Read-only file preview.