Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f79133c9 authored by Roderick Colenbrander's avatar Roderick Colenbrander Committed by Kim Low
Browse files

UPSTREAM: 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: default avatarRoderick Colenbrander <roderick.colenbrander@sony.com>
Signed-off-by: default avatarJiri Kosina <jkosina@suse.cz>
(cherry picked from commit 80786eb9abebce64ec471de12d8ab3072834b333)

Bug: 111431828
Signed-off-by: default avatarKim Low <kim-huei.low@sony.com>
Change-Id: If1aff85b278fd67f488a026f9e9ee47dde58d5af
parent 9b70faa2
Loading
Loading
Loading
Loading
+27 −0
Original line number Diff line number Diff line
@@ -781,6 +781,7 @@ struct motion_output_report_02 {
 * additional +2.
 */
#define DS4_INPUT_REPORT_BUTTON_OFFSET    5
#define DS4_INPUT_REPORT_TIMESTAMP_OFFSET 10
#define DS4_INPUT_REPORT_GYRO_X_OFFSET   13
#define DS4_INPUT_REPORT_BATTERY_OFFSET  30
#define DS4_INPUT_REPORT_TOUCHPAD_OFFSET 33
@@ -837,6 +838,11 @@ struct sony_sc {
	u8 led_delay_on[MAX_LEDS];
	u8 led_delay_off[MAX_LEDS];
	u8 led_count;

	bool timestamp_initialized;
	u16 prev_timestamp;
	unsigned int timestamp_us;

	bool ds4_dongle_connected;
	/* DS4 calibration data */
	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)
	unsigned long flags;
	int n, m, offset, num_touch_data, max_touch_data;
	u8 cable_state, battery_capacity, battery_charging;
	u16 timestamp;

	/* When using Bluetooth the header is 2 bytes longer, so skip these. */
	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)
	offset = data_offset + DS4_INPUT_REPORT_BUTTON_OFFSET;
	input_report_key(sc->touchpad, BTN_LEFT, rd[offset+2] & 0x2);

	/* Convert timestamp (in 5.33us unit) to timestamp_us */
	offset = data_offset + DS4_INPUT_REPORT_TIMESTAMP_OFFSET;
	timestamp = get_unaligned_le16(&rd[offset]);
	if (!sc->timestamp_initialized) {
		sc->timestamp_us = ((unsigned int)timestamp * 16) / 3;
		sc->timestamp_initialized = true;
	} else {
		u16 delta;

		if (sc->prev_timestamp > timestamp)
			delta = (U16_MAX - sc->prev_timestamp + timestamp + 1);
		else
			delta = timestamp - sc->prev_timestamp;
		sc->timestamp_us += (delta * 16) / 3;
	}
	sc->prev_timestamp = timestamp;
	input_event(sc->sensor_dev, EV_MSC, MSC_TIMESTAMP, sc->timestamp_us);

	offset = data_offset + DS4_INPUT_REPORT_GYRO_X_OFFSET;
	for (n = 0; n < 6; n++) {
		/* Store data in int for more precision during mult_frac. */
@@ -1385,6 +1410,8 @@ static int sony_register_sensors(struct sony_sc *sc)
	input_abs_set_res(sc->sensor_dev, ABS_RY, DS4_GYRO_RES_PER_DEG_S);
	input_abs_set_res(sc->sensor_dev, ABS_RZ, DS4_GYRO_RES_PER_DEG_S);

	__set_bit(EV_MSC, sc->sensor_dev->evbit);
	__set_bit(MSC_TIMESTAMP, sc->sensor_dev->mscbit);
	__set_bit(INPUT_PROP_ACCELEROMETER, sc->sensor_dev->propbit);

	ret = input_register_device(sc->sensor_dev);