Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  * Copyright (C) 2020 Invensense, Inc.
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 /* chip initial default configuration */
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         /* reserved values */
0105         0, 0, 0,
0106         /* 8kHz */
0107         125000,
0108         /* 4kHz */
0109         250000,
0110         /* 2kHz */
0111         500000,
0112         /* 1kHz */
0113         1000000,
0114         /* 200Hz */
0115         5000000,
0116         /* 100Hz */
0117         10000000,
0118         /* 50Hz */
0119         20000000,
0120         /* 25Hz */
0121         40000000,
0122         /* 12.5Hz */
0123         80000000,
0124         /* 6.25Hz */
0125         160000000,
0126         /* 3.125Hz */
0127         320000000,
0128         /* 1.5625Hz */
0129         640000000,
0130         /* 500Hz */
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     /* if nothing changed, exit */
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     /* compute required wait time for sensors to stabilize */
0166     sleepval = 0;
0167     /* temperature stabilization time */
0168     if (temp && !oldtemp) {
0169         if (sleepval < INV_ICM42600_TEMP_STARTUP_TIME_MS)
0170             sleepval = INV_ICM42600_TEMP_STARTUP_TIME_MS;
0171     }
0172     /* accel startup time */
0173     if (accel != oldaccel && oldaccel == INV_ICM42600_SENSOR_MODE_OFF) {
0174         /* block any register write for at least 200 µs */
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         /* gyro startup time */
0181         if (oldgyro == INV_ICM42600_SENSOR_MODE_OFF) {
0182             /* block any register write for at least 200 µs */
0183             usleep_range(200, 300);
0184             if (sleepval < INV_ICM42600_GYRO_STARTUP_TIME_MS)
0185                 sleepval = INV_ICM42600_GYRO_STARTUP_TIME_MS;
0186         /* gyro stop time */
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     /* deferred sleep value if sleep pointer is provided or direct sleep */
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     /* Sanitize missing values with current values */
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     /* set ACCEL_CONFIG0 register (accel fullscale & odr) */
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     /* set GYRO_ACCEL_CONFIG0 register (accel filter) */
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     /* set PWR_MGMT0 register (accel sensor mode) */
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     /* sanitize missing values with current values */
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     /* set GYRO_CONFIG0 register (gyro fullscale & odr) */
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     /* set GYRO_ACCEL_CONFIG0 register (gyro filter) */
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     /* set PWR_MGMT0 register (gyro sensor mode) */
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     /* set PWR_MGMT0 register (gyro & accel sensor mode, temp enabled) */
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     /* set GYRO_CONFIG0 register (gyro fullscale & odr) */
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     /* set ACCEL_CONFIG0 register (accel fullscale & odr) */
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     /* set GYRO_ACCEL_CONFIG0 register (gyro & accel filters) */
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     /* update internal conf */
0355     st->conf = *conf;
0356 
0357     return 0;
0358 }
0359 
0360 /**
0361  *  inv_icm42600_setup() - check and setup chip
0362  *  @st:    driver internal state
0363  *  @bus_setup: callback for setting up bus specific registers
0364  *
0365  *  Returns 0 on success, a negative error code otherwise.
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     /* check chip self-identification value */
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     /* reset to make sure previous state are not there */
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     /* set chip bus configuration */
0402     ret = bus_setup(st);
0403     if (ret)
0404         return ret;
0405 
0406     /* sensor data in big-endian (default) */
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     /* FIFO full */
0440     if (status & INV_ICM42600_INT_STATUS_FIFO_FULL)
0441         dev_warn(dev, "FIFO full data lost!\n");
0442 
0443     /* FIFO threshold reached */
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  * inv_icm42600_irq_init() - initialize int pin and interrupt handler
0462  * @st:     driver internal state
0463  * @irq:    irq number
0464  * @irq_type:   irq trigger type
0465  * @open_drain: true if irq is open drain, false for push-pull
0466  *
0467  * Returns 0 on success, a negative error code otherwise.
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     /* configure INT1 interrupt: default is active low on edge */
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     /* Deassert async reset for proper INT pin operation (cf datasheet) */
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     /* wait a little for supply ramp */
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     /* get irq properties, set trigger falling by default */
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     /* setup chip registers */
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     /* setup runtime power management */
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  * Suspend saves sensors state and turns everything off.
0667  * Check first if runtime suspend has not already done the job.
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     /* disable FIFO data streaming */
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  * System resume gets the system back on and restores the sensors state.
0707  * Manually put runtime power management in system active state.
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     /* restore sensors state */
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     /* restore FIFO data streaming */
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 /* Runtime suspend will turn off sensors that are enabled by iio devices. */
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     /* disable all sensors */
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 /* Sensors are enabled by iio devices, no need to turn them back on here. */
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");