inv_icm42600_core.c (20331B)
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/module.h> 9#include <linux/slab.h> 10#include <linux/delay.h> 11#include <linux/mutex.h> 12#include <linux/interrupt.h> 13#include <linux/irq.h> 14#include <linux/regulator/consumer.h> 15#include <linux/pm_runtime.h> 16#include <linux/property.h> 17#include <linux/regmap.h> 18#include <linux/iio/iio.h> 19 20#include "inv_icm42600.h" 21#include "inv_icm42600_buffer.h" 22#include "inv_icm42600_timestamp.h" 23 24static const struct regmap_range_cfg inv_icm42600_regmap_ranges[] = { 25 { 26 .name = "user banks", 27 .range_min = 0x0000, 28 .range_max = 0x4FFF, 29 .selector_reg = INV_ICM42600_REG_BANK_SEL, 30 .selector_mask = INV_ICM42600_BANK_SEL_MASK, 31 .selector_shift = 0, 32 .window_start = 0, 33 .window_len = 0x1000, 34 }, 35}; 36 37const struct regmap_config inv_icm42600_regmap_config = { 38 .reg_bits = 8, 39 .val_bits = 8, 40 .max_register = 0x4FFF, 41 .ranges = inv_icm42600_regmap_ranges, 42 .num_ranges = ARRAY_SIZE(inv_icm42600_regmap_ranges), 43}; 44EXPORT_SYMBOL_GPL(inv_icm42600_regmap_config); 45 46struct inv_icm42600_hw { 47 uint8_t whoami; 48 const char *name; 49 const struct inv_icm42600_conf *conf; 50}; 51 52/* chip initial default configuration */ 53static const struct inv_icm42600_conf inv_icm42600_default_conf = { 54 .gyro = { 55 .mode = INV_ICM42600_SENSOR_MODE_OFF, 56 .fs = INV_ICM42600_GYRO_FS_2000DPS, 57 .odr = INV_ICM42600_ODR_50HZ, 58 .filter = INV_ICM42600_FILTER_BW_ODR_DIV_2, 59 }, 60 .accel = { 61 .mode = INV_ICM42600_SENSOR_MODE_OFF, 62 .fs = INV_ICM42600_ACCEL_FS_16G, 63 .odr = INV_ICM42600_ODR_50HZ, 64 .filter = INV_ICM42600_FILTER_BW_ODR_DIV_2, 65 }, 66 .temp_en = false, 67}; 68 69static const struct inv_icm42600_hw inv_icm42600_hw[INV_CHIP_NB] = { 70 [INV_CHIP_ICM42600] = { 71 .whoami = INV_ICM42600_WHOAMI_ICM42600, 72 .name = "icm42600", 73 .conf = &inv_icm42600_default_conf, 74 }, 75 [INV_CHIP_ICM42602] = { 76 .whoami = INV_ICM42600_WHOAMI_ICM42602, 77 .name = "icm42602", 78 .conf = &inv_icm42600_default_conf, 79 }, 80 [INV_CHIP_ICM42605] = { 81 .whoami = INV_ICM42600_WHOAMI_ICM42605, 82 .name = "icm42605", 83 .conf = &inv_icm42600_default_conf, 84 }, 85 [INV_CHIP_ICM42622] = { 86 .whoami = INV_ICM42600_WHOAMI_ICM42622, 87 .name = "icm42622", 88 .conf = &inv_icm42600_default_conf, 89 }, 90}; 91 92const struct iio_mount_matrix * 93inv_icm42600_get_mount_matrix(const struct iio_dev *indio_dev, 94 const struct iio_chan_spec *chan) 95{ 96 const struct inv_icm42600_state *st = iio_device_get_drvdata(indio_dev); 97 98 return &st->orientation; 99} 100 101uint32_t inv_icm42600_odr_to_period(enum inv_icm42600_odr odr) 102{ 103 static uint32_t odr_periods[INV_ICM42600_ODR_NB] = { 104 /* reserved values */ 105 0, 0, 0, 106 /* 8kHz */ 107 125000, 108 /* 4kHz */ 109 250000, 110 /* 2kHz */ 111 500000, 112 /* 1kHz */ 113 1000000, 114 /* 200Hz */ 115 5000000, 116 /* 100Hz */ 117 10000000, 118 /* 50Hz */ 119 20000000, 120 /* 25Hz */ 121 40000000, 122 /* 12.5Hz */ 123 80000000, 124 /* 6.25Hz */ 125 160000000, 126 /* 3.125Hz */ 127 320000000, 128 /* 1.5625Hz */ 129 640000000, 130 /* 500Hz */ 131 2000000, 132 }; 133 134 return odr_periods[odr]; 135} 136 137static int inv_icm42600_set_pwr_mgmt0(struct inv_icm42600_state *st, 138 enum inv_icm42600_sensor_mode gyro, 139 enum inv_icm42600_sensor_mode accel, 140 bool temp, unsigned int *sleep_ms) 141{ 142 enum inv_icm42600_sensor_mode oldgyro = st->conf.gyro.mode; 143 enum inv_icm42600_sensor_mode oldaccel = st->conf.accel.mode; 144 bool oldtemp = st->conf.temp_en; 145 unsigned int sleepval; 146 unsigned int val; 147 int ret; 148 149 /* if nothing changed, exit */ 150 if (gyro == oldgyro && accel == oldaccel && temp == oldtemp) 151 return 0; 152 153 val = INV_ICM42600_PWR_MGMT0_GYRO(gyro) | 154 INV_ICM42600_PWR_MGMT0_ACCEL(accel); 155 if (!temp) 156 val |= INV_ICM42600_PWR_MGMT0_TEMP_DIS; 157 ret = regmap_write(st->map, INV_ICM42600_REG_PWR_MGMT0, val); 158 if (ret) 159 return ret; 160 161 st->conf.gyro.mode = gyro; 162 st->conf.accel.mode = accel; 163 st->conf.temp_en = temp; 164 165 /* compute required wait time for sensors to stabilize */ 166 sleepval = 0; 167 /* temperature stabilization time */ 168 if (temp && !oldtemp) { 169 if (sleepval < INV_ICM42600_TEMP_STARTUP_TIME_MS) 170 sleepval = INV_ICM42600_TEMP_STARTUP_TIME_MS; 171 } 172 /* accel startup time */ 173 if (accel != oldaccel && oldaccel == INV_ICM42600_SENSOR_MODE_OFF) { 174 /* block any register write for at least 200 µs */ 175 usleep_range(200, 300); 176 if (sleepval < INV_ICM42600_ACCEL_STARTUP_TIME_MS) 177 sleepval = INV_ICM42600_ACCEL_STARTUP_TIME_MS; 178 } 179 if (gyro != oldgyro) { 180 /* gyro startup time */ 181 if (oldgyro == INV_ICM42600_SENSOR_MODE_OFF) { 182 /* block any register write for at least 200 µs */ 183 usleep_range(200, 300); 184 if (sleepval < INV_ICM42600_GYRO_STARTUP_TIME_MS) 185 sleepval = INV_ICM42600_GYRO_STARTUP_TIME_MS; 186 /* gyro stop time */ 187 } else if (gyro == INV_ICM42600_SENSOR_MODE_OFF) { 188 if (sleepval < INV_ICM42600_GYRO_STOP_TIME_MS) 189 sleepval = INV_ICM42600_GYRO_STOP_TIME_MS; 190 } 191 } 192 193 /* deferred sleep value if sleep pointer is provided or direct sleep */ 194 if (sleep_ms) 195 *sleep_ms = sleepval; 196 else if (sleepval) 197 msleep(sleepval); 198 199 return 0; 200} 201 202int inv_icm42600_set_accel_conf(struct inv_icm42600_state *st, 203 struct inv_icm42600_sensor_conf *conf, 204 unsigned int *sleep_ms) 205{ 206 struct inv_icm42600_sensor_conf *oldconf = &st->conf.accel; 207 unsigned int val; 208 int ret; 209 210 /* Sanitize missing values with current values */ 211 if (conf->mode < 0) 212 conf->mode = oldconf->mode; 213 if (conf->fs < 0) 214 conf->fs = oldconf->fs; 215 if (conf->odr < 0) 216 conf->odr = oldconf->odr; 217 if (conf->filter < 0) 218 conf->filter = oldconf->filter; 219 220 /* set ACCEL_CONFIG0 register (accel fullscale & odr) */ 221 if (conf->fs != oldconf->fs || conf->odr != oldconf->odr) { 222 val = INV_ICM42600_ACCEL_CONFIG0_FS(conf->fs) | 223 INV_ICM42600_ACCEL_CONFIG0_ODR(conf->odr); 224 ret = regmap_write(st->map, INV_ICM42600_REG_ACCEL_CONFIG0, val); 225 if (ret) 226 return ret; 227 oldconf->fs = conf->fs; 228 oldconf->odr = conf->odr; 229 } 230 231 /* set GYRO_ACCEL_CONFIG0 register (accel filter) */ 232 if (conf->filter != oldconf->filter) { 233 val = INV_ICM42600_GYRO_ACCEL_CONFIG0_ACCEL_FILT(conf->filter) | 234 INV_ICM42600_GYRO_ACCEL_CONFIG0_GYRO_FILT(st->conf.gyro.filter); 235 ret = regmap_write(st->map, INV_ICM42600_REG_GYRO_ACCEL_CONFIG0, val); 236 if (ret) 237 return ret; 238 oldconf->filter = conf->filter; 239 } 240 241 /* set PWR_MGMT0 register (accel sensor mode) */ 242 return inv_icm42600_set_pwr_mgmt0(st, st->conf.gyro.mode, conf->mode, 243 st->conf.temp_en, sleep_ms); 244} 245 246int inv_icm42600_set_gyro_conf(struct inv_icm42600_state *st, 247 struct inv_icm42600_sensor_conf *conf, 248 unsigned int *sleep_ms) 249{ 250 struct inv_icm42600_sensor_conf *oldconf = &st->conf.gyro; 251 unsigned int val; 252 int ret; 253 254 /* sanitize missing values with current values */ 255 if (conf->mode < 0) 256 conf->mode = oldconf->mode; 257 if (conf->fs < 0) 258 conf->fs = oldconf->fs; 259 if (conf->odr < 0) 260 conf->odr = oldconf->odr; 261 if (conf->filter < 0) 262 conf->filter = oldconf->filter; 263 264 /* set GYRO_CONFIG0 register (gyro fullscale & odr) */ 265 if (conf->fs != oldconf->fs || conf->odr != oldconf->odr) { 266 val = INV_ICM42600_GYRO_CONFIG0_FS(conf->fs) | 267 INV_ICM42600_GYRO_CONFIG0_ODR(conf->odr); 268 ret = regmap_write(st->map, INV_ICM42600_REG_GYRO_CONFIG0, val); 269 if (ret) 270 return ret; 271 oldconf->fs = conf->fs; 272 oldconf->odr = conf->odr; 273 } 274 275 /* set GYRO_ACCEL_CONFIG0 register (gyro filter) */ 276 if (conf->filter != oldconf->filter) { 277 val = INV_ICM42600_GYRO_ACCEL_CONFIG0_ACCEL_FILT(st->conf.accel.filter) | 278 INV_ICM42600_GYRO_ACCEL_CONFIG0_GYRO_FILT(conf->filter); 279 ret = regmap_write(st->map, INV_ICM42600_REG_GYRO_ACCEL_CONFIG0, val); 280 if (ret) 281 return ret; 282 oldconf->filter = conf->filter; 283 } 284 285 /* set PWR_MGMT0 register (gyro sensor mode) */ 286 return inv_icm42600_set_pwr_mgmt0(st, conf->mode, st->conf.accel.mode, 287 st->conf.temp_en, sleep_ms); 288 289 return 0; 290} 291 292int inv_icm42600_set_temp_conf(struct inv_icm42600_state *st, bool enable, 293 unsigned int *sleep_ms) 294{ 295 return inv_icm42600_set_pwr_mgmt0(st, st->conf.gyro.mode, 296 st->conf.accel.mode, enable, 297 sleep_ms); 298} 299 300int inv_icm42600_debugfs_reg(struct iio_dev *indio_dev, unsigned int reg, 301 unsigned int writeval, unsigned int *readval) 302{ 303 struct inv_icm42600_state *st = iio_device_get_drvdata(indio_dev); 304 int ret; 305 306 mutex_lock(&st->lock); 307 308 if (readval) 309 ret = regmap_read(st->map, reg, readval); 310 else 311 ret = regmap_write(st->map, reg, writeval); 312 313 mutex_unlock(&st->lock); 314 315 return ret; 316} 317 318static int inv_icm42600_set_conf(struct inv_icm42600_state *st, 319 const struct inv_icm42600_conf *conf) 320{ 321 unsigned int val; 322 int ret; 323 324 /* set PWR_MGMT0 register (gyro & accel sensor mode, temp enabled) */ 325 val = INV_ICM42600_PWR_MGMT0_GYRO(conf->gyro.mode) | 326 INV_ICM42600_PWR_MGMT0_ACCEL(conf->accel.mode); 327 if (!conf->temp_en) 328 val |= INV_ICM42600_PWR_MGMT0_TEMP_DIS; 329 ret = regmap_write(st->map, INV_ICM42600_REG_PWR_MGMT0, val); 330 if (ret) 331 return ret; 332 333 /* set GYRO_CONFIG0 register (gyro fullscale & odr) */ 334 val = INV_ICM42600_GYRO_CONFIG0_FS(conf->gyro.fs) | 335 INV_ICM42600_GYRO_CONFIG0_ODR(conf->gyro.odr); 336 ret = regmap_write(st->map, INV_ICM42600_REG_GYRO_CONFIG0, val); 337 if (ret) 338 return ret; 339 340 /* set ACCEL_CONFIG0 register (accel fullscale & odr) */ 341 val = INV_ICM42600_ACCEL_CONFIG0_FS(conf->accel.fs) | 342 INV_ICM42600_ACCEL_CONFIG0_ODR(conf->accel.odr); 343 ret = regmap_write(st->map, INV_ICM42600_REG_ACCEL_CONFIG0, val); 344 if (ret) 345 return ret; 346 347 /* set GYRO_ACCEL_CONFIG0 register (gyro & accel filters) */ 348 val = INV_ICM42600_GYRO_ACCEL_CONFIG0_ACCEL_FILT(conf->accel.filter) | 349 INV_ICM42600_GYRO_ACCEL_CONFIG0_GYRO_FILT(conf->gyro.filter); 350 ret = regmap_write(st->map, INV_ICM42600_REG_GYRO_ACCEL_CONFIG0, val); 351 if (ret) 352 return ret; 353 354 /* update internal conf */ 355 st->conf = *conf; 356 357 return 0; 358} 359 360/** 361 * inv_icm42600_setup() - check and setup chip 362 * @st: driver internal state 363 * @bus_setup: callback for setting up bus specific registers 364 * 365 * Returns 0 on success, a negative error code otherwise. 366 */ 367static int inv_icm42600_setup(struct inv_icm42600_state *st, 368 inv_icm42600_bus_setup bus_setup) 369{ 370 const struct inv_icm42600_hw *hw = &inv_icm42600_hw[st->chip]; 371 const struct device *dev = regmap_get_device(st->map); 372 unsigned int val; 373 int ret; 374 375 /* check chip self-identification value */ 376 ret = regmap_read(st->map, INV_ICM42600_REG_WHOAMI, &val); 377 if (ret) 378 return ret; 379 if (val != hw->whoami) { 380 dev_err(dev, "invalid whoami %#02x expected %#02x (%s)\n", 381 val, hw->whoami, hw->name); 382 return -ENODEV; 383 } 384 st->name = hw->name; 385 386 /* reset to make sure previous state are not there */ 387 ret = regmap_write(st->map, INV_ICM42600_REG_DEVICE_CONFIG, 388 INV_ICM42600_DEVICE_CONFIG_SOFT_RESET); 389 if (ret) 390 return ret; 391 msleep(INV_ICM42600_RESET_TIME_MS); 392 393 ret = regmap_read(st->map, INV_ICM42600_REG_INT_STATUS, &val); 394 if (ret) 395 return ret; 396 if (!(val & INV_ICM42600_INT_STATUS_RESET_DONE)) { 397 dev_err(dev, "reset error, reset done bit not set\n"); 398 return -ENODEV; 399 } 400 401 /* set chip bus configuration */ 402 ret = bus_setup(st); 403 if (ret) 404 return ret; 405 406 /* sensor data in big-endian (default) */ 407 ret = regmap_update_bits(st->map, INV_ICM42600_REG_INTF_CONFIG0, 408 INV_ICM42600_INTF_CONFIG0_SENSOR_DATA_ENDIAN, 409 INV_ICM42600_INTF_CONFIG0_SENSOR_DATA_ENDIAN); 410 if (ret) 411 return ret; 412 413 return inv_icm42600_set_conf(st, hw->conf); 414} 415 416static irqreturn_t inv_icm42600_irq_timestamp(int irq, void *_data) 417{ 418 struct inv_icm42600_state *st = _data; 419 420 st->timestamp.gyro = iio_get_time_ns(st->indio_gyro); 421 st->timestamp.accel = iio_get_time_ns(st->indio_accel); 422 423 return IRQ_WAKE_THREAD; 424} 425 426static irqreturn_t inv_icm42600_irq_handler(int irq, void *_data) 427{ 428 struct inv_icm42600_state *st = _data; 429 struct device *dev = regmap_get_device(st->map); 430 unsigned int status; 431 int ret; 432 433 mutex_lock(&st->lock); 434 435 ret = regmap_read(st->map, INV_ICM42600_REG_INT_STATUS, &status); 436 if (ret) 437 goto out_unlock; 438 439 /* FIFO full */ 440 if (status & INV_ICM42600_INT_STATUS_FIFO_FULL) 441 dev_warn(dev, "FIFO full data lost!\n"); 442 443 /* FIFO threshold reached */ 444 if (status & INV_ICM42600_INT_STATUS_FIFO_THS) { 445 ret = inv_icm42600_buffer_fifo_read(st, 0); 446 if (ret) { 447 dev_err(dev, "FIFO read error %d\n", ret); 448 goto out_unlock; 449 } 450 ret = inv_icm42600_buffer_fifo_parse(st); 451 if (ret) 452 dev_err(dev, "FIFO parsing error %d\n", ret); 453 } 454 455out_unlock: 456 mutex_unlock(&st->lock); 457 return IRQ_HANDLED; 458} 459 460/** 461 * inv_icm42600_irq_init() - initialize int pin and interrupt handler 462 * @st: driver internal state 463 * @irq: irq number 464 * @irq_type: irq trigger type 465 * @open_drain: true if irq is open drain, false for push-pull 466 * 467 * Returns 0 on success, a negative error code otherwise. 468 */ 469static int inv_icm42600_irq_init(struct inv_icm42600_state *st, int irq, 470 int irq_type, bool open_drain) 471{ 472 struct device *dev = regmap_get_device(st->map); 473 unsigned int val; 474 int ret; 475 476 /* configure INT1 interrupt: default is active low on edge */ 477 switch (irq_type) { 478 case IRQF_TRIGGER_RISING: 479 case IRQF_TRIGGER_HIGH: 480 val = INV_ICM42600_INT_CONFIG_INT1_ACTIVE_HIGH; 481 break; 482 default: 483 val = INV_ICM42600_INT_CONFIG_INT1_ACTIVE_LOW; 484 break; 485 } 486 487 switch (irq_type) { 488 case IRQF_TRIGGER_LOW: 489 case IRQF_TRIGGER_HIGH: 490 val |= INV_ICM42600_INT_CONFIG_INT1_LATCHED; 491 break; 492 default: 493 break; 494 } 495 496 if (!open_drain) 497 val |= INV_ICM42600_INT_CONFIG_INT1_PUSH_PULL; 498 499 ret = regmap_write(st->map, INV_ICM42600_REG_INT_CONFIG, val); 500 if (ret) 501 return ret; 502 503 /* Deassert async reset for proper INT pin operation (cf datasheet) */ 504 ret = regmap_update_bits(st->map, INV_ICM42600_REG_INT_CONFIG1, 505 INV_ICM42600_INT_CONFIG1_ASYNC_RESET, 0); 506 if (ret) 507 return ret; 508 509 return devm_request_threaded_irq(dev, irq, inv_icm42600_irq_timestamp, 510 inv_icm42600_irq_handler, irq_type, 511 "inv_icm42600", st); 512} 513 514static int inv_icm42600_enable_regulator_vddio(struct inv_icm42600_state *st) 515{ 516 int ret; 517 518 ret = regulator_enable(st->vddio_supply); 519 if (ret) 520 return ret; 521 522 /* wait a little for supply ramp */ 523 usleep_range(3000, 4000); 524 525 return 0; 526} 527 528static void inv_icm42600_disable_vdd_reg(void *_data) 529{ 530 struct inv_icm42600_state *st = _data; 531 const struct device *dev = regmap_get_device(st->map); 532 int ret; 533 534 ret = regulator_disable(st->vdd_supply); 535 if (ret) 536 dev_err(dev, "failed to disable vdd error %d\n", ret); 537} 538 539static void inv_icm42600_disable_vddio_reg(void *_data) 540{ 541 struct inv_icm42600_state *st = _data; 542 const struct device *dev = regmap_get_device(st->map); 543 int ret; 544 545 ret = regulator_disable(st->vddio_supply); 546 if (ret) 547 dev_err(dev, "failed to disable vddio error %d\n", ret); 548} 549 550static void inv_icm42600_disable_pm(void *_data) 551{ 552 struct device *dev = _data; 553 554 pm_runtime_put_sync(dev); 555 pm_runtime_disable(dev); 556} 557 558int inv_icm42600_core_probe(struct regmap *regmap, int chip, int irq, 559 inv_icm42600_bus_setup bus_setup) 560{ 561 struct device *dev = regmap_get_device(regmap); 562 struct inv_icm42600_state *st; 563 struct irq_data *irq_desc; 564 int irq_type; 565 bool open_drain; 566 int ret; 567 568 if (chip <= INV_CHIP_INVALID || chip >= INV_CHIP_NB) { 569 dev_err(dev, "invalid chip = %d\n", chip); 570 return -ENODEV; 571 } 572 573 /* get irq properties, set trigger falling by default */ 574 irq_desc = irq_get_irq_data(irq); 575 if (!irq_desc) { 576 dev_err(dev, "could not find IRQ %d\n", irq); 577 return -EINVAL; 578 } 579 580 irq_type = irqd_get_trigger_type(irq_desc); 581 if (!irq_type) 582 irq_type = IRQF_TRIGGER_FALLING; 583 584 open_drain = device_property_read_bool(dev, "drive-open-drain"); 585 586 st = devm_kzalloc(dev, sizeof(*st), GFP_KERNEL); 587 if (!st) 588 return -ENOMEM; 589 590 dev_set_drvdata(dev, st); 591 mutex_init(&st->lock); 592 st->chip = chip; 593 st->map = regmap; 594 595 ret = iio_read_mount_matrix(dev, &st->orientation); 596 if (ret) { 597 dev_err(dev, "failed to retrieve mounting matrix %d\n", ret); 598 return ret; 599 } 600 601 st->vdd_supply = devm_regulator_get(dev, "vdd"); 602 if (IS_ERR(st->vdd_supply)) 603 return PTR_ERR(st->vdd_supply); 604 605 st->vddio_supply = devm_regulator_get(dev, "vddio"); 606 if (IS_ERR(st->vddio_supply)) 607 return PTR_ERR(st->vddio_supply); 608 609 ret = regulator_enable(st->vdd_supply); 610 if (ret) 611 return ret; 612 msleep(INV_ICM42600_POWER_UP_TIME_MS); 613 614 ret = devm_add_action_or_reset(dev, inv_icm42600_disable_vdd_reg, st); 615 if (ret) 616 return ret; 617 618 ret = inv_icm42600_enable_regulator_vddio(st); 619 if (ret) 620 return ret; 621 622 ret = devm_add_action_or_reset(dev, inv_icm42600_disable_vddio_reg, st); 623 if (ret) 624 return ret; 625 626 /* setup chip registers */ 627 ret = inv_icm42600_setup(st, bus_setup); 628 if (ret) 629 return ret; 630 631 ret = inv_icm42600_timestamp_setup(st); 632 if (ret) 633 return ret; 634 635 ret = inv_icm42600_buffer_init(st); 636 if (ret) 637 return ret; 638 639 st->indio_gyro = inv_icm42600_gyro_init(st); 640 if (IS_ERR(st->indio_gyro)) 641 return PTR_ERR(st->indio_gyro); 642 643 st->indio_accel = inv_icm42600_accel_init(st); 644 if (IS_ERR(st->indio_accel)) 645 return PTR_ERR(st->indio_accel); 646 647 ret = inv_icm42600_irq_init(st, irq, irq_type, open_drain); 648 if (ret) 649 return ret; 650 651 /* setup runtime power management */ 652 ret = pm_runtime_set_active(dev); 653 if (ret) 654 return ret; 655 pm_runtime_get_noresume(dev); 656 pm_runtime_enable(dev); 657 pm_runtime_set_autosuspend_delay(dev, INV_ICM42600_SUSPEND_DELAY_MS); 658 pm_runtime_use_autosuspend(dev); 659 pm_runtime_put(dev); 660 661 return devm_add_action_or_reset(dev, inv_icm42600_disable_pm, dev); 662} 663EXPORT_SYMBOL_GPL(inv_icm42600_core_probe); 664 665/* 666 * Suspend saves sensors state and turns everything off. 667 * Check first if runtime suspend has not already done the job. 668 */ 669static int __maybe_unused inv_icm42600_suspend(struct device *dev) 670{ 671 struct inv_icm42600_state *st = dev_get_drvdata(dev); 672 int ret; 673 674 mutex_lock(&st->lock); 675 676 st->suspended.gyro = st->conf.gyro.mode; 677 st->suspended.accel = st->conf.accel.mode; 678 st->suspended.temp = st->conf.temp_en; 679 if (pm_runtime_suspended(dev)) { 680 ret = 0; 681 goto out_unlock; 682 } 683 684 /* disable FIFO data streaming */ 685 if (st->fifo.on) { 686 ret = regmap_write(st->map, INV_ICM42600_REG_FIFO_CONFIG, 687 INV_ICM42600_FIFO_CONFIG_BYPASS); 688 if (ret) 689 goto out_unlock; 690 } 691 692 ret = inv_icm42600_set_pwr_mgmt0(st, INV_ICM42600_SENSOR_MODE_OFF, 693 INV_ICM42600_SENSOR_MODE_OFF, false, 694 NULL); 695 if (ret) 696 goto out_unlock; 697 698 regulator_disable(st->vddio_supply); 699 700out_unlock: 701 mutex_unlock(&st->lock); 702 return ret; 703} 704 705/* 706 * System resume gets the system back on and restores the sensors state. 707 * Manually put runtime power management in system active state. 708 */ 709static int __maybe_unused inv_icm42600_resume(struct device *dev) 710{ 711 struct inv_icm42600_state *st = dev_get_drvdata(dev); 712 int ret; 713 714 mutex_lock(&st->lock); 715 716 ret = inv_icm42600_enable_regulator_vddio(st); 717 if (ret) 718 goto out_unlock; 719 720 pm_runtime_disable(dev); 721 pm_runtime_set_active(dev); 722 pm_runtime_enable(dev); 723 724 /* restore sensors state */ 725 ret = inv_icm42600_set_pwr_mgmt0(st, st->suspended.gyro, 726 st->suspended.accel, 727 st->suspended.temp, NULL); 728 if (ret) 729 goto out_unlock; 730 731 /* restore FIFO data streaming */ 732 if (st->fifo.on) 733 ret = regmap_write(st->map, INV_ICM42600_REG_FIFO_CONFIG, 734 INV_ICM42600_FIFO_CONFIG_STREAM); 735 736out_unlock: 737 mutex_unlock(&st->lock); 738 return ret; 739} 740 741/* Runtime suspend will turn off sensors that are enabled by iio devices. */ 742static int __maybe_unused inv_icm42600_runtime_suspend(struct device *dev) 743{ 744 struct inv_icm42600_state *st = dev_get_drvdata(dev); 745 int ret; 746 747 mutex_lock(&st->lock); 748 749 /* disable all sensors */ 750 ret = inv_icm42600_set_pwr_mgmt0(st, INV_ICM42600_SENSOR_MODE_OFF, 751 INV_ICM42600_SENSOR_MODE_OFF, false, 752 NULL); 753 if (ret) 754 goto error_unlock; 755 756 regulator_disable(st->vddio_supply); 757 758error_unlock: 759 mutex_unlock(&st->lock); 760 return ret; 761} 762 763/* Sensors are enabled by iio devices, no need to turn them back on here. */ 764static int __maybe_unused inv_icm42600_runtime_resume(struct device *dev) 765{ 766 struct inv_icm42600_state *st = dev_get_drvdata(dev); 767 int ret; 768 769 mutex_lock(&st->lock); 770 771 ret = inv_icm42600_enable_regulator_vddio(st); 772 773 mutex_unlock(&st->lock); 774 return ret; 775} 776 777const struct dev_pm_ops inv_icm42600_pm_ops = { 778 SET_SYSTEM_SLEEP_PM_OPS(inv_icm42600_suspend, inv_icm42600_resume) 779 SET_RUNTIME_PM_OPS(inv_icm42600_runtime_suspend, 780 inv_icm42600_runtime_resume, NULL) 781}; 782EXPORT_SYMBOL_GPL(inv_icm42600_pm_ops); 783 784MODULE_AUTHOR("InvenSense, Inc."); 785MODULE_DESCRIPTION("InvenSense ICM-426xx device driver"); 786MODULE_LICENSE("GPL");