lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <7f562418-f56c-07bb-27b4-d2e54834ef2f@theobroma-systems.com>
Date:   Mon, 4 Jul 2022 18:49:54 +0200
From:   Quentin Schulz <quentin.schulz@...obroma-systems.com>
To:     Jonathan Cameron <jic23@...nel.org>,
        Quentin Schulz <foss+kernel@...il.net>
Cc:     lars@...afoo.de, linux-iio@...r.kernel.org,
        linux-kernel@...r.kernel.org
Subject: Re: [PATCH] iio: accel: mxc4005: report orientation of accelerometer

Hi Jonathan,

On 6/19/22 16:27, Jonathan Cameron wrote:
> On Wed, 15 Jun 2022 13:02:40 +0200
> Quentin Schulz <foss+kernel@...il.net> wrote:
> 
>> From: Quentin Schulz <quentin.schulz@...obroma-systems.com>
>>
> Hi Quentin,
> 
> Interesting / horribly ill defined little feature ;)
> 
>> The accelerometer can report precise values for x, y and z accelerations
>> but it can also simply report its orientation on XY plane and Z axis.
>>
>> Since the orientation of the device may be enough information for
>> userspace and allows to avoid expensive fusion algorithms, let's add
>> support for it.
>>
>> The orientation register stores a 2b value for XY plane orientation:
>> between 225° and 315°, returns 0, between 315° and 45°, 1, between 45°
>> and 135°, 2 and between 135° and 225°, 3. We "round" those to 270°,
>> 0°, 90° and 180° degrees.
> 
> Wow. The datasheet description of this very confusing...

I'm relieved I'm not the only one confused by this datasheet :)

> One key thing is we need to be careful of is that tilt (x/y is
> not always available - but rather shows the last, and probably
> now garbage, value)

Being pedantic here, not garbage, but outdated. This register exists so 
that the values aren't garbage (at the cost of being outdated). Except 
this small notion, I agree on the statement.

>>
>> For Z axis, the register bit returns 0 if facing the user, 1 otherwise,
>> which the driver translates to 0° and 180° respectively.
> 
> I assume facing up vs facing down?  User might be lying on their
> back in which case this description doesn't work.  The datasheet

Correct, I was playing with the device while seated, hence the bias. But 
yes, everything is relative to Earth gravity, so face up/down is a 
better description indeed.

> also talks about the case where g lies near the XY plane and hence
> the z axis is horizontal.
> 
> 
>>
>> Those values are proper if the accelerometer is mounted such that the
>> XYZ axes are as follows when the device is facing the user in portrait
>> mode (respecting the right-hand rule):
>>
>>       y
>>       ^
>>       |
>>       |
>>       |
>>       +----------> x
>>      /
>>     /
>>    /
>>   L
>> z
>>
>> Since this information is very basic, imprecise (only 4 values for XY
>> plane and 2 for Z axis) and can be extrapolated from the actual,
>> precise, x, y and z acceleration values, it is not made available
>> through buffers.
>>
>> A change in XY plane or Z axis orientation can also trigger an interrupt
>> but this feature is not added in this commit.
>>
>> Signed-off-by: Quentin Schulz <quentin.schulz@...obroma-systems.com>
>> ---
>>   drivers/iio/accel/mxc4005.c | 39 +++++++++++++++++++++++++++++++++++++
>>   1 file changed, 39 insertions(+)
>>
>> diff --git a/drivers/iio/accel/mxc4005.c b/drivers/iio/accel/mxc4005.c
>> index b3afbf064915..61f24058d239 100644
>> --- a/drivers/iio/accel/mxc4005.c
>> +++ b/drivers/iio/accel/mxc4005.c
>> @@ -20,6 +20,11 @@
>>   #define MXC4005_IRQ_NAME		"mxc4005_event"
>>   #define MXC4005_REGMAP_NAME		"mxc4005_regmap"
>>   
>> +#define MXC4005_REG_TILT_ORIENT		0x01
>> +#define MXC4005_REG_TILT_ORIENT_Z_MASK		BIT(6)
> 
> I think you need to deal with BIT(7) as well.
> 
>> +#define MXC4005_REG_TILT_ORIENT_XY_MASK		GENMASK(5, 4)
>> +#define MXC4005_REG_TILT_ORIENT_XY_SHIFT	4
> 
> Don't define the shift, you can use FIELD_GET(MASK, val)
> 

Wasn't aware of this neat macro, thanks for the heads up.

