linux-iio.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Lars-Peter Clausen <lars@metafoo.de>
To: "Nuno Sá" <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>,
	Alexandru Ardelean <alexandru.ardelean@analog.com>,
	Michael Hennerich <Michael.Hennerich@analog.com>
Subject: Re: [PATCH v2 5/6] iio: imu: Add support for adis16475
Date: Mon, 16 Mar 2020 15:26:31 +0100	[thread overview]
Message-ID: <07c41ab8-7b09-0eb3-ce9d-d7773f5186b8@metafoo.de> (raw)
In-Reply-To: <20200316125312.39178-6-nuno.sa@analog.com>

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.

> +
> +	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"
> +	 * 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.

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.

> +	[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.

>
> +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.


> +	/* 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.

> +		adis->xfer[1].len += 6 * sizeof(u16);
> +		dev_dbg(&adis->spi->dev, "Enable burst32 mode, xfer:%d",
> +			adis->xfer[1].len);
> +
> +	} else if (!st->lsb_flag && st->burst32) {
> +		const u16 en = ADIS16500_BURST32(0);
> +
> +		ret = __adis_update_bits(&st->adis, ADIS16475_REG_MSG_CTRL,
> +					 ADIS16500_BURST32_MASK, en);
> +		if (ret < 0)
> +			return;
> +
> +		st->burst32 = false;
> +		/* Remove the extra bits */
> +		adis->burst->extra_len -= 6 * sizeof(u16);
> +		adis->xfer[1].len -= 6 * sizeof(u16);
> +		dev_dbg(&adis->spi->dev, "Disable burst32 mode, xfer:%d\n",
> +			adis->xfer[1].len);
> +	}
> +}
> +


  reply	other threads:[~2020-03-16 14:26 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 [this message]
2020-03-17 16:40     ` Sa, Nuno
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=07c41ab8-7b09-0eb3-ce9d-d7773f5186b8@metafoo.de \
    --to=lars@metafoo.de \
    --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=linux-iio@vger.kernel.org \
    --cc=mark.rutland@arm.com \
    --cc=nuno.sa@analog.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).