forked from Minki/linux
Second set of IIO fixes for the 4.9 cycle.
Interestingly scale related fixes for accelerometers at both ends of the range. Obviously more varied devices turning up than we've seen before! * ad5933 - fix an uninitialized value in a return case that is winding up GCC. * hid sensors - missing pm function prevents hid rotations sensors from working on newer ISH hubs (works by luck on older ones) - increase of scale precision needed to fix a case where on a yoga 260 the reported scale is 0 (presumably a high precision but very low g sensor). * st_sensors - fix an issue seen with the hs3lis331dl where the range is much greater than previous devices (100's of g) and hence the per bit scale is greater than 1. -----BEGIN PGP SIGNATURE----- iQIuBAABCAAYBQJYH3AgERxqaWMyM0BrZXJuZWwub3JnAAoJEFSFNJnE9BaI7s0P /RitgKHURPOdUS51Y19slkC/K6S4QaSD7DzH8jRtEmR9iZJjJJwE0ZgCQcmcwd70 tlKZU0PoQcfU6zL0tmW8HX7A48IWfSETLa5Uxv+7lY11u2VLXpMLvMjlJWXYrKPK FXUUpLacPhER91VlAQpmQKeGuuo8DhGp4tUUeSTCH+RDfKSluN8cOUFAfFMrN6FT GDuXxKGrLcyKjXW/OvNsimsJyyx8BGrLMCwjJbikTmvHCh2AztCFkgt3rTemU9Xh fwamxWZu3ezP6+gj554+PNQOe4Z+h3869hzEWu3Oa93ez5cFINm/f258GjfNQP1q JA57kCwx3nb4SNYHvG7TK154aYQzq5YTkuSEeCz7SUP7WNSWwzBISHJ0ZH++ymIK smIqXTMg8SKgxBupba5JOyc6lI/5t6sKiB0iROxrWbTDEh4jGFdCwcNL2duarWMx As4Tgu/3TnhuWA+7MY0FZB4Es0JBdaeXK5D6OKiy0T/6N/m0fzYhX72Fk47LHX4m WV855PifjjCBqnll4JT49ijXF81E4JZkwl2s2t7K0u43OEjv36L9PfpcKL0xKGx3 XepjqJiC4MPlJj2sKSmOEtq2G+AcGphW/1vbKhLjRva4OphiV78lMKIiSTWi9IaN LIFVCGe149i1xCH5LQQKDvX+wGMgUsXLl/aCezKd2dLE =KcFP -----END PGP SIGNATURE----- Merge tag 'iio-fixes-for-4.9b' of git://git.kernel.org/pub/scm/linux/kernel/git/jic23/iio into staging-linus Second set of IIO fixes for the 4.9 cycle. Interestingly scale related fixes for accelerometers at both ends of the range. Obviously more varied devices turning up than we've seen before! * ad5933 - fix an uninitialized value in a return case that is winding up GCC. * hid sensors - missing pm function prevents hid rotations sensors from working on newer ISH hubs (works by luck on older ones) - increase of scale precision needed to fix a case where on a yoga 260 the reported scale is 0 (presumably a high precision but very low g sensor). * st_sensors - fix an issue seen with the hs3lis331dl where the range is much greater than previous devices (100's of g) and hence the per bit scale is greater than 1.
This commit is contained in:
commit
371c6d9727
@ -743,8 +743,8 @@ static int st_accel_read_raw(struct iio_dev *indio_dev,
|
||||
|
||||
return IIO_VAL_INT;
|
||||
case IIO_CHAN_INFO_SCALE:
|
||||
*val = 0;
|
||||
*val2 = adata->current_fullscale->gain;
|
||||
*val = adata->current_fullscale->gain / 1000000;
|
||||
*val2 = adata->current_fullscale->gain % 1000000;
|
||||
return IIO_VAL_INT_PLUS_MICRO;
|
||||
case IIO_CHAN_INFO_SAMP_FREQ:
|
||||
*val = adata->odr;
|
||||
@ -763,9 +763,13 @@ static int st_accel_write_raw(struct iio_dev *indio_dev,
|
||||
int err;
|
||||
|
||||
switch (mask) {
|
||||
case IIO_CHAN_INFO_SCALE:
|
||||
err = st_sensors_set_fullscale_by_gain(indio_dev, val2);
|
||||
case IIO_CHAN_INFO_SCALE: {
|
||||
int gain;
|
||||
|
||||
gain = val * 1000000 + val2;
|
||||
err = st_sensors_set_fullscale_by_gain(indio_dev, gain);
|
||||
break;
|
||||
}
|
||||
case IIO_CHAN_INFO_SAMP_FREQ:
|
||||
if (val2)
|
||||
return -EINVAL;
|
||||
|
@ -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);
|
||||
|
||||
|
@ -612,7 +612,7 @@ EXPORT_SYMBOL(st_sensors_sysfs_sampling_frequency_avail);
|
||||
ssize_t st_sensors_sysfs_scale_avail(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
int i, len = 0;
|
||||
int i, len = 0, q, r;
|
||||
struct iio_dev *indio_dev = dev_get_drvdata(dev);
|
||||
struct st_sensor_data *sdata = iio_priv(indio_dev);
|
||||
|
||||
@ -621,8 +621,10 @@ ssize_t st_sensors_sysfs_scale_avail(struct device *dev,
|
||||
if (sdata->sensor_settings->fs.fs_avl[i].num == 0)
|
||||
break;
|
||||
|
||||
len += scnprintf(buf + len, PAGE_SIZE - len, "0.%06u ",
|
||||
sdata->sensor_settings->fs.fs_avl[i].gain);
|
||||
q = sdata->sensor_settings->fs.fs_avl[i].gain / 1000000;
|
||||
r = sdata->sensor_settings->fs.fs_avl[i].gain % 1000000;
|
||||
|
||||
len += scnprintf(buf + len, PAGE_SIZE - len, "%u.%06u ", q, r);
|
||||
}
|
||||
mutex_unlock(&indio_dev->mlock);
|
||||
buf[len - 1] = '\n';
|
||||
|
@ -335,6 +335,7 @@ static struct platform_driver hid_dev_rot_platform_driver = {
|
||||
.id_table = hid_dev_rot_ids,
|
||||
.driver = {
|
||||
.name = KBUILD_MODNAME,
|
||||
.pm = &hid_sensor_pm_ops,
|
||||
},
|
||||
.probe = hid_dev_rot_probe,
|
||||
.remove = hid_dev_rot_remove,
|
||||
|
@ -655,6 +655,7 @@ static void ad5933_work(struct work_struct *work)
|
||||
__be16 buf[2];
|
||||
int val[2];
|
||||
unsigned char status;
|
||||
int ret;
|
||||
|
||||
mutex_lock(&indio_dev->mlock);
|
||||
if (st->state == AD5933_CTRL_INIT_START_FREQ) {
|
||||
@ -662,19 +663,22 @@ static void ad5933_work(struct work_struct *work)
|
||||
ad5933_cmd(st, AD5933_CTRL_START_SWEEP);
|
||||
st->state = AD5933_CTRL_START_SWEEP;
|
||||
schedule_delayed_work(&st->work, st->poll_time_jiffies);
|
||||
mutex_unlock(&indio_dev->mlock);
|
||||
return;
|
||||
goto out;
|
||||
}
|
||||
|
||||
ad5933_i2c_read(st->client, AD5933_REG_STATUS, 1, &status);
|
||||
ret = ad5933_i2c_read(st->client, AD5933_REG_STATUS, 1, &status);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
if (status & AD5933_STAT_DATA_VALID) {
|
||||
int scan_count = bitmap_weight(indio_dev->active_scan_mask,
|
||||
indio_dev->masklength);
|
||||
ad5933_i2c_read(st->client,
|
||||
ret = ad5933_i2c_read(st->client,
|
||||
test_bit(1, indio_dev->active_scan_mask) ?
|
||||
AD5933_REG_REAL_DATA : AD5933_REG_IMAG_DATA,
|
||||
scan_count * 2, (u8 *)buf);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
if (scan_count == 2) {
|
||||
val[0] = be16_to_cpu(buf[0]);
|
||||
@ -686,8 +690,7 @@ static void ad5933_work(struct work_struct *work)
|
||||
} else {
|
||||
/* no data available - try again later */
|
||||
schedule_delayed_work(&st->work, st->poll_time_jiffies);
|
||||
mutex_unlock(&indio_dev->mlock);
|
||||
return;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (status & AD5933_STAT_SWEEP_DONE) {
|
||||
@ -700,7 +703,7 @@ static void ad5933_work(struct work_struct *work)
|
||||
ad5933_cmd(st, AD5933_CTRL_INC_FREQ);
|
||||
schedule_delayed_work(&st->work, st->poll_time_jiffies);
|
||||
}
|
||||
|
||||
out:
|
||||
mutex_unlock(&indio_dev->mlock);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user