xref: /linux/drivers/iio/imu/inv_icm42607/inv_icm42607_core.c (revision 67f8bc848ee31831336bd478e57d2f993551902e)
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  * Copyright (C) 2026 InvenSense, Inc.
4  */
5 
6 #include <linux/bitfield.h>
7 #include <linux/cleanup.h>
8 #include <linux/delay.h>
9 #include <linux/device.h>
10 #include <linux/err.h>
11 #include <linux/iio/iio.h>
12 #include <linux/ktime.h>
13 #include <linux/module.h>
14 #include <linux/mutex.h>
15 #include <linux/pm_runtime.h>
16 #include <linux/regmap.h>
17 #include <linux/regulator/consumer.h>
18 #include <linux/time.h>
19 #include <linux/timekeeping.h>
20 #include <linux/types.h>
21 
22 #include <asm/byteorder.h>
23 
24 #include "inv_icm42607.h"
25 
26 static bool inv_icm42607_is_readable_reg(struct device *dev, unsigned int reg)
27 {
28 	switch (reg) {
29 	case INV_ICM42607_REG_MCLK_RDY ... INV_ICM42607_REG_INT_CONFIG:
30 	case INV_ICM42607_REG_TEMP_DATA1 ... INV_ICM42607_REG_TMST_FSYNCL:
31 	case INV_ICM42607_REG_APEX_DATA4 ... INV_ICM42607_REG_INTF_CONFIG1:
32 	case INV_ICM42607_REG_INT_STATUS_DRDY ... INV_ICM42607_REG_FIFO_DATA:
33 	case INV_ICM42607_REG_WHOAMI:
34 		return true;
35 	}
36 
37 	return false;
38 }
39 
40 static bool inv_icm42607_is_writeable_reg(struct device *dev, unsigned int reg)
41 {
42 	switch (reg) {
43 	case INV_ICM42607_REG_DEVICE_CONFIG ... INV_ICM42607_REG_INT_CONFIG:
44 	case INV_ICM42607_REG_PWR_MGMT0 ... INV_ICM42607_REG_INT_SOURCE4:
45 	case INV_ICM42607_REG_INTF_CONFIG0 ... INV_ICM42607_REG_INTF_CONFIG1:
46 		return true;
47 	}
48 
49 	return false;
50 }
51 
52 static bool inv_icm42607_is_volatile_reg(struct device *dev, unsigned int reg)
53 {
54 	switch (reg) {
55 	case INV_ICM42607_REG_MCLK_RDY:
56 	case INV_ICM42607_REG_SIGNAL_PATH_RESET:
57 	case INV_ICM42607_REG_TEMP_DATA1 ... INV_ICM42607_REG_APEX_DATA5:
58 	case INV_ICM42607_REG_APEX_CONFIG0:
59 	case INV_ICM42607_REG_FIFO_LOST_PKT0 ... INV_ICM42607_REG_APEX_DATA3:
60 	case INV_ICM42607_REG_INT_STATUS_DRDY:
61 	case INV_ICM42607_REG_INT_STATUS ... INV_ICM42607_REG_FIFO_DATA:
62 		return true;
63 	}
64 
65 	return false;
66 }
67 
68 const struct regmap_config inv_icm42607_regmap_config = {
69 	.reg_bits = 8,
70 	.val_bits = 8,
71 	.writeable_reg = inv_icm42607_is_writeable_reg,
72 	.readable_reg = inv_icm42607_is_readable_reg,
73 	.volatile_reg = inv_icm42607_is_volatile_reg,
74 	.max_register = INV_ICM42607_REG_WHOAMI,
75 	.cache_type = REGCACHE_MAPLE,
76 };
77 EXPORT_SYMBOL_NS_GPL(inv_icm42607_regmap_config, "IIO_ICM42607");
78 
79 /* chip initial default configuration */
80 static const struct inv_icm42607_conf inv_icm42607_default_conf = {
81 	.gyro = {
82 		.mode = INV_ICM42607_SENSOR_MODE_OFF,
83 		.fs = INV_ICM42607_GYRO_FS_1000DPS,
84 		.odr = INV_ICM42607_ODR_100HZ,
85 		.filter = INV_ICM42607_FILTER_BW_25HZ,
86 	},
87 	.accel = {
88 		.mode = INV_ICM42607_SENSOR_MODE_OFF,
89 		.fs = INV_ICM42607_ACCEL_FS_4G,
90 		.odr = INV_ICM42607_ODR_100HZ,
91 		.filter = INV_ICM42607_FILTER_BW_25HZ,
92 	},
93 };
94 
95 const struct inv_icm42607_hw inv_icm42607_hw_data = {
96 	.whoami = INV_ICM42607_WHOAMI,
97 	.name = "icm42607",
98 	.conf = &inv_icm42607_default_conf,
99 };
100 EXPORT_SYMBOL_NS_GPL(inv_icm42607_hw_data, "IIO_ICM42607");
101 
102 const struct inv_icm42607_hw inv_icm42607p_hw_data = {
103 	.whoami = INV_ICM42607P_WHOAMI,
104 	.name = "icm42607p",
105 	.conf = &inv_icm42607_default_conf,
106 };
107 EXPORT_SYMBOL_NS_GPL(inv_icm42607p_hw_data, "IIO_ICM42607");
108 
109 const struct iio_mount_matrix *
110 inv_icm42607_get_mount_matrix(struct iio_dev *indio_dev,
111 			      const struct iio_chan_spec *chan)
112 {
113 	const struct inv_icm42607_state *st = iio_device_get_drvdata(indio_dev);
114 
115 	return &st->orientation;
116 }
117 
118 static u32 inv_icm42607_odr_to_period_us(enum inv_icm42607_odr odr)
119 {
120 	static const u32 odr_periods[INV_ICM42607_ODR_NB] = {
121 		/* Reserved values */
122 		0, 0, 0, 0, 0,
123 		/* 1600Hz */
124 		625,
125 		/* 800Hz */
126 		1250,
127 		/* 400Hz */
128 		2500,
129 		/* 200Hz */
130 		5000,
131 		/* 100 Hz */
132 		10000,
133 		/* 50Hz */
134 		20000,
135 		/* 25Hz */
136 		40000,
137 		/* 12.5Hz */
138 		80000,
139 		/* 6.25Hz */
140 		160000,
141 		/* 3.125Hz */
142 		320000,
143 		/* 1.5625Hz */
144 		640000,
145 	};
146 
147 	odr = clamp(odr, INV_ICM42607_ODR_1600HZ, INV_ICM42607_ODR_1_5625HZ_LP);
148 
149 	return odr_periods[odr];
150 }
151 
152 int inv_icm42607_get_pwr_mgmt0(struct inv_icm42607_state *st,
153 			       enum inv_icm42607_sensor_mode *gyro,
154 			       enum inv_icm42607_sensor_mode *accel)
155 {
156 	unsigned int val;
157 	int ret;
158 
159 	ret = regmap_read(st->map, INV_ICM42607_REG_PWR_MGMT0, &val);
160 	if (ret)
161 		return ret;
162 
163 	*gyro = FIELD_GET(INV_ICM42607_PWR_MGMT0_GYRO_MODE_MASK, val);
164 	*accel = FIELD_GET(INV_ICM42607_PWR_MGMT0_ACCEL_MODE_MASK, val);
165 
166 	return 0;
167 }
168 
169 static int inv_icm42607_set_pwr_mgmt0(struct inv_icm42607_state *st,
170 				      enum inv_icm42607_sensor_mode gyro,
171 				      enum inv_icm42607_sensor_mode accel)
172 {
173 	enum inv_icm42607_sensor_mode oldaccel, oldgyro;
174 	unsigned int sleepval_us, odr_us;
175 	unsigned int val;
176 	s64 disable_wait;
177 	int ret;
178 
179 	ret = inv_icm42607_get_pwr_mgmt0(st, &oldgyro, &oldaccel);
180 	if (ret)
181 		return ret;
182 
183 	if (gyro == oldgyro && accel == oldaccel)
184 		return 0;
185 
186 	/*
187 	 * Datasheet on page 14.26 says we need to ensure the gyro sensor is on
188 	 * for a minimum of 45ms. So if we transition from an on state to an
189 	 * off state make sure at least 45ms have passed before power off and
190 	 * wait if it hasn't. In case some platforms don't respond well to a
191 	 * sleep of 0, make sure the fsleep duration is > 0.
192 	 */
193 	if (!gyro && oldgyro) {
194 		disable_wait = clamp(ktime_us_delta(st->conf.gyro_stop, ktime_get()),
195 				     0, INV_ICM42607_GYRO_STOP_TIME_US);
196 
197 		if (disable_wait > 0)
198 			fsleep(disable_wait);
199 	}
200 
201 	val = FIELD_PREP(INV_ICM42607_PWR_MGMT0_GYRO_MODE_MASK, gyro) |
202 	      FIELD_PREP(INV_ICM42607_PWR_MGMT0_ACCEL_MODE_MASK, accel);
203 	ret = regmap_write(st->map, INV_ICM42607_REG_PWR_MGMT0, val);
204 	if (ret)
205 		return ret;
206 
207 	/*
208 	 * If a state change occurs from off to on, sleep for the startup time
209 	 * of the sensor. Since more than one sensor can be transitioned from
210 	 * off to on, select the maximum time from each of the sensors changing
211 	 * from off to on. Also account for the time it takes for the first
212 	 * sample to be ready by looking up the odr value and adding it to the
213 	 * sleep time. The startup time for the temp sensor is considerably
214 	 * smaller than the startup time for the other sensors and one or more
215 	 * are required to be on for the temp sensor to function, so any start
216 	 * delay should be enough.
217 	 */
218 	sleepval_us = 0;
219 	odr_us = 0;
220 	if (accel && !oldaccel) {
221 		sleepval_us = max(sleepval_us, INV_ICM42607_ACCEL_STARTUP_TIME_US);
222 		odr_us = max(odr_us, inv_icm42607_odr_to_period_us(st->conf.accel.odr));
223 	}
224 
225 	if (gyro && !oldgyro) {
226 		sleepval_us = max(sleepval_us, INV_ICM42607_GYRO_STARTUP_TIME_US);
227 		odr_us = max(odr_us, inv_icm42607_odr_to_period_us(st->conf.gyro.odr));
228 		/* Track the earliest we can turn off the gyroscope. */
229 		st->conf.gyro_stop = ktime_add_us(ktime_get(),
230 						  INV_ICM42607_GYRO_STOP_TIME_US);
231 	}
232 
233 	sleepval_us += odr_us;
234 
235 	/*
236 	 * Only sleep if sleepval_us is greater than 0 in case some platforms
237 	 * have issues with a 0 delay. The 0 delay can happen if one or both
238 	 * sensors is shut down.
239 	 */
240 	if (sleepval_us > 0)
241 		fsleep(sleepval_us);
242 
243 	return 0;
244 }
245 
246 /*
247  * Sanity test between old and new config values, and note if we need
248  * to update register config0 or config1.
249  */
250 static void inv_icm42607_update_config(struct inv_icm42607_sensor_conf *conf,
251 				       struct inv_icm42607_sensor_conf *oldconf,
252 				       bool *config0, bool *config1)
253 {
254 	if (conf->mode < 0)
255 		conf->mode = oldconf->mode;
256 	if (conf->fs < 0)
257 		conf->fs = oldconf->fs;
258 	if (conf->odr < 0)
259 		conf->odr = oldconf->odr;
260 	if (conf->filter < 0)
261 		conf->filter = oldconf->filter;
262 
263 	*config0 = (conf->fs != oldconf->fs) || (conf->odr != oldconf->odr);
264 
265 	*config1 = (conf->filter != oldconf->filter);
266 }
267 
268 int inv_icm42607_set_sensor_conf(struct inv_icm42607_state *st,
269 				 struct inv_icm42607_sensor_conf *conf,
270 				 enum iio_chan_type chan_type)
271 {
272 	enum inv_icm42607_sensor_mode accel_mode, gyro_mode;
273 	struct inv_icm42607_sensor_conf *oldconf;
274 	bool config0, config1;
275 	unsigned int val;
276 	int ret;
277 
278 	switch (chan_type) {
279 	case IIO_ACCEL:
280 		oldconf = &st->conf.accel;
281 		break;
282 	case IIO_ANGL_VEL:
283 		oldconf = &st->conf.gyro;
284 		break;
285 	default:
286 		return -EINVAL;
287 	}
288 
289 	/*
290 	 * Since we are only making one-shot calls today, we can avoid needless
291 	 * on/off cycles if we rely on the runtime power management to handle
292 	 * shutting off the sensors when not in use. The downside is if we
293 	 * enable both sensors then only read from one, we have to wait for
294 	 * runtime PM to turn it off. So just keep the mode of the sensor we
295 	 * are not actively using to whatever it's already set as.
296 	 */
297 	ret = inv_icm42607_get_pwr_mgmt0(st, &gyro_mode, &accel_mode);
298 	if (ret)
299 		return ret;
300 
301 	inv_icm42607_update_config(conf, oldconf, &config0, &config1);
302 
303 	if (config0) {
304 		if (chan_type == IIO_ANGL_VEL) {
305 			val = FIELD_PREP(INV_ICM42607_GYRO_CONFIG0_FS_SEL_MASK, conf->fs);
306 			val |= FIELD_PREP(INV_ICM42607_GYRO_CONFIG0_ODR_MASK, conf->odr);
307 			ret = regmap_write(st->map, INV_ICM42607_REG_GYRO_CONFIG0, val);
308 		} else {
309 			val = FIELD_PREP(INV_ICM42607_ACCEL_CONFIG0_FS_SEL_MASK, conf->fs);
310 			val |= FIELD_PREP(INV_ICM42607_ACCEL_CONFIG0_ODR_MASK, conf->odr);
311 			ret = regmap_write(st->map, INV_ICM42607_REG_ACCEL_CONFIG0, val);
312 		}
313 		if (ret)
314 			return ret;
315 
316 		oldconf->fs = conf->fs;
317 		oldconf->odr = conf->odr;
318 	}
319 
320 	if (config1) {
321 		if (chan_type == IIO_ANGL_VEL) {
322 			val = FIELD_PREP(INV_ICM42607_GYRO_CONFIG1_FILTER_MASK,
323 					 conf->filter);
324 			ret = regmap_update_bits(st->map, INV_ICM42607_REG_GYRO_CONFIG1,
325 						 INV_ICM42607_GYRO_CONFIG1_FILTER_MASK, val);
326 		} else {
327 			val = FIELD_PREP(INV_ICM42607_ACCEL_CONFIG1_FILTER_MASK,
328 					 conf->filter);
329 			ret = regmap_update_bits(st->map, INV_ICM42607_REG_ACCEL_CONFIG1,
330 						 INV_ICM42607_ACCEL_CONFIG1_FILTER_MASK, val);
331 		}
332 		if (ret)
333 			return ret;
334 
335 		oldconf->filter = conf->filter;
336 	}
337 
338 	oldconf->mode = conf->mode;
339 
340 	switch (chan_type) {
341 	case IIO_ACCEL:
342 		return inv_icm42607_set_pwr_mgmt0(st, gyro_mode, conf->mode);
343 	case IIO_ANGL_VEL:
344 		return inv_icm42607_set_pwr_mgmt0(st, conf->mode, accel_mode);
345 	default:
346 		return -EINVAL;
347 	}
348 }
349 
350 int inv_icm42607_read_sensor(struct iio_dev *indio_dev,
351 			     struct iio_chan_spec const *chan,
352 			     s16 *val)
353 {
354 	struct inv_icm42607_sensor_conf conf = INV_ICM42607_SENSOR_CONF_INIT;
355 	struct inv_icm42607_state *st = iio_device_get_drvdata(indio_dev);
356 	struct inv_icm42607_sensor_state *sensor_st = iio_priv(indio_dev);
357 	struct device *dev = regmap_get_device(st->map);
358 	unsigned int reg;
359 	__be16 data;
360 	int ret;
361 
362 	if ((chan->type != IIO_ANGL_VEL) && (chan->type != IIO_ACCEL))
363 		return -EINVAL;
364 
365 	switch (chan->channel2) {
366 	case IIO_MOD_X:
367 		if (chan->type == IIO_ANGL_VEL)
368 			reg = INV_ICM42607_REG_GYRO_DATA_X1;
369 		else
370 			reg = INV_ICM42607_REG_ACCEL_DATA_X1;
371 		break;
372 	case IIO_MOD_Y:
373 		if (chan->type == IIO_ANGL_VEL)
374 			reg = INV_ICM42607_REG_GYRO_DATA_Y1;
375 		else
376 			reg = INV_ICM42607_REG_ACCEL_DATA_Y1;
377 		break;
378 	case IIO_MOD_Z:
379 		if (chan->type == IIO_ANGL_VEL)
380 			reg = INV_ICM42607_REG_GYRO_DATA_Z1;
381 		else
382 			reg = INV_ICM42607_REG_ACCEL_DATA_Z1;
383 		break;
384 	default:
385 		return -EINVAL;
386 	}
387 
388 	PM_RUNTIME_ACQUIRE_AUTOSUSPEND(dev, pm);
389 	ret = PM_RUNTIME_ACQUIRE_ERR(&pm);
390 	if (ret)
391 		return ret;
392 
393 	guard(mutex)(&st->lock);
394 
395 	/* enable sensor */
396 	conf.mode = sensor_st->power_mode;
397 	conf.filter = sensor_st->filter;
398 	ret = inv_icm42607_set_sensor_conf(st, &conf, chan->type);
399 	if (ret)
400 		return ret;
401 
402 	/* read sensor register data */
403 	ret = regmap_bulk_read(st->map, reg, &data, sizeof(data));
404 	if (ret)
405 		return ret;
406 
407 	*val = be16_to_cpu(data);
408 	if (*val == INV_ICM42607_DATA_INVALID)
409 		return -EINVAL;
410 
411 	return 0;
412 }
413 
414 static int inv_icm42607_set_init_conf(struct inv_icm42607_state *st,
415 				      const struct inv_icm42607_conf *conf)
416 {
417 	unsigned int val;
418 	int ret;
419 
420 	val = FIELD_PREP(INV_ICM42607_PWR_MGMT0_GYRO_MODE_MASK, conf->gyro.mode);
421 	val |= FIELD_PREP(INV_ICM42607_PWR_MGMT0_ACCEL_MODE_MASK, conf->accel.mode);
422 	ret = regmap_write(st->map, INV_ICM42607_REG_PWR_MGMT0, val);
423 	if (ret)
424 		return ret;
425 
426 	val = FIELD_PREP(INV_ICM42607_GYRO_CONFIG0_FS_SEL_MASK, conf->gyro.fs);
427 	val |= FIELD_PREP(INV_ICM42607_GYRO_CONFIG0_ODR_MASK, conf->gyro.odr);
428 	ret = regmap_write(st->map, INV_ICM42607_REG_GYRO_CONFIG0, val);
429 	if (ret)
430 		return ret;
431 
432 	val = FIELD_PREP(INV_ICM42607_ACCEL_CONFIG0_FS_SEL_MASK, conf->accel.fs);
433 	val |= FIELD_PREP(INV_ICM42607_ACCEL_CONFIG0_ODR_MASK, conf->accel.odr);
434 	ret = regmap_write(st->map, INV_ICM42607_REG_ACCEL_CONFIG0, val);
435 	if (ret)
436 		return ret;
437 
438 	val = FIELD_PREP(INV_ICM42607_GYRO_CONFIG1_FILTER_MASK, conf->gyro.filter);
439 	ret = regmap_update_bits(st->map, INV_ICM42607_REG_GYRO_CONFIG1,
440 				 INV_ICM42607_GYRO_CONFIG1_FILTER_MASK, val);
441 	if (ret)
442 		return ret;
443 
444 	val = FIELD_PREP(INV_ICM42607_ACCEL_CONFIG1_FILTER_MASK, conf->accel.filter);
445 	ret = regmap_update_bits(st->map, INV_ICM42607_REG_ACCEL_CONFIG1,
446 				 INV_ICM42607_ACCEL_CONFIG1_FILTER_MASK, val);
447 	if (ret)
448 		return ret;
449 
450 	val = FIELD_PREP(INV_ICM42607_TEMP_CONFIG0_FILTER_MASK,
451 			 INV_ICM42607_TEMP_FILTER_BW_34HZ);
452 	ret = regmap_update_bits(st->map, INV_ICM42607_REG_TEMP_CONFIG0,
453 				 INV_ICM42607_TEMP_CONFIG0_FILTER_MASK, val);
454 	if (ret)
455 		return ret;
456 
457 	st->conf = *conf;
458 
459 	return 0;
460 }
461 
462 static int inv_icm42607_setup(struct inv_icm42607_state *st,
463 			      inv_icm42607_bus_setup inv_icm42607_bus_setup)
464 {
465 	const struct device *dev = regmap_get_device(st->map);
466 	unsigned int val;
467 	int ret;
468 
469 	ret = regmap_read(st->map, INV_ICM42607_REG_WHOAMI, &val);
470 	if (ret)
471 		return ret;
472 
473 	/* Warn, but don't fail. */
474 	if (val != st->hw->whoami)
475 		dev_warn(dev, "Unknown whoami %#02x expected %#02x (%s)\n",
476 			 val, st->hw->whoami, st->hw->name);
477 
478 	ret = regmap_write(st->map, INV_ICM42607_REG_SIGNAL_PATH_RESET,
479 			   INV_ICM42607_SIGNAL_PATH_RESET_SOFT_RESET);
480 	if (ret)
481 		return ret;
482 
483 	fsleep(1 * USEC_PER_MSEC);
484 
485 	/*
486 	 * No polling interval specified in datasheet, so use reset time as
487 	 * polling interval and 10x reset time as timeout period.
488 	 */
489 	ret = regmap_read_poll_timeout(st->map, INV_ICM42607_REG_INT_STATUS,
490 				       val, val & INV_ICM42607_INT_STATUS_RESET_DONE,
491 				       1 * USEC_PER_MSEC, 10 * USEC_PER_MSEC);
492 	if (ret)
493 		return dev_err_probe(dev, ret,
494 				     "reset error, reset done bit not set\n");
495 
496 	/* Sync the regcache again after a reset. */
497 	regcache_mark_dirty(st->map);
498 	ret = regcache_sync(st->map);
499 	if (ret)
500 		return ret;
501 
502 	ret = inv_icm42607_bus_setup(st);
503 	if (ret)
504 		return ret;
505 
506 	ret = regmap_set_bits(st->map, INV_ICM42607_REG_INTF_CONFIG0,
507 			      INV_ICM42607_INTF_CONFIG0_SENSOR_DATA_ENDIAN);
508 	if (ret)
509 		return ret;
510 
511 	val = FIELD_PREP(INV_ICM42607_INTF_CONFIG1_CLKSEL_MASK,
512 			 INV_ICM42607_INTF_CONFIG1_CLKSEL_PLL);
513 	ret = regmap_update_bits(st->map, INV_ICM42607_REG_INTF_CONFIG1,
514 				 INV_ICM42607_INTF_CONFIG1_CLKSEL_MASK,
515 				 val);
516 	if (ret)
517 		return ret;
518 
519 	return inv_icm42607_set_init_conf(st, st->hw->conf);
520 }
521 
522 static int inv_icm42607_enable_vddio_reg(struct inv_icm42607_state *st)
523 {
524 	int ret;
525 
526 	if (st->vddio_en)
527 		return 0;
528 
529 	ret = regulator_enable(st->vddio_supply);
530 	if (ret)
531 		return ret;
532 
533 	fsleep(INV_ICM42607_POWER_UP_TIME_US);
534 
535 	st->vddio_en = true;
536 
537 	return 0;
538 }
539 
540 static void inv_icm42607_sensors_off(void *_data)
541 {
542 	struct inv_icm42607_state *st = _data;
543 	const struct device *dev = regmap_get_device(st->map);
544 	int ret;
545 
546 	guard(mutex)(&st->lock);
547 
548 	st->conf.gyro.mode = INV_ICM42607_SENSOR_MODE_OFF;
549 	st->conf.accel.mode = INV_ICM42607_SENSOR_MODE_OFF;
550 
551 	ret = inv_icm42607_set_pwr_mgmt0(st, st->conf.gyro.mode,
552 					 st->conf.accel.mode);
553 	if (ret)
554 		dev_err(dev, "Unable to turn off sensors\n");
555 }
556 
557 static void inv_icm42607_disable_vddio_reg(void *_data)
558 {
559 	struct inv_icm42607_state *st = _data;
560 
561 	if (!st->vddio_en)
562 		return;
563 
564 	regulator_disable(st->vddio_supply);
565 
566 	st->vddio_en = false;
567 }
568 
569 int inv_icm42607_core_probe(struct regmap *regmap,
570 			    const struct inv_icm42607_hw *hw,
571 			    inv_icm42607_bus_setup inv_icm42607_bus_setup)
572 {
573 	struct device *dev = regmap_get_device(regmap);
574 	struct inv_icm42607_state *st;
575 	int ret;
576 
577 	st = devm_kzalloc(dev, sizeof(*st), GFP_KERNEL);
578 	if (!st)
579 		return -ENOMEM;
580 
581 	dev_set_drvdata(dev, st);
582 
583 	ret = devm_mutex_init(dev, &st->lock);
584 	if (ret)
585 		return ret;
586 
587 	st->hw = hw;
588 	st->map = regmap;
589 
590 	ret = iio_read_mount_matrix(dev, &st->orientation);
591 	if (ret)
592 		return dev_err_probe(dev, ret,
593 				     "failed to retrieve mounting matrix\n");
594 
595 	ret = devm_regulator_get_enable(dev, "vdd");
596 	if (ret)
597 		return dev_err_probe(dev, ret,
598 				     "Failed to get vdd regulator\n");
599 
600 	st->vddio_supply = devm_regulator_get(dev, "vddio");
601 	if (IS_ERR(st->vddio_supply))
602 		return dev_err_probe(dev, PTR_ERR(st->vddio_supply),
603 				     "Failed to get vddio regulator\n");
604 
605 	ret = inv_icm42607_enable_vddio_reg(st);
606 	if (ret)
607 		return ret;
608 
609 	ret = devm_add_action_or_reset(dev, inv_icm42607_disable_vddio_reg, st);
610 	if (ret)
611 		return ret;
612 
613 	/* Setup chip registers (includes WHOAMI check, reset check, bus setup) */
614 	ret = inv_icm42607_setup(st, inv_icm42607_bus_setup);
615 	if (ret)
616 		return ret;
617 
618 	/*
619 	 * Ensure if sensors get turned on at some point, they're turned off
620 	 * as part of teardown.
621 	 */
622 	ret = devm_add_action_or_reset(dev, inv_icm42607_sensors_off, st);
623 	if (ret)
624 		return ret;
625 
626 	ret = devm_pm_runtime_set_active_enabled(dev);
627 	if (ret)
628 		return ret;
629 
630 	pm_runtime_set_autosuspend_delay(dev, INV_ICM42607_SUSPEND_DELAY_MS);
631 	pm_runtime_use_autosuspend(dev);
632 
633 	/* Initialize IIO device for Accel */
634 	st->indio_accel = inv_icm42607_accel_init(st);
635 	if (IS_ERR(st->indio_accel))
636 		return PTR_ERR(st->indio_accel);
637 
638 	/* Initialize IIO device for Gyro */
639 	st->indio_gyro = inv_icm42607_gyro_init(st);
640 	if (IS_ERR(st->indio_gyro))
641 		return PTR_ERR(st->indio_gyro);
642 
643 	return 0;
644 }
645 EXPORT_SYMBOL_NS_GPL(inv_icm42607_core_probe, "IIO_ICM42607");
646 
647 static int inv_icm42607_suspend(struct device *dev)
648 {
649 	struct inv_icm42607_state *st = dev_get_drvdata(dev);
650 	int ret;
651 
652 	ret = pm_runtime_force_suspend(dev);
653 	if (ret)
654 		return ret;
655 
656 	inv_icm42607_disable_vddio_reg(st);
657 
658 	return 0;
659 }
660 
661 static int inv_icm42607_resume(struct device *dev)
662 {
663 	struct inv_icm42607_state *st = dev_get_drvdata(dev);
664 	int ret;
665 
666 	ret = inv_icm42607_enable_vddio_reg(st);
667 	if (ret)
668 		return ret;
669 
670 	/* Sync the regcache again after regulator shutdown. */
671 	regcache_mark_dirty(st->map);
672 	ret = regcache_sync(st->map);
673 	if (ret)
674 		return ret;
675 
676 	return pm_runtime_force_resume(dev);
677 }
678 
679 static int inv_icm42607_runtime_suspend(struct device *dev)
680 {
681 	struct inv_icm42607_state *st = dev_get_drvdata(dev);
682 
683 	/*
684 	 * Set sensors state to off. Since we only support one-shot
685 	 * today we can use runtime PM to turn sensors off when not
686 	 * in use, and then when needed the reads/writes will
687 	 * re-enable the sensors as needed. This reduces complexity,
688 	 * however the tradeoff is that an unused sensor won't be
689 	 * turned off until the entire chip is no longer in use.
690 	 */
691 	inv_icm42607_sensors_off(st);
692 	return 0;
693 }
694 
695 EXPORT_NS_GPL_DEV_PM_OPS(inv_icm42607_pm_ops, IIO_ICM42607) = {
696 	SYSTEM_SLEEP_PM_OPS(inv_icm42607_suspend, inv_icm42607_resume)
697 	RUNTIME_PM_OPS(inv_icm42607_runtime_suspend, NULL, NULL)
698 };
699 
700 MODULE_AUTHOR("InvenSense, Inc.");
701 MODULE_DESCRIPTION("InvenSense ICM-42607 device driver");
702 MODULE_LICENSE("GPL");
703