drivers/iio/imu/inv_icm45600/inv_icm45600_gyro.c

Source file repositories/reference/linux-study-clean/drivers/iio/imu/inv_icm45600/inv_icm45600_gyro.c

File Facts

System
Linux kernel
Corpus path
drivers/iio/imu/inv_icm45600/inv_icm45600_gyro.c
Extension
.c
Size
21675 bytes
Lines
792
Domain
Driver Families
Bucket
drivers/iio
Inferred role
Driver Families: implementation source
Status
source implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

struct inv_icm45600_gyro_buffer {
	struct inv_icm45600_fifo_sensor_data gyro;
	s16 temp;
	aligned_s64 timestamp;
};

static const unsigned long inv_icm45600_gyro_scan_masks[] = {
	/* 3-axis gyro + temperature */
	BIT(INV_ICM45600_GYRO_SCAN_X) |
	BIT(INV_ICM45600_GYRO_SCAN_Y) |
	BIT(INV_ICM45600_GYRO_SCAN_Z) |
	BIT(INV_ICM45600_GYRO_SCAN_TEMP),
	0
};

/* enable gyroscope sensor and FIFO write */
static int inv_icm45600_gyro_update_scan_mode(struct iio_dev *indio_dev,
					      const unsigned long *scan_mask)
{
	struct inv_icm45600_state *st = iio_device_get_drvdata(indio_dev);
	struct inv_icm45600_sensor_state *gyro_st = iio_priv(indio_dev);
	struct inv_icm45600_sensor_conf conf = INV_ICM45600_SENSOR_CONF_KEEP_VALUES;
	unsigned int fifo_en = 0;
	unsigned int sleep = 0;
	int ret;

	scoped_guard(mutex, &st->lock) {
		if (*scan_mask & BIT(INV_ICM45600_GYRO_SCAN_TEMP))
			fifo_en |= INV_ICM45600_SENSOR_TEMP;

		if (*scan_mask & (BIT(INV_ICM45600_GYRO_SCAN_X) |
				 BIT(INV_ICM45600_GYRO_SCAN_Y) |
				 BIT(INV_ICM45600_GYRO_SCAN_Z))) {
			/* enable gyro sensor */
			conf.mode = gyro_st->power_mode;
			ret = inv_icm45600_set_gyro_conf(st, &conf, &sleep);
			if (ret)
				return ret;
			fifo_en |= INV_ICM45600_SENSOR_GYRO;
		}
		ret = inv_icm45600_buffer_set_fifo_en(st, fifo_en | st->fifo.en);
	}
	if (sleep)
		msleep(sleep);

	return ret;
}

static int _inv_icm45600_gyro_read_sensor(struct inv_icm45600_state *st,
					  struct inv_icm45600_sensor_state *gyro_st,
					  unsigned int reg, int *val)
{
	struct inv_icm45600_sensor_conf conf = INV_ICM45600_SENSOR_CONF_KEEP_VALUES;
	int ret;

	/* enable gyro sensor */
	conf.mode = gyro_st->power_mode;
	ret = inv_icm45600_set_gyro_conf(st, &conf, NULL);
	if (ret)
		return ret;

	/* read gyro register data */
	ret = regmap_bulk_read(st->map, reg, &st->buffer.u16, sizeof(st->buffer.u16));
	if (ret)
		return ret;

	*val = sign_extend32(le16_to_cpup(&st->buffer.u16), 15);
	if (*val == INV_ICM45600_DATA_INVALID)
		return -ENODATA;

	return 0;
}

static int inv_icm45600_gyro_read_sensor(struct iio_dev *indio_dev,
					 struct iio_chan_spec const *chan,
					 int *val)
{
	struct inv_icm45600_state *st = iio_device_get_drvdata(indio_dev);
	struct inv_icm45600_sensor_state *gyro_st = iio_priv(indio_dev);
	struct device *dev = regmap_get_device(st->map);
	unsigned int reg;
	int ret;

	if (chan->type != IIO_ANGL_VEL)
		return -EINVAL;

	switch (chan->channel2) {
	case IIO_MOD_X:
		reg = INV_ICM45600_REG_GYRO_DATA_X;
		break;

Annotation

Implementation Notes