diff options
author | Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com> | 2015-02-19 18:33:56 -0500 |
---|---|---|
committer | Jiri Kosina <jkosina@suse.cz> | 2015-02-23 09:16:37 -0500 |
commit | b3f4737d00de317d1549d5cb5b1dad90e19f5cec (patch) | |
tree | 92cb55d8f19f340f2daf779336368cb3a34e8426 /drivers/hid | |
parent | cb67126f32f008b9abe97fbfca9b23a797b2458a (diff) |
HID: hid-sensor-hub: Extend API for async reads
Add additional flag to read in async mode. In this mode the caller will get
reply via registered callback for capture_sample. Callbacks can be registered
using sensor_hub_register_callback function. The usage id parameter of the
capture_sample can be matched with the usage id of the requested attribute.
Signed-off-by: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
Acked-by: Jonathan Cameron <jic23@kernel.org>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
Diffstat (limited to 'drivers/hid')
-rw-r--r-- | drivers/hid/hid-sensor-hub.c | 65 |
1 files changed, 35 insertions, 30 deletions
diff --git a/drivers/hid/hid-sensor-hub.c b/drivers/hid/hid-sensor-hub.c index c325f85fa3a6..0a9162363164 100644 --- a/drivers/hid/hid-sensor-hub.c +++ b/drivers/hid/hid-sensor-hub.c | |||
@@ -250,48 +250,53 @@ EXPORT_SYMBOL_GPL(sensor_hub_get_feature); | |||
250 | 250 | ||
251 | int sensor_hub_input_attr_get_raw_value(struct hid_sensor_hub_device *hsdev, | 251 | int sensor_hub_input_attr_get_raw_value(struct hid_sensor_hub_device *hsdev, |
252 | u32 usage_id, | 252 | u32 usage_id, |
253 | u32 attr_usage_id, u32 report_id) | 253 | u32 attr_usage_id, u32 report_id, |
254 | enum sensor_hub_read_flags flag) | ||
254 | { | 255 | { |
255 | struct sensor_hub_data *data = hid_get_drvdata(hsdev->hdev); | 256 | struct sensor_hub_data *data = hid_get_drvdata(hsdev->hdev); |
256 | unsigned long flags; | 257 | unsigned long flags; |
257 | struct hid_report *report; | 258 | struct hid_report *report; |
258 | int ret_val = 0; | 259 | int ret_val = 0; |
259 | 260 | ||
260 | mutex_lock(&hsdev->mutex); | 261 | report = sensor_hub_report(report_id, hsdev->hdev, |
261 | memset(&hsdev->pending, 0, sizeof(hsdev->pending)); | 262 | HID_INPUT_REPORT); |
262 | init_completion(&hsdev->pending.ready); | ||
263 | hsdev->pending.usage_id = usage_id; | ||
264 | hsdev->pending.attr_usage_id = attr_usage_id; | ||
265 | hsdev->pending.raw_size = 0; | ||
266 | |||
267 | spin_lock_irqsave(&data->lock, flags); | ||
268 | hsdev->pending.status = true; | ||
269 | spin_unlock_irqrestore(&data->lock, flags); | ||
270 | report = sensor_hub_report(report_id, hsdev->hdev, HID_INPUT_REPORT); | ||
271 | if (!report) | 263 | if (!report) |
272 | goto err_free; | 264 | return -EINVAL; |
273 | 265 | ||
266 | mutex_lock(&hsdev->mutex); | ||
267 | if (flag == SENSOR_HUB_SYNC) { | ||
268 | memset(&hsdev->pending, 0, sizeof(hsdev->pending)); | ||
269 | init_completion(&hsdev->pending.ready); | ||
270 | hsdev->pending.usage_id = usage_id; | ||
271 | hsdev->pending.attr_usage_id = attr_usage_id; | ||
272 | hsdev->pending.raw_size = 0; | ||
273 | |||
274 | spin_lock_irqsave(&data->lock, flags); | ||
275 | hsdev->pending.status = true; | ||
276 | spin_unlock_irqrestore(&data->lock, flags); | ||
277 | } | ||
274 | mutex_lock(&data->mutex); | 278 | mutex_lock(&data->mutex); |
275 | hid_hw_request(hsdev->hdev, report, HID_REQ_GET_REPORT); | 279 | hid_hw_request(hsdev->hdev, report, HID_REQ_GET_REPORT); |
276 | mutex_unlock(&data->mutex); | 280 | mutex_unlock(&data->mutex); |
277 | wait_for_completion_interruptible_timeout(&hsdev->pending.ready, HZ*5); | 281 | if (flag == SENSOR_HUB_SYNC) { |
278 | switch (hsdev->pending.raw_size) { | 282 | wait_for_completion_interruptible_timeout( |
279 | case 1: | 283 | &hsdev->pending.ready, HZ*5); |
280 | ret_val = *(u8 *)hsdev->pending.raw_data; | 284 | switch (hsdev->pending.raw_size) { |
281 | break; | 285 | case 1: |
282 | case 2: | 286 | ret_val = *(u8 *)hsdev->pending.raw_data; |
283 | ret_val = *(u16 *)hsdev->pending.raw_data; | 287 | break; |
284 | break; | 288 | case 2: |
285 | case 4: | 289 | ret_val = *(u16 *)hsdev->pending.raw_data; |
286 | ret_val = *(u32 *)hsdev->pending.raw_data; | 290 | break; |
287 | break; | 291 | case 4: |
288 | default: | 292 | ret_val = *(u32 *)hsdev->pending.raw_data; |
289 | ret_val = 0; | 293 | break; |
294 | default: | ||
295 | ret_val = 0; | ||
296 | } | ||
297 | kfree(hsdev->pending.raw_data); | ||
298 | hsdev->pending.status = false; | ||
290 | } | 299 | } |
291 | kfree(hsdev->pending.raw_data); | ||
292 | |||
293 | err_free: | ||
294 | hsdev->pending.status = false; | ||
295 | mutex_unlock(&hsdev->mutex); | 300 | mutex_unlock(&hsdev->mutex); |
296 | 301 | ||
297 | return ret_val; | 302 | return ret_val; |