drivers/iio/imu/inv_icm42600/inv_icm42600_gyro.c

Source file repositories/reference/linux-study-clean/drivers/iio/imu/inv_icm42600/inv_icm42600_gyro.c

File Facts

System
Linux kernel
Corpus path
drivers/iio/imu/inv_icm42600/inv_icm42600_gyro.c
Extension
.c
Size
22409 bytes
Lines
827
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_icm42600_gyro_buffer {
	struct inv_icm42600_fifo_sensor_data gyro;
	s16 temp;
	aligned_s64 timestamp;
};

#define INV_ICM42600_SCAN_MASK_GYRO_3AXIS				\
	(BIT(INV_ICM42600_GYRO_SCAN_X) |				\
	BIT(INV_ICM42600_GYRO_SCAN_Y) |					\
	BIT(INV_ICM42600_GYRO_SCAN_Z))

#define INV_ICM42600_SCAN_MASK_TEMP	BIT(INV_ICM42600_GYRO_SCAN_TEMP)

static const unsigned long inv_icm42600_gyro_scan_masks[] = {
	/* 3-axis gyro + temperature */
	INV_ICM42600_SCAN_MASK_GYRO_3AXIS | INV_ICM42600_SCAN_MASK_TEMP,
	0,
};

/* enable gyroscope sensor and FIFO write */
static int inv_icm42600_gyro_update_scan_mode(struct iio_dev *indio_dev,
					      const unsigned long *scan_mask)
{
	struct inv_icm42600_state *st = iio_device_get_drvdata(indio_dev);
	struct inv_icm42600_sensor_conf conf = INV_ICM42600_SENSOR_CONF_INIT;
	unsigned int fifo_en = 0;
	unsigned int sleep_gyro = 0;
	unsigned int sleep_temp = 0;
	unsigned int sleep;
	int ret;

	mutex_lock(&st->lock);

	if (*scan_mask & INV_ICM42600_SCAN_MASK_TEMP) {
		/* enable temp sensor */
		ret = inv_icm42600_set_temp_conf(st, true, &sleep_temp);
		if (ret)
			goto out_unlock;
		fifo_en |= INV_ICM42600_SENSOR_TEMP;
	}

	if (*scan_mask & INV_ICM42600_SCAN_MASK_GYRO_3AXIS) {
		/* enable gyro sensor */
		conf.mode = INV_ICM42600_SENSOR_MODE_LOW_NOISE;
		ret = inv_icm42600_set_gyro_conf(st, &conf, &sleep_gyro);
		if (ret)
			goto out_unlock;
		fifo_en |= INV_ICM42600_SENSOR_GYRO;
	}

	/* update data FIFO write */
	ret = inv_icm42600_buffer_set_fifo_en(st, fifo_en | st->fifo.en);

out_unlock:
	mutex_unlock(&st->lock);
	/* sleep maximum required time */
	sleep = max(sleep_gyro, sleep_temp);
	if (sleep)
		msleep(sleep);
	return ret;
}

static int inv_icm42600_gyro_read_sensor(struct inv_icm42600_state *st,
					 struct iio_chan_spec const *chan,
					 s16 *val)
{
	struct device *dev = regmap_get_device(st->map);
	struct inv_icm42600_sensor_conf conf = INV_ICM42600_SENSOR_CONF_INIT;
	unsigned int reg;
	__be16 *data;
	int ret;

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

	switch (chan->channel2) {
	case IIO_MOD_X:
		reg = INV_ICM42600_REG_GYRO_DATA_X;
		break;
	case IIO_MOD_Y:
		reg = INV_ICM42600_REG_GYRO_DATA_Y;
		break;
	case IIO_MOD_Z:
		reg = INV_ICM42600_REG_GYRO_DATA_Z;
		break;
	default:
		return -EINVAL;
	}

	pm_runtime_get_sync(dev);

Annotation

Implementation Notes