Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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.

+52 -42
+8 -4
drivers/iio/accel/st_accel_core.c
··· 743 743 744 744 return IIO_VAL_INT; 745 745 case IIO_CHAN_INFO_SCALE: 746 - *val = 0; 747 - *val2 = adata->current_fullscale->gain; 746 + *val = adata->current_fullscale->gain / 1000000; 747 + *val2 = adata->current_fullscale->gain % 1000000; 748 748 return IIO_VAL_INT_PLUS_MICRO; 749 749 case IIO_CHAN_INFO_SAMP_FREQ: 750 750 *val = adata->odr; ··· 763 763 int err; 764 764 765 765 switch (mask) { 766 - case IIO_CHAN_INFO_SCALE: 767 - err = st_sensors_set_fullscale_by_gain(indio_dev, val2); 766 + case IIO_CHAN_INFO_SCALE: { 767 + int gain; 768 + 769 + gain = val * 1000000 + val2; 770 + err = st_sensors_set_fullscale_by_gain(indio_dev, gain); 768 771 break; 772 + } 769 773 case IIO_CHAN_INFO_SAMP_FREQ: 770 774 if (val2) 771 775 return -EINVAL;
+28 -28
drivers/iio/common/hid-sensors/hid-sensor-attributes.c
··· 30 30 u32 usage_id; 31 31 int unit; /* 0 for default others from HID sensor spec */ 32 32 int scale_val0; /* scale, whole number */ 33 - int scale_val1; /* scale, fraction in micros */ 33 + int scale_val1; /* scale, fraction in nanos */ 34 34 } unit_conversion[] = { 35 - {HID_USAGE_SENSOR_ACCEL_3D, 0, 9, 806650}, 35 + {HID_USAGE_SENSOR_ACCEL_3D, 0, 9, 806650000}, 36 36 {HID_USAGE_SENSOR_ACCEL_3D, 37 37 HID_USAGE_SENSOR_UNITS_METERS_PER_SEC_SQRD, 1, 0}, 38 38 {HID_USAGE_SENSOR_ACCEL_3D, 39 - HID_USAGE_SENSOR_UNITS_G, 9, 806650}, 39 + HID_USAGE_SENSOR_UNITS_G, 9, 806650000}, 40 40 41 - {HID_USAGE_SENSOR_GYRO_3D, 0, 0, 17453}, 41 + {HID_USAGE_SENSOR_GYRO_3D, 0, 0, 17453293}, 42 42 {HID_USAGE_SENSOR_GYRO_3D, 43 43 HID_USAGE_SENSOR_UNITS_RADIANS_PER_SECOND, 1, 0}, 44 44 {HID_USAGE_SENSOR_GYRO_3D, 45 - HID_USAGE_SENSOR_UNITS_DEGREES_PER_SECOND, 0, 17453}, 45 + HID_USAGE_SENSOR_UNITS_DEGREES_PER_SECOND, 0, 17453293}, 46 46 47 - {HID_USAGE_SENSOR_COMPASS_3D, 0, 0, 1000}, 47 + {HID_USAGE_SENSOR_COMPASS_3D, 0, 0, 1000000}, 48 48 {HID_USAGE_SENSOR_COMPASS_3D, HID_USAGE_SENSOR_UNITS_GAUSS, 1, 0}, 49 49 50 - {HID_USAGE_SENSOR_INCLINOMETER_3D, 0, 0, 17453}, 50 + {HID_USAGE_SENSOR_INCLINOMETER_3D, 0, 0, 17453293}, 51 51 {HID_USAGE_SENSOR_INCLINOMETER_3D, 52 - HID_USAGE_SENSOR_UNITS_DEGREES, 0, 17453}, 52 + HID_USAGE_SENSOR_UNITS_DEGREES, 0, 17453293}, 53 53 {HID_USAGE_SENSOR_INCLINOMETER_3D, 54 54 HID_USAGE_SENSOR_UNITS_RADIANS, 1, 0}, 55 55 ··· 57 57 {HID_USAGE_SENSOR_ALS, HID_USAGE_SENSOR_UNITS_LUX, 1, 0}, 58 58 59 59 {HID_USAGE_SENSOR_PRESSURE, 0, 100, 0}, 60 - {HID_USAGE_SENSOR_PRESSURE, HID_USAGE_SENSOR_UNITS_PASCAL, 0, 1000}, 60 + {HID_USAGE_SENSOR_PRESSURE, HID_USAGE_SENSOR_UNITS_PASCAL, 0, 1000000}, 61 61 }; 62 62 63 63 static int pow_10(unsigned power) ··· 266 266 /* 267 267 * This fuction applies the unit exponent to the scale. 268 268 * For example: 269 - * 9.806650 ->exp:2-> val0[980]val1[665000] 270 - * 9.000806 ->exp:2-> val0[900]val1[80600] 271 - * 0.174535 ->exp:2-> val0[17]val1[453500] 272 - * 1.001745 ->exp:0-> val0[1]val1[1745] 273 - * 1.001745 ->exp:2-> val0[100]val1[174500] 274 - * 1.001745 ->exp:4-> val0[10017]val1[450000] 275 - * 9.806650 ->exp:-2-> val0[0]val1[98066] 269 + * 9.806650000 ->exp:2-> val0[980]val1[665000000] 270 + * 9.000806000 ->exp:2-> val0[900]val1[80600000] 271 + * 0.174535293 ->exp:2-> val0[17]val1[453529300] 272 + * 1.001745329 ->exp:0-> val0[1]val1[1745329] 273 + * 1.001745329 ->exp:2-> val0[100]val1[174532900] 274 + * 1.001745329 ->exp:4-> val0[10017]val1[453290000] 275 + * 9.806650000 ->exp:-2-> val0[0]val1[98066500] 276 276 */ 277 - static void adjust_exponent_micro(int *val0, int *val1, int scale0, 277 + static void adjust_exponent_nano(int *val0, int *val1, int scale0, 278 278 int scale1, int exp) 279 279 { 280 280 int i; ··· 285 285 if (exp > 0) { 286 286 *val0 = scale0 * pow_10(exp); 287 287 res = 0; 288 - if (exp > 6) { 288 + if (exp > 9) { 289 289 *val1 = 0; 290 290 return; 291 291 } 292 292 for (i = 0; i < exp; ++i) { 293 - x = scale1 / pow_10(5 - i); 293 + x = scale1 / pow_10(8 - i); 294 294 res += (pow_10(exp - 1 - i) * x); 295 - scale1 = scale1 % pow_10(5 - i); 295 + scale1 = scale1 % pow_10(8 - i); 296 296 } 297 297 *val0 += res; 298 298 *val1 = scale1 * pow_10(exp); 299 299 } else if (exp < 0) { 300 300 exp = abs(exp); 301 - if (exp > 6) { 301 + if (exp > 9) { 302 302 *val0 = *val1 = 0; 303 303 return; 304 304 } 305 305 *val0 = scale0 / pow_10(exp); 306 306 rem = scale0 % pow_10(exp); 307 307 res = 0; 308 - for (i = 0; i < (6 - exp); ++i) { 309 - x = scale1 / pow_10(5 - i); 310 - res += (pow_10(5 - exp - i) * x); 311 - scale1 = scale1 % pow_10(5 - i); 308 + for (i = 0; i < (9 - exp); ++i) { 309 + x = scale1 / pow_10(8 - i); 310 + res += (pow_10(8 - exp - i) * x); 311 + scale1 = scale1 % pow_10(8 - i); 312 312 } 313 - *val1 = rem * pow_10(6 - exp) + res; 313 + *val1 = rem * pow_10(9 - exp) + res; 314 314 } else { 315 315 *val0 = scale0; 316 316 *val1 = scale1; ··· 332 332 unit_conversion[i].unit == attr_info->units) { 333 333 exp = hid_sensor_convert_exponent( 334 334 attr_info->unit_expo); 335 - adjust_exponent_micro(val0, val1, 335 + adjust_exponent_nano(val0, val1, 336 336 unit_conversion[i].scale_val0, 337 337 unit_conversion[i].scale_val1, exp); 338 338 break; 339 339 } 340 340 } 341 341 342 - return IIO_VAL_INT_PLUS_MICRO; 342 + return IIO_VAL_INT_PLUS_NANO; 343 343 } 344 344 EXPORT_SYMBOL(hid_sensor_format_scale); 345 345
+5 -3
drivers/iio/common/st_sensors/st_sensors_core.c
··· 612 612 ssize_t st_sensors_sysfs_scale_avail(struct device *dev, 613 613 struct device_attribute *attr, char *buf) 614 614 { 615 - int i, len = 0; 615 + int i, len = 0, q, r; 616 616 struct iio_dev *indio_dev = dev_get_drvdata(dev); 617 617 struct st_sensor_data *sdata = iio_priv(indio_dev); 618 618 ··· 621 621 if (sdata->sensor_settings->fs.fs_avl[i].num == 0) 622 622 break; 623 623 624 - len += scnprintf(buf + len, PAGE_SIZE - len, "0.%06u ", 625 - sdata->sensor_settings->fs.fs_avl[i].gain); 624 + q = sdata->sensor_settings->fs.fs_avl[i].gain / 1000000; 625 + r = sdata->sensor_settings->fs.fs_avl[i].gain % 1000000; 626 + 627 + len += scnprintf(buf + len, PAGE_SIZE - len, "%u.%06u ", q, r); 626 628 } 627 629 mutex_unlock(&indio_dev->mlock); 628 630 buf[len - 1] = '\n';
+1
drivers/iio/orientation/hid-sensor-rotation.c
··· 335 335 .id_table = hid_dev_rot_ids, 336 336 .driver = { 337 337 .name = KBUILD_MODNAME, 338 + .pm = &hid_sensor_pm_ops, 338 339 }, 339 340 .probe = hid_dev_rot_probe, 340 341 .remove = hid_dev_rot_remove,
+10 -7
drivers/staging/iio/impedance-analyzer/ad5933.c
··· 655 655 __be16 buf[2]; 656 656 int val[2]; 657 657 unsigned char status; 658 + int ret; 658 659 659 660 mutex_lock(&indio_dev->mlock); 660 661 if (st->state == AD5933_CTRL_INIT_START_FREQ) { ··· 663 662 ad5933_cmd(st, AD5933_CTRL_START_SWEEP); 664 663 st->state = AD5933_CTRL_START_SWEEP; 665 664 schedule_delayed_work(&st->work, st->poll_time_jiffies); 666 - mutex_unlock(&indio_dev->mlock); 667 - return; 665 + goto out; 668 666 } 669 667 670 - ad5933_i2c_read(st->client, AD5933_REG_STATUS, 1, &status); 668 + ret = ad5933_i2c_read(st->client, AD5933_REG_STATUS, 1, &status); 669 + if (ret) 670 + goto out; 671 671 672 672 if (status & AD5933_STAT_DATA_VALID) { 673 673 int scan_count = bitmap_weight(indio_dev->active_scan_mask, 674 674 indio_dev->masklength); 675 - ad5933_i2c_read(st->client, 675 + ret = ad5933_i2c_read(st->client, 676 676 test_bit(1, indio_dev->active_scan_mask) ? 677 677 AD5933_REG_REAL_DATA : AD5933_REG_IMAG_DATA, 678 678 scan_count * 2, (u8 *)buf); 679 + if (ret) 680 + goto out; 679 681 680 682 if (scan_count == 2) { 681 683 val[0] = be16_to_cpu(buf[0]); ··· 690 686 } else { 691 687 /* no data available - try again later */ 692 688 schedule_delayed_work(&st->work, st->poll_time_jiffies); 693 - mutex_unlock(&indio_dev->mlock); 694 - return; 689 + goto out; 695 690 } 696 691 697 692 if (status & AD5933_STAT_SWEEP_DONE) { ··· 703 700 ad5933_cmd(st, AD5933_CTRL_INC_FREQ); 704 701 schedule_delayed_work(&st->work, st->poll_time_jiffies); 705 702 } 706 - 703 + out: 707 704 mutex_unlock(&indio_dev->mlock); 708 705 } 709 706