aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSrinivas Pandruvada <srinivas.pandruvada@linux.intel.com>2017-04-07 20:13:17 -0400
committerJonathan Cameron <jic23@kernel.org>2017-04-08 10:13:36 -0400
commit5d9854eaea776441b38a9a45b4e6879524c4f48c (patch)
tree305609e2526bcb3432b5b0abc98efe074c822d48
parenta6d361404d81a03107a3475876afc22e1b84d5de (diff)
iio: hid-sensor: Store restore poll and hysteresis on S3
This change undo the change done by 'commit 3bec24747446 ("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: 3bec24747446 ("iio: hid-sensor-trigger: Change get poll value function order to avoid sensor properties losing after resume from S3") Reported-by: Ritesh Raj Sarraf <rrs@researchut.com> Tested-by: Ritesh Raj Sarraf <rrs@researchut.com> Tested-by: Song, Hongyan <hongyan.song@intel.com> Cc: stable@vger.kernel.org Signed-off-by: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com> Signed-off-by: Jonathan Cameron <jic23@kernel.org>
-rw-r--r--drivers/iio/common/hid-sensors/hid-sensor-attributes.c26
-rw-r--r--drivers/iio/common/hid-sensors/hid-sensor-trigger.c20
-rw-r--r--include/linux/hid-sensor-hub.h2
3 files changed, 43 insertions, 5 deletions
diff --git a/drivers/iio/common/hid-sensors/hid-sensor-attributes.c b/drivers/iio/common/hid-sensors/hid-sensor-attributes.c
index 01e02b9926d4..ca742ac8f128 100644
--- a/drivers/iio/common/hid-sensors/hid-sensor-attributes.c
+++ b/drivers/iio/common/hid-sensors/hid-sensor-attributes.c
@@ -221,7 +221,15 @@ int hid_sensor_write_samp_freq_value(struct hid_sensor_common *st,
221 if (ret < 0 || value < 0) 221 if (ret < 0 || value < 0)
222 ret = -EINVAL; 222 ret = -EINVAL;
223 223
224 return ret; 224 ret = sensor_hub_get_feature(st->hsdev,
225 st->poll.report_id,
226 st->poll.index, sizeof(value), &value);
227 if (ret < 0 || value < 0)
228 return -EINVAL;
229
230 st->poll_interval = value;
231
232 return 0;
225} 233}
226EXPORT_SYMBOL(hid_sensor_write_samp_freq_value); 234EXPORT_SYMBOL(hid_sensor_write_samp_freq_value);
227 235
@@ -266,7 +274,16 @@ int hid_sensor_write_raw_hyst_value(struct hid_sensor_common *st,
266 if (ret < 0 || value < 0) 274 if (ret < 0 || value < 0)
267 ret = -EINVAL; 275 ret = -EINVAL;
268 276
269 return ret; 277 ret = sensor_hub_get_feature(st->hsdev,
278 st->sensitivity.report_id,
279 st->sensitivity.index, sizeof(value),
280 &value);
281 if (ret < 0 || value < 0)
282 return -EINVAL;
283
284 st->raw_hystersis = value;
285
286 return 0;
270} 287}
271EXPORT_SYMBOL(hid_sensor_write_raw_hyst_value); 288EXPORT_SYMBOL(hid_sensor_write_raw_hyst_value);
272 289
@@ -369,6 +386,9 @@ int hid_sensor_get_reporting_interval(struct hid_sensor_hub_device *hsdev,
369 /* Default unit of measure is milliseconds */ 386 /* Default unit of measure is milliseconds */
370 if (st->poll.units == 0) 387 if (st->poll.units == 0)
371 st->poll.units = HID_USAGE_SENSOR_UNITS_MILLISECOND; 388 st->poll.units = HID_USAGE_SENSOR_UNITS_MILLISECOND;
389
390 st->poll_interval = -1;
391
372 return 0; 392 return 0;
373 393
374} 394}
@@ -399,6 +419,8 @@ int hid_sensor_parse_common_attributes(struct hid_sensor_hub_device *hsdev,
399 HID_USAGE_SENSOR_PROP_SENSITIVITY_ABS, 419 HID_USAGE_SENSOR_PROP_SENSITIVITY_ABS,
400 &st->sensitivity); 420 &st->sensitivity);
401 421
422 st->raw_hystersis = -1;
423
402 sensor_hub_input_get_attribute_info(hsdev, 424 sensor_hub_input_get_attribute_info(hsdev,
403 HID_INPUT_REPORT, usage_id, 425 HID_INPUT_REPORT, usage_id,
404 HID_USAGE_SENSOR_TIME_TIMESTAMP, 426 HID_USAGE_SENSOR_TIME_TIMESTAMP,
diff --git a/drivers/iio/common/hid-sensors/hid-sensor-trigger.c b/drivers/iio/common/hid-sensors/hid-sensor-trigger.c
index ecf592d69043..60829340a82e 100644
--- a/drivers/iio/common/hid-sensors/hid-sensor-trigger.c
+++ b/drivers/iio/common/hid-sensors/hid-sensor-trigger.c
@@ -51,6 +51,8 @@ static int _hid_sensor_power_state(struct hid_sensor_common *st, bool state)
51 st->report_state.report_id, 51 st->report_state.report_id,
52 st->report_state.index, 52 st->report_state.index,
53 HID_USAGE_SENSOR_PROP_REPORTING_STATE_ALL_EVENTS_ENUM); 53 HID_USAGE_SENSOR_PROP_REPORTING_STATE_ALL_EVENTS_ENUM);
54
55 poll_value = hid_sensor_read_poll_value(st);
54 } else { 56 } else {
55 int val; 57 int val;
56 58
@@ -87,9 +89,7 @@ static int _hid_sensor_power_state(struct hid_sensor_common *st, bool state)
87 sensor_hub_get_feature(st->hsdev, st->power_state.report_id, 89 sensor_hub_get_feature(st->hsdev, st->power_state.report_id,
88 st->power_state.index, 90 st->power_state.index,
89 sizeof(state_val), &state_val); 91 sizeof(state_val), &state_val);
90 if (state) 92 if (state && poll_value)
91 poll_value = hid_sensor_read_poll_value(st);
92 if (poll_value > 0)
93 msleep_interruptible(poll_value * 2); 93 msleep_interruptible(poll_value * 2);
94 94
95 return 0; 95 return 0;
@@ -127,6 +127,20 @@ static void hid_sensor_set_power_work(struct work_struct *work)
127 struct hid_sensor_common *attrb = container_of(work, 127 struct hid_sensor_common *attrb = container_of(work,
128 struct hid_sensor_common, 128 struct hid_sensor_common,
129 work); 129 work);
130
131 if (attrb->poll_interval >= 0)
132 sensor_hub_set_feature(attrb->hsdev, attrb->poll.report_id,
133 attrb->poll.index,
134 sizeof(attrb->poll_interval),
135 &attrb->poll_interval);
136
137 if (attrb->raw_hystersis >= 0)
138 sensor_hub_set_feature(attrb->hsdev,
139 attrb->sensitivity.report_id,
140 attrb->sensitivity.index,
141 sizeof(attrb->raw_hystersis),
142 &attrb->raw_hystersis);
143
130 _hid_sensor_power_state(attrb, true); 144 _hid_sensor_power_state(attrb, true);
131} 145}
132 146
diff --git a/include/linux/hid-sensor-hub.h b/include/linux/hid-sensor-hub.h
index 7ef111d3ecc5..f32d7c392c1e 100644
--- a/include/linux/hid-sensor-hub.h
+++ b/include/linux/hid-sensor-hub.h
@@ -231,6 +231,8 @@ struct hid_sensor_common {
231 unsigned usage_id; 231 unsigned usage_id;
232 atomic_t data_ready; 232 atomic_t data_ready;
233 atomic_t user_requested_state; 233 atomic_t user_requested_state;
234 int poll_interval;
235 int raw_hystersis;
234 struct iio_trigger *trigger; 236 struct iio_trigger *trigger;
235 int timestamp_ns_scale; 237 int timestamp_ns_scale;
236 struct hid_sensor_hub_attribute_info poll; 238 struct hid_sensor_hub_attribute_info poll;