Commit 371c6d97 authored by Greg Kroah-Hartman's avatar Greg Kroah-Hartman

Merge tag 'iio-fixes-for-4.9b' of...

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.
parents a909d3e6 6f77199e
......@@ -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);
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment