drivers/iio/imu/inv_icm45600/inv_icm45600_core.c

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

File Facts

System
Linux kernel
Corpus path
drivers/iio/imu/inv_icm45600/inv_icm45600_core.c
Extension
.c
Size
28031 bytes
Lines
995
Domain
Driver Families
Bucket
drivers/iio
Inferred role
Driver Families: exported/initcall integration point
Status
integration 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

if (conf->odr <= INV_ICM45600_ODR_800HZ_LN) {
			conf->mode = INV_ICM45600_SENSOR_MODE_LOW_NOISE;
		} else {
			conf->mode = INV_ICM45600_SENSOR_MODE_LOW_POWER;
			/* sanitize averaging value depending on ODR for low-power mode */
			/* maximum 1x @400Hz */
			if (conf->odr == INV_ICM45600_ODR_400HZ)
				conf->filter = INV_ICM45600_ACCEL_LP_AVG_SEL_1X;
			else
				conf->filter = INV_ICM45600_ACCEL_LP_AVG_SEL_4X;
		}
	}

	/* Set accel fullscale & odr. */
	if (conf->fs != oldconf->fs || conf->odr != oldconf->odr) {
		val = FIELD_PREP(INV_ICM45600_ACCEL_CONFIG0_FS_MASK, conf->fs) |
		      FIELD_PREP(INV_ICM45600_ACCEL_CONFIG0_ODR_MASK, conf->odr);
		ret = regmap_write(st->map, INV_ICM45600_REG_ACCEL_CONFIG0, val);
		if (ret)
			return ret;
		oldconf->fs = conf->fs;
		oldconf->odr = conf->odr;
	}

	/* Set accel low-power average filter. */
	if (conf->filter != oldconf->filter) {
		ret = regmap_write(st->map, INV_ICM45600_IPREG_SYS2_REG_129,
				   conf->filter);
		if (ret)
			return ret;
		oldconf->filter = conf->filter;
	}

	/* Update the sensor accel mode. */
	return inv_icm45600_set_pwr_mgmt0(st, st->conf.gyro.mode, conf->mode,
					  sleep_ms);
}

int inv_icm45600_set_gyro_conf(struct inv_icm45600_state *st,
			       struct inv_icm45600_sensor_conf *conf,
			       unsigned int *sleep_ms)
{
	struct inv_icm45600_sensor_conf *oldconf = &st->conf.gyro;
	unsigned int val;
	int ret;

	inv_icm45600_set_default_conf(conf, oldconf);

	/* Force the power mode against ODR when sensor is on. */
	if (conf->mode > INV_ICM45600_SENSOR_MODE_STANDBY) {
		if (conf->odr >= INV_ICM45600_ODR_6_25HZ_LP) {
			conf->mode = INV_ICM45600_SENSOR_MODE_LOW_POWER;
			conf->filter = INV_ICM45600_GYRO_LP_AVG_SEL_8X;
		} else {
			conf->mode = INV_ICM45600_SENSOR_MODE_LOW_NOISE;
		}
	}

	/* Set gyro fullscale & odr. */
	if (conf->fs != oldconf->fs || conf->odr != oldconf->odr) {
		val = FIELD_PREP(INV_ICM45600_GYRO_CONFIG0_FS_MASK, conf->fs) |
		      FIELD_PREP(INV_ICM45600_GYRO_CONFIG0_ODR_MASK, conf->odr);
		ret = regmap_write(st->map, INV_ICM45600_REG_GYRO_CONFIG0, val);
		if (ret)
			return ret;
		oldconf->fs = conf->fs;
		oldconf->odr = conf->odr;
	}

	/* Set gyro low-power average filter. */
	if (conf->filter != oldconf->filter) {
		val = FIELD_PREP(INV_ICM45600_IPREG_SYS1_170_GYRO_LP_AVG_MASK, conf->filter);
		ret = regmap_update_bits(st->map, INV_ICM45600_IPREG_SYS1_REG_170,
					 INV_ICM45600_IPREG_SYS1_170_GYRO_LP_AVG_MASK, val);
		if (ret)
			return ret;
		oldconf->filter = conf->filter;
	}

	/* Update the sensor gyro mode. */
	return inv_icm45600_set_pwr_mgmt0(st, conf->mode, st->conf.accel.mode,
					  sleep_ms);
}

int inv_icm45600_debugfs_reg(struct iio_dev *indio_dev, unsigned int reg,
			     unsigned int writeval, unsigned int *readval)
{
	struct inv_icm45600_state *st = iio_device_get_drvdata(indio_dev);

	guard(mutex)(&st->lock);

Annotation

Implementation Notes