aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSrinivas Pandruvada <srinivas.pandruvada@linux.intel.com>2015-02-19 18:33:56 -0500
committerJiri Kosina <jkosina@suse.cz>2015-02-23 09:16:37 -0500
commitb3f4737d00de317d1549d5cb5b1dad90e19f5cec (patch)
tree92cb55d8f19f340f2daf779336368cb3a34e8426
parentcb67126f32f008b9abe97fbfca9b23a797b2458a (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.c65
-rw-r--r--drivers/iio/accel/hid-sensor-accel-3d.c3
-rw-r--r--drivers/iio/gyro/hid-sensor-gyro-3d.c3
-rw-r--r--drivers/iio/light/hid-sensor-als.c3
-rw-r--r--drivers/iio/light/hid-sensor-prox.c3
-rw-r--r--drivers/iio/magnetometer/hid-sensor-magn-3d.c3
-rw-r--r--drivers/iio/orientation/hid-sensor-incl-3d.c3
-rw-r--r--drivers/iio/pressure/hid-sensor-press.c3
-rw-r--r--drivers/rtc/rtc-hid-sensor-time.c2
-rw-r--r--include/linux/hid-sensor-hub.h20
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
251int sensor_hub_input_attr_get_raw_value(struct hid_sensor_hub_device *hsdev, 251int 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
293err_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
182enum sensor_hub_read_flags {
183 SENSOR_HUB_SYNC,
184 SENSOR_HUB_ASYNC,
185};
186
182int sensor_hub_input_attr_get_raw_value(struct hid_sensor_hub_device *hsdev, 187int 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