diff options
author | Roderick Colenbrander <roderick.colenbrander@sony.com> | 2017-03-07 18:45:02 -0500 |
---|---|---|
committer | Jiri Kosina <jkosina@suse.cz> | 2017-03-21 10:11:55 -0400 |
commit | 80786eb9abebce64ec471de12d8ab3072834b333 (patch) | |
tree | 72faeac2e5a4aed7fafa2b688772a362b796972a | |
parent | 55a07d62db0feda2e37f6962a1b2799e2a8b42ba (diff) |
HID: sony: Report hardware timestamp for DS4 sensor values
Report the hardware timestamp inside each HID report through
MSC_TIMESTAMP for motion sensor values.
Signed-off-by: Roderick Colenbrander <roderick.colenbrander@sony.com>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
-rw-r--r-- | drivers/hid/hid-sony.c | 27 |
1 files changed, 27 insertions, 0 deletions
diff --git a/drivers/hid/hid-sony.c b/drivers/hid/hid-sony.c index fedaebe0363f..dab4aefd841e 100644 --- a/drivers/hid/hid-sony.c +++ b/drivers/hid/hid-sony.c | |||
@@ -781,6 +781,7 @@ struct motion_output_report_02 { | |||
781 | * additional +2. | 781 | * additional +2. |
782 | */ | 782 | */ |
783 | #define DS4_INPUT_REPORT_BUTTON_OFFSET 5 | 783 | #define DS4_INPUT_REPORT_BUTTON_OFFSET 5 |
784 | #define DS4_INPUT_REPORT_TIMESTAMP_OFFSET 10 | ||
784 | #define DS4_INPUT_REPORT_GYRO_X_OFFSET 13 | 785 | #define DS4_INPUT_REPORT_GYRO_X_OFFSET 13 |
785 | #define DS4_INPUT_REPORT_BATTERY_OFFSET 30 | 786 | #define DS4_INPUT_REPORT_BATTERY_OFFSET 30 |
786 | #define DS4_INPUT_REPORT_TOUCHPAD_OFFSET 33 | 787 | #define DS4_INPUT_REPORT_TOUCHPAD_OFFSET 33 |
@@ -837,6 +838,11 @@ struct sony_sc { | |||
837 | u8 led_delay_on[MAX_LEDS]; | 838 | u8 led_delay_on[MAX_LEDS]; |
838 | u8 led_delay_off[MAX_LEDS]; | 839 | u8 led_delay_off[MAX_LEDS]; |
839 | u8 led_count; | 840 | u8 led_count; |
841 | |||
842 | bool timestamp_initialized; | ||
843 | u16 prev_timestamp; | ||
844 | unsigned int timestamp_us; | ||
845 | |||
840 | bool ds4_dongle_connected; | 846 | bool ds4_dongle_connected; |
841 | /* DS4 calibration data */ | 847 | /* DS4 calibration data */ |
842 | struct ds4_calibration_data ds4_calib_data[6]; | 848 | struct ds4_calibration_data ds4_calib_data[6]; |
@@ -1031,6 +1037,7 @@ static void dualshock4_parse_report(struct sony_sc *sc, u8 *rd, int size) | |||
1031 | unsigned long flags; | 1037 | unsigned long flags; |
1032 | int n, m, offset, num_touch_data, max_touch_data; | 1038 | int n, m, offset, num_touch_data, max_touch_data; |
1033 | u8 cable_state, battery_capacity, battery_charging; | 1039 | u8 cable_state, battery_capacity, battery_charging; |
1040 | u16 timestamp; | ||
1034 | 1041 | ||
1035 | /* When using Bluetooth the header is 2 bytes longer, so skip these. */ | 1042 | /* When using Bluetooth the header is 2 bytes longer, so skip these. */ |
1036 | int data_offset = (sc->quirks & DUALSHOCK4_CONTROLLER_USB) ? 0 : 2; | 1043 | int data_offset = (sc->quirks & DUALSHOCK4_CONTROLLER_USB) ? 0 : 2; |
@@ -1039,6 +1046,24 @@ static void dualshock4_parse_report(struct sony_sc *sc, u8 *rd, int size) | |||
1039 | offset = data_offset + DS4_INPUT_REPORT_BUTTON_OFFSET; | 1046 | offset = data_offset + DS4_INPUT_REPORT_BUTTON_OFFSET; |
1040 | input_report_key(sc->touchpad, BTN_LEFT, rd[offset+2] & 0x2); | 1047 | input_report_key(sc->touchpad, BTN_LEFT, rd[offset+2] & 0x2); |
1041 | 1048 | ||
1049 | /* Convert timestamp (in 5.33us unit) to timestamp_us */ | ||
1050 | offset = data_offset + DS4_INPUT_REPORT_TIMESTAMP_OFFSET; | ||
1051 | timestamp = get_unaligned_le16(&rd[offset]); | ||
1052 | if (!sc->timestamp_initialized) { | ||
1053 | sc->timestamp_us = ((unsigned int)timestamp * 16) / 3; | ||
1054 | sc->timestamp_initialized = true; | ||
1055 | } else { | ||
1056 | u16 delta; | ||
1057 | |||
1058 | if (sc->prev_timestamp > timestamp) | ||
1059 | delta = (U16_MAX - sc->prev_timestamp + timestamp + 1); | ||
1060 | else | ||
1061 | delta = timestamp - sc->prev_timestamp; | ||
1062 | sc->timestamp_us += (delta * 16) / 3; | ||
1063 | } | ||
1064 | sc->prev_timestamp = timestamp; | ||
1065 | input_event(sc->sensor_dev, EV_MSC, MSC_TIMESTAMP, sc->timestamp_us); | ||
1066 | |||
1042 | offset = data_offset + DS4_INPUT_REPORT_GYRO_X_OFFSET; | 1067 | offset = data_offset + DS4_INPUT_REPORT_GYRO_X_OFFSET; |
1043 | for (n = 0; n < 6; n++) { | 1068 | for (n = 0; n < 6; n++) { |
1044 | /* Store data in int for more precision during mult_frac. */ | 1069 | /* Store data in int for more precision during mult_frac. */ |
@@ -1385,6 +1410,8 @@ static int sony_register_sensors(struct sony_sc *sc) | |||
1385 | input_abs_set_res(sc->sensor_dev, ABS_RY, DS4_GYRO_RES_PER_DEG_S); | 1410 | input_abs_set_res(sc->sensor_dev, ABS_RY, DS4_GYRO_RES_PER_DEG_S); |
1386 | input_abs_set_res(sc->sensor_dev, ABS_RZ, DS4_GYRO_RES_PER_DEG_S); | 1411 | input_abs_set_res(sc->sensor_dev, ABS_RZ, DS4_GYRO_RES_PER_DEG_S); |
1387 | 1412 | ||
1413 | __set_bit(EV_MSC, sc->sensor_dev->evbit); | ||
1414 | __set_bit(MSC_TIMESTAMP, sc->sensor_dev->mscbit); | ||
1388 | __set_bit(INPUT_PROP_ACCELEROMETER, sc->sensor_dev->propbit); | 1415 | __set_bit(INPUT_PROP_ACCELEROMETER, sc->sensor_dev->propbit); |
1389 | 1416 | ||
1390 | ret = input_register_device(sc->sensor_dev); | 1417 | ret = input_register_device(sc->sensor_dev); |