Commit 6bee0b1f authored by Srinivas Pandruvada's avatar Srinivas Pandruvada Committed by Greg Kroah-Hartman

iio: hid-sensor: Store restore poll and hysteresis on S3

commit 5d9854ea upstream.

This change undo the change done by 'commit 3bec2474
("iio: hid-sensor-trigger: Change get poll value function order to avoid
sensor properties losing after resume from S3")' as this breaks some
USB/i2c sensor hubs.

Instead of relying on HW for restoring poll and hysteresis, driver stores
and restores on resume (S3). In this way user space modified settings are
not lost for any kind of sensor hub behavior.

In this change, whenever user space modifies sampling frequency or
hysteresis driver will get the feature value from the hub and store in the
per device hid_sensor_common data structure. On resume callback from S3,
system will set the feature to sensor hub, if user space ever modified the
feature value.

Fixes: 3bec2474 ("iio: hid-sensor-trigger: Change get poll value function order to avoid sensor properties losing after resume from S3")
Reported-by: default avatarRitesh Raj Sarraf <rrs@researchut.com>
Tested-by: default avatarRitesh Raj Sarraf <rrs@researchut.com>
Tested-by: default avatarSong, Hongyan <hongyan.song@intel.com>
Signed-off-by: default avatarSrinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
Signed-off-by: default avatarJonathan Cameron <jic23@kernel.org>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent a99462b1
...@@ -217,7 +217,15 @@ int hid_sensor_write_samp_freq_value(struct hid_sensor_common *st, ...@@ -217,7 +217,15 @@ int hid_sensor_write_samp_freq_value(struct hid_sensor_common *st,
if (ret < 0 || value < 0) if (ret < 0 || value < 0)
ret = -EINVAL; ret = -EINVAL;
return ret; ret = sensor_hub_get_feature(st->hsdev,
st->poll.report_id,
st->poll.index, sizeof(value), &value);
if (ret < 0 || value < 0)
return -EINVAL;
st->poll_interval = value;
return 0;
} }
EXPORT_SYMBOL(hid_sensor_write_samp_freq_value); EXPORT_SYMBOL(hid_sensor_write_samp_freq_value);
...@@ -259,7 +267,16 @@ int hid_sensor_write_raw_hyst_value(struct hid_sensor_common *st, ...@@ -259,7 +267,16 @@ int hid_sensor_write_raw_hyst_value(struct hid_sensor_common *st,
if (ret < 0 || value < 0) if (ret < 0 || value < 0)
ret = -EINVAL; ret = -EINVAL;
return ret; ret = sensor_hub_get_feature(st->hsdev,
st->sensitivity.report_id,
st->sensitivity.index, sizeof(value),
&value);
if (ret < 0 || value < 0)
return -EINVAL;
st->raw_hystersis = value;
return 0;
} }
EXPORT_SYMBOL(hid_sensor_write_raw_hyst_value); EXPORT_SYMBOL(hid_sensor_write_raw_hyst_value);
...@@ -355,6 +372,9 @@ int hid_sensor_get_reporting_interval(struct hid_sensor_hub_device *hsdev, ...@@ -355,6 +372,9 @@ int hid_sensor_get_reporting_interval(struct hid_sensor_hub_device *hsdev,
/* Default unit of measure is milliseconds */ /* Default unit of measure is milliseconds */
if (st->poll.units == 0) if (st->poll.units == 0)
st->poll.units = HID_USAGE_SENSOR_UNITS_MILLISECOND; st->poll.units = HID_USAGE_SENSOR_UNITS_MILLISECOND;
st->poll_interval = -1;
return 0; return 0;
} }
...@@ -377,6 +397,8 @@ int hid_sensor_parse_common_attributes(struct hid_sensor_hub_device *hsdev, ...@@ -377,6 +397,8 @@ int hid_sensor_parse_common_attributes(struct hid_sensor_hub_device *hsdev,
HID_USAGE_SENSOR_PROY_POWER_STATE, HID_USAGE_SENSOR_PROY_POWER_STATE,
&st->power_state); &st->power_state);
st->raw_hystersis = -1;
sensor_hub_input_get_attribute_info(hsdev, sensor_hub_input_get_attribute_info(hsdev,
HID_FEATURE_REPORT, usage_id, HID_FEATURE_REPORT, usage_id,
HID_USAGE_SENSOR_PROP_SENSITIVITY_ABS, HID_USAGE_SENSOR_PROP_SENSITIVITY_ABS,
......
...@@ -51,6 +51,8 @@ static int _hid_sensor_power_state(struct hid_sensor_common *st, bool state) ...@@ -51,6 +51,8 @@ static int _hid_sensor_power_state(struct hid_sensor_common *st, bool state)
st->report_state.report_id, st->report_state.report_id,
st->report_state.index, st->report_state.index,
HID_USAGE_SENSOR_PROP_REPORTING_STATE_ALL_EVENTS_ENUM); HID_USAGE_SENSOR_PROP_REPORTING_STATE_ALL_EVENTS_ENUM);
poll_value = hid_sensor_read_poll_value(st);
} else { } else {
int val; int val;
...@@ -87,9 +89,7 @@ static int _hid_sensor_power_state(struct hid_sensor_common *st, bool state) ...@@ -87,9 +89,7 @@ static int _hid_sensor_power_state(struct hid_sensor_common *st, bool state)
sensor_hub_get_feature(st->hsdev, st->power_state.report_id, sensor_hub_get_feature(st->hsdev, st->power_state.report_id,
st->power_state.index, st->power_state.index,
sizeof(state_val), &state_val); sizeof(state_val), &state_val);
if (state) if (state && poll_value)
poll_value = hid_sensor_read_poll_value(st);
if (poll_value > 0)
msleep_interruptible(poll_value * 2); msleep_interruptible(poll_value * 2);
return 0; return 0;
...@@ -127,6 +127,20 @@ static void hid_sensor_set_power_work(struct work_struct *work) ...@@ -127,6 +127,20 @@ static void hid_sensor_set_power_work(struct work_struct *work)
struct hid_sensor_common *attrb = container_of(work, struct hid_sensor_common *attrb = container_of(work,
struct hid_sensor_common, struct hid_sensor_common,
work); work);
if (attrb->poll_interval >= 0)
sensor_hub_set_feature(attrb->hsdev, attrb->poll.report_id,
attrb->poll.index,
sizeof(attrb->poll_interval),
&attrb->poll_interval);
if (attrb->raw_hystersis >= 0)
sensor_hub_set_feature(attrb->hsdev,
attrb->sensitivity.report_id,
attrb->sensitivity.index,
sizeof(attrb->raw_hystersis),
&attrb->raw_hystersis);
_hid_sensor_power_state(attrb, true); _hid_sensor_power_state(attrb, true);
} }
......
...@@ -231,6 +231,8 @@ struct hid_sensor_common { ...@@ -231,6 +231,8 @@ struct hid_sensor_common {
unsigned usage_id; unsigned usage_id;
atomic_t data_ready; atomic_t data_ready;
atomic_t user_requested_state; atomic_t user_requested_state;
int poll_interval;
int raw_hystersis;
struct iio_trigger *trigger; struct iio_trigger *trigger;
struct hid_sensor_hub_attribute_info poll; struct hid_sensor_hub_attribute_info poll;
struct hid_sensor_hub_attribute_info report_state; struct hid_sensor_hub_attribute_info report_state;
......
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