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 | |
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>
-rw-r--r-- | drivers/hid/hid-sensor-hub.c | 65 | ||||
-rw-r--r-- | drivers/iio/accel/hid-sensor-accel-3d.c | 3 | ||||
-rw-r--r-- | drivers/iio/gyro/hid-sensor-gyro-3d.c | 3 | ||||
-rw-r--r-- | drivers/iio/light/hid-sensor-als.c | 3 | ||||
-rw-r--r-- | drivers/iio/light/hid-sensor-prox.c | 3 | ||||
-rw-r--r-- | drivers/iio/magnetometer/hid-sensor-magn-3d.c | 3 | ||||
-rw-r--r-- | drivers/iio/orientation/hid-sensor-incl-3d.c | 3 | ||||
-rw-r--r-- | drivers/iio/pressure/hid-sensor-press.c | 3 | ||||
-rw-r--r-- | drivers/rtc/rtc-hid-sensor-time.c | 2 | ||||
-rw-r--r-- | include/linux/hid-sensor-hub.h | 20 |
10 files changed, 64 insertions, 44 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; |
diff --git a/drivers/iio/accel/hid-sensor-accel-3d.c b/drivers/iio/accel/hid-sensor-accel-3d.c index d5d95317003a..0085c2faeaaa 100644 --- a/drivers/iio/accel/hid-sensor-accel-3d.c +++ b/drivers/iio/accel/hid-sensor-accel-3d.c | |||
@@ -130,7 +130,8 @@ static int accel_3d_read_raw(struct iio_dev *indio_dev, | |||
130 | *val = sensor_hub_input_attr_get_raw_value( | 130 | *val = sensor_hub_input_attr_get_raw_value( |
131 | accel_state->common_attributes.hsdev, | 131 | accel_state->common_attributes.hsdev, |
132 | HID_USAGE_SENSOR_ACCEL_3D, address, | 132 | HID_USAGE_SENSOR_ACCEL_3D, address, |
133 | report_id); | 133 | report_id, |
134 | SENSOR_HUB_SYNC); | ||
134 | else { | 135 | else { |
135 | *val = 0; | 136 | *val = 0; |
136 | hid_sensor_power_state(&accel_state->common_attributes, | 137 | hid_sensor_power_state(&accel_state->common_attributes, |
diff --git a/drivers/iio/gyro/hid-sensor-gyro-3d.c b/drivers/iio/gyro/hid-sensor-gyro-3d.c index a3ea1e8785d7..bdcd105aba26 100644 --- a/drivers/iio/gyro/hid-sensor-gyro-3d.c +++ b/drivers/iio/gyro/hid-sensor-gyro-3d.c | |||
@@ -130,7 +130,8 @@ static int gyro_3d_read_raw(struct iio_dev *indio_dev, | |||
130 | *val = sensor_hub_input_attr_get_raw_value( | 130 | *val = sensor_hub_input_attr_get_raw_value( |
131 | gyro_state->common_attributes.hsdev, | 131 | gyro_state->common_attributes.hsdev, |
132 | HID_USAGE_SENSOR_GYRO_3D, address, | 132 | HID_USAGE_SENSOR_GYRO_3D, address, |
133 | report_id); | 133 | report_id, |
134 | SENSOR_HUB_SYNC); | ||
134 | else { | 135 | else { |
135 | *val = 0; | 136 | *val = 0; |
136 | hid_sensor_power_state(&gyro_state->common_attributes, | 137 | hid_sensor_power_state(&gyro_state->common_attributes, |
diff --git a/drivers/iio/light/hid-sensor-als.c b/drivers/iio/light/hid-sensor-als.c index a5283d75c096..321862da626b 100644 --- a/drivers/iio/light/hid-sensor-als.c +++ b/drivers/iio/light/hid-sensor-als.c | |||
@@ -109,7 +109,8 @@ static int als_read_raw(struct iio_dev *indio_dev, | |||
109 | *val = sensor_hub_input_attr_get_raw_value( | 109 | *val = sensor_hub_input_attr_get_raw_value( |
110 | als_state->common_attributes.hsdev, | 110 | als_state->common_attributes.hsdev, |
111 | HID_USAGE_SENSOR_ALS, address, | 111 | HID_USAGE_SENSOR_ALS, address, |
112 | report_id); | 112 | report_id, |
113 | SENSOR_HUB_SYNC); | ||
113 | hid_sensor_power_state(&als_state->common_attributes, | 114 | hid_sensor_power_state(&als_state->common_attributes, |
114 | false); | 115 | false); |
115 | } else { | 116 | } else { |
diff --git a/drivers/iio/light/hid-sensor-prox.c b/drivers/iio/light/hid-sensor-prox.c index f5a514698fd8..db9c60e47276 100644 --- a/drivers/iio/light/hid-sensor-prox.c +++ b/drivers/iio/light/hid-sensor-prox.c | |||
@@ -105,7 +105,8 @@ static int prox_read_raw(struct iio_dev *indio_dev, | |||
105 | *val = sensor_hub_input_attr_get_raw_value( | 105 | *val = sensor_hub_input_attr_get_raw_value( |
106 | prox_state->common_attributes.hsdev, | 106 | prox_state->common_attributes.hsdev, |
107 | HID_USAGE_SENSOR_PROX, address, | 107 | HID_USAGE_SENSOR_PROX, address, |
108 | report_id); | 108 | report_id, |
109 | SENSOR_HUB_SYNC); | ||
109 | hid_sensor_power_state(&prox_state->common_attributes, | 110 | hid_sensor_power_state(&prox_state->common_attributes, |
110 | false); | 111 | false); |
111 | } else { | 112 | } else { |
diff --git a/drivers/iio/magnetometer/hid-sensor-magn-3d.c b/drivers/iio/magnetometer/hid-sensor-magn-3d.c index 6294575d2777..4d299f39ffd1 100644 --- a/drivers/iio/magnetometer/hid-sensor-magn-3d.c +++ b/drivers/iio/magnetometer/hid-sensor-magn-3d.c | |||
@@ -178,7 +178,8 @@ static int magn_3d_read_raw(struct iio_dev *indio_dev, | |||
178 | *val = sensor_hub_input_attr_get_raw_value( | 178 | *val = sensor_hub_input_attr_get_raw_value( |
179 | magn_state->common_attributes.hsdev, | 179 | magn_state->common_attributes.hsdev, |
180 | HID_USAGE_SENSOR_COMPASS_3D, address, | 180 | HID_USAGE_SENSOR_COMPASS_3D, address, |
181 | report_id); | 181 | report_id, |
182 | SENSOR_HUB_SYNC); | ||
182 | else { | 183 | else { |
183 | *val = 0; | 184 | *val = 0; |
184 | hid_sensor_power_state(&magn_state->common_attributes, | 185 | hid_sensor_power_state(&magn_state->common_attributes, |
diff --git a/drivers/iio/orientation/hid-sensor-incl-3d.c b/drivers/iio/orientation/hid-sensor-incl-3d.c index 1ff181bbbcef..45bed080b4a6 100644 --- a/drivers/iio/orientation/hid-sensor-incl-3d.c +++ b/drivers/iio/orientation/hid-sensor-incl-3d.c | |||
@@ -132,7 +132,8 @@ static int incl_3d_read_raw(struct iio_dev *indio_dev, | |||
132 | *val = sensor_hub_input_attr_get_raw_value( | 132 | *val = sensor_hub_input_attr_get_raw_value( |
133 | incl_state->common_attributes.hsdev, | 133 | incl_state->common_attributes.hsdev, |
134 | HID_USAGE_SENSOR_INCLINOMETER_3D, address, | 134 | HID_USAGE_SENSOR_INCLINOMETER_3D, address, |
135 | report_id); | 135 | report_id, |
136 | SENSOR_HUB_SYNC); | ||
136 | else { | 137 | else { |
137 | hid_sensor_power_state(&incl_state->common_attributes, | 138 | hid_sensor_power_state(&incl_state->common_attributes, |
138 | false); | 139 | false); |
diff --git a/drivers/iio/pressure/hid-sensor-press.c b/drivers/iio/pressure/hid-sensor-press.c index 764928682df2..ac150f0c8b02 100644 --- a/drivers/iio/pressure/hid-sensor-press.c +++ b/drivers/iio/pressure/hid-sensor-press.c | |||
@@ -108,7 +108,8 @@ static int press_read_raw(struct iio_dev *indio_dev, | |||
108 | *val = sensor_hub_input_attr_get_raw_value( | 108 | *val = sensor_hub_input_attr_get_raw_value( |
109 | press_state->common_attributes.hsdev, | 109 | press_state->common_attributes.hsdev, |
110 | HID_USAGE_SENSOR_PRESSURE, address, | 110 | HID_USAGE_SENSOR_PRESSURE, address, |
111 | report_id); | 111 | report_id, |
112 | SENSOR_HUB_SYNC); | ||
112 | hid_sensor_power_state(&press_state->common_attributes, | 113 | hid_sensor_power_state(&press_state->common_attributes, |
113 | false); | 114 | false); |
114 | } else { | 115 | } else { |
diff --git a/drivers/rtc/rtc-hid-sensor-time.c b/drivers/rtc/rtc-hid-sensor-time.c index ae7c2ba440cf..af4f85a66b39 100644 --- a/drivers/rtc/rtc-hid-sensor-time.c +++ b/drivers/rtc/rtc-hid-sensor-time.c | |||
@@ -213,7 +213,7 @@ static int hid_rtc_read_time(struct device *dev, struct rtc_time *tm) | |||
213 | /* get a report with all values through requesting one value */ | 213 | /* get a report with all values through requesting one value */ |
214 | sensor_hub_input_attr_get_raw_value(time_state->common_attributes.hsdev, | 214 | sensor_hub_input_attr_get_raw_value(time_state->common_attributes.hsdev, |
215 | HID_USAGE_SENSOR_TIME, hid_time_addresses[0], | 215 | HID_USAGE_SENSOR_TIME, hid_time_addresses[0], |
216 | time_state->info[0].report_id); | 216 | time_state->info[0].report_id, SENSOR_HUB_SYNC); |
217 | /* wait for all values (event) */ | 217 | /* wait for all values (event) */ |
218 | ret = wait_for_completion_killable_timeout( | 218 | ret = wait_for_completion_killable_timeout( |
219 | &time_state->comp_last_time, HZ*6); | 219 | &time_state->comp_last_time, HZ*6); |
diff --git a/include/linux/hid-sensor-hub.h b/include/linux/hid-sensor-hub.h index 60a34277ddf2..4c49b041922d 100644 --- a/include/linux/hid-sensor-hub.h +++ b/include/linux/hid-sensor-hub.h | |||
@@ -169,19 +169,27 @@ int sensor_hub_input_get_attribute_info(struct hid_sensor_hub_device *hsdev, | |||
169 | struct hid_sensor_hub_attribute_info *info); | 169 | struct hid_sensor_hub_attribute_info *info); |
170 | 170 | ||
171 | /** | 171 | /** |
172 | * sensor_hub_input_attr_get_raw_value() - Synchronous read request | 172 | * sensor_hub_input_attr_get_raw_value() - Attribute read request |
173 | * @usage_id: Attribute usage id of parent physical device as per spec | 173 | * @usage_id: Attribute usage id of parent physical device as per spec |
174 | * @attr_usage_id: Attribute usage id as per spec | 174 | * @attr_usage_id: Attribute usage id as per spec |
175 | * @report_id: Report id to look for | 175 | * @report_id: Report id to look for |
176 | * @flag: Synchronous or asynchronous read | ||
176 | * | 177 | * |
177 | * Issues a synchronous read request for an input attribute. Returns | 178 | * Issues a synchronous or asynchronous read request for an input attribute. |
178 | * data upto 32 bits. Since client can get events, so this call should | 179 | * Returns data upto 32 bits. |
179 | * not be used for data paths, this will impact performance. | ||
180 | */ | 180 | */ |
181 | 181 | ||
182 | enum sensor_hub_read_flags { | ||
183 | SENSOR_HUB_SYNC, | ||
184 | SENSOR_HUB_ASYNC, | ||
185 | }; | ||
186 | |||
182 | int sensor_hub_input_attr_get_raw_value(struct hid_sensor_hub_device *hsdev, | 187 | int sensor_hub_input_attr_get_raw_value(struct hid_sensor_hub_device *hsdev, |
183 | u32 usage_id, | 188 | u32 usage_id, |
184 | u32 attr_usage_id, u32 report_id); | 189 | u32 attr_usage_id, u32 report_id, |
190 | enum sensor_hub_read_flags flag | ||
191 | ); | ||
192 | |||
185 | /** | 193 | /** |
186 | * sensor_hub_set_feature() - Feature set request | 194 | * sensor_hub_set_feature() - Feature set request |
187 | * @report_id: Report id to look for | 195 | * @report_id: Report id to look for |