drivers/iio/imu/inv_icm42600/inv_icm42600_accel.c

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

File Facts

System
Linux kernel
Corpus path
drivers/iio/imu/inv_icm42600/inv_icm42600_accel.c
Extension
.c
Size
33502 bytes
Lines
1246
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_accel_buffer {
	struct inv_icm42600_fifo_sensor_data accel;
	s16 temp;
	aligned_s64 timestamp;
};

#define INV_ICM42600_SCAN_MASK_ACCEL_3AXIS				\
	(BIT(INV_ICM42600_ACCEL_SCAN_X) |				\
	BIT(INV_ICM42600_ACCEL_SCAN_Y) |				\
	BIT(INV_ICM42600_ACCEL_SCAN_Z))

#define INV_ICM42600_SCAN_MASK_TEMP	BIT(INV_ICM42600_ACCEL_SCAN_TEMP)

static const unsigned long inv_icm42600_accel_scan_masks[] = {
	/* 3-axis accel + temperature */
	INV_ICM42600_SCAN_MASK_ACCEL_3AXIS | INV_ICM42600_SCAN_MASK_TEMP,
	0,
};

/* enable accelerometer sensor and FIFO write */
static int inv_icm42600_accel_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_state *accel_st = iio_priv(indio_dev);
	struct inv_icm42600_sensor_conf conf = INV_ICM42600_SENSOR_CONF_INIT;
	unsigned int fifo_en = 0;
	unsigned int sleep_temp = 0;
	unsigned int sleep_accel = 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_ACCEL_3AXIS) {
		/* enable accel sensor */
		conf.mode = accel_st->power_mode;
		conf.filter = accel_st->filter;
		ret = inv_icm42600_set_accel_conf(st, &conf, &sleep_accel);
		if (ret)
			goto out_unlock;
		fifo_en |= INV_ICM42600_SENSOR_ACCEL;
	}

	/* 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_accel, sleep_temp);
	if (sleep)
		msleep(sleep);
	return ret;
}

static int inv_icm42600_accel_read_sensor(struct iio_dev *indio_dev,
					  struct iio_chan_spec const *chan,
					  s16 *val)
{
	struct inv_icm42600_state *st = iio_device_get_drvdata(indio_dev);
	struct inv_icm42600_sensor_state *accel_st = iio_priv(indio_dev);
	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_ACCEL)
		return -EINVAL;

	switch (chan->channel2) {
	case IIO_MOD_X:
		reg = INV_ICM42600_REG_ACCEL_DATA_X;
		break;
	case IIO_MOD_Y:
		reg = INV_ICM42600_REG_ACCEL_DATA_Y;
		break;
	case IIO_MOD_Z:
		reg = INV_ICM42600_REG_ACCEL_DATA_Z;
		break;
	default:

Annotation

Implementation Notes