aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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