Skip to content

Commit

Permalink
Merge tag 'iio-fixes-for-4.20a' of git://git.kernel.org/pub/scm/linux…
Browse files Browse the repository at this point in the history
…/kernel/git/jic23/iio into staging-linus

Jonathan writes:

First set of IIO fixes for the 4.20 cycle.

* st_magn
  - Avoid an ordering issue that lead to large numbers of unhandled
    interrupts whilst enabling buffered capture.
* hid-sensors
  - Fix a long running problem with signed values reading wrong from
    sysfs on these sensors.   It appears people were only using the
    buffered interface.  These typically occur in laptops so chances
    are everyone was using the sensor-proxy which will use the buffered
    interface by default.

* tag 'iio-fixes-for-4.20a' of git://git.kernel.org/pub/scm/linux/kernel/git/jic23/iio:
  iio/hid-sensors: Fix IIO_CHAN_INFO_RAW returning wrong values for signed numbers
  iio:st_magn: Fix enable device after trigger
  • Loading branch information
Greg Kroah-Hartman committed Nov 22, 2018
2 parents 5a96b2d + 0145b50 commit c648284
Show file tree
Hide file tree
Showing 14 changed files with 55 additions and 34 deletions.
2 changes: 1 addition & 1 deletion drivers/hid/hid-sensor-custom.c
Original file line number Diff line number Diff line change
Expand Up @@ -358,7 +358,7 @@ static ssize_t show_value(struct device *dev, struct device_attribute *attr,
sensor_inst->hsdev,
sensor_inst->hsdev->usage,
usage, report_id,
SENSOR_HUB_SYNC);
SENSOR_HUB_SYNC, false);
} else if (!strncmp(name, "units", strlen("units")))
value = sensor_inst->fields[field_index].attribute.units;
else if (!strncmp(name, "unit-expo", strlen("unit-expo")))
Expand Down
13 changes: 10 additions & 3 deletions drivers/hid/hid-sensor-hub.c
Original file line number Diff line number Diff line change
Expand Up @@ -299,7 +299,8 @@ EXPORT_SYMBOL_GPL(sensor_hub_get_feature);
int sensor_hub_input_attr_get_raw_value(struct hid_sensor_hub_device *hsdev,
u32 usage_id,
u32 attr_usage_id, u32 report_id,
enum sensor_hub_read_flags flag)
enum sensor_hub_read_flags flag,
bool is_signed)
{
struct sensor_hub_data *data = hid_get_drvdata(hsdev->hdev);
unsigned long flags;
Expand Down Expand Up @@ -331,10 +332,16 @@ int sensor_hub_input_attr_get_raw_value(struct hid_sensor_hub_device *hsdev,
&hsdev->pending.ready, HZ*5);
switch (hsdev->pending.raw_size) {
case 1:
ret_val = *(u8 *)hsdev->pending.raw_data;
if (is_signed)
ret_val = *(s8 *)hsdev->pending.raw_data;
else
ret_val = *(u8 *)hsdev->pending.raw_data;
break;
case 2:
ret_val = *(u16 *)hsdev->pending.raw_data;
if (is_signed)
ret_val = *(s16 *)hsdev->pending.raw_data;
else
ret_val = *(u16 *)hsdev->pending.raw_data;
break;
case 4:
ret_val = *(u32 *)hsdev->pending.raw_data;
Expand Down
5 changes: 4 additions & 1 deletion drivers/iio/accel/hid-sensor-accel-3d.c
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,7 @@ static int accel_3d_read_raw(struct iio_dev *indio_dev,
int report_id = -1;
u32 address;
int ret_type;
s32 min;
struct hid_sensor_hub_device *hsdev =
accel_state->common_attributes.hsdev;

Expand All @@ -158,12 +159,14 @@ static int accel_3d_read_raw(struct iio_dev *indio_dev,
case IIO_CHAN_INFO_RAW:
hid_sensor_power_state(&accel_state->common_attributes, true);
report_id = accel_state->accel[chan->scan_index].report_id;
min = accel_state->accel[chan->scan_index].logical_minimum;
address = accel_3d_addresses[chan->scan_index];
if (report_id >= 0)
*val = sensor_hub_input_attr_get_raw_value(
accel_state->common_attributes.hsdev,
hsdev->usage, address, report_id,
SENSOR_HUB_SYNC);
SENSOR_HUB_SYNC,
min < 0);
else {
*val = 0;
hid_sensor_power_state(&accel_state->common_attributes,
Expand Down
5 changes: 4 additions & 1 deletion drivers/iio/gyro/hid-sensor-gyro-3d.c
Original file line number Diff line number Diff line change
Expand Up @@ -111,20 +111,23 @@ static int gyro_3d_read_raw(struct iio_dev *indio_dev,
int report_id = -1;
u32 address;
int ret_type;
s32 min;

*val = 0;
*val2 = 0;
switch (mask) {
case IIO_CHAN_INFO_RAW:
hid_sensor_power_state(&gyro_state->common_attributes, true);
report_id = gyro_state->gyro[chan->scan_index].report_id;
min = gyro_state->gyro[chan->scan_index].logical_minimum;
address = gyro_3d_addresses[chan->scan_index];
if (report_id >= 0)
*val = sensor_hub_input_attr_get_raw_value(
gyro_state->common_attributes.hsdev,
HID_USAGE_SENSOR_GYRO_3D, address,
report_id,
SENSOR_HUB_SYNC);
SENSOR_HUB_SYNC,
min < 0);
else {
*val = 0;
hid_sensor_power_state(&gyro_state->common_attributes,
Expand Down
3 changes: 2 additions & 1 deletion drivers/iio/humidity/hid-sensor-humidity.c
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,8 @@ static int humidity_read_raw(struct iio_dev *indio_dev,
HID_USAGE_SENSOR_HUMIDITY,
HID_USAGE_SENSOR_ATMOSPHERIC_HUMIDITY,
humid_st->humidity_attr.report_id,
SENSOR_HUB_SYNC);
SENSOR_HUB_SYNC,
humid_st->humidity_attr.logical_minimum < 0);
hid_sensor_power_state(&humid_st->common_attributes, false);

return IIO_VAL_INT;
Expand Down
8 changes: 5 additions & 3 deletions drivers/iio/light/hid-sensor-als.c
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ static int als_read_raw(struct iio_dev *indio_dev,
int report_id = -1;
u32 address;
int ret_type;
s32 min;

*val = 0;
*val2 = 0;
Expand All @@ -102,8 +103,8 @@ static int als_read_raw(struct iio_dev *indio_dev,
case CHANNEL_SCAN_INDEX_INTENSITY:
case CHANNEL_SCAN_INDEX_ILLUM:
report_id = als_state->als_illum.report_id;
address =
HID_USAGE_SENSOR_LIGHT_ILLUM;
min = als_state->als_illum.logical_minimum;
address = HID_USAGE_SENSOR_LIGHT_ILLUM;
break;
default:
report_id = -1;
Expand All @@ -116,7 +117,8 @@ static int als_read_raw(struct iio_dev *indio_dev,
als_state->common_attributes.hsdev,
HID_USAGE_SENSOR_ALS, address,
report_id,
SENSOR_HUB_SYNC);
SENSOR_HUB_SYNC,
min < 0);
hid_sensor_power_state(&als_state->common_attributes,
false);
} else {
Expand Down
8 changes: 5 additions & 3 deletions drivers/iio/light/hid-sensor-prox.c
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ static int prox_read_raw(struct iio_dev *indio_dev,
int report_id = -1;
u32 address;
int ret_type;
s32 min;

*val = 0;
*val2 = 0;
Expand All @@ -81,8 +82,8 @@ static int prox_read_raw(struct iio_dev *indio_dev,
switch (chan->scan_index) {
case CHANNEL_SCAN_INDEX_PRESENCE:
report_id = prox_state->prox_attr.report_id;
address =
HID_USAGE_SENSOR_HUMAN_PRESENCE;
min = prox_state->prox_attr.logical_minimum;
address = HID_USAGE_SENSOR_HUMAN_PRESENCE;
break;
default:
report_id = -1;
Expand All @@ -95,7 +96,8 @@ static int prox_read_raw(struct iio_dev *indio_dev,
prox_state->common_attributes.hsdev,
HID_USAGE_SENSOR_PROX, address,
report_id,
SENSOR_HUB_SYNC);
SENSOR_HUB_SYNC,
min < 0);
hid_sensor_power_state(&prox_state->common_attributes,
false);
} else {
Expand Down
8 changes: 5 additions & 3 deletions drivers/iio/magnetometer/hid-sensor-magn-3d.c
Original file line number Diff line number Diff line change
Expand Up @@ -163,21 +163,23 @@ static int magn_3d_read_raw(struct iio_dev *indio_dev,
int report_id = -1;
u32 address;
int ret_type;
s32 min;

*val = 0;
*val2 = 0;
switch (mask) {
case IIO_CHAN_INFO_RAW:
hid_sensor_power_state(&magn_state->magn_flux_attributes, true);
report_id =
magn_state->magn[chan->address].report_id;
report_id = magn_state->magn[chan->address].report_id;
min = magn_state->magn[chan->address].logical_minimum;
address = magn_3d_addresses[chan->address];
if (report_id >= 0)
*val = sensor_hub_input_attr_get_raw_value(
magn_state->magn_flux_attributes.hsdev,
HID_USAGE_SENSOR_COMPASS_3D, address,
report_id,
SENSOR_HUB_SYNC);
SENSOR_HUB_SYNC,
min < 0);
else {
*val = 0;
hid_sensor_power_state(
Expand Down
12 changes: 3 additions & 9 deletions drivers/iio/magnetometer/st_magn_buffer.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,6 @@ int st_magn_trig_set_state(struct iio_trigger *trig, bool state)
return st_sensors_set_dataready_irq(indio_dev, state);
}

static int st_magn_buffer_preenable(struct iio_dev *indio_dev)
{
return st_sensors_set_enable(indio_dev, true);
}

static int st_magn_buffer_postenable(struct iio_dev *indio_dev)
{
int err;
Expand All @@ -50,7 +45,7 @@ static int st_magn_buffer_postenable(struct iio_dev *indio_dev)
if (err < 0)
goto st_magn_buffer_postenable_error;

return err;
return st_sensors_set_enable(indio_dev, true);

st_magn_buffer_postenable_error:
kfree(mdata->buffer_data);
Expand All @@ -63,19 +58,18 @@ static int st_magn_buffer_predisable(struct iio_dev *indio_dev)
int err;
struct st_sensor_data *mdata = iio_priv(indio_dev);

err = iio_triggered_buffer_predisable(indio_dev);
err = st_sensors_set_enable(indio_dev, false);
if (err < 0)
goto st_magn_buffer_predisable_error;

err = st_sensors_set_enable(indio_dev, false);
err = iio_triggered_buffer_predisable(indio_dev);

st_magn_buffer_predisable_error:
kfree(mdata->buffer_data);
return err;
}

static const struct iio_buffer_setup_ops st_magn_buffer_setup_ops = {
.preenable = &st_magn_buffer_preenable,
.postenable = &st_magn_buffer_postenable,
.predisable = &st_magn_buffer_predisable,
};
Expand Down
8 changes: 5 additions & 3 deletions drivers/iio/orientation/hid-sensor-incl-3d.c
Original file line number Diff line number Diff line change
Expand Up @@ -111,21 +111,23 @@ static int incl_3d_read_raw(struct iio_dev *indio_dev,
int report_id = -1;
u32 address;
int ret_type;
s32 min;

*val = 0;
*val2 = 0;
switch (mask) {
case IIO_CHAN_INFO_RAW:
hid_sensor_power_state(&incl_state->common_attributes, true);
report_id =
incl_state->incl[chan->scan_index].report_id;
report_id = incl_state->incl[chan->scan_index].report_id;
min = incl_state->incl[chan->scan_index].logical_minimum;
address = incl_3d_addresses[chan->scan_index];
if (report_id >= 0)
*val = sensor_hub_input_attr_get_raw_value(
incl_state->common_attributes.hsdev,
HID_USAGE_SENSOR_INCLINOMETER_3D, address,
report_id,
SENSOR_HUB_SYNC);
SENSOR_HUB_SYNC,
min < 0);
else {
hid_sensor_power_state(&incl_state->common_attributes,
false);
Expand Down
8 changes: 5 additions & 3 deletions drivers/iio/pressure/hid-sensor-press.c
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ static int press_read_raw(struct iio_dev *indio_dev,
int report_id = -1;
u32 address;
int ret_type;
s32 min;

*val = 0;
*val2 = 0;
Expand All @@ -85,8 +86,8 @@ static int press_read_raw(struct iio_dev *indio_dev,
switch (chan->scan_index) {
case CHANNEL_SCAN_INDEX_PRESSURE:
report_id = press_state->press_attr.report_id;
address =
HID_USAGE_SENSOR_ATMOSPHERIC_PRESSURE;
min = press_state->press_attr.logical_minimum;
address = HID_USAGE_SENSOR_ATMOSPHERIC_PRESSURE;
break;
default:
report_id = -1;
Expand All @@ -99,7 +100,8 @@ static int press_read_raw(struct iio_dev *indio_dev,
press_state->common_attributes.hsdev,
HID_USAGE_SENSOR_PRESSURE, address,
report_id,
SENSOR_HUB_SYNC);
SENSOR_HUB_SYNC,
min < 0);
hid_sensor_power_state(&press_state->common_attributes,
false);
} else {
Expand Down
3 changes: 2 additions & 1 deletion drivers/iio/temperature/hid-sensor-temperature.c
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,8 @@ static int temperature_read_raw(struct iio_dev *indio_dev,
HID_USAGE_SENSOR_TEMPERATURE,
HID_USAGE_SENSOR_DATA_ENVIRONMENTAL_TEMPERATURE,
temp_st->temperature_attr.report_id,
SENSOR_HUB_SYNC);
SENSOR_HUB_SYNC,
temp_st->temperature_attr.logical_minimum < 0);
hid_sensor_power_state(
&temp_st->common_attributes,
false);
Expand Down
2 changes: 1 addition & 1 deletion drivers/rtc/rtc-hid-sensor-time.c
Original file line number Diff line number Diff line change
Expand Up @@ -213,7 +213,7 @@ static int hid_rtc_read_time(struct device *dev, struct rtc_time *tm)
/* get a report with all values through requesting one value */
sensor_hub_input_attr_get_raw_value(time_state->common_attributes.hsdev,
HID_USAGE_SENSOR_TIME, hid_time_addresses[0],
time_state->info[0].report_id, SENSOR_HUB_SYNC);
time_state->info[0].report_id, SENSOR_HUB_SYNC, false);
/* wait for all values (event) */
ret = wait_for_completion_killable_timeout(
&time_state->comp_last_time, HZ*6);
Expand Down
4 changes: 3 additions & 1 deletion include/linux/hid-sensor-hub.h
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,7 @@ int sensor_hub_input_get_attribute_info(struct hid_sensor_hub_device *hsdev,
* @attr_usage_id: Attribute usage id as per spec
* @report_id: Report id to look for
* @flag: Synchronous or asynchronous read
* @is_signed: If true then fields < 32 bits will be sign-extended
*
* Issues a synchronous or asynchronous read request for an input attribute.
* Returns data upto 32 bits.
Expand All @@ -190,7 +191,8 @@ enum sensor_hub_read_flags {
int sensor_hub_input_attr_get_raw_value(struct hid_sensor_hub_device *hsdev,
u32 usage_id,
u32 attr_usage_id, u32 report_id,
enum sensor_hub_read_flags flag
enum sensor_hub_read_flags flag,
bool is_signed
);

/**
Expand Down

0 comments on commit c648284

Please sign in to comment.