iio: hid-sensors: Increase the precision of scale to fix wrong reading interpretation.
While testing, it was observed that on some platforms the scale value from iio sysfs for gyroscope is always 0 (E.g. Yoga 260). This results in the final angular velocity component values to be zeros. This is caused by insufficient precision of scale value displayed in sysfs. If the precision is changed to nano from current micro, then this is sufficient to display the scale value on this platform. Since this can be a problem for all other HID sensors, increase scale precision of all HID sensors to nano from current micro. Results on Yoga 260: name scale before scale now -------------------------------------------- gyro_3d 0.000000 0.000000174 als 0.001000 0.001000000 magn_3d 0.000001 0.000001000 accel_3d 0.000009 0.000009806 Signed-off-by: Song Hongyan <hongyan.song@intel.com> Acked-by: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com> Cc: <Stable@vger.kernel.org> Signed-off-by: Jonathan Cameron <jic23@kernel.org>
This commit is contained in:
parent
8af644a7d6
commit
6f77199e9e
@ -30,26 +30,26 @@ static struct {
|
||||
u32 usage_id;
|
||||
int unit; /* 0 for default others from HID sensor spec */
|
||||
int scale_val0; /* scale, whole number */
|
||||
int scale_val1; /* scale, fraction in micros */
|
||||
int scale_val1; /* scale, fraction in nanos */
|
||||
} unit_conversion[] = {
|
||||
{HID_USAGE_SENSOR_ACCEL_3D, 0, 9, 806650},
|
||||
{HID_USAGE_SENSOR_ACCEL_3D, 0, 9, 806650000},
|
||||
{HID_USAGE_SENSOR_ACCEL_3D,
|
||||
HID_USAGE_SENSOR_UNITS_METERS_PER_SEC_SQRD, 1, 0},
|
||||
{HID_USAGE_SENSOR_ACCEL_3D,
|
||||
HID_USAGE_SENSOR_UNITS_G, 9, 806650},
|
||||
HID_USAGE_SENSOR_UNITS_G, 9, 806650000},
|
||||
|
||||
{HID_USAGE_SENSOR_GYRO_3D, 0, 0, 17453},
|
||||
{HID_USAGE_SENSOR_GYRO_3D, 0, 0, 17453293},
|
||||
{HID_USAGE_SENSOR_GYRO_3D,
|
||||
HID_USAGE_SENSOR_UNITS_RADIANS_PER_SECOND, 1, 0},
|
||||
{HID_USAGE_SENSOR_GYRO_3D,
|
||||
HID_USAGE_SENSOR_UNITS_DEGREES_PER_SECOND, 0, 17453},
|
||||
HID_USAGE_SENSOR_UNITS_DEGREES_PER_SECOND, 0, 17453293},
|
||||
|
||||
{HID_USAGE_SENSOR_COMPASS_3D, 0, 0, 1000},
|
||||
{HID_USAGE_SENSOR_COMPASS_3D, 0, 0, 1000000},
|
||||
{HID_USAGE_SENSOR_COMPASS_3D, HID_USAGE_SENSOR_UNITS_GAUSS, 1, 0},
|
||||
|
||||
{HID_USAGE_SENSOR_INCLINOMETER_3D, 0, 0, 17453},
|
||||
{HID_USAGE_SENSOR_INCLINOMETER_3D, 0, 0, 17453293},
|
||||
{HID_USAGE_SENSOR_INCLINOMETER_3D,
|
||||
HID_USAGE_SENSOR_UNITS_DEGREES, 0, 17453},
|
||||
HID_USAGE_SENSOR_UNITS_DEGREES, 0, 17453293},
|
||||
{HID_USAGE_SENSOR_INCLINOMETER_3D,
|
||||
HID_USAGE_SENSOR_UNITS_RADIANS, 1, 0},
|
||||
|
||||
@ -57,7 +57,7 @@ static struct {
|
||||
{HID_USAGE_SENSOR_ALS, HID_USAGE_SENSOR_UNITS_LUX, 1, 0},
|
||||
|
||||
{HID_USAGE_SENSOR_PRESSURE, 0, 100, 0},
|
||||
{HID_USAGE_SENSOR_PRESSURE, HID_USAGE_SENSOR_UNITS_PASCAL, 0, 1000},
|
||||
{HID_USAGE_SENSOR_PRESSURE, HID_USAGE_SENSOR_UNITS_PASCAL, 0, 1000000},
|
||||
};
|
||||
|
||||
static int pow_10(unsigned power)
|
||||
@ -266,15 +266,15 @@ EXPORT_SYMBOL(hid_sensor_write_raw_hyst_value);
|
||||
/*
|
||||
* This fuction applies the unit exponent to the scale.
|
||||
* For example:
|
||||
* 9.806650 ->exp:2-> val0[980]val1[665000]
|
||||
* 9.000806 ->exp:2-> val0[900]val1[80600]
|
||||
* 0.174535 ->exp:2-> val0[17]val1[453500]
|
||||
* 1.001745 ->exp:0-> val0[1]val1[1745]
|
||||
* 1.001745 ->exp:2-> val0[100]val1[174500]
|
||||
* 1.001745 ->exp:4-> val0[10017]val1[450000]
|
||||
* 9.806650 ->exp:-2-> val0[0]val1[98066]
|
||||
* 9.806650000 ->exp:2-> val0[980]val1[665000000]
|
||||
* 9.000806000 ->exp:2-> val0[900]val1[80600000]
|
||||
* 0.174535293 ->exp:2-> val0[17]val1[453529300]
|
||||
* 1.001745329 ->exp:0-> val0[1]val1[1745329]
|
||||
* 1.001745329 ->exp:2-> val0[100]val1[174532900]
|
||||
* 1.001745329 ->exp:4-> val0[10017]val1[453290000]
|
||||
* 9.806650000 ->exp:-2-> val0[0]val1[98066500]
|
||||
*/
|
||||
static void adjust_exponent_micro(int *val0, int *val1, int scale0,
|
||||
static void adjust_exponent_nano(int *val0, int *val1, int scale0,
|
||||
int scale1, int exp)
|
||||
{
|
||||
int i;
|
||||
@ -285,32 +285,32 @@ static void adjust_exponent_micro(int *val0, int *val1, int scale0,
|
||||
if (exp > 0) {
|
||||
*val0 = scale0 * pow_10(exp);
|
||||
res = 0;
|
||||
if (exp > 6) {
|
||||
if (exp > 9) {
|
||||
*val1 = 0;
|
||||
return;
|
||||
}
|
||||
for (i = 0; i < exp; ++i) {
|
||||
x = scale1 / pow_10(5 - i);
|
||||
x = scale1 / pow_10(8 - i);
|
||||
res += (pow_10(exp - 1 - i) * x);
|
||||
scale1 = scale1 % pow_10(5 - i);
|
||||
scale1 = scale1 % pow_10(8 - i);
|
||||
}
|
||||
*val0 += res;
|
||||
*val1 = scale1 * pow_10(exp);
|
||||
} else if (exp < 0) {
|
||||
exp = abs(exp);
|
||||
if (exp > 6) {
|
||||
if (exp > 9) {
|
||||
*val0 = *val1 = 0;
|
||||
return;
|
||||
}
|
||||
*val0 = scale0 / pow_10(exp);
|
||||
rem = scale0 % pow_10(exp);
|
||||
res = 0;
|
||||
for (i = 0; i < (6 - exp); ++i) {
|
||||
x = scale1 / pow_10(5 - i);
|
||||
res += (pow_10(5 - exp - i) * x);
|
||||
scale1 = scale1 % pow_10(5 - i);
|
||||
for (i = 0; i < (9 - exp); ++i) {
|
||||
x = scale1 / pow_10(8 - i);
|
||||
res += (pow_10(8 - exp - i) * x);
|
||||
scale1 = scale1 % pow_10(8 - i);
|
||||
}
|
||||
*val1 = rem * pow_10(6 - exp) + res;
|
||||
*val1 = rem * pow_10(9 - exp) + res;
|
||||
} else {
|
||||
*val0 = scale0;
|
||||
*val1 = scale1;
|
||||
@ -332,14 +332,14 @@ int hid_sensor_format_scale(u32 usage_id,
|
||||
unit_conversion[i].unit == attr_info->units) {
|
||||
exp = hid_sensor_convert_exponent(
|
||||
attr_info->unit_expo);
|
||||
adjust_exponent_micro(val0, val1,
|
||||
adjust_exponent_nano(val0, val1,
|
||||
unit_conversion[i].scale_val0,
|
||||
unit_conversion[i].scale_val1, exp);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return IIO_VAL_INT_PLUS_MICRO;
|
||||
return IIO_VAL_INT_PLUS_NANO;
|
||||
}
|
||||
EXPORT_SYMBOL(hid_sensor_format_scale);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user