linux-iio.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: "Sa, Nuno" <Nuno.Sa@analog.com>
To: Lars-Peter Clausen <lars@metafoo.de>,
	"linux-iio@vger.kernel.org" <linux-iio@vger.kernel.org>,
	"devicetree@vger.kernel.org" <devicetree@vger.kernel.org>
Cc: Jonathan Cameron <jic23@kernel.org>,
	Hartmut Knaack <knaack.h@gmx.de>,
	Peter Meerwald-Stadler <pmeerw@pmeerw.net>,
	Rob Herring <robh+dt@kernel.org>,
	Mark Rutland <mark.rutland@arm.com>,
	"Ardelean, Alexandru" <alexandru.Ardelean@analog.com>,
	"Hennerich, Michael" <Michael.Hennerich@analog.com>
Subject: RE: [PATCH v2 5/6] iio: imu: Add support for adis16475
Date: Tue, 17 Mar 2020 16:40:50 +0000	[thread overview]
Message-ID: <BN6PR03MB334727AEEEDD8FDC424A633E99F60@BN6PR03MB3347.namprd03.prod.outlook.com> (raw)
In-Reply-To: <07c41ab8-7b09-0eb3-ce9d-d7773f5186b8@metafoo.de>


> -----Original Message-----
> From: Lars-Peter Clausen <lars@metafoo.de>
> Sent: Montag, 16. März 2020 15:27
> To: Sa, Nuno <Nuno.Sa@analog.com>; linux-iio@vger.kernel.org;
> devicetree@vger.kernel.org
> Cc: Jonathan Cameron <jic23@kernel.org>; Hartmut Knaack
> <knaack.h@gmx.de>; Peter Meerwald-Stadler <pmeerw@pmeerw.net>; Rob
> Herring <robh+dt@kernel.org>; Mark Rutland <mark.rutland@arm.com>;
> Ardelean, Alexandru <alexandru.Ardelean@analog.com>; Hennerich, Michael
> <Michael.Hennerich@analog.com>
> Subject: Re: [PATCH v2 5/6] iio: imu: Add support for adis16475
> 
> On 3/16/20 1:53 PM, Nuno Sá wrote:
> > Support ADIS16475 and similar IMU devices. These devices are
> > a precision, miniature MEMS inertial measurement unit (IMU) that
> > includes a triaxial gyroscope and a triaxial accelerometer. Each
> > inertial sensor combines with signal conditioning that optimizes
> > dynamic performance.
> >
> > The driver adds support for the following devices:
> >   * adis16470, adis16475, adis16477, adis16465, adis16467, adis16500,
> >     adis16505, adis16507.
> >
> Looks very good, just a few comments and questions. I like the solution
> for the 32-bit registers.
> 
> > +static int adis16475_set_freq(struct adis16475 *st, const u32 freq)
> > +{
> > +	u16 dec;
> > +	int ret;
> > +
> > +	if (freq == 0 || freq > st->clk_freq)
> > +		return -EINVAL;
> 
> Maybe round down if freq is larger the maximum rate. I believe we do
> that same for other drivers.

Can do that...

> > +
> > +	dec = DIV_ROUND_CLOSEST(st->clk_freq, freq);
> > +
> > +	if (dec)
> > +		dec--;
> > +
> > +	if (dec > st->info->max_dec)
> > +		dec = st->info->max_dec;
> > +
> > +	ret = adis_write_reg_16(&st->adis, ADIS16475_REG_DEC_RATE, dec);
> > +	if (ret)
> > +		return ret;
> > +
> > +	/*
> > +	 * If decimation is used, then gyro and accel data will have meaningfull
> Typo: "meaningful"

Ack

> > +	 * bits on the LSB registers. This info is used on the trigger handler.
> > +	 */
> > +	if (!dec)
> > +		clear_bit(ADIS16475_LSB_DEC_MASK, &st->lsb_flag);
> > +	else
> > +		set_bit(ADIS16475_LSB_DEC_MASK, &st->lsb_flag);
> > +
> > +	return 0;
> > +}
> > +
> > +/* The values are approximated. */
> > +static const u32 adis16475_3db_freqs[] = {
> > +	[0] = 720, /* Filter disabled, full BW (~720Hz) */
> > +	[1] = 360,
> > +	[2] = 164,
> 
> 164 is the only one that does not follow the pattern of 720 / (2**n).
> Not sure if that is on purpose. But either way where did you find the
> bandwidths for the different filter settings? I had a quick look at the
> datasheet and could not find anything.
> 

So, when I started the driver and looked to other examples I also wondered about
this. So, basically I asked (internally) about this table to the Application engineer
responsible for this parts and got an excel sheet with this values calculated for a
sampling rate of 2khz.

> Maybe it also makes sense to consider the clock rate when running in
> sync mode as the bandwidth will be a function of the sampling rate.
> 

Hmm, that is true. The sampling rate also contributes to the system bandwidth
Need to check if we can calculate this in the kernel though...

> > +	[3] = 80,
> > +	[4] = 40,
> > +	[5] = 20,
> > +	[6] = 10,
> > +	[7] = 10, /* not a valid setting */
> > +};
> > +
> > +static int adis16475_get_filter(struct adis16475 *st, u32 *filter)
> > +{
> > +	u16 filter_sz;
> > +	int ret;
> > +	const int mask = ADIS16475_FILT_CTRL_MASK;
> > +
> > +	ret = adis_read_reg_16(&st->adis, ADIS16475_REG_FILT_CTRL,
> &filter_sz);
> > +	if (ret)
> > +		return ret;
> > +
> > +	*filter = adis16475_3db_freqs[filter_sz & mask];
> > +
> > +	return 0;
> > +}
> > +
> > +static int adis16475_set_filter(struct adis16475 *st, const u32 filter)
> > +{
> > +	int i;
> > +	int ret;
> > +
> > +	for (i = ARRAY_SIZE(adis16475_3db_freqs) - 1; i >= 1; i--) {
> > +		if (adis16475_3db_freqs[i] >= filter)
> > +			break;
> > +	}
> 
> If the filter frequency is less or equal to 10, this will pick 7 for i.
> But the comment above says that it is an invalid setting.
> 

Good catch! I believe the part will just automatically convert it to 6. Either way,
better play safe.

> >
> > +static u16 adis16475_validate_crc(const u8 *buffer, const u16 crc,
> > +				  const bool burst32)
> Return type is u16, but the return value is bool. Also validate kind of
> suggests that it returns true if valid, but right now it returns true if
> invalid.
> > +{
> > +	int i;
> > +	u16 __crc = 0;
> 
> I find having both __crc and crc a bit confusing, maybe give them names
> which better describe them. Maybe computed_crc or expected_crc. Or as an
> alternative I think also just crc -= buffer[i] in the loop and crc != 0
> at the end should work.
> 

Hmm, I like the alternative...

> 
> > +	/* extra 6 elements for low gyro and accel */
> > +	const u16 sz = burst32 ? ADIS16475_BURST32_MAX_DATA :
> > +		ADIS16475_BURST_MAX_DATA;
> > +
> > +	for (i = 0; i < sz - 2; i++)
> > +		__crc += buffer[i];
> > +
> > +	return (__crc != crc);
> > +}
> > +
> > +static void adis16475_burst32_check(struct adis16475 *st)
> > +{
> > +	int ret;
> > +	struct adis *adis = &st->adis;
> > +
> > +	if (!st->info->has_burst32)
> > +		return;
> > +
> > +	if (st->lsb_flag && !st->burst32) {
> > +		const u16 en = ADIS16500_BURST32(1);
> > +
> > +		ret = __adis_update_bits(&st->adis,
> ADIS16475_REG_MSG_CTRL,
> > +					 ADIS16500_BURST32_MASK, en);
> > +		if (ret < 0)
> > +			return;
> > +
> > +		st->burst32 = true;
> > +		/*
> > +		 * In 32bit mode we need extra 2 bytes for all gyro
> > +		 * and accel channels.
> > +		 */
> > +		adis->burst->extra_len += 6 * sizeof(u16);
> 
> I believe this breaks if you have more than one device instance as
> adis->burst points to a global struct that is shared between all
> instances. extra_len should probably be part of the adis struct itself
> and then make the burst field const.
> 

Ups, definitely a problem! This extra_len is actually something that I don't like. I have
some local patches to get rid of this variable. So, burst_len is being calculated like this

/* All but the timestamp channel */
burst_length = (indio_dev->num_channels - 1) * sizeof(u16);
burst_length += adis->burst->extra_len;

This is done in the library which in my opinion is wrong. The library should not assume that
a timestamp channel is defined. IMHO, it would be just simpler and direct if users define burst_len
directly (replacing extra_len) which is actually constant in a lot of devices...

Either way, we still need a variable in the adis struct which can actually change per "instance"...
Maybe I just go with your suggestion and leave the replacement of extra_len for a future patch.

- Nuno Sá

  reply	other threads:[~2020-03-17 16:41 UTC|newest]

Thread overview: 15+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-03-16 12:53 [PATCH v2 0/6] Support ADIS16475 and similar IMUs Nuno Sá
2020-03-16 12:53 ` [PATCH v2 1/6] iio: imu: adis: Add Managed device functions Nuno Sá
2020-03-16 14:27   ` Lars-Peter Clausen
2020-03-16 12:53 ` [PATCH v2 2/6] iio: imu: adis: Add irq mask variable Nuno Sá
2020-03-16 13:31   ` Lars-Peter Clausen
2020-03-16 12:53 ` [PATCH v2 3/6] iio: adis: Add adis_update_bits() APIs Nuno Sá
2020-03-22 18:15   ` Jonathan Cameron
2020-03-16 12:53 ` [PATCH v2 4/6] iio: adis: Add burst_max_len variable Nuno Sá
2020-03-16 12:53 ` [PATCH v2 5/6] iio: imu: Add support for adis16475 Nuno Sá
2020-03-16 14:26   ` Lars-Peter Clausen
2020-03-17 16:40     ` Sa, Nuno [this message]
2020-03-16 12:53 ` [PATCH v2 6/6] dt-bindings: iio: Add adis16475 documentation Nuno Sá
2020-03-22 18:23   ` Jonathan Cameron
2020-03-30 20:32   ` Rob Herring
2020-03-31  9:11     ` Sa, Nuno

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=BN6PR03MB334727AEEEDD8FDC424A633E99F60@BN6PR03MB3347.namprd03.prod.outlook.com \
    --to=nuno.sa@analog.com \
    --cc=Michael.Hennerich@analog.com \
    --cc=alexandru.Ardelean@analog.com \
    --cc=devicetree@vger.kernel.org \
    --cc=jic23@kernel.org \
    --cc=knaack.h@gmx.de \
    --cc=lars@metafoo.de \
    --cc=linux-iio@vger.kernel.org \
    --cc=mark.rutland@arm.com \
    --cc=pmeerw@pmeerw.net \
    --cc=robh+dt@kernel.org \
    /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).