0001
0002
0003
0004
0005
0006 #include <linux/kernel.h>
0007 #include <linux/device.h>
0008 #include <linux/module.h>
0009 #include <linux/slab.h>
0010 #include <linux/delay.h>
0011 #include <linux/mutex.h>
0012 #include <linux/interrupt.h>
0013 #include <linux/irq.h>
0014 #include <linux/regulator/consumer.h>
0015 #include <linux/pm_runtime.h>
0016 #include <linux/property.h>
0017 #include <linux/regmap.h>
0018 #include <linux/iio/iio.h>
0019
0020 #include "inv_icm42600.h"
0021 #include "inv_icm42600_buffer.h"
0022 #include "inv_icm42600_timestamp.h"
0023
0024 static const struct regmap_range_cfg inv_icm42600_regmap_ranges[] = {
0025 {
0026 .name = "user banks",
0027 .range_min = 0x0000,
0028 .range_max = 0x4FFF,
0029 .selector_reg = INV_ICM42600_REG_BANK_SEL,
0030 .selector_mask = INV_ICM42600_BANK_SEL_MASK,
0031 .selector_shift = 0,
0032 .window_start = 0,
0033 .window_len = 0x1000,
0034 },
0035 };
0036
0037 const struct regmap_config inv_icm42600_regmap_config = {
0038 .reg_bits = 8,
0039 .val_bits = 8,
0040 .max_register = 0x4FFF,
0041 .ranges = inv_icm42600_regmap_ranges,
0042 .num_ranges = ARRAY_SIZE(inv_icm42600_regmap_ranges),
0043 };
0044 EXPORT_SYMBOL_GPL(inv_icm42600_regmap_config);
0045
0046 struct inv_icm42600_hw {
0047 uint8_t whoami;
0048 const char *name;
0049 const struct inv_icm42600_conf *conf;
0050 };
0051
0052
0053 static const struct inv_icm42600_conf inv_icm42600_default_conf = {
0054 .gyro = {
0055 .mode = INV_ICM42600_SENSOR_MODE_OFF,
0056 .fs = INV_ICM42600_GYRO_FS_2000DPS,
0057 .odr = INV_ICM42600_ODR_50HZ,
0058 .filter = INV_ICM42600_FILTER_BW_ODR_DIV_2,
0059 },
0060 .accel = {
0061 .mode = INV_ICM42600_SENSOR_MODE_OFF,
0062 .fs = INV_ICM42600_ACCEL_FS_16G,
0063 .odr = INV_ICM42600_ODR_50HZ,
0064 .filter = INV_ICM42600_FILTER_BW_ODR_DIV_2,
0065 },
0066 .temp_en = false,
0067 };
0068
0069 static const struct inv_icm42600_hw inv_icm42600_hw[INV_CHIP_NB] = {
0070 [INV_CHIP_ICM42600] = {
0071 .whoami = INV_ICM42600_WHOAMI_ICM42600,
0072 .name = "icm42600",
0073 .conf = &inv_icm42600_default_conf,
0074 },
0075 [INV_CHIP_ICM42602] = {
0076 .whoami = INV_ICM42600_WHOAMI_ICM42602,
0077 .name = "icm42602",
0078 .conf = &inv_icm42600_default_conf,
0079 },
0080 [INV_CHIP_ICM42605] = {
0081 .whoami = INV_ICM42600_WHOAMI_ICM42605,
0082 .name = "icm42605",
0083 .conf = &inv_icm42600_default_conf,
0084 },
0085 [INV_CHIP_ICM42622] = {
0086 .whoami = INV_ICM42600_WHOAMI_ICM42622,
0087 .name = "icm42622",
0088 .conf = &inv_icm42600_default_conf,
0089 },
0090 };
0091
0092 const struct iio_mount_matrix *
0093 inv_icm42600_get_mount_matrix(const struct iio_dev *indio_dev,
0094 const struct iio_chan_spec *chan)
0095 {
0096 const struct inv_icm42600_state *st = iio_device_get_drvdata(indio_dev);
0097
0098 return &st->orientation;
0099 }
0100
0101 uint32_t inv_icm42600_odr_to_period(enum inv_icm42600_odr odr)
0102 {
0103 static uint32_t odr_periods[INV_ICM42600_ODR_NB] = {
0104
0105 0, 0, 0,
0106
0107 125000,
0108
0109 250000,
0110
0111 500000,
0112
0113 1000000,
0114
0115 5000000,
0116
0117 10000000,
0118
0119 20000000,
0120
0121 40000000,
0122
0123 80000000,
0124
0125 160000000,
0126
0127 320000000,
0128
0129 640000000,
0130
0131 2000000,
0132 };
0133
0134 return odr_periods[odr];
0135 }
0136
0137 static int inv_icm42600_set_pwr_mgmt0(struct inv_icm42600_state *st,
0138 enum inv_icm42600_sensor_mode gyro,
0139 enum inv_icm42600_sensor_mode accel,
0140 bool temp, unsigned int *sleep_ms)
0141 {
0142 enum inv_icm42600_sensor_mode oldgyro = st->conf.gyro.mode;
0143 enum inv_icm42600_sensor_mode oldaccel = st->conf.accel.mode;
0144 bool oldtemp = st->conf.temp_en;
0145 unsigned int sleepval;
0146 unsigned int val;
0147 int ret;
0148
0149
0150 if (gyro == oldgyro && accel == oldaccel && temp == oldtemp)
0151 return 0;
0152
0153 val = INV_ICM42600_PWR_MGMT0_GYRO(gyro) |
0154 INV_ICM42600_PWR_MGMT0_ACCEL(accel);
0155 if (!temp)
0156 val |= INV_ICM42600_PWR_MGMT0_TEMP_DIS;
0157 ret = regmap_write(st->map, INV_ICM42600_REG_PWR_MGMT0, val);
0158 if (ret)
0159 return ret;
0160
0161 st->conf.gyro.mode = gyro;
0162 st->conf.accel.mode = accel;
0163 st->conf.temp_en = temp;
0164
0165
0166 sleepval = 0;
0167
0168 if (temp && !oldtemp) {
0169 if (sleepval < INV_ICM42600_TEMP_STARTUP_TIME_MS)
0170 sleepval = INV_ICM42600_TEMP_STARTUP_TIME_MS;
0171 }
0172
0173 if (accel != oldaccel && oldaccel == INV_ICM42600_SENSOR_MODE_OFF) {
0174
0175 usleep_range(200, 300);
0176 if (sleepval < INV_ICM42600_ACCEL_STARTUP_TIME_MS)
0177 sleepval = INV_ICM42600_ACCEL_STARTUP_TIME_MS;
0178 }
0179 if (gyro != oldgyro) {
0180
0181 if (oldgyro == INV_ICM42600_SENSOR_MODE_OFF) {
0182
0183 usleep_range(200, 300);
0184 if (sleepval < INV_ICM42600_GYRO_STARTUP_TIME_MS)
0185 sleepval = INV_ICM42600_GYRO_STARTUP_TIME_MS;
0186
0187 } else if (gyro == INV_ICM42600_SENSOR_MODE_OFF) {
0188 if (sleepval < INV_ICM42600_GYRO_STOP_TIME_MS)
0189 sleepval = INV_ICM42600_GYRO_STOP_TIME_MS;
0190 }
0191 }
0192
0193
0194 if (sleep_ms)
0195 *sleep_ms = sleepval;
0196 else if (sleepval)
0197 msleep(sleepval);
0198
0199 return 0;
0200 }
0201
0202 int inv_icm42600_set_accel_conf(struct inv_icm42600_state *st,
0203 struct inv_icm42600_sensor_conf *conf,
0204 unsigned int *sleep_ms)
0205 {
0206 struct inv_icm42600_sensor_conf *oldconf = &st->conf.accel;
0207 unsigned int val;
0208 int ret;
0209
0210
0211 if (conf->mode < 0)
0212 conf->mode = oldconf->mode;
0213 if (conf->fs < 0)
0214 conf->fs = oldconf->fs;
0215 if (conf->odr < 0)
0216 conf->odr = oldconf->odr;
0217 if (conf->filter < 0)
0218 conf->filter = oldconf->filter;
0219
0220
0221 if (conf->fs != oldconf->fs || conf->odr != oldconf->odr) {
0222 val = INV_ICM42600_ACCEL_CONFIG0_FS(conf->fs) |
0223 INV_ICM42600_ACCEL_CONFIG0_ODR(conf->odr);
0224 ret = regmap_write(st->map, INV_ICM42600_REG_ACCEL_CONFIG0, val);
0225 if (ret)
0226 return ret;
0227 oldconf->fs = conf->fs;
0228 oldconf->odr = conf->odr;
0229 }
0230
0231
0232 if (conf->filter != oldconf->filter) {
0233 val = INV_ICM42600_GYRO_ACCEL_CONFIG0_ACCEL_FILT(conf->filter) |
0234 INV_ICM42600_GYRO_ACCEL_CONFIG0_GYRO_FILT(st->conf.gyro.filter);
0235 ret = regmap_write(st->map, INV_ICM42600_REG_GYRO_ACCEL_CONFIG0, val);
0236 if (ret)
0237 return ret;
0238 oldconf->filter = conf->filter;
0239 }
0240
0241
0242 return inv_icm42600_set_pwr_mgmt0(st, st->conf.gyro.mode, conf->mode,
0243 st->conf.temp_en, sleep_ms);
0244 }
0245
0246 int inv_icm42600_set_gyro_conf(struct inv_icm42600_state *st,
0247 struct inv_icm42600_sensor_conf *conf,
0248 unsigned int *sleep_ms)
0249 {
0250 struct inv_icm42600_sensor_conf *oldconf = &st->conf.gyro;
0251 unsigned int val;
0252 int ret;
0253
0254
0255 if (conf->mode < 0)
0256 conf->mode = oldconf->mode;
0257 if (conf->fs < 0)
0258 conf->fs = oldconf->fs;
0259 if (conf->odr < 0)
0260 conf->odr = oldconf->odr;
0261 if (conf->filter < 0)
0262 conf->filter = oldconf->filter;
0263
0264
0265 if (conf->fs != oldconf->fs || conf->odr != oldconf->odr) {
0266 val = INV_ICM42600_GYRO_CONFIG0_FS(conf->fs) |
0267 INV_ICM42600_GYRO_CONFIG0_ODR(conf->odr);
0268 ret = regmap_write(st->map, INV_ICM42600_REG_GYRO_CONFIG0, val);
0269 if (ret)
0270 return ret;
0271 oldconf->fs = conf->fs;
0272 oldconf->odr = conf->odr;
0273 }
0274
0275
0276 if (conf->filter != oldconf->filter) {
0277 val = INV_ICM42600_GYRO_ACCEL_CONFIG0_ACCEL_FILT(st->conf.accel.filter) |
0278 INV_ICM42600_GYRO_ACCEL_CONFIG0_GYRO_FILT(conf->filter);
0279 ret = regmap_write(st->map, INV_ICM42600_REG_GYRO_ACCEL_CONFIG0, val);
0280 if (ret)
0281 return ret;
0282 oldconf->filter = conf->filter;
0283 }
0284
0285
0286 return inv_icm42600_set_pwr_mgmt0(st, conf->mode, st->conf.accel.mode,
0287 st->conf.temp_en, sleep_ms);
0288
0289 return 0;
0290 }
0291
0292 int inv_icm42600_set_temp_conf(struct inv_icm42600_state *st, bool enable,
0293 unsigned int *sleep_ms)
0294 {
0295 return inv_icm42600_set_pwr_mgmt0(st, st->conf.gyro.mode,
0296 st->conf.accel.mode, enable,
0297 sleep_ms);
0298 }
0299
0300 int inv_icm42600_debugfs_reg(struct iio_dev *indio_dev, unsigned int reg,
0301 unsigned int writeval, unsigned int *readval)
0302 {
0303 struct inv_icm42600_state *st = iio_device_get_drvdata(indio_dev);
0304 int ret;
0305
0306 mutex_lock(&st->lock);
0307
0308 if (readval)
0309 ret = regmap_read(st->map, reg, readval);
0310 else
0311 ret = regmap_write(st->map, reg, writeval);
0312
0313 mutex_unlock(&st->lock);
0314
0315 return ret;
0316 }
0317
0318 static int inv_icm42600_set_conf(struct inv_icm42600_state *st,
0319 const struct inv_icm42600_conf *conf)
0320 {
0321 unsigned int val;
0322 int ret;
0323
0324
0325 val = INV_ICM42600_PWR_MGMT0_GYRO(conf->gyro.mode) |
0326 INV_ICM42600_PWR_MGMT0_ACCEL(conf->accel.mode);
0327 if (!conf->temp_en)
0328 val |= INV_ICM42600_PWR_MGMT0_TEMP_DIS;
0329 ret = regmap_write(st->map, INV_ICM42600_REG_PWR_MGMT0, val);
0330 if (ret)
0331 return ret;
0332
0333
0334 val = INV_ICM42600_GYRO_CONFIG0_FS(conf->gyro.fs) |
0335 INV_ICM42600_GYRO_CONFIG0_ODR(conf->gyro.odr);
0336 ret = regmap_write(st->map, INV_ICM42600_REG_GYRO_CONFIG0, val);
0337 if (ret)
0338 return ret;
0339
0340
0341 val = INV_ICM42600_ACCEL_CONFIG0_FS(conf->accel.fs) |
0342 INV_ICM42600_ACCEL_CONFIG0_ODR(conf->accel.odr);
0343 ret = regmap_write(st->map, INV_ICM42600_REG_ACCEL_CONFIG0, val);
0344 if (ret)
0345 return ret;
0346
0347
0348 val = INV_ICM42600_GYRO_ACCEL_CONFIG0_ACCEL_FILT(conf->accel.filter) |
0349 INV_ICM42600_GYRO_ACCEL_CONFIG0_GYRO_FILT(conf->gyro.filter);
0350 ret = regmap_write(st->map, INV_ICM42600_REG_GYRO_ACCEL_CONFIG0, val);
0351 if (ret)
0352 return ret;
0353
0354
0355 st->conf = *conf;
0356
0357 return 0;
0358 }
0359
0360
0361
0362
0363
0364
0365
0366
0367 static int inv_icm42600_setup(struct inv_icm42600_state *st,
0368 inv_icm42600_bus_setup bus_setup)
0369 {
0370 const struct inv_icm42600_hw *hw = &inv_icm42600_hw[st->chip];
0371 const struct device *dev = regmap_get_device(st->map);
0372 unsigned int val;
0373 int ret;
0374
0375
0376 ret = regmap_read(st->map, INV_ICM42600_REG_WHOAMI, &val);
0377 if (ret)
0378 return ret;
0379 if (val != hw->whoami) {
0380 dev_err(dev, "invalid whoami %#02x expected %#02x (%s)\n",
0381 val, hw->whoami, hw->name);
0382 return -ENODEV;
0383 }
0384 st->name = hw->name;
0385
0386
0387 ret = regmap_write(st->map, INV_ICM42600_REG_DEVICE_CONFIG,
0388 INV_ICM42600_DEVICE_CONFIG_SOFT_RESET);
0389 if (ret)
0390 return ret;
0391 msleep(INV_ICM42600_RESET_TIME_MS);
0392
0393 ret = regmap_read(st->map, INV_ICM42600_REG_INT_STATUS, &val);
0394 if (ret)
0395 return ret;
0396 if (!(val & INV_ICM42600_INT_STATUS_RESET_DONE)) {
0397 dev_err(dev, "reset error, reset done bit not set\n");
0398 return -ENODEV;
0399 }
0400
0401
0402 ret = bus_setup(st);
0403 if (ret)
0404 return ret;
0405
0406
0407 ret = regmap_update_bits(st->map, INV_ICM42600_REG_INTF_CONFIG0,
0408 INV_ICM42600_INTF_CONFIG0_SENSOR_DATA_ENDIAN,
0409 INV_ICM42600_INTF_CONFIG0_SENSOR_DATA_ENDIAN);
0410 if (ret)
0411 return ret;
0412
0413 return inv_icm42600_set_conf(st, hw->conf);
0414 }
0415
0416 static irqreturn_t inv_icm42600_irq_timestamp(int irq, void *_data)
0417 {
0418 struct inv_icm42600_state *st = _data;
0419
0420 st->timestamp.gyro = iio_get_time_ns(st->indio_gyro);
0421 st->timestamp.accel = iio_get_time_ns(st->indio_accel);
0422
0423 return IRQ_WAKE_THREAD;
0424 }
0425
0426 static irqreturn_t inv_icm42600_irq_handler(int irq, void *_data)
0427 {
0428 struct inv_icm42600_state *st = _data;
0429 struct device *dev = regmap_get_device(st->map);
0430 unsigned int status;
0431 int ret;
0432
0433 mutex_lock(&st->lock);
0434
0435 ret = regmap_read(st->map, INV_ICM42600_REG_INT_STATUS, &status);
0436 if (ret)
0437 goto out_unlock;
0438
0439
0440 if (status & INV_ICM42600_INT_STATUS_FIFO_FULL)
0441 dev_warn(dev, "FIFO full data lost!\n");
0442
0443
0444 if (status & INV_ICM42600_INT_STATUS_FIFO_THS) {
0445 ret = inv_icm42600_buffer_fifo_read(st, 0);
0446 if (ret) {
0447 dev_err(dev, "FIFO read error %d\n", ret);
0448 goto out_unlock;
0449 }
0450 ret = inv_icm42600_buffer_fifo_parse(st);
0451 if (ret)
0452 dev_err(dev, "FIFO parsing error %d\n", ret);
0453 }
0454
0455 out_unlock:
0456 mutex_unlock(&st->lock);
0457 return IRQ_HANDLED;
0458 }
0459
0460
0461
0462
0463
0464
0465
0466
0467
0468
0469 static int inv_icm42600_irq_init(struct inv_icm42600_state *st, int irq,
0470 int irq_type, bool open_drain)
0471 {
0472 struct device *dev = regmap_get_device(st->map);
0473 unsigned int val;
0474 int ret;
0475
0476
0477 switch (irq_type) {
0478 case IRQF_TRIGGER_RISING:
0479 case IRQF_TRIGGER_HIGH:
0480 val = INV_ICM42600_INT_CONFIG_INT1_ACTIVE_HIGH;
0481 break;
0482 default:
0483 val = INV_ICM42600_INT_CONFIG_INT1_ACTIVE_LOW;
0484 break;
0485 }
0486
0487 switch (irq_type) {
0488 case IRQF_TRIGGER_LOW:
0489 case IRQF_TRIGGER_HIGH:
0490 val |= INV_ICM42600_INT_CONFIG_INT1_LATCHED;
0491 break;
0492 default:
0493 break;
0494 }
0495
0496 if (!open_drain)
0497 val |= INV_ICM42600_INT_CONFIG_INT1_PUSH_PULL;
0498
0499 ret = regmap_write(st->map, INV_ICM42600_REG_INT_CONFIG, val);
0500 if (ret)
0501 return ret;
0502
0503
0504 ret = regmap_update_bits(st->map, INV_ICM42600_REG_INT_CONFIG1,
0505 INV_ICM42600_INT_CONFIG1_ASYNC_RESET, 0);
0506 if (ret)
0507 return ret;
0508
0509 return devm_request_threaded_irq(dev, irq, inv_icm42600_irq_timestamp,
0510 inv_icm42600_irq_handler, irq_type,
0511 "inv_icm42600", st);
0512 }
0513
0514 static int inv_icm42600_enable_regulator_vddio(struct inv_icm42600_state *st)
0515 {
0516 int ret;
0517
0518 ret = regulator_enable(st->vddio_supply);
0519 if (ret)
0520 return ret;
0521
0522
0523 usleep_range(3000, 4000);
0524
0525 return 0;
0526 }
0527
0528 static void inv_icm42600_disable_vdd_reg(void *_data)
0529 {
0530 struct inv_icm42600_state *st = _data;
0531 const struct device *dev = regmap_get_device(st->map);
0532 int ret;
0533
0534 ret = regulator_disable(st->vdd_supply);
0535 if (ret)
0536 dev_err(dev, "failed to disable vdd error %d\n", ret);
0537 }
0538
0539 static void inv_icm42600_disable_vddio_reg(void *_data)
0540 {
0541 struct inv_icm42600_state *st = _data;
0542 const struct device *dev = regmap_get_device(st->map);
0543 int ret;
0544
0545 ret = regulator_disable(st->vddio_supply);
0546 if (ret)
0547 dev_err(dev, "failed to disable vddio error %d\n", ret);
0548 }
0549
0550 static void inv_icm42600_disable_pm(void *_data)
0551 {
0552 struct device *dev = _data;
0553
0554 pm_runtime_put_sync(dev);
0555 pm_runtime_disable(dev);
0556 }
0557
0558 int inv_icm42600_core_probe(struct regmap *regmap, int chip, int irq,
0559 inv_icm42600_bus_setup bus_setup)
0560 {
0561 struct device *dev = regmap_get_device(regmap);
0562 struct inv_icm42600_state *st;
0563 struct irq_data *irq_desc;
0564 int irq_type;
0565 bool open_drain;
0566 int ret;
0567
0568 if (chip <= INV_CHIP_INVALID || chip >= INV_CHIP_NB) {
0569 dev_err(dev, "invalid chip = %d\n", chip);
0570 return -ENODEV;
0571 }
0572
0573
0574 irq_desc = irq_get_irq_data(irq);
0575 if (!irq_desc) {
0576 dev_err(dev, "could not find IRQ %d\n", irq);
0577 return -EINVAL;
0578 }
0579
0580 irq_type = irqd_get_trigger_type(irq_desc);
0581 if (!irq_type)
0582 irq_type = IRQF_TRIGGER_FALLING;
0583
0584 open_drain = device_property_read_bool(dev, "drive-open-drain");
0585
0586 st = devm_kzalloc(dev, sizeof(*st), GFP_KERNEL);
0587 if (!st)
0588 return -ENOMEM;
0589
0590 dev_set_drvdata(dev, st);
0591 mutex_init(&st->lock);
0592 st->chip = chip;
0593 st->map = regmap;
0594
0595 ret = iio_read_mount_matrix(dev, &st->orientation);
0596 if (ret) {
0597 dev_err(dev, "failed to retrieve mounting matrix %d\n", ret);
0598 return ret;
0599 }
0600
0601 st->vdd_supply = devm_regulator_get(dev, "vdd");
0602 if (IS_ERR(st->vdd_supply))
0603 return PTR_ERR(st->vdd_supply);
0604
0605 st->vddio_supply = devm_regulator_get(dev, "vddio");
0606 if (IS_ERR(st->vddio_supply))
0607 return PTR_ERR(st->vddio_supply);
0608
0609 ret = regulator_enable(st->vdd_supply);
0610 if (ret)
0611 return ret;
0612 msleep(INV_ICM42600_POWER_UP_TIME_MS);
0613
0614 ret = devm_add_action_or_reset(dev, inv_icm42600_disable_vdd_reg, st);
0615 if (ret)
0616 return ret;
0617
0618 ret = inv_icm42600_enable_regulator_vddio(st);
0619 if (ret)
0620 return ret;
0621
0622 ret = devm_add_action_or_reset(dev, inv_icm42600_disable_vddio_reg, st);
0623 if (ret)
0624 return ret;
0625
0626
0627 ret = inv_icm42600_setup(st, bus_setup);
0628 if (ret)
0629 return ret;
0630
0631 ret = inv_icm42600_timestamp_setup(st);
0632 if (ret)
0633 return ret;
0634
0635 ret = inv_icm42600_buffer_init(st);
0636 if (ret)
0637 return ret;
0638
0639 st->indio_gyro = inv_icm42600_gyro_init(st);
0640 if (IS_ERR(st->indio_gyro))
0641 return PTR_ERR(st->indio_gyro);
0642
0643 st->indio_accel = inv_icm42600_accel_init(st);
0644 if (IS_ERR(st->indio_accel))
0645 return PTR_ERR(st->indio_accel);
0646
0647 ret = inv_icm42600_irq_init(st, irq, irq_type, open_drain);
0648 if (ret)
0649 return ret;
0650
0651
0652 ret = pm_runtime_set_active(dev);
0653 if (ret)
0654 return ret;
0655 pm_runtime_get_noresume(dev);
0656 pm_runtime_enable(dev);
0657 pm_runtime_set_autosuspend_delay(dev, INV_ICM42600_SUSPEND_DELAY_MS);
0658 pm_runtime_use_autosuspend(dev);
0659 pm_runtime_put(dev);
0660
0661 return devm_add_action_or_reset(dev, inv_icm42600_disable_pm, dev);
0662 }
0663 EXPORT_SYMBOL_GPL(inv_icm42600_core_probe);
0664
0665
0666
0667
0668
0669 static int __maybe_unused inv_icm42600_suspend(struct device *dev)
0670 {
0671 struct inv_icm42600_state *st = dev_get_drvdata(dev);
0672 int ret;
0673
0674 mutex_lock(&st->lock);
0675
0676 st->suspended.gyro = st->conf.gyro.mode;
0677 st->suspended.accel = st->conf.accel.mode;
0678 st->suspended.temp = st->conf.temp_en;
0679 if (pm_runtime_suspended(dev)) {
0680 ret = 0;
0681 goto out_unlock;
0682 }
0683
0684
0685 if (st->fifo.on) {
0686 ret = regmap_write(st->map, INV_ICM42600_REG_FIFO_CONFIG,
0687 INV_ICM42600_FIFO_CONFIG_BYPASS);
0688 if (ret)
0689 goto out_unlock;
0690 }
0691
0692 ret = inv_icm42600_set_pwr_mgmt0(st, INV_ICM42600_SENSOR_MODE_OFF,
0693 INV_ICM42600_SENSOR_MODE_OFF, false,
0694 NULL);
0695 if (ret)
0696 goto out_unlock;
0697
0698 regulator_disable(st->vddio_supply);
0699
0700 out_unlock:
0701 mutex_unlock(&st->lock);
0702 return ret;
0703 }
0704
0705
0706
0707
0708
0709 static int __maybe_unused inv_icm42600_resume(struct device *dev)
0710 {
0711 struct inv_icm42600_state *st = dev_get_drvdata(dev);
0712 int ret;
0713
0714 mutex_lock(&st->lock);
0715
0716 ret = inv_icm42600_enable_regulator_vddio(st);
0717 if (ret)
0718 goto out_unlock;
0719
0720 pm_runtime_disable(dev);
0721 pm_runtime_set_active(dev);
0722 pm_runtime_enable(dev);
0723
0724
0725 ret = inv_icm42600_set_pwr_mgmt0(st, st->suspended.gyro,
0726 st->suspended.accel,
0727 st->suspended.temp, NULL);
0728 if (ret)
0729 goto out_unlock;
0730
0731
0732 if (st->fifo.on)
0733 ret = regmap_write(st->map, INV_ICM42600_REG_FIFO_CONFIG,
0734 INV_ICM42600_FIFO_CONFIG_STREAM);
0735
0736 out_unlock:
0737 mutex_unlock(&st->lock);
0738 return ret;
0739 }
0740
0741
0742 static int __maybe_unused inv_icm42600_runtime_suspend(struct device *dev)
0743 {
0744 struct inv_icm42600_state *st = dev_get_drvdata(dev);
0745 int ret;
0746
0747 mutex_lock(&st->lock);
0748
0749
0750 ret = inv_icm42600_set_pwr_mgmt0(st, INV_ICM42600_SENSOR_MODE_OFF,
0751 INV_ICM42600_SENSOR_MODE_OFF, false,
0752 NULL);
0753 if (ret)
0754 goto error_unlock;
0755
0756 regulator_disable(st->vddio_supply);
0757
0758 error_unlock:
0759 mutex_unlock(&st->lock);
0760 return ret;
0761 }
0762
0763
0764 static int __maybe_unused inv_icm42600_runtime_resume(struct device *dev)
0765 {
0766 struct inv_icm42600_state *st = dev_get_drvdata(dev);
0767 int ret;
0768
0769 mutex_lock(&st->lock);
0770
0771 ret = inv_icm42600_enable_regulator_vddio(st);
0772
0773 mutex_unlock(&st->lock);
0774 return ret;
0775 }
0776
0777 const struct dev_pm_ops inv_icm42600_pm_ops = {
0778 SET_SYSTEM_SLEEP_PM_OPS(inv_icm42600_suspend, inv_icm42600_resume)
0779 SET_RUNTIME_PM_OPS(inv_icm42600_runtime_suspend,
0780 inv_icm42600_runtime_resume, NULL)
0781 };
0782 EXPORT_SYMBOL_GPL(inv_icm42600_pm_ops);
0783
0784 MODULE_AUTHOR("InvenSense, Inc.");
0785 MODULE_DESCRIPTION("InvenSense ICM-426xx device driver");
0786 MODULE_LICENSE("GPL");