diff options
| -rw-r--r-- | drivers/hid/hid-sensor-hub.c | 15 | ||||
| -rw-r--r-- | drivers/iio/common/hid-sensors/hid-sensor-attributes.c | 13 | ||||
| -rw-r--r-- | drivers/iio/common/hid-sensors/hid-sensor-trigger.c | 4 | ||||
| -rw-r--r-- | include/linux/hid-sensor-hub.h | 8 |
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: | |||
| 223 | EXPORT_SYMBOL_GPL(sensor_hub_set_feature); | 223 | EXPORT_SYMBOL_GPL(sensor_hub_set_feature); |
| 224 | 224 | ||
| 225 | int sensor_hub_get_feature(struct hid_sensor_hub_device *hsdev, u32 report_id, | 225 | int 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 | ||
| 243 | done_proc: | 254 | done_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 | } |
| 83 | EXPORT_SYMBOL(hid_sensor_power_state); | 83 | EXPORT_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 | */ |
| 214 | int sensor_hub_get_feature(struct hid_sensor_hub_device *hsdev, u32 report_id, | 216 | int 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 | ||
