[PATCH V13 8/9] iio: imu: inv_icm42607: Add Gyroscope to icm42607

Chris Morgan macromorgan at hotmail.com
Mon Jun 22 19:37:04 PDT 2026


On Sun, Jun 21, 2026 at 06:34:08PM +0100, Jonathan Cameron wrote:
> On Mon, 15 Jun 2026 12:25:51 -0500
> Chris Morgan <macroalpha82 at gmail.com> wrote:
> 
> > From: Chris Morgan <macromorgan at hotmail.com>
> > 
> > Add gyroscope functions to the icm42607 driver.
> > 
> > Signed-off-by: Chris Morgan <macromorgan at hotmail.com>
> There is another bit of sashiko stuff in here. Please
> take a look
> https://sashiko.dev/#/patchset/20260615172554.160910-1-macroalpha82%40gmail.com
> 
> I think it is correct about there being a path in which the
> gyro ends up always enabled along side anything else after
> the first read.
> 
> In general there seems to be a bit of mix on whether the caller
> or the power management function should be responsible for the caching
> of state.
> 
> I know you look at Sashiko so I could just have waited a bit, but
> I was reviewing anyway so took a look and having done that might
> as well highlight some stuff!
> 
> Jonathan
> 
> > diff --git a/drivers/iio/imu/inv_icm42607/inv_icm42607_core.c b/drivers/iio/imu/inv_icm42607/inv_icm42607_core.c
> > index eb239987a1ce..23ca7529825c 100644
> > --- a/drivers/iio/imu/inv_icm42607/inv_icm42607_core.c
> > +++ b/drivers/iio/imu/inv_icm42607/inv_icm42607_core.c
> > @@ -218,6 +218,49 @@ int inv_icm42607_set_accel_conf(struct inv_icm42607_state *st,
> >  					  st->conf.temp_en, sleep_ms);
> >  }
> >  
> > +int inv_icm42607_set_gyro_conf(struct inv_icm42607_state *st,
> > +			       struct inv_icm42607_sensor_conf *conf,
> > +			       unsigned int *sleep_ms)
> > +{
> > +	struct inv_icm42607_sensor_conf *oldconf = &st->conf.gyro;
> > +	unsigned int val;
> > +	int ret;
> > +
> > +	if (conf->mode < 0)
> > +		conf->mode = oldconf->mode;
> > +	if (conf->fs < 0)
> > +		conf->fs = oldconf->fs;
> > +	if (conf->odr < 0)
> > +		conf->odr = oldconf->odr;
> > +	if (conf->filter < 0)
> > +		conf->filter = oldconf->filter;
> > +
> > +	if (conf->fs != oldconf->fs || conf->odr != oldconf->odr) {
> > +		val = FIELD_PREP(INV_ICM42607_GYRO_CONFIG0_FS_SEL_MASK,
> > +				 conf->fs);
> > +		val |= FIELD_PREP(INV_ICM42607_GYRO_CONFIG0_ODR_MASK,
> > +				  conf->odr);
> > +		ret = regmap_write(st->map, INV_ICM42607_REG_GYRO_CONFIG0, val);
> > +		if (ret)
> > +			return ret;
> > +		oldconf->fs = conf->fs;
> > +		oldconf->odr = conf->odr;
> > +	}
> > +
> > +	if (conf->filter != oldconf->filter) {
> > +		val = FIELD_PREP(INV_ICM42607_GYRO_CONFIG1_FILTER_MASK,
> > +				 conf->filter);
> > +		ret = regmap_update_bits(st->map, INV_ICM42607_REG_GYRO_CONFIG1,
> > +					 INV_ICM42607_GYRO_CONFIG1_FILTER_MASK, val);
> > +		if (ret)
> > +			return ret;
> > +		oldconf->filter = conf->filter;
> > +	}
> > +
> > +	return inv_icm42607_set_pwr_mgmt0(st, conf->mode, st->conf.accel.mode,
> > +					  st->conf.temp_en, sleep_ms);
> > +}
> 
> > diff --git a/drivers/iio/imu/inv_icm42607/inv_icm42607_gyro.c b/drivers/iio/imu/inv_icm42607/inv_icm42607_gyro.c
> > new file mode 100644
> > index 000000000000..ef73560b39d7
> > --- /dev/null
> > +++ b/drivers/iio/imu/inv_icm42607/inv_icm42607_gyro.c
> 
> > +static int inv_icm42607_gyro_read_sensor(struct iio_dev *indio_dev,
> > +					 struct iio_chan_spec const *chan,
> > +					 s16 *val)
> > +{
> > +	struct inv_icm42607_sensor_conf conf = INV_ICM42607_SENSOR_CONF_INIT;
> > +	struct inv_icm42607_state *st = iio_device_get_drvdata(indio_dev);
> > +	struct inv_icm42607_sensor_state *gyro_st = iio_priv(indio_dev);
> > +	struct device *dev = regmap_get_device(st->map);
> > +	unsigned int reg;
> > +	u8 data[2];
> > +	int ret;
> > +
> > +	if (chan->type != IIO_ANGL_VEL)
> > +		return -EINVAL;
> > +
> > +	switch (chan->channel2) {
> > +	case IIO_MOD_X:
> > +		reg = INV_ICM42607_REG_GYRO_DATA_X1;
> > +		break;
> > +	case IIO_MOD_Y:
> > +		reg = INV_ICM42607_REG_GYRO_DATA_Y1;
> > +		break;
> > +	case IIO_MOD_Z:
> > +		reg = INV_ICM42607_REG_GYRO_DATA_Z1;
> > +		break;
> > +	default:
> > +		return -EINVAL;
> > +	}
> > +
> > +	PM_RUNTIME_ACQUIRE_AUTOSUSPEND(dev, pm);
> > +	ret = PM_RUNTIME_ACQUIRE_ERR(&pm);
> > +	if (ret)
> > +		return ret;
> > +
> > +	guard(mutex)(&st->lock);
> > +
> > +	/* enable gyro sensor */
> > +	conf.mode = gyro_st->power_mode;
> > +	conf.filter = gyro_st->filter;
> > +	ret = inv_icm42607_set_gyro_conf(st, &conf, NULL);
> The sashiko report is basically:
> 
> This turns it on, and runtime pm will turn it off but the
> state cached ends up such that it is turned on again for
> any runtime pm resume.

Yep, for this and for the accel sensor it looks like it gets stuck on.
I've revamped this code for the next round and so far it looks like the
sensor is powering down correctly.

> 
> > +	if (ret)
> > +		return ret;
> > +
> > +	/* read gyro register data */
> > +	ret = regmap_bulk_read(st->map, reg, data, sizeof(data));
> > +	if (ret)
> > +		return ret;
> > +
> > +	*val = get_unaligned_be16(data);
> > +	if (*val == INV_ICM42607_DATA_INVALID)
> > +		return -EINVAL;
> > +
> > +	return 0;
> > +}
> 

Thank you,
Chris



More information about the Linux-rockchip mailing list