>> +
>>   #define MXC4005_REG_XOUT_UPPER		0x03
>>   #define MXC4005_REG_XOUT_LOWER		0x04
>>   #define MXC4005_REG_YOUT_UPPER		0x05
>> @@ -96,6 +101,7 @@ static const struct attribute_group mxc4005_attrs_group = {
>>   static bool mxc4005_is_readable_reg(struct device *dev, unsigned int reg)
>>   {
>>   	switch (reg) {
>> +	case MXC4005_REG_TILT_ORIENT:
>>   	case MXC4005_REG_XOUT_UPPER:
>>   	case MXC4005_REG_XOUT_LOWER:
>>   	case MXC4005_REG_YOUT_UPPER:
>> @@ -214,6 +220,28 @@ static int mxc4005_read_raw(struct iio_dev *indio_dev,
>>   	int ret;
>>   
>>   	switch (mask) {
>> +	case IIO_CHAN_INFO_PROCESSED:
>> +		switch (chan->type) {
>> +		case IIO_ROT:
>> +			ret = regmap_read(data->regmap, chan->address, val);
>> +			if (ret < 0) {
>> +				dev_err(data->dev, "failed to read rotation\n");
>> +				return ret;
>> +			}
>> +
>> +			if (chan->channel2 == IIO_MOD_X_AND_Y) {
>> +				*val &= MXC4005_REG_TILT_ORIENT_XY_MASK;
>> +				*val >>= MXC4005_REG_TILT_ORIENT_XY_SHIFT;
> FIELD_GET()
> 
>> +				/* 00 = 270°; 01 = 0°; 10 = 90°; 11 = 180° */
>> +				*val = (360 + (*val - 1) * 90) % 360;
> 
> In event of tilt not being set (BIT (7)) I think you should return an error
> code here.  -EBUSY perhaps? To reflect the fact we don't have valid data.
> 

Difficult to find the appropriate error code to return. It's not 
technically busy, especially if the device stays in that position 
forever, it'll never return a valid value.

>> +			} else {
>> +				*val &= MXC4005_REG_TILT_ORIENT_Z_MASK;
>> +				*val = *val ? 180 : 0;
> Documentation for this is really confusing, as it refers to a circumstance
> when it can be assumed to be horizontal, but then doesn't define it.
> 
> It might be a simple as tilt being set and thus indicating significant
> acceleration due to gravity in the xy plane.
> However, the Z orientation is still updated in that case...
> 

I'm wondering if it's not an exclusive validity of axes. E.g. XY plane 
is valid only when Z is not and vice-versa?

"The vertical/horizontal Z axis
orientation is determined by the same criteria used to determine the 
XY-plane off-axis tilt angle" seems to indicate that the TILT bit 
defines whether the Z axis is vertical or horizontal.

"When the XY plane
has a sufficiently small off-axis tilt angle, XY orientation detection 
is valid (and continues to be updated), and the Z
axis is detected as horizontal" would mean Z is just not usable when XY 
orientation is valid (because Z is horizontal and thus does not have a 
big enough acceleration to be usable).

"When off-axis tilt angle exceeds the
threshold discussed above, the Z axis is detected as either vertical up 
or vertical down, depending on the sign of the
Z axis acceleration output." could be interpreted as "when XY 
orientation is invalid, Z orientation is either vertical up or down".

>> +			}
>> +			return IIO_VAL_INT;
>> +		default:
>> +			return -EINVAL;
>> +		}
>>   	case IIO_CHAN_INFO_RAW:
>>   		switch (chan->type) {
>>   		case IIO_ACCEL:
>> @@ -287,11 +315,22 @@ static const unsigned long mxc4005_scan_masks[] = {
>>   	},							\
>>   }
>>   
>> +#define MXC4005_CHANNEL_ORIENTATION(_axis) {			\
>> +	.type = IIO_ROT,					\
> 
> Hmm.  Should this be rotation or inclination (so referenced
> to gravity).  Inclination is not particularly tightly defined but the
> point is that it is relative to gravity - kind of a special case of
> rot.
> 
> For the adis16209 we handled inclination and rotation.  I think rotation
> in that device corresponds to XY here. (though it's oddly defined for
> X axis, whereas I'm fairly sure it should be Z - as rotation 'about'
> z axis). The Z one here should I think be an inclination because it's not
> about any particular axis.
> 
> We also have angle to confuse matters. In that case intent was 'between'
> two things. Arguably all the uses of rot are as well, just that one of those
> things is gravity or magnetic north.  With hindsight I think we could have
> gotten away with one of them, but hard to tidy up now.
> 

You mentioned the three candidates I had in mind, but none seemed to 
perfectly match (or maybe I'm just confused about the difference between 
the three and just can't make up my mind) so I picked rotation because 
the English term seemed closer to what I think those values represent?

> In conclusion, what you have here I think is best described as
> IIO_ROT about Z axis (the XY one)

I disagree, this would mean that having XY plane parallel to ground and 
rotate the device along the Z axis (so XY plane staying parallel to 
ground) should change the value of this IIO_ROT on Z axis, but it does 
not if I'm not mistaken (I assume because the acceleration on X and Y 
axes are too small because the axes are parallel to the ground).

But that also kind of highlights that IIO_ROT for Z as I've done it in 
the patch probably isn't correct either and inclination would probably 
match best?

I feel like this will be an interesting discussion :)

Cheers,
Quentin

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