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á
next prev parent 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).