File Index
Files and directories
Sign in
FILE

inv_icm45600_gyro.c

File preview with syntax highlighting.

linux-6.19.14/drivers/iio/imu/inv_icm45600/inv_icm45600_gyro.c C
  1// SPDX-License-Identifier: GPL-2.0-or-later
  2/*
  3 * Copyright (C) 2025 Invensense, Inc.
  4 */
  5
  6#include <linux/delay.h>
  7#include <linux/device.h>
  8#include <linux/err.h>
  9#include <linux/math64.h>
 10#include <linux/mutex.h>
 11#include <linux/pm_runtime.h>
 12#include <linux/regmap.h>
 13#include <linux/types.h>
 14
 15#include <linux/iio/buffer.h>
 16#include <linux/iio/common/inv_sensors_timestamp.h>
 17#include <linux/iio/iio.h>
 18#include <linux/iio/kfifo_buf.h>
 19
 20#include "inv_icm45600_buffer.h"
 21#include "inv_icm45600.h"
 22
 23enum inv_icm45600_gyro_scan {
 24	INV_ICM45600_GYRO_SCAN_X,
 25	INV_ICM45600_GYRO_SCAN_Y,
 26	INV_ICM45600_GYRO_SCAN_Z,
 27	INV_ICM45600_GYRO_SCAN_TEMP,
 28	INV_ICM45600_GYRO_SCAN_TIMESTAMP,
 29};
 30
 31static const struct iio_chan_spec_ext_info inv_icm45600_gyro_ext_infos[] = {
 32	IIO_MOUNT_MATRIX(IIO_SHARED_BY_ALL, inv_icm45600_get_mount_matrix),
 33	{ }
 34};
 35
 36#define INV_ICM45600_GYRO_CHAN(_modifier, _index, _ext_info)		\
 37	{								\
 38		.type = IIO_ANGL_VEL,					\
 39		.modified = 1,						\
 40		.channel2 = _modifier,					\
 41		.info_mask_separate =					\
 42			BIT(IIO_CHAN_INFO_RAW) |			\
 43			BIT(IIO_CHAN_INFO_CALIBBIAS),			\
 44		.info_mask_shared_by_type =				\
 45			BIT(IIO_CHAN_INFO_SCALE),			\
 46		.info_mask_shared_by_type_available =			\
 47			BIT(IIO_CHAN_INFO_SCALE) |			\
 48			BIT(IIO_CHAN_INFO_CALIBBIAS),			\
 49		.info_mask_shared_by_all =				\
 50			BIT(IIO_CHAN_INFO_SAMP_FREQ),			\
 51		.info_mask_shared_by_all_available =			\
 52			BIT(IIO_CHAN_INFO_SAMP_FREQ),			\
 53		.scan_index = _index,					\
 54		.scan_type = {						\
 55			.sign = 's',					\
 56			.realbits = 16,					\
 57			.storagebits = 16,				\
 58			.endianness = IIO_LE,				\
 59		},							\
 60		.ext_info = _ext_info,					\
 61	}
 62
 63static const struct iio_chan_spec inv_icm45600_gyro_channels[] = {
 64	INV_ICM45600_GYRO_CHAN(IIO_MOD_X, INV_ICM45600_GYRO_SCAN_X,
 65			       inv_icm45600_gyro_ext_infos),
 66	INV_ICM45600_GYRO_CHAN(IIO_MOD_Y, INV_ICM45600_GYRO_SCAN_Y,
 67			       inv_icm45600_gyro_ext_infos),
 68	INV_ICM45600_GYRO_CHAN(IIO_MOD_Z, INV_ICM45600_GYRO_SCAN_Z,
 69			       inv_icm45600_gyro_ext_infos),
 70	INV_ICM45600_TEMP_CHAN(INV_ICM45600_GYRO_SCAN_TEMP),
 71	IIO_CHAN_SOFT_TIMESTAMP(INV_ICM45600_GYRO_SCAN_TIMESTAMP),
 72};
 73
 74/*
 75 * IIO buffer data: size must be a power of 2 and timestamp aligned
 76 * 16 bytes: 6 bytes angular velocity, 2 bytes temperature, 8 bytes timestamp
 77 */
 78struct inv_icm45600_gyro_buffer {
 79	struct inv_icm45600_fifo_sensor_data gyro;
 80	s16 temp;
 81	aligned_s64 timestamp;
 82};
 83
 84static const unsigned long inv_icm45600_gyro_scan_masks[] = {
 85	/* 3-axis gyro + temperature */
 86	BIT(INV_ICM45600_GYRO_SCAN_X) |
 87	BIT(INV_ICM45600_GYRO_SCAN_Y) |
 88	BIT(INV_ICM45600_GYRO_SCAN_Z) |
 89	BIT(INV_ICM45600_GYRO_SCAN_TEMP),
 90	0
 91};
 92
 93/* enable gyroscope sensor and FIFO write */
 94static int inv_icm45600_gyro_update_scan_mode(struct iio_dev *indio_dev,
 95					      const unsigned long *scan_mask)
 96{
 97	struct inv_icm45600_state *st = iio_device_get_drvdata(indio_dev);
 98	struct inv_icm45600_sensor_state *gyro_st = iio_priv(indio_dev);
 99	struct inv_icm45600_sensor_conf conf = INV_ICM45600_SENSOR_CONF_KEEP_VALUES;
100	unsigned int fifo_en = 0;
101	unsigned int sleep = 0;
102	int ret;
103
104	scoped_guard(mutex, &st->lock) {
105		if (*scan_mask & BIT(INV_ICM45600_GYRO_SCAN_TEMP))
106			fifo_en |= INV_ICM45600_SENSOR_TEMP;
107
108		if (*scan_mask & (BIT(INV_ICM45600_GYRO_SCAN_X) |
109				 BIT(INV_ICM45600_GYRO_SCAN_Y) |
110				 BIT(INV_ICM45600_GYRO_SCAN_Z))) {
111			/* enable gyro sensor */
112			conf.mode = gyro_st->power_mode;
113			ret = inv_icm45600_set_gyro_conf(st, &conf, &sleep);
114			if (ret)
115				return ret;
116			fifo_en |= INV_ICM45600_SENSOR_GYRO;
117		}
118		ret = inv_icm45600_buffer_set_fifo_en(st, fifo_en | st->fifo.en);
119	}
120	if (sleep)
121		msleep(sleep);
122
123	return ret;
124}
125
126static int _inv_icm45600_gyro_read_sensor(struct inv_icm45600_state *st,
127					  struct inv_icm45600_sensor_state *gyro_st,
128					  unsigned int reg, int *val)
129{
130	struct inv_icm45600_sensor_conf conf = INV_ICM45600_SENSOR_CONF_KEEP_VALUES;
131	int ret;
132
133	/* enable gyro sensor */
134	conf.mode = gyro_st->power_mode;
135	ret = inv_icm45600_set_gyro_conf(st, &conf, NULL);
136	if (ret)
137		return ret;
138
139	/* read gyro register data */
140	ret = regmap_bulk_read(st->map, reg, &st->buffer.u16, sizeof(st->buffer.u16));
141	if (ret)
142		return ret;
143
144	*val = sign_extend32(le16_to_cpup(&st->buffer.u16), 15);
145	if (*val == INV_ICM45600_DATA_INVALID)
146		return -ENODATA;
147
148	return 0;
149}
150
151static int inv_icm45600_gyro_read_sensor(struct iio_dev *indio_dev,
152					 struct iio_chan_spec const *chan,
153					 int *val)
154{
155	struct inv_icm45600_state *st = iio_device_get_drvdata(indio_dev);
156	struct inv_icm45600_sensor_state *gyro_st = iio_priv(indio_dev);
157	struct device *dev = regmap_get_device(st->map);
158	unsigned int reg;
159	int ret;
160
161	if (chan->type != IIO_ANGL_VEL)
162		return -EINVAL;
163
164	switch (chan->channel2) {
165	case IIO_MOD_X:
166		reg = INV_ICM45600_REG_GYRO_DATA_X;
167		break;
168	case IIO_MOD_Y:
169		reg = INV_ICM45600_REG_GYRO_DATA_Y;
170		break;
171	case IIO_MOD_Z:
172		reg = INV_ICM45600_REG_GYRO_DATA_Z;
173		break;
174	default:
175		return -EINVAL;
176	}
177
178	ret = pm_runtime_resume_and_get(dev);
179	if (ret)
180		return ret;
181
182	scoped_guard(mutex, &st->lock)
183		ret = _inv_icm45600_gyro_read_sensor(st, gyro_st, reg, val);
184
185	pm_runtime_put_autosuspend(dev);
186
187	return ret;
188}
189
190/* IIO format int + nano */
191const int inv_icm45600_gyro_scale[][2] = {
192	/* +/- 2000dps => 0.001065264 rad/s */
193	[INV_ICM45600_GYRO_FS_2000DPS] = { 0, 1065264 },
194	/* +/- 1000dps => 0.000532632 rad/s */
195	[INV_ICM45600_GYRO_FS_1000DPS] = { 0, 532632 },
196	/* +/- 500dps => 0.000266316 rad/s */
197	[INV_ICM45600_GYRO_FS_500DPS] = { 0, 266316 },
198	/* +/- 250dps => 0.000133158 rad/s */
199	[INV_ICM45600_GYRO_FS_250DPS] = { 0, 133158 },
200	/* +/- 125dps => 0.000066579 rad/s */
201	[INV_ICM45600_GYRO_FS_125DPS] = { 0, 66579 },
202	/* +/- 62.5dps => 0.000033290 rad/s */
203	[INV_ICM45600_GYRO_FS_62_5DPS] = { 0, 33290 },
204	/* +/- 31.25dps => 0.000016645 rad/s */
205	[INV_ICM45600_GYRO_FS_31_25DPS] = { 0, 16645 },
206	/* +/- 15.625dps => 0.000008322 rad/s */
207	[INV_ICM45600_GYRO_FS_15_625DPS] = { 0, 8322 },
208};
209
210/* IIO format int + nano */
211const int inv_icm45686_gyro_scale[][2] = {
212	/* +/- 4000dps => 0.002130529 rad/s */
213	[INV_ICM45686_GYRO_FS_4000DPS] = { 0, 2130529 },
214	/* +/- 2000dps => 0.001065264 rad/s */
215	[INV_ICM45686_GYRO_FS_2000DPS] = { 0, 1065264 },
216	/* +/- 1000dps => 0.000532632 rad/s */
217	[INV_ICM45686_GYRO_FS_1000DPS] = { 0, 532632 },
218	/* +/- 500dps => 0.000266316 rad/s */
219	[INV_ICM45686_GYRO_FS_500DPS] = { 0, 266316 },
220	/* +/- 250dps => 0.000133158 rad/s */
221	[INV_ICM45686_GYRO_FS_250DPS] = { 0, 133158 },
222	/* +/- 125dps => 0.000066579 rad/s */
223	[INV_ICM45686_GYRO_FS_125DPS] = { 0, 66579 },
224	/* +/- 62.5dps => 0.000033290 rad/s */
225	[INV_ICM45686_GYRO_FS_62_5DPS] = { 0, 33290 },
226	/* +/- 31.25dps => 0.000016645 rad/s */
227	[INV_ICM45686_GYRO_FS_31_25DPS] = { 0, 16645 },
228	/* +/- 15.625dps => 0.000008322 rad/s */
229	[INV_ICM45686_GYRO_FS_15_625DPS] = { 0, 8322 },
230};
231
232static int inv_icm45600_gyro_read_scale(struct iio_dev *indio_dev,
233					int *val, int *val2)
234{
235	struct inv_icm45600_state *st = iio_device_get_drvdata(indio_dev);
236	struct inv_icm45600_sensor_state *gyro_st = iio_priv(indio_dev);
237	unsigned int idx;
238
239	idx = st->conf.gyro.fs;
240
241	/* Full scale register starts at 1 for not High FSR parts */
242	if (gyro_st->scales ==  (const int *)&inv_icm45600_gyro_scale)
243		idx--;
244
245	*val = gyro_st->scales[2 * idx];
246	*val2 = gyro_st->scales[2 * idx + 1];
247	return IIO_VAL_INT_PLUS_NANO;
248}
249
250static int inv_icm45600_gyro_write_scale(struct iio_dev *indio_dev,
251					 int val, int val2)
252{
253	struct inv_icm45600_state *st = iio_device_get_drvdata(indio_dev);
254	struct inv_icm45600_sensor_state *gyro_st = iio_priv(indio_dev);
255	struct device *dev = regmap_get_device(st->map);
256	unsigned int idx;
257	struct inv_icm45600_sensor_conf conf = INV_ICM45600_SENSOR_CONF_KEEP_VALUES;
258	int ret;
259
260	for (idx = 0; idx < gyro_st->scales_len; idx += 2) {
261		if (val == gyro_st->scales[idx] &&
262		    val2 == gyro_st->scales[idx + 1])
263			break;
264	}
265	if (idx == gyro_st->scales_len)
266		return -EINVAL;
267
268	conf.fs = idx / 2;
269
270	/* Full scale register starts at 1 for not High FSR parts */
271	if (gyro_st->scales == (const int *)&inv_icm45600_gyro_scale)
272		conf.fs++;
273
274	ret = pm_runtime_resume_and_get(dev);
275	if (ret)
276		return ret;
277
278	scoped_guard(mutex, &st->lock)
279		ret = inv_icm45600_set_gyro_conf(st, &conf, NULL);
280
281	pm_runtime_put_autosuspend(dev);
282
283	return ret;
284}
285
286/* IIO format int + micro */
287static const int inv_icm45600_gyro_odr[] = {
288	1, 562500,	/* 1.5625Hz */
289	3, 125000,	/* 3.125Hz */
290	6, 250000,	/* 6.25Hz */
291	12, 500000,	/* 12.5Hz */
292	25, 0,		/* 25Hz */
293	50, 0,		/* 50Hz */
294	100, 0,		/* 100Hz */
295	200, 0,		/* 200Hz */
296	400, 0,		/* 400Hz */
297	800, 0,		/* 800Hz */
298	1600, 0,	/* 1.6kHz */
299	3200, 0,	/* 3.2kHz */
300	6400, 0,	/* 6.4kHz */
301};
302
303static const int inv_icm45600_gyro_odr_conv[] = {
304	INV_ICM45600_ODR_1_5625HZ_LP,
305	INV_ICM45600_ODR_3_125HZ_LP,
306	INV_ICM45600_ODR_6_25HZ_LP,
307	INV_ICM45600_ODR_12_5HZ,
308	INV_ICM45600_ODR_25HZ,
309	INV_ICM45600_ODR_50HZ,
310	INV_ICM45600_ODR_100HZ,
311	INV_ICM45600_ODR_200HZ,
312	INV_ICM45600_ODR_400HZ,
313	INV_ICM45600_ODR_800HZ_LN,
314	INV_ICM45600_ODR_1600HZ_LN,
315	INV_ICM45600_ODR_3200HZ_LN,
316	INV_ICM45600_ODR_6400HZ_LN,
317};
318
319static int inv_icm45600_gyro_read_odr(struct inv_icm45600_state *st,
320				      int *val, int *val2)
321{
322	unsigned int odr;
323	unsigned int i;
324
325	odr = st->conf.gyro.odr;
326
327	for (i = 0; i < ARRAY_SIZE(inv_icm45600_gyro_odr_conv); ++i) {
328		if (inv_icm45600_gyro_odr_conv[i] == odr)
329			break;
330	}
331	if (i >= ARRAY_SIZE(inv_icm45600_gyro_odr_conv))
332		return -EINVAL;
333
334	*val = inv_icm45600_gyro_odr[2 * i];
335	*val2 = inv_icm45600_gyro_odr[2 * i + 1];
336
337	return IIO_VAL_INT_PLUS_MICRO;
338}
339
340static int _inv_icm45600_gyro_write_odr(struct iio_dev *indio_dev, int odr)
341{
342	struct inv_icm45600_state *st = iio_device_get_drvdata(indio_dev);
343	struct inv_icm45600_sensor_state *gyro_st = iio_priv(indio_dev);
344	struct inv_sensors_timestamp *ts = &gyro_st->ts;
345	struct inv_icm45600_sensor_conf conf = INV_ICM45600_SENSOR_CONF_KEEP_VALUES;
346	int ret;
347
348	conf.odr = odr;
349	ret = inv_sensors_timestamp_update_odr(ts, inv_icm45600_odr_to_period(conf.odr),
350						iio_buffer_enabled(indio_dev));
351	if (ret)
352		return ret;
353
354	if (st->conf.gyro.mode != INV_ICM45600_SENSOR_MODE_OFF)
355		conf.mode = gyro_st->power_mode;
356
357	ret = inv_icm45600_set_gyro_conf(st, &conf, NULL);
358	if (ret)
359		return ret;
360
361	inv_icm45600_buffer_update_fifo_period(st);
362	inv_icm45600_buffer_update_watermark(st);
363
364	return 0;
365}
366
367static int inv_icm45600_gyro_write_odr(struct iio_dev *indio_dev,
368				       int val, int val2)
369{
370	struct inv_icm45600_state *st = iio_device_get_drvdata(indio_dev);
371	struct device *dev = regmap_get_device(st->map);
372	unsigned int idx;
373	int odr;
374	int ret;
375
376	for (idx = 0; idx < ARRAY_SIZE(inv_icm45600_gyro_odr); idx += 2) {
377		if (val == inv_icm45600_gyro_odr[idx] &&
378		    val2 == inv_icm45600_gyro_odr[idx + 1])
379			break;
380	}
381	if (idx >= ARRAY_SIZE(inv_icm45600_gyro_odr))
382		return -EINVAL;
383
384	odr = inv_icm45600_gyro_odr_conv[idx / 2];
385
386	ret = pm_runtime_resume_and_get(dev);
387	if (ret)
388		return ret;
389
390	scoped_guard(mutex, &st->lock)
391		ret = _inv_icm45600_gyro_write_odr(indio_dev, odr);
392
393	pm_runtime_put_autosuspend(dev);
394
395	return ret;
396}
397
398/*
399 * Calibration bias values, IIO range format int + nano.
400 * Value is limited to +/-62.5dps coded on 14 bits signed. Step is 7.5mdps.
401 */
402static int inv_icm45600_gyro_calibbias[] = {
403	-1, 90830336,	/* min: -1.090830336 rad/s */
404	0, 133158,	/* step: 0.000133158 rad/s */
405	1, 90697178,	/* max: 1.090697178 rad/s */
406};
407
408static int inv_icm45600_gyro_read_offset(struct inv_icm45600_state *st,
409					 struct iio_chan_spec const *chan,
410					 int *val, int *val2)
411{
412	struct device *dev = regmap_get_device(st->map);
413	s64 val64;
414	s32 bias;
415	unsigned int reg;
416	s16 offset;
417	int ret;
418
419	if (chan->type != IIO_ANGL_VEL)
420		return -EINVAL;
421
422	switch (chan->channel2) {
423	case IIO_MOD_X:
424		reg = INV_ICM45600_IPREG_SYS1_REG_42;
425		break;
426	case IIO_MOD_Y:
427		reg = INV_ICM45600_IPREG_SYS1_REG_56;
428		break;
429	case IIO_MOD_Z:
430		reg = INV_ICM45600_IPREG_SYS1_REG_70;
431		break;
432	default:
433		return -EINVAL;
434	}
435
436	ret = pm_runtime_resume_and_get(dev);
437	if (ret)
438		return ret;
439
440	scoped_guard(mutex, &st->lock)
441		ret = regmap_bulk_read(st->map, reg, &st->buffer.u16, sizeof(st->buffer.u16));
442
443	pm_runtime_put_autosuspend(dev);
444	if (ret)
445		return ret;
446
447	offset = le16_to_cpup(&st->buffer.u16) & INV_ICM45600_GYRO_OFFUSER_MASK;
448	/* 14 bits signed value */
449	offset = sign_extend32(offset, 13);
450
451	/*
452	 * convert raw offset to dps then to rad/s
453	 * 14 bits signed raw max 62.5 to dps: 625 / 81920
454	 * dps to rad: Pi / 180
455	 * result in nano (1000000000)
456	 * (offset * 625 * Pi * 1000000000) / (81920 * 180)
457	 */
458	val64 = (s64)offset * 625LL * 3141592653LL;
459	/* for rounding, add + or - divisor (81920 * 180) divided by 2 */
460	if (val64 >= 0)
461		val64 += 81920 * 180 / 2;
462	else
463		val64 -= 81920 * 180 / 2;
464	bias = div_s64(val64, 81920 * 180);
465	*val = bias / 1000000000L;
466	*val2 = bias % 1000000000L;
467
468	return IIO_VAL_INT_PLUS_NANO;
469}
470
471static int inv_icm45600_gyro_write_offset(struct inv_icm45600_state *st,
472					  struct iio_chan_spec const *chan,
473					  int val, int val2)
474{
475	struct device *dev = regmap_get_device(st->map);
476	s64 val64, min, max;
477	unsigned int reg;
478	s16 offset;
479	int ret;
480
481	if (chan->type != IIO_ANGL_VEL)
482		return -EINVAL;
483
484	switch (chan->channel2) {
485	case IIO_MOD_X:
486		reg = INV_ICM45600_IPREG_SYS1_REG_42;
487		break;
488	case IIO_MOD_Y:
489		reg = INV_ICM45600_IPREG_SYS1_REG_56;
490		break;
491	case IIO_MOD_Z:
492		reg = INV_ICM45600_IPREG_SYS1_REG_70;
493		break;
494	default:
495		return -EINVAL;
496	}
497
498	/* inv_icm45600_gyro_calibbias: min - step - max in nano */
499	min = (s64)inv_icm45600_gyro_calibbias[0] * 1000000000LL -
500	      (s64)inv_icm45600_gyro_calibbias[1];
501	max = (s64)inv_icm45600_gyro_calibbias[4] * 1000000000LL +
502	      (s64)inv_icm45600_gyro_calibbias[5];
503	val64 = (s64)val * 1000000000LL;
504	if (val >= 0)
505		val64 += (s64)val2;
506	else
507		val64 -= (s64)val2;
508	if (val64 < min || val64 > max)
509		return -EINVAL;
510
511	/*
512	 * convert rad/s to dps then to raw value
513	 * rad to dps: 180 / Pi
514	 * dps to raw 14 bits signed, max 62.5: 8192 / 62.5
515	 * val in nano (1000000000)
516	 * val * 180 * 8192 / (Pi * 1000000000 * 62.5)
517	 */
518	val64 = val64 * 180LL * 8192;
519	/* for rounding, add + or - divisor (314159265 * 625) divided by 2 */
520	if (val64 >= 0)
521		val64 += 314159265LL * 625LL / 2LL;
522	else
523		val64 -= 314159265LL * 625LL / 2LL;
524	offset = div64_s64(val64, 314159265LL * 625LL);
525
526	/* clamp value limited to 14 bits signed */
527	offset = clamp(offset, -8192, 8191);
528
529	st->buffer.u16 = cpu_to_le16(offset & INV_ICM45600_GYRO_OFFUSER_MASK);
530
531	ret = pm_runtime_resume_and_get(dev);
532	if (ret)
533		return ret;
534
535	scoped_guard(mutex, &st->lock)
536		ret = regmap_bulk_write(st->map, reg, &st->buffer.u16, sizeof(st->buffer.u16));
537
538	pm_runtime_put_autosuspend(dev);
539	return ret;
540}
541
542static int inv_icm45600_gyro_read_raw(struct iio_dev *indio_dev,
543				      struct iio_chan_spec const *chan,
544				      int *val, int *val2, long mask)
545{
546	struct inv_icm45600_state *st = iio_device_get_drvdata(indio_dev);
547	int ret;
548
549	switch (chan->type) {
550	case IIO_ANGL_VEL:
551		break;
552	case IIO_TEMP:
553		return inv_icm45600_temp_read_raw(indio_dev, chan, val, val2, mask);
554	default:
555		return -EINVAL;
556	}
557
558	switch (mask) {
559	case IIO_CHAN_INFO_RAW:
560		if (!iio_device_claim_direct(indio_dev))
561			return -EBUSY;
562		ret = inv_icm45600_gyro_read_sensor(indio_dev, chan, val);
563		iio_device_release_direct(indio_dev);
564		if (ret)
565			return ret;
566		return IIO_VAL_INT;
567	case IIO_CHAN_INFO_SCALE:
568		return inv_icm45600_gyro_read_scale(indio_dev, val, val2);
569	case IIO_CHAN_INFO_SAMP_FREQ:
570		return inv_icm45600_gyro_read_odr(st, val, val2);
571	case IIO_CHAN_INFO_CALIBBIAS:
572		return inv_icm45600_gyro_read_offset(st, chan, val, val2);
573	default:
574		return -EINVAL;
575	}
576}
577
578static int inv_icm45600_gyro_read_avail(struct iio_dev *indio_dev,
579					struct iio_chan_spec const *chan,
580					const int **vals,
581					int *type, int *length, long mask)
582{
583	struct inv_icm45600_sensor_state *gyro_st = iio_priv(indio_dev);
584
585	if (chan->type != IIO_ANGL_VEL)
586		return -EINVAL;
587
588	switch (mask) {
589	case IIO_CHAN_INFO_SCALE:
590		*vals = gyro_st->scales;
591		*type = IIO_VAL_INT_PLUS_NANO;
592		*length = gyro_st->scales_len;
593		return IIO_AVAIL_LIST;
594	case IIO_CHAN_INFO_SAMP_FREQ:
595		*vals = inv_icm45600_gyro_odr;
596		*type = IIO_VAL_INT_PLUS_MICRO;
597		*length = ARRAY_SIZE(inv_icm45600_gyro_odr);
598		return IIO_AVAIL_LIST;
599	case IIO_CHAN_INFO_CALIBBIAS:
600		*vals = inv_icm45600_gyro_calibbias;
601		*type = IIO_VAL_INT_PLUS_NANO;
602		return IIO_AVAIL_RANGE;
603	default:
604		return -EINVAL;
605	}
606}
607
608static int inv_icm45600_gyro_write_raw(struct iio_dev *indio_dev,
609				       struct iio_chan_spec const *chan,
610				       int val, int val2, long mask)
611{
612	struct inv_icm45600_state *st = iio_device_get_drvdata(indio_dev);
613	int ret;
614
615	if (chan->type != IIO_ANGL_VEL)
616		return -EINVAL;
617
618	switch (mask) {
619	case IIO_CHAN_INFO_SCALE:
620		if (!iio_device_claim_direct(indio_dev))
621			return -EBUSY;
622		ret = inv_icm45600_gyro_write_scale(indio_dev, val, val2);
623		iio_device_release_direct(indio_dev);
624		return ret;
625	case IIO_CHAN_INFO_SAMP_FREQ:
626		return inv_icm45600_gyro_write_odr(indio_dev, val, val2);
627	case IIO_CHAN_INFO_CALIBBIAS:
628		if (!iio_device_claim_direct(indio_dev))
629			return -EBUSY;
630		ret = inv_icm45600_gyro_write_offset(st, chan, val, val2);
631		iio_device_release_direct(indio_dev);
632		return ret;
633	default:
634		return -EINVAL;
635	}
636}
637
638static int inv_icm45600_gyro_write_raw_get_fmt(struct iio_dev *indio_dev,
639					       struct iio_chan_spec const *chan,
640					       long mask)
641{
642	if (chan->type != IIO_ANGL_VEL)
643		return -EINVAL;
644
645	switch (mask) {
646	case IIO_CHAN_INFO_SCALE:
647		return IIO_VAL_INT_PLUS_NANO;
648	case IIO_CHAN_INFO_SAMP_FREQ:
649		return IIO_VAL_INT_PLUS_MICRO;
650	case IIO_CHAN_INFO_CALIBBIAS:
651		return IIO_VAL_INT_PLUS_NANO;
652	default:
653		return -EINVAL;
654	}
655}
656
657static int inv_icm45600_gyro_hwfifo_set_watermark(struct iio_dev *indio_dev,
658						  unsigned int val)
659{
660	struct inv_icm45600_state *st = iio_device_get_drvdata(indio_dev);
661
662	guard(mutex)(&st->lock);
663
664	st->fifo.watermark.gyro = val;
665	return inv_icm45600_buffer_update_watermark(st);
666}
667
668static int inv_icm45600_gyro_hwfifo_flush(struct iio_dev *indio_dev,
669					  unsigned int count)
670{
671	struct inv_icm45600_state *st = iio_device_get_drvdata(indio_dev);
672	int ret;
673
674	if (count == 0)
675		return 0;
676
677	guard(mutex)(&st->lock);
678
679	ret = inv_icm45600_buffer_hwfifo_flush(st, count);
680	if (ret)
681		return ret;
682
683	return st->fifo.nb.gyro;
684}
685
686static const struct iio_info inv_icm45600_gyro_info = {
687	.read_raw = inv_icm45600_gyro_read_raw,
688	.read_avail = inv_icm45600_gyro_read_avail,
689	.write_raw = inv_icm45600_gyro_write_raw,
690	.write_raw_get_fmt = inv_icm45600_gyro_write_raw_get_fmt,
691	.debugfs_reg_access = inv_icm45600_debugfs_reg,
692	.update_scan_mode = inv_icm45600_gyro_update_scan_mode,
693	.hwfifo_set_watermark = inv_icm45600_gyro_hwfifo_set_watermark,
694	.hwfifo_flush_to_buffer = inv_icm45600_gyro_hwfifo_flush,
695};
696
697struct iio_dev *inv_icm45600_gyro_init(struct inv_icm45600_state *st)
698{
699	struct device *dev = regmap_get_device(st->map);
700	struct inv_icm45600_sensor_state *gyro_st;
701	struct inv_sensors_timestamp_chip ts_chip;
702	struct iio_dev *indio_dev;
703	const char *name;
704	int ret;
705
706	name = devm_kasprintf(dev, GFP_KERNEL, "%s-gyro", st->chip_info->name);
707	if (!name)
708		return ERR_PTR(-ENOMEM);
709
710	indio_dev = devm_iio_device_alloc(dev, sizeof(*gyro_st));
711	if (!indio_dev)
712		return ERR_PTR(-ENOMEM);
713	gyro_st = iio_priv(indio_dev);
714
715	gyro_st->scales = st->chip_info->gyro_scales;
716	gyro_st->scales_len = st->chip_info->gyro_scales_len * 2;
717
718	/* low-noise by default at init */
719	gyro_st->power_mode = INV_ICM45600_SENSOR_MODE_LOW_NOISE;
720
721	/*
722	 * clock period is 32kHz (31250ns)
723	 * jitter is +/- 2% (20 per mille)
724	 */
725	ts_chip.clock_period = 31250;
726	ts_chip.jitter = 20;
727	ts_chip.init_period = inv_icm45600_odr_to_period(st->conf.gyro.odr);
728	inv_sensors_timestamp_init(&gyro_st->ts, &ts_chip);
729
730	iio_device_set_drvdata(indio_dev, st);
731	indio_dev->name = name;
732	indio_dev->info = &inv_icm45600_gyro_info;
733	indio_dev->modes = INDIO_DIRECT_MODE;
734	indio_dev->channels = inv_icm45600_gyro_channels;
735	indio_dev->num_channels = ARRAY_SIZE(inv_icm45600_gyro_channels);
736	indio_dev->available_scan_masks = inv_icm45600_gyro_scan_masks;
737	indio_dev->setup_ops = &inv_icm45600_buffer_ops;
738
739	ret = devm_iio_kfifo_buffer_setup(dev, indio_dev,
740					  &inv_icm45600_buffer_ops);
741	if (ret)
742		return ERR_PTR(ret);
743
744	ret = devm_iio_device_register(dev, indio_dev);
745	if (ret)
746		return ERR_PTR(ret);
747
748	return indio_dev;
749}
750
751int inv_icm45600_gyro_parse_fifo(struct iio_dev *indio_dev)
752{
753	struct inv_icm45600_state *st = iio_device_get_drvdata(indio_dev);
754	struct inv_icm45600_sensor_state *gyro_st = iio_priv(indio_dev);
755	struct inv_sensors_timestamp *ts = &gyro_st->ts;
756	ssize_t i, size;
757	unsigned int no;
758
759	/* parse all fifo packets */
760	for (i = 0, no = 0; i < st->fifo.count; i += size, ++no) {
761		struct inv_icm45600_gyro_buffer buffer = { };
762		const struct inv_icm45600_fifo_sensor_data *accel, *gyro;
763		const __le16 *timestamp;
764		const s8 *temp;
765		unsigned int odr;
766		s64 ts_val;
767
768		size = inv_icm45600_fifo_decode_packet(&st->fifo.data[i],
769				&accel, &gyro, &temp, &timestamp, &odr);
770		/* quit if error or FIFO is empty */
771		if (size <= 0)
772			return size;
773
774		/* skip packet if no gyro data or data is invalid */
775		if (gyro == NULL || !inv_icm45600_fifo_is_data_valid(gyro))
776			continue;
777
778		/* update odr */
779		if (odr & INV_ICM45600_SENSOR_GYRO)
780			inv_sensors_timestamp_apply_odr(ts, st->fifo.period,
781							st->fifo.nb.total, no);
782
783		memcpy(&buffer.gyro, gyro, sizeof(buffer.gyro));
784		/* convert 8 bits FIFO temperature in high resolution format */
785		buffer.temp = temp ? (*temp * 64) : 0;
786		ts_val = inv_sensors_timestamp_pop(ts);
787		iio_push_to_buffers_with_ts(indio_dev, &buffer, sizeof(buffer), ts_val);
788	}
789
790	return 0;
791}
~/ Read-only file preview.