ISH based sensors do not naturally return data in the W3C 'natural' orientation. They returns all data inverted, to match Microsoft Windows requirement: [https://docs.microsoft.com/en-us/windows/uwp/devices-sensors/sensors#accelerometer] """ If the device has the SimpleOrientation of FaceUp on a table, then the accelerometer would read -1 G on the Z axis. """ While W3C defines [https://www.w3.org/TR/motion-sensors/#accelerometer-sensor] """The Accelerometer sensor is an inertial-frame sensor, this means that when the device is in free fall, the acceleration is 0 m/s2 in the falling direction, and when a device is laying flat on a table, the acceleration in upwards direction will be equal to the Earth gravity, i.e. g ≡ 9.8 m/s2 as it is measuring the force of the table pushing the device upwards.""" Fixes all HID sensors that defines IIO_MOD_[XYZ] attributes. Tested on "HP Spectre x360 Convertible 13" and "Dell XPS 13 9365". Signed-off-by: Gwendal Grignou <gwendal@xxxxxxxxxxxx> --- drivers/iio/accel/hid-sensor-accel-3d.c | 3 +++ .../hid-sensors/hid-sensor-attributes.c | 21 +++++++++++++++++++ drivers/iio/gyro/hid-sensor-gyro-3d.c | 3 +++ drivers/iio/magnetometer/hid-sensor-magn-3d.c | 3 +++ include/linux/hid-sensor-hub.h | 2 ++ 5 files changed, 32 insertions(+) diff --git a/drivers/iio/accel/hid-sensor-accel-3d.c b/drivers/iio/accel/hid-sensor-accel-3d.c index a2def6f9380a3..980bbd7fba502 100644 --- a/drivers/iio/accel/hid-sensor-accel-3d.c +++ b/drivers/iio/accel/hid-sensor-accel-3d.c @@ -59,6 +59,7 @@ static const struct iio_chan_spec accel_3d_channels[] = { BIT(IIO_CHAN_INFO_SAMP_FREQ) | BIT(IIO_CHAN_INFO_HYSTERESIS), .scan_index = CHANNEL_SCAN_INDEX_X, + .ext_info = hid_sensor_ext_info, }, { .type = IIO_ACCEL, .modified = 1, @@ -69,6 +70,7 @@ static const struct iio_chan_spec accel_3d_channels[] = { BIT(IIO_CHAN_INFO_SAMP_FREQ) | BIT(IIO_CHAN_INFO_HYSTERESIS), .scan_index = CHANNEL_SCAN_INDEX_Y, + .ext_info = hid_sensor_ext_info, }, { .type = IIO_ACCEL, .modified = 1, @@ -79,6 +81,7 @@ static const struct iio_chan_spec accel_3d_channels[] = { BIT(IIO_CHAN_INFO_SAMP_FREQ) | BIT(IIO_CHAN_INFO_HYSTERESIS), .scan_index = CHANNEL_SCAN_INDEX_Z, + .ext_info = hid_sensor_ext_info, }, IIO_CHAN_SOFT_TIMESTAMP(CHANNEL_SCAN_INDEX_TIMESTAMP) }; diff --git a/drivers/iio/common/hid-sensors/hid-sensor-attributes.c b/drivers/iio/common/hid-sensors/hid-sensor-attributes.c index 9b279937a24e0..e367e4b482ef0 100644 --- a/drivers/iio/common/hid-sensors/hid-sensor-attributes.c +++ b/drivers/iio/common/hid-sensors/hid-sensor-attributes.c @@ -585,6 +585,27 @@ int hid_sensor_parse_common_attributes(struct hid_sensor_hub_device *hsdev, } EXPORT_SYMBOL_NS(hid_sensor_parse_common_attributes, IIO_HID); +static const struct iio_mount_matrix hid_sensor_windows_axis = { + .rotation = { + "-1", "0", "0", + "0", "-1", "0", + "0", "0", "-1" + } +}; + +static const struct iio_mount_matrix * +hid_sensor_get_mount_matrix(const struct iio_dev *indio_dev, + const struct iio_chan_spec *chan) +{ + return &hid_sensor_windows_axis; +} + +const struct iio_chan_spec_ext_info hid_sensor_ext_info[] = { + IIO_MOUNT_MATRIX(IIO_SHARED_BY_TYPE, hid_sensor_get_mount_matrix), + { } +}; +EXPORT_SYMBOL(hid_sensor_ext_info); + MODULE_AUTHOR("Srinivas Pandruvada <srinivas.pandruvada@xxxxxxxxx>"); MODULE_DESCRIPTION("HID Sensor common attribute processing"); MODULE_LICENSE("GPL"); diff --git a/drivers/iio/gyro/hid-sensor-gyro-3d.c b/drivers/iio/gyro/hid-sensor-gyro-3d.c index 8f0ad022c7f1b..b852f5166bb21 100644 --- a/drivers/iio/gyro/hid-sensor-gyro-3d.c +++ b/drivers/iio/gyro/hid-sensor-gyro-3d.c @@ -58,6 +58,7 @@ static const struct iio_chan_spec gyro_3d_channels[] = { BIT(IIO_CHAN_INFO_SAMP_FREQ) | BIT(IIO_CHAN_INFO_HYSTERESIS), .scan_index = CHANNEL_SCAN_INDEX_X, + .ext_info = hid_sensor_ext_info, }, { .type = IIO_ANGL_VEL, .modified = 1, @@ -68,6 +69,7 @@ static const struct iio_chan_spec gyro_3d_channels[] = { BIT(IIO_CHAN_INFO_SAMP_FREQ) | BIT(IIO_CHAN_INFO_HYSTERESIS), .scan_index = CHANNEL_SCAN_INDEX_Y, + .ext_info = hid_sensor_ext_info, }, { .type = IIO_ANGL_VEL, .modified = 1, @@ -78,6 +80,7 @@ static const struct iio_chan_spec gyro_3d_channels[] = { BIT(IIO_CHAN_INFO_SAMP_FREQ) | BIT(IIO_CHAN_INFO_HYSTERESIS), .scan_index = CHANNEL_SCAN_INDEX_Z, + .ext_info = hid_sensor_ext_info, }, IIO_CHAN_SOFT_TIMESTAMP(CHANNEL_SCAN_INDEX_TIMESTAMP) }; diff --git a/drivers/iio/magnetometer/hid-sensor-magn-3d.c b/drivers/iio/magnetometer/hid-sensor-magn-3d.c index e85a3a8eea908..aefbdb9b0869a 100644 --- a/drivers/iio/magnetometer/hid-sensor-magn-3d.c +++ b/drivers/iio/magnetometer/hid-sensor-magn-3d.c @@ -74,6 +74,7 @@ static const struct iio_chan_spec magn_3d_channels[] = { BIT(IIO_CHAN_INFO_SCALE) | BIT(IIO_CHAN_INFO_SAMP_FREQ) | BIT(IIO_CHAN_INFO_HYSTERESIS), + .ext_info = hid_sensor_ext_info, }, { .type = IIO_MAGN, .modified = 1, @@ -83,6 +84,7 @@ static const struct iio_chan_spec magn_3d_channels[] = { BIT(IIO_CHAN_INFO_SCALE) | BIT(IIO_CHAN_INFO_SAMP_FREQ) | BIT(IIO_CHAN_INFO_HYSTERESIS), + .ext_info = hid_sensor_ext_info, }, { .type = IIO_MAGN, .modified = 1, @@ -92,6 +94,7 @@ static const struct iio_chan_spec magn_3d_channels[] = { BIT(IIO_CHAN_INFO_SCALE) | BIT(IIO_CHAN_INFO_SAMP_FREQ) | BIT(IIO_CHAN_INFO_HYSTERESIS), + .ext_info = hid_sensor_ext_info, }, { .type = IIO_ROT, .modified = 1, diff --git a/include/linux/hid-sensor-hub.h b/include/linux/hid-sensor-hub.h index c27329e2a5ad5..ee7d5b430a785 100644 --- a/include/linux/hid-sensor-hub.h +++ b/include/linux/hid-sensor-hub.h @@ -236,6 +236,8 @@ struct hid_sensor_common { struct work_struct work; }; +extern const struct iio_chan_spec_ext_info hid_sensor_ext_info[]; + /* Convert from hid unit expo to regular exponent */ static inline int hid_sensor_convert_exponent(int unit_expo) { -- 2.37.0.rc0.161.g10f37bed90-goog