File Index
Files and directories
Sign in
FILE

inv_icm45600_core.c

File preview with syntax highlighting.

linux-6.19.14/drivers/iio/imu/inv_icm45600/inv_icm45600_core.c C
  1// SPDX-License-Identifier: GPL-2.0-or-later
  2/* Copyright (C) 2025 Invensense, Inc. */
  3
  4#include <linux/bitfield.h>
  5#include <linux/delay.h>
  6#include <linux/device.h>
  7#include <linux/err.h>
  8#include <linux/interrupt.h>
  9#include <linux/irq.h>
 10#include <linux/limits.h>
 11#include <linux/minmax.h>
 12#include <linux/module.h>
 13#include <linux/mutex.h>
 14#include <linux/pm_runtime.h>
 15#include <linux/property.h>
 16#include <linux/regmap.h>
 17#include <linux/regulator/consumer.h>
 18#include <linux/time.h>
 19#include <linux/types.h>
 20
 21#include <asm/byteorder.h>
 22
 23#include <linux/iio/iio.h>
 24
 25#include "inv_icm45600_buffer.h"
 26#include "inv_icm45600.h"
 27
 28static int inv_icm45600_ireg_read(struct regmap *map, unsigned int reg,
 29				   u8 *data, size_t count)
 30{
 31	const struct device *dev = regmap_get_device(map);
 32	struct inv_icm45600_state *st = dev_get_drvdata(dev);
 33	unsigned int d;
 34	size_t i;
 35	int ret;
 36
 37	st->buffer.ireg[0] = FIELD_GET(INV_ICM45600_REG_BANK_MASK, reg);
 38	st->buffer.ireg[1] = FIELD_GET(INV_ICM45600_REG_ADDR_MASK, reg);
 39
 40	/* Burst write address. */
 41	ret = regmap_bulk_write(map, INV_ICM45600_REG_IREG_ADDR, st->buffer.ireg, 2);
 42	/*
 43	 * Wait while the device is busy processing the address.
 44	 * Datasheet: 13.3 MINIMUM WAIT TIME-GAP
 45	 */
 46	fsleep(INV_ICM45600_IREG_DELAY_US);
 47	if (ret)
 48		return ret;
 49
 50	/* Read the data. */
 51	for (i = 0; i < count; i++) {
 52		ret = regmap_read(map, INV_ICM45600_REG_IREG_DATA, &d);
 53		/*
 54		 * Wait while the device is busy processing the address.
 55		 * Datasheet: 13.3 MINIMUM WAIT TIME-GAP
 56		 */
 57		fsleep(INV_ICM45600_IREG_DELAY_US);
 58		if (ret)
 59			return ret;
 60		data[i] = d;
 61	}
 62
 63	return 0;
 64}
 65
 66static int inv_icm45600_ireg_write(struct regmap *map, unsigned int reg,
 67				   const u8 *data, size_t count)
 68{
 69	const struct device *dev = regmap_get_device(map);
 70	struct inv_icm45600_state *st = dev_get_drvdata(dev);
 71	size_t i;
 72	int ret;
 73
 74	st->buffer.ireg[0] = FIELD_GET(INV_ICM45600_REG_BANK_MASK, reg);
 75	st->buffer.ireg[1] = FIELD_GET(INV_ICM45600_REG_ADDR_MASK, reg);
 76	st->buffer.ireg[2] = data[0];
 77
 78	/* Burst write address and first byte. */
 79	ret = regmap_bulk_write(map, INV_ICM45600_REG_IREG_ADDR, st->buffer.ireg, 3);
 80	/*
 81	 * Wait while the device is busy processing the address.
 82	 * Datasheet: 13.3 MINIMUM WAIT TIME-GAP
 83	 */
 84	fsleep(INV_ICM45600_IREG_DELAY_US);
 85	if (ret)
 86		return ret;
 87
 88	/* Write the remaining bytes. */
 89	for (i = 1; i < count; i++) {
 90		ret = regmap_write(map, INV_ICM45600_REG_IREG_DATA, data[i]);
 91		/*
 92		 * Wait while the device is busy processing the address.
 93		 * Datasheet: 13.3 MINIMUM WAIT TIME-GAP
 94		 */
 95		fsleep(INV_ICM45600_IREG_DELAY_US);
 96		if (ret)
 97			return ret;
 98	}
 99
100	return 0;
101}
102
103static int inv_icm45600_read(void *context, const void *reg_buf, size_t reg_size,
104			  void *val_buf, size_t val_size)
105{
106	unsigned int reg = be16_to_cpup(reg_buf);
107	struct regmap *map = context;
108
109	if (FIELD_GET(INV_ICM45600_REG_BANK_MASK, reg))
110		return inv_icm45600_ireg_read(map, reg, val_buf, val_size);
111
112	return regmap_bulk_read(map, FIELD_GET(INV_ICM45600_REG_ADDR_MASK, reg),
113				val_buf, val_size);
114}
115
116static int inv_icm45600_write(void *context, const void *data, size_t count)
117{
118	const u8 *d = data;
119	unsigned int reg = be16_to_cpup(data);
120	struct regmap *map = context;
121
122	if (FIELD_GET(INV_ICM45600_REG_BANK_MASK, reg))
123		return inv_icm45600_ireg_write(map, reg, d + 2, count - 2);
124
125	return regmap_bulk_write(map, FIELD_GET(INV_ICM45600_REG_ADDR_MASK, reg),
126				 d + 2, count - 2);
127}
128
129static const struct regmap_bus inv_icm45600_regmap_bus = {
130	.read = inv_icm45600_read,
131	.write = inv_icm45600_write,
132};
133
134static const struct regmap_config inv_icm45600_regmap_config = {
135	.reg_bits = 16,
136	.val_bits = 8,
137};
138
139/* These are the chip initial default configurations (default FS value is based on icm45686) */
140static const struct inv_icm45600_conf inv_icm45600_default_conf = {
141	.gyro = {
142		.mode = INV_ICM45600_SENSOR_MODE_OFF,
143		.fs = INV_ICM45686_GYRO_FS_2000DPS,
144		.odr = INV_ICM45600_ODR_800HZ_LN,
145		.filter = INV_ICM45600_GYRO_LP_AVG_SEL_8X,
146	},
147	.accel = {
148		.mode = INV_ICM45600_SENSOR_MODE_OFF,
149		.fs = INV_ICM45686_ACCEL_FS_16G,
150		.odr = INV_ICM45600_ODR_800HZ_LN,
151		.filter = INV_ICM45600_ACCEL_LP_AVG_SEL_4X,
152	},
153};
154
155static const struct inv_icm45600_conf inv_icm45686_default_conf = {
156	.gyro = {
157		.mode = INV_ICM45600_SENSOR_MODE_OFF,
158		.fs = INV_ICM45686_GYRO_FS_4000DPS,
159		.odr = INV_ICM45600_ODR_800HZ_LN,
160		.filter = INV_ICM45600_GYRO_LP_AVG_SEL_8X,
161	},
162	.accel = {
163		.mode = INV_ICM45600_SENSOR_MODE_OFF,
164		.fs = INV_ICM45686_ACCEL_FS_32G,
165		.odr = INV_ICM45600_ODR_800HZ_LN,
166		.filter = INV_ICM45600_ACCEL_LP_AVG_SEL_4X,
167	},
168};
169
170const struct inv_icm45600_chip_info inv_icm45605_chip_info = {
171	.whoami = INV_ICM45600_WHOAMI_ICM45605,
172	.name = "icm45605",
173	.conf = &inv_icm45600_default_conf,
174	.accel_scales = (const int *)inv_icm45600_accel_scale,
175	.accel_scales_len = INV_ICM45600_ACCEL_FS_MAX,
176	.gyro_scales = (const int *)inv_icm45600_gyro_scale,
177	.gyro_scales_len = INV_ICM45600_GYRO_FS_MAX,
178};
179EXPORT_SYMBOL_NS_GPL(inv_icm45605_chip_info, "IIO_ICM45600");
180
181const struct inv_icm45600_chip_info inv_icm45606_chip_info = {
182	.whoami = INV_ICM45600_WHOAMI_ICM45606,
183	.name = "icm45606",
184	.conf = &inv_icm45600_default_conf,
185	.accel_scales = (const int *)inv_icm45600_accel_scale,
186	.accel_scales_len = INV_ICM45600_ACCEL_FS_MAX,
187	.gyro_scales = (const int *)inv_icm45600_gyro_scale,
188	.gyro_scales_len = INV_ICM45600_GYRO_FS_MAX,
189};
190EXPORT_SYMBOL_NS_GPL(inv_icm45606_chip_info, "IIO_ICM45600");
191
192const struct inv_icm45600_chip_info inv_icm45608_chip_info = {
193	.whoami = INV_ICM45600_WHOAMI_ICM45608,
194	.name = "icm45608",
195	.conf = &inv_icm45600_default_conf,
196	.accel_scales = (const int *)inv_icm45600_accel_scale,
197	.accel_scales_len = INV_ICM45600_ACCEL_FS_MAX,
198	.gyro_scales = (const int *)inv_icm45600_gyro_scale,
199	.gyro_scales_len = INV_ICM45600_GYRO_FS_MAX,
200};
201EXPORT_SYMBOL_NS_GPL(inv_icm45608_chip_info, "IIO_ICM45600");
202
203const struct inv_icm45600_chip_info inv_icm45634_chip_info = {
204	.whoami = INV_ICM45600_WHOAMI_ICM45634,
205	.name = "icm45634",
206	.conf = &inv_icm45600_default_conf,
207	.accel_scales = (const int *)inv_icm45600_accel_scale,
208	.accel_scales_len = INV_ICM45600_ACCEL_FS_MAX,
209	.gyro_scales = (const int *)inv_icm45600_gyro_scale,
210	.gyro_scales_len = INV_ICM45600_GYRO_FS_MAX,
211};
212EXPORT_SYMBOL_NS_GPL(inv_icm45634_chip_info, "IIO_ICM45600");
213
214const struct inv_icm45600_chip_info inv_icm45686_chip_info = {
215	.whoami = INV_ICM45600_WHOAMI_ICM45686,
216	.name = "icm45686",
217	.conf = &inv_icm45686_default_conf,
218	.accel_scales = (const int *)inv_icm45686_accel_scale,
219	.accel_scales_len = INV_ICM45686_ACCEL_FS_MAX,
220	.gyro_scales = (const int *)inv_icm45686_gyro_scale,
221	.gyro_scales_len = INV_ICM45686_GYRO_FS_MAX,
222};
223EXPORT_SYMBOL_NS_GPL(inv_icm45686_chip_info, "IIO_ICM45600");
224
225const struct inv_icm45600_chip_info inv_icm45687_chip_info = {
226	.whoami = INV_ICM45600_WHOAMI_ICM45687,
227	.name = "icm45687",
228	.conf = &inv_icm45686_default_conf,
229	.accel_scales = (const int *)inv_icm45686_accel_scale,
230	.accel_scales_len = INV_ICM45686_ACCEL_FS_MAX,
231	.gyro_scales = (const int *)inv_icm45686_gyro_scale,
232	.gyro_scales_len = INV_ICM45686_GYRO_FS_MAX,
233};
234EXPORT_SYMBOL_NS_GPL(inv_icm45687_chip_info, "IIO_ICM45600");
235
236const struct inv_icm45600_chip_info inv_icm45688p_chip_info = {
237	.whoami = INV_ICM45600_WHOAMI_ICM45688P,
238	.name = "icm45688p",
239	.conf = &inv_icm45686_default_conf,
240	.accel_scales = (const int *)inv_icm45686_accel_scale,
241	.accel_scales_len = INV_ICM45686_ACCEL_FS_MAX,
242	.gyro_scales = (const int *)inv_icm45686_gyro_scale,
243	.gyro_scales_len = INV_ICM45686_GYRO_FS_MAX,
244};
245EXPORT_SYMBOL_NS_GPL(inv_icm45688p_chip_info, "IIO_ICM45600");
246
247const struct inv_icm45600_chip_info inv_icm45689_chip_info = {
248	.whoami = INV_ICM45600_WHOAMI_ICM45689,
249	.name = "icm45689",
250	.conf = &inv_icm45686_default_conf,
251	.accel_scales = (const int *)inv_icm45686_accel_scale,
252	.accel_scales_len = INV_ICM45686_ACCEL_FS_MAX,
253	.gyro_scales = (const int *)inv_icm45686_gyro_scale,
254	.gyro_scales_len = INV_ICM45686_GYRO_FS_MAX,
255};
256EXPORT_SYMBOL_NS_GPL(inv_icm45689_chip_info, "IIO_ICM45600");
257
258const struct iio_mount_matrix *
259inv_icm45600_get_mount_matrix(const struct iio_dev *indio_dev,
260			      const struct iio_chan_spec *chan)
261{
262	const struct inv_icm45600_state *st = iio_device_get_drvdata(indio_dev);
263
264	return &st->orientation;
265}
266
267u32 inv_icm45600_odr_to_period(enum inv_icm45600_odr odr)
268{
269	static const u32 odr_periods[INV_ICM45600_ODR_MAX] = {
270		/* 3 first values are reserved, left to 0 */
271		[INV_ICM45600_ODR_6400HZ_LN]   = 156250,
272		[INV_ICM45600_ODR_3200HZ_LN]   = 312500,
273		[INV_ICM45600_ODR_1600HZ_LN]   = 625000,
274		[INV_ICM45600_ODR_800HZ_LN]    = 1250000,
275		[INV_ICM45600_ODR_400HZ]       = 2500000,
276		[INV_ICM45600_ODR_200HZ]       = 5000000,
277		[INV_ICM45600_ODR_100HZ]       = 10000000,
278		[INV_ICM45600_ODR_50HZ]        = 20000000,
279		[INV_ICM45600_ODR_25HZ]        = 40000000,
280		[INV_ICM45600_ODR_12_5HZ]      = 80000000,
281		[INV_ICM45600_ODR_6_25HZ_LP]   = 160000000,
282		[INV_ICM45600_ODR_3_125HZ_LP]  = 320000000,
283		[INV_ICM45600_ODR_1_5625HZ_LP] = 640000000,
284	};
285
286	return odr_periods[odr];
287}
288
289static int inv_icm45600_set_pwr_mgmt0(struct inv_icm45600_state *st,
290				      enum inv_icm45600_sensor_mode gyro,
291				      enum inv_icm45600_sensor_mode accel,
292				      unsigned int *sleep_ms)
293{
294	enum inv_icm45600_sensor_mode oldgyro = st->conf.gyro.mode;
295	enum inv_icm45600_sensor_mode oldaccel = st->conf.accel.mode;
296	unsigned int sleepval;
297	unsigned int val;
298	int ret;
299
300	/* if nothing changed, exit */
301	if (gyro == oldgyro && accel == oldaccel)
302		return 0;
303
304	val = FIELD_PREP(INV_ICM45600_PWR_MGMT0_GYRO_MODE_MASK, gyro) |
305	      FIELD_PREP(INV_ICM45600_PWR_MGMT0_ACCEL_MODE_MASK, accel);
306	ret = regmap_write(st->map, INV_ICM45600_REG_PWR_MGMT0, val);
307	if (ret)
308		return ret;
309
310	st->conf.gyro.mode = gyro;
311	st->conf.accel.mode = accel;
312
313	/* Compute the required wait time for sensors to stabilize. */
314	sleepval = 0;
315	if (accel != oldaccel && oldaccel == INV_ICM45600_SENSOR_MODE_OFF)
316		sleepval = max(sleepval, INV_ICM45600_ACCEL_STARTUP_TIME_MS);
317
318	if (gyro != oldgyro) {
319		if (oldgyro == INV_ICM45600_SENSOR_MODE_OFF)
320			sleepval = max(sleepval, INV_ICM45600_GYRO_STARTUP_TIME_MS);
321		else if (gyro == INV_ICM45600_SENSOR_MODE_OFF)
322			sleepval = max(sleepval, INV_ICM45600_GYRO_STOP_TIME_MS);
323	}
324
325	/* Deferred sleep value if sleep pointer is provided or direct sleep */
326	if (sleep_ms)
327		*sleep_ms = sleepval;
328	else if (sleepval)
329		msleep(sleepval);
330
331	return 0;
332}
333
334static void inv_icm45600_set_default_conf(struct inv_icm45600_sensor_conf *conf,
335					  struct inv_icm45600_sensor_conf *oldconf)
336{
337	/* Sanitize missing values with current values. */
338	if (conf->mode == U8_MAX)
339		conf->mode = oldconf->mode;
340	if (conf->fs == U8_MAX)
341		conf->fs = oldconf->fs;
342	if (conf->odr == U8_MAX)
343		conf->odr = oldconf->odr;
344	if (conf->filter == U8_MAX)
345		conf->filter = oldconf->filter;
346}
347
348int inv_icm45600_set_accel_conf(struct inv_icm45600_state *st,
349				struct inv_icm45600_sensor_conf *conf,
350				unsigned int *sleep_ms)
351{
352	struct inv_icm45600_sensor_conf *oldconf = &st->conf.accel;
353	unsigned int val;
354	int ret;
355
356	inv_icm45600_set_default_conf(conf, oldconf);
357
358	/* Force the power mode against the ODR when sensor is on. */
359	if (conf->mode > INV_ICM45600_SENSOR_MODE_STANDBY) {
360		if (conf->odr <= INV_ICM45600_ODR_800HZ_LN) {
361			conf->mode = INV_ICM45600_SENSOR_MODE_LOW_NOISE;
362		} else {
363			conf->mode = INV_ICM45600_SENSOR_MODE_LOW_POWER;
364			/* sanitize averaging value depending on ODR for low-power mode */
365			/* maximum 1x @400Hz */
366			if (conf->odr == INV_ICM45600_ODR_400HZ)
367				conf->filter = INV_ICM45600_ACCEL_LP_AVG_SEL_1X;
368			else
369				conf->filter = INV_ICM45600_ACCEL_LP_AVG_SEL_4X;
370		}
371	}
372
373	/* Set accel fullscale & odr. */
374	if (conf->fs != oldconf->fs || conf->odr != oldconf->odr) {
375		val = FIELD_PREP(INV_ICM45600_ACCEL_CONFIG0_FS_MASK, conf->fs) |
376		      FIELD_PREP(INV_ICM45600_ACCEL_CONFIG0_ODR_MASK, conf->odr);
377		ret = regmap_write(st->map, INV_ICM45600_REG_ACCEL_CONFIG0, val);
378		if (ret)
379			return ret;
380		oldconf->fs = conf->fs;
381		oldconf->odr = conf->odr;
382	}
383
384	/* Set accel low-power average filter. */
385	if (conf->filter != oldconf->filter) {
386		ret = regmap_write(st->map, INV_ICM45600_IPREG_SYS2_REG_129,
387				   conf->filter);
388		if (ret)
389			return ret;
390		oldconf->filter = conf->filter;
391	}
392
393	/* Update the sensor accel mode. */
394	return inv_icm45600_set_pwr_mgmt0(st, st->conf.gyro.mode, conf->mode,
395					  sleep_ms);
396}
397
398int inv_icm45600_set_gyro_conf(struct inv_icm45600_state *st,
399			       struct inv_icm45600_sensor_conf *conf,
400			       unsigned int *sleep_ms)
401{
402	struct inv_icm45600_sensor_conf *oldconf = &st->conf.gyro;
403	unsigned int val;
404	int ret;
405
406	inv_icm45600_set_default_conf(conf, oldconf);
407
408	/* Force the power mode against ODR when sensor is on. */
409	if (conf->mode > INV_ICM45600_SENSOR_MODE_STANDBY) {
410		if (conf->odr >= INV_ICM45600_ODR_6_25HZ_LP) {
411			conf->mode = INV_ICM45600_SENSOR_MODE_LOW_POWER;
412			conf->filter = INV_ICM45600_GYRO_LP_AVG_SEL_8X;
413		} else {
414			conf->mode = INV_ICM45600_SENSOR_MODE_LOW_NOISE;
415		}
416	}
417
418	/* Set gyro fullscale & odr. */
419	if (conf->fs != oldconf->fs || conf->odr != oldconf->odr) {
420		val = FIELD_PREP(INV_ICM45600_GYRO_CONFIG0_FS_MASK, conf->fs) |
421		      FIELD_PREP(INV_ICM45600_GYRO_CONFIG0_ODR_MASK, conf->odr);
422		ret = regmap_write(st->map, INV_ICM45600_REG_GYRO_CONFIG0, val);
423		if (ret)
424			return ret;
425		oldconf->fs = conf->fs;
426		oldconf->odr = conf->odr;
427	}
428
429	/* Set gyro low-power average filter. */
430	if (conf->filter != oldconf->filter) {
431		val = FIELD_PREP(INV_ICM45600_IPREG_SYS1_170_GYRO_LP_AVG_MASK, conf->filter);
432		ret = regmap_update_bits(st->map, INV_ICM45600_IPREG_SYS1_REG_170,
433					 INV_ICM45600_IPREG_SYS1_170_GYRO_LP_AVG_MASK, val);
434		if (ret)
435			return ret;
436		oldconf->filter = conf->filter;
437	}
438
439	/* Update the sensor gyro mode. */
440	return inv_icm45600_set_pwr_mgmt0(st, conf->mode, st->conf.accel.mode,
441					  sleep_ms);
442}
443
444int inv_icm45600_debugfs_reg(struct iio_dev *indio_dev, unsigned int reg,
445			     unsigned int writeval, unsigned int *readval)
446{
447	struct inv_icm45600_state *st = iio_device_get_drvdata(indio_dev);
448
449	guard(mutex)(&st->lock);
450
451	if (readval)
452		return regmap_read(st->map, reg, readval);
453	else
454		return regmap_write(st->map, reg, writeval);
455}
456
457static int inv_icm45600_set_conf(struct inv_icm45600_state *st,
458				 const struct inv_icm45600_conf *conf)
459{
460	unsigned int val;
461	int ret;
462
463	val = FIELD_PREP(INV_ICM45600_PWR_MGMT0_GYRO_MODE_MASK, conf->gyro.mode) |
464	      FIELD_PREP(INV_ICM45600_PWR_MGMT0_ACCEL_MODE_MASK, conf->accel.mode);
465	ret = regmap_write(st->map, INV_ICM45600_REG_PWR_MGMT0, val);
466	if (ret)
467		return ret;
468
469	val = FIELD_PREP(INV_ICM45600_GYRO_CONFIG0_FS_MASK, conf->gyro.fs) |
470	      FIELD_PREP(INV_ICM45600_GYRO_CONFIG0_ODR_MASK, conf->gyro.odr);
471	ret = regmap_write(st->map, INV_ICM45600_REG_GYRO_CONFIG0, val);
472	if (ret)
473		return ret;
474
475	val = FIELD_PREP(INV_ICM45600_ACCEL_CONFIG0_FS_MASK, conf->accel.fs) |
476	      FIELD_PREP(INV_ICM45600_ACCEL_CONFIG0_ODR_MASK, conf->accel.odr);
477	ret = regmap_write(st->map, INV_ICM45600_REG_ACCEL_CONFIG0, val);
478	if (ret)
479		return ret;
480
481	/* Save configuration. */
482	st->conf = *conf;
483
484	return 0;
485}
486
487/**
488 *  inv_icm45600_setup() - check and setup chip
489 *  @st:	driver internal state
490 *  @chip_info:	detected chip description
491 *  @reset:	define whether a reset is required or not
492 *  @bus_setup:	callback for setting up bus specific registers
493 *
494 *  Returns: 0 on success, a negative error code otherwise.
495 */
496static int inv_icm45600_setup(struct inv_icm45600_state *st,
497				const struct inv_icm45600_chip_info *chip_info,
498				bool reset, inv_icm45600_bus_setup bus_setup)
499{
500	const struct device *dev = regmap_get_device(st->map);
501	unsigned int val;
502	int ret;
503
504	/* Set chip bus configuration if specified. */
505	if (bus_setup) {
506		ret = bus_setup(st);
507		if (ret)
508			return ret;
509	}
510
511	/* Check chip self-identification value. */
512	ret = regmap_read(st->map, INV_ICM45600_REG_WHOAMI, &val);
513	if (ret)
514		return ret;
515	if (val != chip_info->whoami) {
516		/*
517		 * SPI interface has no ack mechanism.
518		 * 0xFF or 0x00 whoami means no response from the device.
519		 */
520		if (val == U8_MAX || val == 0)
521			return dev_err_probe(dev, -ENODEV,
522					     "Invalid whoami %#02x expected %#02x (%s)\n",
523					     val, chip_info->whoami, chip_info->name);
524
525		dev_warn(dev, "Unexpected whoami %#02x expected %#02x (%s)\n",
526			 val, chip_info->whoami, chip_info->name);
527	}
528
529	st->chip_info = chip_info;
530
531	if (reset) {
532		/* Reset previous state. */
533		ret = regmap_write(st->map, INV_ICM45600_REG_MISC2,
534				   INV_ICM45600_MISC2_SOFT_RESET);
535		if (ret)
536			return ret;
537		/*
538		 * IMU reset time.
539		 * Datasheet: 16.84 REG_MISC2
540		 */
541		fsleep(USEC_PER_MSEC);
542
543		if (bus_setup) {
544			ret = bus_setup(st);
545			if (ret)
546				return ret;
547		}
548
549		ret = regmap_read(st->map, INV_ICM45600_REG_INT_STATUS, &val);
550		if (ret)
551			return ret;
552		if (!(val & INV_ICM45600_INT_STATUS_RESET_DONE)) {
553			dev_err(dev, "reset error, reset done bit not set\n");
554			return -ENODEV;
555		}
556	}
557
558	return inv_icm45600_set_conf(st, chip_info->conf);
559}
560
561static irqreturn_t inv_icm45600_irq_timestamp(int irq, void *_data)
562{
563	struct inv_icm45600_state *st = _data;
564
565	st->timestamp.gyro = iio_get_time_ns(st->indio_gyro);
566	st->timestamp.accel = iio_get_time_ns(st->indio_accel);
567
568	return IRQ_WAKE_THREAD;
569}
570
571static irqreturn_t inv_icm45600_irq_handler(int irq, void *_data)
572{
573	struct inv_icm45600_state *st = _data;
574	struct device *dev = regmap_get_device(st->map);
575	unsigned int mask, status;
576	int ret;
577
578	guard(mutex)(&st->lock);
579
580	ret = regmap_read(st->map, INV_ICM45600_REG_INT_STATUS, &status);
581	if (ret)
582		return IRQ_HANDLED;
583
584	/* Read the FIFO data. */
585	mask = INV_ICM45600_INT_STATUS_FIFO_THS | INV_ICM45600_INT_STATUS_FIFO_FULL;
586	if (status & mask) {
587		ret = inv_icm45600_buffer_fifo_read(st, 0);
588		if (ret) {
589			dev_err(dev, "FIFO read error %d\n", ret);
590			return IRQ_HANDLED;
591		}
592		ret = inv_icm45600_buffer_fifo_parse(st);
593		if (ret)
594			dev_err(dev, "FIFO parsing error %d\n", ret);
595	}
596
597	/* FIFO full warning. */
598	if (status & INV_ICM45600_INT_STATUS_FIFO_FULL)
599		dev_warn(dev, "FIFO full possible data lost!\n");
600
601	return IRQ_HANDLED;
602}
603
604/**
605 * inv_icm45600_irq_init() - initialize int pin and interrupt handler
606 * @st:		driver internal state
607 * @irq:	irq number
608 * @irq_type:	irq trigger type
609 * @open_drain:	true if irq is open drain, false for push-pull
610 *
611 * Returns: 0 on success, a negative error code otherwise.
612 */
613static int inv_icm45600_irq_init(struct inv_icm45600_state *st, int irq,
614				 int irq_type, bool open_drain)
615{
616	struct device *dev = regmap_get_device(st->map);
617	unsigned int val;
618	int ret;
619
620	/* Configure INT1 interrupt: default is active low on edge. */
621	switch (irq_type) {
622	case IRQF_TRIGGER_RISING:
623	case IRQF_TRIGGER_HIGH:
624		val = INV_ICM45600_INT1_CONFIG2_ACTIVE_HIGH;
625		break;
626	default:
627		val = INV_ICM45600_INT1_CONFIG2_ACTIVE_LOW;
628		break;
629	}
630
631	switch (irq_type) {
632	case IRQF_TRIGGER_LOW:
633	case IRQF_TRIGGER_HIGH:
634		val |= INV_ICM45600_INT1_CONFIG2_LATCHED;
635		break;
636	default:
637		break;
638	}
639
640	if (open_drain)
641		val |= INV_ICM45600_INT1_CONFIG2_OPEN_DRAIN;
642
643	ret = regmap_write(st->map, INV_ICM45600_REG_INT1_CONFIG2, val);
644	if (ret)
645		return ret;
646
647	return devm_request_threaded_irq(dev, irq, inv_icm45600_irq_timestamp,
648					 inv_icm45600_irq_handler, irq_type | IRQF_ONESHOT,
649					 "inv_icm45600", st);
650}
651
652static int inv_icm45600_timestamp_setup(struct inv_icm45600_state *st)
653{
654	/* Enable timestamps. */
655	return regmap_set_bits(st->map, INV_ICM45600_REG_SMC_CONTROL_0,
656			       INV_ICM45600_SMC_CONTROL_0_TMST_EN);
657}
658
659static int inv_icm45600_enable_regulator_vddio(struct inv_icm45600_state *st)
660{
661	int ret;
662
663	ret = regulator_enable(st->vddio_supply);
664	if (ret)
665		return ret;
666
667	/*
668	 * Wait a little for supply ramp.
669	 * Duration is empirically defined.
670	 */
671	fsleep(3 * USEC_PER_MSEC);
672
673	return 0;
674}
675
676static void inv_icm45600_disable_vddio_reg(void *_data)
677{
678	struct inv_icm45600_state *st = _data;
679	struct device *dev = regmap_get_device(st->map);
680
681	if (pm_runtime_status_suspended(dev))
682		return;
683
684	regulator_disable(st->vddio_supply);
685}
686
687int inv_icm45600_core_probe(struct regmap *regmap, const struct inv_icm45600_chip_info *chip_info,
688			    bool reset, inv_icm45600_bus_setup bus_setup)
689{
690	struct device *dev = regmap_get_device(regmap);
691	struct inv_icm45600_state *st;
692	struct regmap *regmap_custom;
693	struct fwnode_handle *fwnode;
694	int irq, irq_type;
695	bool open_drain;
696	int ret;
697
698	/* Get INT1 only supported interrupt. */
699	fwnode = dev_fwnode(dev);
700	irq = fwnode_irq_get_byname(fwnode, "int1");
701	if (irq < 0)
702		return dev_err_probe(dev, irq, "Missing int1 interrupt\n");
703
704	irq_type = irq_get_trigger_type(irq);
705
706	open_drain = device_property_read_bool(dev, "drive-open-drain");
707
708	regmap_custom = devm_regmap_init(dev, &inv_icm45600_regmap_bus, regmap,
709					 &inv_icm45600_regmap_config);
710	if (IS_ERR(regmap_custom))
711		return dev_err_probe(dev, PTR_ERR(regmap_custom), "Failed to register regmap\n");
712
713	st = devm_kzalloc(dev, sizeof(*st), GFP_KERNEL);
714	if (!st)
715		return -ENOMEM;
716
717	dev_set_drvdata(dev, st);
718
719	st->fifo.data = devm_kzalloc(dev, 8192, GFP_KERNEL);
720	if (!st->fifo.data)
721		return -ENOMEM;
722
723	ret = devm_mutex_init(dev, &st->lock);
724	if (ret)
725		return ret;
726
727	st->map = regmap_custom;
728
729	ret = iio_read_mount_matrix(dev, &st->orientation);
730	if (ret)
731		return dev_err_probe(dev, ret, "Failed to retrieve mounting matrix\n");
732
733	st->vddio_supply = devm_regulator_get(dev, "vddio");
734	if (IS_ERR(st->vddio_supply))
735		return PTR_ERR(st->vddio_supply);
736
737	ret = devm_regulator_get_enable(dev, "vdd");
738	if (ret)
739		return dev_err_probe(dev, ret, "Failed to get vdd regulator\n");
740
741	/*
742	 * Supply ramp time + Start-up time.
743	 * Datasheet: 3.3.2 A.C. Electrical Characteristics
744	 */
745	fsleep(5 * USEC_PER_MSEC);
746
747	/* set pm_runtime active early for disable vddio resource cleanup */
748	ret = pm_runtime_set_active(dev);
749	if (ret)
750		return ret;
751
752	ret = inv_icm45600_enable_regulator_vddio(st);
753	if (ret)
754		return ret;
755
756	ret = devm_add_action_or_reset(dev, inv_icm45600_disable_vddio_reg, st);
757	if (ret)
758		return ret;
759
760	ret = inv_icm45600_setup(st, chip_info, reset, bus_setup);
761	if (ret)
762		return ret;
763
764	ret = inv_icm45600_timestamp_setup(st);
765	if (ret)
766		return ret;
767
768	ret = inv_icm45600_buffer_init(st);
769	if (ret)
770		return ret;
771
772	st->indio_gyro = inv_icm45600_gyro_init(st);
773	if (IS_ERR(st->indio_gyro))
774		return PTR_ERR(st->indio_gyro);
775
776	st->indio_accel = inv_icm45600_accel_init(st);
777	if (IS_ERR(st->indio_accel))
778		return PTR_ERR(st->indio_accel);
779
780	ret = inv_icm45600_irq_init(st, irq, irq_type, open_drain);
781	if (ret)
782		return ret;
783
784	ret = devm_pm_runtime_enable(dev);
785	if (ret)
786		return ret;
787
788	pm_runtime_get_noresume(dev);
789	pm_runtime_set_autosuspend_delay(dev, 2 * USEC_PER_MSEC);
790	pm_runtime_use_autosuspend(dev);
791	pm_runtime_put(dev);
792
793	return 0;
794}
795EXPORT_SYMBOL_NS_GPL(inv_icm45600_core_probe, "IIO_ICM45600");
796
797/*
798 * Suspend saves sensors state and turns everything off.
799 */
800static int inv_icm45600_suspend(struct device *dev)
801{
802	struct inv_icm45600_state *st = dev_get_drvdata(dev);
803	int ret;
804
805	scoped_guard(mutex, &st->lock) {
806		/* Disable FIFO data streaming. */
807		if (st->fifo.on) {
808			unsigned int val;
809
810			/* Clear FIFO_CONFIG3_IF_EN before changing the FIFO configuration */
811			ret = regmap_clear_bits(st->map, INV_ICM45600_REG_FIFO_CONFIG3,
812						INV_ICM45600_FIFO_CONFIG3_IF_EN);
813			if (ret)
814				return ret;
815			val = FIELD_PREP(INV_ICM45600_FIFO_CONFIG0_MODE_MASK,
816					 INV_ICM45600_FIFO_CONFIG0_MODE_BYPASS);
817			ret = regmap_update_bits(st->map, INV_ICM45600_REG_FIFO_CONFIG0,
818						 INV_ICM45600_FIFO_CONFIG0_MODE_MASK, val);
819			if (ret)
820				return ret;
821		}
822
823		/* Save sensors states */
824		st->suspended.gyro = st->conf.gyro.mode;
825		st->suspended.accel = st->conf.accel.mode;
826	}
827
828	return pm_runtime_force_suspend(dev);
829}
830
831/*
832 * System resume gets the system back on and restores the sensors state.
833 * Manually put runtime power management in system active state.
834 */
835static int inv_icm45600_resume(struct device *dev)
836{
837	struct inv_icm45600_state *st = dev_get_drvdata(dev);
838	int ret;
839
840	ret = pm_runtime_force_resume(dev);
841	if (ret)
842		return ret;
843
844	scoped_guard(mutex, &st->lock) {
845		/* Restore sensors state. */
846		ret = inv_icm45600_set_pwr_mgmt0(st, st->suspended.gyro,
847						 st->suspended.accel, NULL);
848		if (ret)
849			return ret;
850
851		/* Restore FIFO data streaming. */
852		if (st->fifo.on) {
853			struct inv_icm45600_sensor_state *gyro_st = iio_priv(st->indio_gyro);
854			struct inv_icm45600_sensor_state *accel_st = iio_priv(st->indio_accel);
855			unsigned int val;
856
857			inv_sensors_timestamp_reset(&gyro_st->ts);
858			inv_sensors_timestamp_reset(&accel_st->ts);
859			val = FIELD_PREP(INV_ICM45600_FIFO_CONFIG0_MODE_MASK,
860					 INV_ICM45600_FIFO_CONFIG0_MODE_STREAM);
861			ret = regmap_update_bits(st->map, INV_ICM45600_REG_FIFO_CONFIG0,
862						 INV_ICM45600_FIFO_CONFIG0_MODE_MASK, val);
863			if (ret)
864				return ret;
865			/* FIFO_CONFIG3_IF_EN must only be set at end of FIFO the configuration */
866			ret = regmap_set_bits(st->map, INV_ICM45600_REG_FIFO_CONFIG3,
867					      INV_ICM45600_FIFO_CONFIG3_IF_EN);
868			if (ret)
869				return ret;
870		}
871	}
872
873	return ret;
874}
875
876/* Runtime suspend will turn off sensors that are enabled by iio devices. */
877static int inv_icm45600_runtime_suspend(struct device *dev)
878{
879	struct inv_icm45600_state *st = dev_get_drvdata(dev);
880	int ret;
881
882	guard(mutex)(&st->lock);
883
884	/* disable all sensors */
885	ret = inv_icm45600_set_pwr_mgmt0(st, INV_ICM45600_SENSOR_MODE_OFF,
886					 INV_ICM45600_SENSOR_MODE_OFF, NULL);
887	if (ret)
888		return ret;
889
890	regulator_disable(st->vddio_supply);
891
892	return 0;
893}
894
895/* Sensors are enabled by iio devices, no need to turn them back on here. */
896static int inv_icm45600_runtime_resume(struct device *dev)
897{
898	struct inv_icm45600_state *st = dev_get_drvdata(dev);
899
900	guard(mutex)(&st->lock);
901
902	return inv_icm45600_enable_regulator_vddio(st);
903}
904
905static int _inv_icm45600_temp_read(struct inv_icm45600_state *st, s16 *temp)
906{
907	struct inv_icm45600_sensor_conf conf = INV_ICM45600_SENSOR_CONF_KEEP_VALUES;
908	int ret;
909
910	/* Make sure a sensor is on. */
911	if (st->conf.gyro.mode == INV_ICM45600_SENSOR_MODE_OFF &&
912	    st->conf.accel.mode == INV_ICM45600_SENSOR_MODE_OFF) {
913		conf.mode = INV_ICM45600_SENSOR_MODE_LOW_POWER;
914		ret = inv_icm45600_set_accel_conf(st, &conf, NULL);
915		if (ret)
916			return ret;
917	}
918
919	ret = regmap_bulk_read(st->map, INV_ICM45600_REG_TEMP_DATA,
920			       &st->buffer.u16, sizeof(st->buffer.u16));
921	if (ret)
922		return ret;
923
924	*temp = (s16)le16_to_cpup(&st->buffer.u16);
925	if (*temp == INV_ICM45600_DATA_INVALID)
926		return -EINVAL;
927
928	return 0;
929}
930
931static int inv_icm45600_temp_read(struct inv_icm45600_state *st, s16 *temp)
932{
933	struct device *dev = regmap_get_device(st->map);
934	int ret;
935
936	ret = pm_runtime_resume_and_get(dev);
937	if (ret)
938		return ret;
939
940	scoped_guard(mutex, &st->lock)
941		ret = _inv_icm45600_temp_read(st, temp);
942
943	pm_runtime_put_autosuspend(dev);
944
945	return ret;
946}
947
948int inv_icm45600_temp_read_raw(struct iio_dev *indio_dev,
949			       struct iio_chan_spec const *chan,
950			       int *val, int *val2, long mask)
951{
952	struct inv_icm45600_state *st = iio_device_get_drvdata(indio_dev);
953	s16 temp;
954	int ret;
955
956	if (chan->type != IIO_TEMP)
957		return -EINVAL;
958
959	switch (mask) {
960	case IIO_CHAN_INFO_RAW:
961		ret = inv_icm45600_temp_read(st, &temp);
962		if (ret)
963			return ret;
964		*val = temp;
965		return IIO_VAL_INT;
966	/*
967	 * T°C = (temp / 128) + 25
968	 * Tm°C = ((temp + 25 * 128) / 128)) * 1000
969	 * Tm°C = (temp + 3200) * (1000 / 128)
970	 * scale: 1000 / 128 = 7.8125
971	 * offset: 3200
972	 */
973	case IIO_CHAN_INFO_SCALE:
974		*val = 7;
975		*val2 = 812500;
976		return IIO_VAL_INT_PLUS_MICRO;
977	case IIO_CHAN_INFO_OFFSET:
978		*val = 3200;
979		return IIO_VAL_INT;
980	default:
981		return -EINVAL;
982	}
983}
984
985EXPORT_NS_GPL_DEV_PM_OPS(inv_icm45600_pm_ops, IIO_ICM45600) = {
986	SYSTEM_SLEEP_PM_OPS(inv_icm45600_suspend, inv_icm45600_resume)
987	RUNTIME_PM_OPS(inv_icm45600_runtime_suspend,
988			   inv_icm45600_runtime_resume, NULL)
989};
990
991MODULE_AUTHOR("InvenSense, Inc.");
992MODULE_DESCRIPTION("InvenSense ICM-456xx device driver");
993MODULE_LICENSE("GPL");
994MODULE_IMPORT_NS("IIO_INV_SENSORS_TIMESTAMP");
~/ Read-only file preview.