aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSrinivas Pandruvada <srinivas.pandruvada@linux.intel.com>2015-02-19 18:35:25 -0500
committerJiri Kosina <jkosina@suse.cz>2015-02-23 09:19:49 -0500
commit6adc83fca74ab73abcbd3b394cf3a8fd3701db99 (patch)
tree57cd3f15e4b469ddf6ccb177edd473a80d1658cb
parentb3f4737d00de317d1549d5cb5b1dad90e19f5cec (diff)
HID: hid-sensor-hub: Enhance get feature report API
Some hid sensor feature report can contain more than one reports. This API can now support receiving multiple values from the feature report. Also update the parameters in the users of this API. 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.c15
-rw-r--r--drivers/iio/common/hid-sensors/hid-sensor-attributes.c13
-rw-r--r--drivers/iio/common/hid-sensors/hid-sensor-trigger.c4
-rw-r--r--include/linux/hid-sensor-hub.h8
4 files changed, 27 insertions, 13 deletions
diff --git a/drivers/hid/hid-sensor-hub.c b/drivers/hid/hid-sensor-hub.c
index 0a9162363164..c025c489270d 100644
--- a/drivers/hid/hid-sensor-hub.c
+++ b/drivers/hid/hid-sensor-hub.c
@@ -223,10 +223,11 @@ done_proc:
223EXPORT_SYMBOL_GPL(sensor_hub_set_feature); 223EXPORT_SYMBOL_GPL(sensor_hub_set_feature);
224 224
225int sensor_hub_get_feature(struct hid_sensor_hub_device *hsdev, u32 report_id, 225int sensor_hub_get_feature(struct hid_sensor_hub_device *hsdev, u32 report_id,
226 u32 field_index, s32 *value) 226 u32 field_index, int buffer_size, void *buffer)
227{ 227{
228 struct hid_report *report; 228 struct hid_report *report;
229 struct sensor_hub_data *data = hid_get_drvdata(hsdev->hdev); 229 struct sensor_hub_data *data = hid_get_drvdata(hsdev->hdev);
230 int report_size;
230 int ret = 0; 231 int ret = 0;
231 232
232 mutex_lock(&data->mutex); 233 mutex_lock(&data->mutex);
@@ -238,7 +239,17 @@ int sensor_hub_get_feature(struct hid_sensor_hub_device *hsdev, u32 report_id,
238 } 239 }
239 hid_hw_request(hsdev->hdev, report, HID_REQ_GET_REPORT); 240 hid_hw_request(hsdev->hdev, report, HID_REQ_GET_REPORT);
240 hid_hw_wait(hsdev->hdev); 241 hid_hw_wait(hsdev->hdev);
241 *value = report->field[field_index]->value[0]; 242
243 /* calculate number of bytes required to read this field */
244 report_size = DIV_ROUND_UP(report->field[field_index]->report_size,
245 8) *
246 report->field[field_index]->report_count;
247 if (!report_size) {
248 ret = -EINVAL;
249 goto done_proc;
250 }
251 ret = min(report_size, buffer_size);
252 memcpy(buffer, report->field[field_index]->value, ret);
242 253
243done_proc: 254done_proc:
244 mutex_unlock(&data->mutex); 255 mutex_unlock(&data->mutex);
diff --git a/drivers/iio/common/hid-sensors/hid-sensor-attributes.c b/drivers/iio/common/hid-sensors/hid-sensor-attributes.c
index 25b01e156d82..e1435e98636d 100644
--- a/drivers/iio/common/hid-sensors/hid-sensor-attributes.c
+++ b/drivers/iio/common/hid-sensors/hid-sensor-attributes.c
@@ -153,8 +153,8 @@ s32 hid_sensor_read_poll_value(struct hid_sensor_common *st)
153 int ret; 153 int ret;
154 154
155 ret = sensor_hub_get_feature(st->hsdev, 155 ret = sensor_hub_get_feature(st->hsdev,
156 st->poll.report_id, 156 st->poll.report_id,
157 st->poll.index, &value); 157 st->poll.index, sizeof(value), &value);
158 158
159 if (ret < 0 || value < 0) { 159 if (ret < 0 || value < 0) {
160 return -EINVAL; 160 return -EINVAL;
@@ -174,8 +174,8 @@ int hid_sensor_read_samp_freq_value(struct hid_sensor_common *st,
174 int ret; 174 int ret;
175 175
176 ret = sensor_hub_get_feature(st->hsdev, 176 ret = sensor_hub_get_feature(st->hsdev,
177 st->poll.report_id, 177 st->poll.report_id,
178 st->poll.index, &value); 178 st->poll.index, sizeof(value), &value);
179 if (ret < 0 || value < 0) { 179 if (ret < 0 || value < 0) {
180 *val1 = *val2 = 0; 180 *val1 = *val2 = 0;
181 return -EINVAL; 181 return -EINVAL;
@@ -229,8 +229,9 @@ int hid_sensor_read_raw_hyst_value(struct hid_sensor_common *st,
229 int ret; 229 int ret;
230 230
231 ret = sensor_hub_get_feature(st->hsdev, 231 ret = sensor_hub_get_feature(st->hsdev,
232 st->sensitivity.report_id, 232 st->sensitivity.report_id,
233 st->sensitivity.index, &value); 233 st->sensitivity.index, sizeof(value),
234 &value);
234 if (ret < 0 || value < 0) { 235 if (ret < 0 || value < 0) {
235 *val1 = *val2 = 0; 236 *val1 = *val2 = 0;
236 return -EINVAL; 237 return -EINVAL;
diff --git a/drivers/iio/common/hid-sensors/hid-sensor-trigger.c b/drivers/iio/common/hid-sensors/hid-sensor-trigger.c
index 92068cdbf8c7..ef0c495a8ef9 100644
--- a/drivers/iio/common/hid-sensors/hid-sensor-trigger.c
+++ b/drivers/iio/common/hid-sensors/hid-sensor-trigger.c
@@ -76,8 +76,8 @@ int hid_sensor_power_state(struct hid_sensor_common *st, bool state)
76 } 76 }
77 77
78 sensor_hub_get_feature(st->hsdev, st->power_state.report_id, 78 sensor_hub_get_feature(st->hsdev, st->power_state.report_id,
79 st->power_state.index, 79 st->power_state.index,
80 &state_val); 80 sizeof(state_val), &state_val);
81 return 0; 81 return 0;
82} 82}
83EXPORT_SYMBOL(hid_sensor_power_state); 83EXPORT_SYMBOL(hid_sensor_power_state);
diff --git a/include/linux/hid-sensor-hub.h b/include/linux/hid-sensor-hub.h
index 4c49b041922d..1db332066669 100644
--- a/include/linux/hid-sensor-hub.h
+++ b/include/linux/hid-sensor-hub.h
@@ -206,13 +206,15 @@ int sensor_hub_set_feature(struct hid_sensor_hub_device *hsdev, u32 report_id,
206* sensor_hub_get_feature() - Feature get request 206* sensor_hub_get_feature() - Feature get request
207* @report_id: Report id to look for 207* @report_id: Report id to look for
208* @field_index: Field index inside a report 208* @field_index: Field index inside a report
209* @value: Place holder for return value 209* @buffer_size: size of the buffer
210* @buffer: buffer to copy output
210* 211*
211* Used to get a field in feature report. For example this can get polling 212* Used to get a field in feature report. For example this can get polling
212* interval, sensitivity, activate/deactivate state. 213* interval, sensitivity, activate/deactivate state. On success it returns
214* number of bytes copied to buffer. On failure, it returns value < 0.
213*/ 215*/
214int sensor_hub_get_feature(struct hid_sensor_hub_device *hsdev, u32 report_id, 216int sensor_hub_get_feature(struct hid_sensor_hub_device *hsdev, u32 report_id,
215 u32 field_index, s32 *value); 217 u32 field_index, int buffer_size, void *buffer);
216 218
217/* hid-sensor-attributes */ 219/* hid-sensor-attributes */
218 220