linux-iio.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Jonathan Cameron <jic23@kernel.org>
To: Lorenzo Bianconi <lorenzo@kernel.org>
Cc: Mario Tesi <mario.tesi@st.com>,
	lorenzo.bianconi83@gmail.com, knaack.h@gmx.de, lars@metafoo.de,
	pmeerw@pmeerw.net, linux-iio@vger.kernel.org
Subject: Re: [PATCH] iio: imu: st_lsm6dsx: add odr calibration feature
Date: Sat, 12 Oct 2019 14:20:04 +0100	[thread overview]
Message-ID: <20191012142004.42cb7ce4@archlinux> (raw)
In-Reply-To: <20191007140727.GE3192@localhost.localdomain>

On Mon, 7 Oct 2019 16:07:27 +0200
Lorenzo Bianconi <lorenzo@kernel.org> wrote:

> > 	On LSM6DSO/LSM6DSR/LSM6DSOX/ASM330LHH and ISH330DHCX
> > 	devices it is possible to trim the hardware timestamp
> > 	resolution through the FREQ_FINE[7:0] bits of the
> > 	INTERNAL_FREQ_FINE register, which contains the difference
> > 	in percentage of the effective ODR (and timestamp rate)
> > 	with respect to the typical value.
> > 
> > 	The formula for calculating the effective ODR reported
> > 	in the application notes has been linearized to the first
> > 	order to simplify the calculation (pls. see note on source
> > 	code).
> > 
> > 	This change may be useful in the outcome of CTS
> > 	tests regarding the SingleSensorTests and the
> > 	SensorTest#testSensorTimeStamps for high ODRs
> > 
> > Signed-off-by: Mario Tesi <mario.tesi@st.com>  
> 
> Acked-by: Lorenzo Bianconi <lorenzo@kernel.org>
Hi.

The leading tabs on the commit message are a bit unusual,
but as far as I can tell the code is good.

Applied to the togreg branch of iio.git and pushed out
as testing for the autobuilders to play with it.

Thanks,

Jonathan

