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