> 
> > ---
> >  drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h        |  4 ++++
> >  drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_buffer.c |  5 ++---
> >  drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c   | 23 +++++++++++++++++++++++
> >  3 files changed, 29 insertions(+), 3 deletions(-)
> > 
> > diff --git a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h
> > index 7485423..9a40587 100644
> > --- a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h
> > +++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h
> > @@ -153,12 +153,14 @@ struct st_lsm6dsx_fifo_ops {
> >   * @hr_timer: Hw timer resolution register info (addr + mask).
> >   * @fifo_en: Hw timer FIFO enable register info (addr + mask).
> >   * @decimator: Hw timer FIFO decimator register info (addr + mask).
> > + * @freq_fine: Difference in % of ODR with respect to the typical.
> >   */
> >  struct st_lsm6dsx_hw_ts_settings {
> >  	struct st_lsm6dsx_reg timer_en;
> >  	struct st_lsm6dsx_reg hr_timer;
> >  	struct st_lsm6dsx_reg fifo_en;
> >  	struct st_lsm6dsx_reg decimator;
> > +	u8 freq_fine;
> >  };
> >  
> >  /**
> > @@ -344,6 +346,7 @@ struct st_lsm6dsx_sensor {
> >   * @fifo_mode: FIFO operating mode supported by the device.
> >   * @suspend_mask: Suspended sensor bitmask.
> >   * @enable_mask: Enabled sensor bitmask.
> > + * @ts_gain: Hw timestamp rate after internal calibration.
> >   * @ts_sip: Total number of timestamp samples in a given pattern.
> >   * @sip: Total number of samples (acc/gyro/ts) in a given pattern.
> >   * @buff: Device read buffer.
> > @@ -365,6 +368,7 @@ struct st_lsm6dsx_hw {
> >  	enum st_lsm6dsx_fifo_mode fifo_mode;
> >  	u8 suspend_mask;
> >  	u8 enable_mask;
> > +	s64 ts_gain;
> >  	u8 ts_sip;
> >  	u8 sip;
> >  
> > diff --git a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_buffer.c b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_buffer.c
> > index cabd4bf..d7cacb9 100644
> > --- a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_buffer.c
> > +++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_buffer.c
> > @@ -50,7 +50,6 @@
> >  
> >  #define ST_LSM6DSX_MAX_FIFO_ODR_VAL		0x08
> >  
> > -#define ST_LSM6DSX_TS_SENSITIVITY		25000UL /* 25us */
> >  #define ST_LSM6DSX_TS_RESET_VAL			0xaa
> >  
> >  struct st_lsm6dsx_decimator_entry {
> > @@ -423,7 +422,7 @@ int st_lsm6dsx_read_fifo(struct st_lsm6dsx_hw *hw)
> >  				 */
> >  				if (!reset_ts && ts >= 0xff0000)
> >  					reset_ts = true;
> > -				ts *= ST_LSM6DSX_TS_SENSITIVITY;
> > +				ts *= hw->ts_gain;
> >  
> >  				offset += ST_LSM6DSX_SAMPLE_SIZE;
> >  			}
> > @@ -566,7 +565,7 @@ int st_lsm6dsx_read_tagged_fifo(struct st_lsm6dsx_hw *hw)
> >  				 */
> >  				if (!reset_ts && ts >= 0xffff0000)
> >  					reset_ts = true;
> > -				ts *= ST_LSM6DSX_TS_SENSITIVITY;
> > +				ts *= hw->ts_gain;
> >  			} else {
> >  				st_lsm6dsx_push_tagged_data(hw, tag, iio_buff,
> >  							    ts);
> > diff --git a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c
> > index bacc908..2b54ce1 100644
> > --- a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c
> > +++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c
> > @@ -63,6 +63,8 @@
> >  
> >  #define ST_LSM6DSX_REG_WHOAMI_ADDR		0x0f
> >  
> > +#define ST_LSM6DSX_TS_SENSITIVITY		25000UL /* 25us */
> > +
> >  static const struct iio_chan_spec st_lsm6dsx_acc_channels[] = {
> >  	ST_LSM6DSX_CHANNEL_ACC(IIO_ACCEL, 0x28, IIO_MOD_X, 0),
> >  	ST_LSM6DSX_CHANNEL_ACC(IIO_ACCEL, 0x2a, IIO_MOD_Y, 1),
> > @@ -832,6 +834,7 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = {
> >  				.addr = 0x0a,
> >  				.mask = GENMASK(7, 6),
> >  			},
> > +			.freq_fine = 0x63,
> >  		},
> >  		.shub_settings = {
> >  			.page_mux = {
> > @@ -1020,6 +1023,7 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = {
> >  				.addr = 0x0a,
> >  				.mask = GENMASK(7, 6),
> >  			},
> > +			.freq_fine = 0x63,
> >  		},
> >  		.event_settings = {
> >  			.enable_reg = {
> > @@ -1185,6 +1189,7 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = {
> >  				.addr = 0x0a,
> >  				.mask = GENMASK(7, 6),
> >  			},
> > +			.freq_fine = 0x63,
> >  		},
> >  		.shub_settings = {
> >  			.page_mux = {
> > @@ -1874,6 +1879,24 @@ static int st_lsm6dsx_init_hw_timer(struct st_lsm6dsx_hw *hw)
> >  		if (err < 0)
> >  			return err;
> >  	}
> > +
> > +	/* calibrate timestamp sensitivity */
> > +	hw->ts_gain = ST_LSM6DSX_TS_SENSITIVITY;
> > +	if (ts_settings->freq_fine) {
> > +		err = regmap_read(hw->regmap, ts_settings->freq_fine, &val);
> > +		if (err < 0)
> > +			return err;
> > +
> > +		/*
> > +		 * linearize the AN5192 formula:
> > +		 * 1 / (1 + x) ~= 1 - x (Taylor’s Series)
> > +		 * ttrim[s] = 1 / (40000 * (1 + 0.0015 * val))
> > +		 * ttrim[ns] ~= 25000 - 37.5 * val
> > +		 * ttrim[ns] ~= 25000 - (37500 * val) / 1000
> > +		 */
> > +		hw->ts_gain -= ((s8)val * 37500) / 1000;
> > +	}
> > +
> >  	return 0;
> >  }
> >  
> > -- 
> > 2.7.4
> >   


      reply	other threads:[~2019-10-12 13:20 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-10-07 13:56 [PATCH] iio: imu: st_lsm6dsx: add odr calibration feature Mario Tesi
2019-10-07 14:07 ` Lorenzo Bianconi
2019-10-12 13:20   ` Jonathan Cameron [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20191012142004.42cb7ce4@archlinux \
    --to=jic23@kernel.org \
    --cc=knaack.h@gmx.de \
    --cc=lars@metafoo.de \
    --cc=linux-iio@vger.kernel.org \
    --cc=lorenzo.bianconi83@gmail.com \
    --cc=lorenzo@kernel.org \
    --cc=mario.tesi@st.com \
    --cc=pmeerw@pmeerw.net \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).