All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/8] HID: sony: DS4 updates
@ 2016-11-23 22:07 Roderick Colenbrander
  2016-11-23 22:07 ` [PATCH 1/8] HID: sony: Fix memory issue when connecting device using both Bluetooth and USB Roderick Colenbrander
                   ` (8 more replies)
  0 siblings, 9 replies; 21+ messages in thread
From: Roderick Colenbrander @ 2016-11-23 22:07 UTC (permalink / raw)
  To: linux-input
  Cc: Dmitry Torokhov, Jiri Kosina, Benjamin Tissoires, Simon Wood,
	Frank Praznik, Tim Bird, Roderick Colenbrander

From: Roderick Colenbrander <roderick.colenbrander@sony.com>

I would like to share various updates to the DS4 driver. The first
4 patches are bug fixes and improvements discussed in various
discussions on linux-input:
- Fix issue when mixing USB and Bluetooth due to failure behind
  the scens in sony_input_configured. Benjamin suggested the
  fix we added.
- The touchpad is a separate device to avoid touch influencing
  the analog sticks, which happened due to use of input_mt_sync.
- The DS4 code now complies to the Linux game controller spec.
  We work with SDL2, the biggest DS4 user, to make sure it can
  handle the different mappings. If desired we could make the DS3
  comply as well and make similar changes.
- Make DS4 motion sensors a separate device, so applications
  don't have to use 'non-existing' axes. Updated the event code
  specs to allow gyroscope data when INPUT_PROP_ACCELEROMETER is
  set as suggested by Peter Hutterer.

The next 2 patches add the unique ID to the USB device and add
support for a new DS4 device.

The last 2 patches add calibration and timestamp to the motion
sensors, which finally makes the motion sensors usable.

As part of the changes we started to wonder if we should drop
HID report fixups altogether for the DS4. It is used right now
to have the hid-core layer be able to handle events for the
'misbehaving' report ID 17. I'm aware though of various cross
platform libraries parsing DS4 HID reports, which are seeing
inconsistent views per OS. Not sure what we should do, we could
change this in a future patch. We would need to manually report
buttons / axes when on Bluetooth for report ID 17.

Thanks,
Roderick

Roderick Colenbrander (8):
  HID: sony: Fix memory issue when connecting device using both
    Bluetooth and USB
  HID: sony: Make the DS4 touchpad a separate device
  HID: sony: Comply to Linux gamepad spec for DS4
  HID: sony: Report DS4 motion sensors through a separate device
  HID: sony: Use DS4 MAC address as unique identifier on USB
  HID: sony: Support DS4 dongle
  HID: sony: Calibrate DS4 motion sensors
  HID: sony: Report hardware timestamp for DS4 sensor values

 Documentation/input/event-codes.txt |   5 +-
 drivers/hid/hid-core.c              |   1 +
 drivers/hid/hid-ids.h               |   1 +
 drivers/hid/hid-sony.c              | 790 +++++++++++++++++++++---------------
 include/uapi/linux/input.h          |  11 +-
 5 files changed, 477 insertions(+), 331 deletions(-)

-- 
2.7.4


^ permalink raw reply	[flat|nested] 21+ messages in thread

* [PATCH 1/8] HID: sony: Fix memory issue when connecting device using both Bluetooth and USB
  2016-11-23 22:07 [PATCH 0/8] HID: sony: DS4 updates Roderick Colenbrander
@ 2016-11-23 22:07 ` Roderick Colenbrander
  2016-11-23 22:07 ` [PATCH 2/8] HID: sony: Make the DS4 touchpad a separate device Roderick Colenbrander
                   ` (7 subsequent siblings)
  8 siblings, 0 replies; 21+ messages in thread
From: Roderick Colenbrander @ 2016-11-23 22:07 UTC (permalink / raw)
  To: linux-input
  Cc: Dmitry Torokhov, Jiri Kosina, Benjamin Tissoires, Simon Wood,
	Frank Praznik, Tim Bird, Roderick Colenbrander

From: Roderick Colenbrander <roderick.colenbrander@sony.com>

A previous patch moved most input initialization from sony_probe to
sony_input_configured to avoid some race conditions. The driver has some
special logic to prevent the device to get registered twice in case the
user connects it both over Bluetooth and USB. When this condition
happens sony_input_configured returns a failure, but sony_probe continues
as hid_hw_start doesn't fail. As was discussed on linux-input, it is
acceptable for this function to fail.

This patch adds a check for the HID_CLAIMED_INPUT flag within sony_probe
to determine whether initialization succeeded correctly. The flag is
not set by the HID layer when sony_input_configured fails.

Signed-off-by: Roderick Colenbrander <roderick.colenbrander@sony.com>
---
 drivers/hid/hid-sony.c | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/drivers/hid/hid-sony.c b/drivers/hid/hid-sony.c
index 14763cd..3385006 100644
--- a/drivers/hid/hid-sony.c
+++ b/drivers/hid/hid-sony.c
@@ -2524,6 +2524,19 @@ static int sony_probe(struct hid_device *hdev, const struct hid_device_id *id)
 		return ret;
 	}
 
+	/* sony_input_configured can fail, but this doesn't result
+	 * in hid_hw_start failures (intended). Check whether
+	 * the HID layer claimed the device else fail.
+	 * We don't know the actual reason for the failure, most
+	 * likely it is due to EEXIST in case of double connection
+	 * of USB and Bluetooth, but could have been due to ENOMEM
+	 * or other reasons as well.
+	 */
+	if (!(hdev->claimed & HID_CLAIMED_INPUT)) {
+		hid_err(hdev, "failed to claim input\n");
+		return -ENODEV;
+	}
+
 	return ret;
 }
 
-- 
2.7.4


^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH 2/8] HID: sony: Make the DS4 touchpad a separate device
  2016-11-23 22:07 [PATCH 0/8] HID: sony: DS4 updates Roderick Colenbrander
  2016-11-23 22:07 ` [PATCH 1/8] HID: sony: Fix memory issue when connecting device using both Bluetooth and USB Roderick Colenbrander
@ 2016-11-23 22:07 ` Roderick Colenbrander
  2016-11-23 22:07 ` [PATCH 3/8] HID: sony: Comply to Linux gamepad spec for DS4 Roderick Colenbrander
                   ` (6 subsequent siblings)
  8 siblings, 0 replies; 21+ messages in thread
From: Roderick Colenbrander @ 2016-11-23 22:07 UTC (permalink / raw)
  To: linux-input
  Cc: Dmitry Torokhov, Jiri Kosina, Benjamin Tissoires, Simon Wood,
	Frank Praznik, Tim Bird, Roderick Colenbrander

From: Roderick Colenbrander <roderick.colenbrander@sony.com>

The dualshock 4 supports both analog sticks of which one uses
ABS_X/_Y and a touchpad. In a recent discussion with Dmitry about
some input-mt changes we proposed for disabling pointer emulation from
input_mt_sync_frame, Dmitry mentioned ABS_X/_Y should report the
same data as ABS_MT_POSITION_X/_Y. The current driver is mixing axes
for different subdevices. It was suggested to make the touchpad
its own sub-device.

This patch turns the touchpad into its own device. In addition
this patch also moves the button underneath the touchpad into
the new device. It felt like this button should be part of the
device. No known user space application (not even SDL2) seems to
be using it.

Signed-off-by: Roderick Colenbrander <roderick.colenbrander@sony.com>
---
 drivers/hid/hid-sony.c | 105 +++++++++++++++++++++++++++++++++++++++----------
 1 file changed, 84 insertions(+), 21 deletions(-)

diff --git a/drivers/hid/hid-sony.c b/drivers/hid/hid-sony.c
index 3385006..995b5cf 100644
--- a/drivers/hid/hid-sony.c
+++ b/drivers/hid/hid-sony.c
@@ -376,7 +376,7 @@ static u8 dualshock4_usb_rdesc[] = {
 	0x65, 0x00,         /*      Unit,                           */
 	0x05, 0x09,         /*      Usage Page (Button),            */
 	0x19, 0x01,         /*      Usage Minimum (01h),            */
-	0x29, 0x0E,         /*      Usage Maximum (0Eh),            */
+	0x29, 0x0D,         /*      Usage Maximum (0Dh),            */
 	0x15, 0x00,         /*      Logical Minimum (0),            */
 	0x25, 0x01,         /*      Logical Maximum (1),            */
 	0x75, 0x01,         /*      Report Size (1),                */
@@ -689,7 +689,7 @@ static u8 dualshock4_bt_rdesc[] = {
 	0x81, 0x42,         /*      Input (Variable, Null State),   */
 	0x05, 0x09,         /*      Usage Page (Button),            */
 	0x19, 0x01,         /*      Usage Minimum (01h),            */
-	0x29, 0x0E,         /*      Usage Maximum (0Eh),            */
+	0x29, 0x0D,         /*      Usage Maximum (0Dh),            */
 	0x15, 0x00,         /*      Logical Minimum (0),            */
 	0x25, 0x01,         /*      Logical Maximum (1),            */
 	0x75, 0x01,         /*      Report Size (1),                */
@@ -1033,9 +1033,12 @@ struct motion_output_report_02 {
 /* Offsets relative to USB input report (0x1). Bluetooth (0x11) requires an
  * additional +2.
  */
+#define DS4_INPUT_REPORT_BUTTON_OFFSET    5
 #define DS4_INPUT_REPORT_BATTERY_OFFSET  30
 #define DS4_INPUT_REPORT_TOUCHPAD_OFFSET 33
 
+#define DS4_TOUCHPAD_SUFFIX " Touchpad"
+
 static DEFINE_SPINLOCK(sony_dev_list_lock);
 static LIST_HEAD(sony_device_list);
 static DEFINE_IDA(sony_device_id_allocator);
@@ -1044,6 +1047,7 @@ struct sony_sc {
 	spinlock_t lock;
 	struct list_head list_node;
 	struct hid_device *hdev;
+	struct input_dev *touchpad;
 	struct led_classdev *leds[MAX_LEDS];
 	unsigned long quirks;
 	struct work_struct state_worker;
@@ -1228,9 +1232,6 @@ static void sixaxis_parse_report(struct sony_sc *sc, u8 *rd, int size)
 
 static void dualshock4_parse_report(struct sony_sc *sc, u8 *rd, int size)
 {
-	struct hid_input *hidinput = list_entry(sc->hdev->inputs.next,
-						struct hid_input, list);
-	struct input_dev *input_dev = hidinput->input;
 	unsigned long flags;
 	int n, m, offset, num_touch_data, max_touch_data;
 	u8 cable_state, battery_capacity, battery_charging;
@@ -1238,6 +1239,10 @@ static void dualshock4_parse_report(struct sony_sc *sc, u8 *rd, int size)
 	/* When using Bluetooth the header is 2 bytes longer, so skip these. */
 	int data_offset = (sc->quirks & DUALSHOCK4_CONTROLLER_USB) ? 0 : 2;
 
+	/* Second bit of third button byte is for the touchpad button. */
+	offset = data_offset + DS4_INPUT_REPORT_BUTTON_OFFSET;
+	input_report_key(sc->touchpad, BTN_LEFT, rd[offset+2] & 0x2);
+
 	/*
 	 * The lower 4 bits of byte 30 (or 32 for BT) contain the battery level
 	 * and the 5th bit contains the USB cable state.
@@ -1303,18 +1308,18 @@ static void dualshock4_parse_report(struct sony_sc *sc, u8 *rd, int size)
 			y = ((rd[offset+2] & 0xF0) >> 4) | (rd[offset+3] << 4);
 
 			active = !(rd[offset] >> 7);
-			input_mt_slot(input_dev, n);
-			input_mt_report_slot_state(input_dev, MT_TOOL_FINGER, active);
+			input_mt_slot(sc->touchpad, n);
+			input_mt_report_slot_state(sc->touchpad, MT_TOOL_FINGER, active);
 
 			if (active) {
-				input_report_abs(input_dev, ABS_MT_POSITION_X, x);
-				input_report_abs(input_dev, ABS_MT_POSITION_Y, y);
+				input_report_abs(sc->touchpad, ABS_MT_POSITION_X, x);
+				input_report_abs(sc->touchpad, ABS_MT_POSITION_Y, y);
 			}
 
 			offset += 4;
 		}
-		input_mt_sync_frame(input_dev);
-		input_sync(input_dev);
+		input_mt_sync_frame(sc->touchpad);
+		input_sync(sc->touchpad);
 	}
 }
 
@@ -1415,22 +1420,77 @@ static int sony_mapping(struct hid_device *hdev, struct hid_input *hi,
 	return 0;
 }
 
-static int sony_register_touchpad(struct hid_input *hi, int touch_count,
+static int sony_register_touchpad(struct sony_sc *sc, int touch_count,
 					int w, int h)
 {
-	struct input_dev *input_dev = hi->input;
+	size_t name_sz;
+	char *name;
 	int ret;
 
-	ret = input_mt_init_slots(input_dev, touch_count, 0);
+	sc->touchpad = input_allocate_device();
+	if (!sc->touchpad)
+		return -ENOMEM;
+
+	input_set_drvdata(sc->touchpad, sc);
+	sc->touchpad->dev.parent = &sc->hdev->dev;
+	sc->touchpad->phys = sc->hdev->phys;
+	sc->touchpad->uniq = sc->hdev->uniq;
+	sc->touchpad->id.bustype = sc->hdev->bus;
+	sc->touchpad->id.vendor = sc->hdev->vendor;
+	sc->touchpad->id.product = sc->hdev->product;
+	sc->touchpad->id.version = sc->hdev->version;
+
+	/* Append a suffix to the controller name as there are various
+	 * DS4 compatible non-Sony devices with different names.
+	 */
+	name_sz = strlen(sc->hdev->name) + sizeof(DS4_TOUCHPAD_SUFFIX);
+	name = kzalloc(name_sz, GFP_KERNEL);
+	if (!name) {
+		ret = -ENOMEM;
+		goto err;
+	}
+	snprintf(name, name_sz, "%s" DS4_TOUCHPAD_SUFFIX, sc->hdev->name);
+	sc->touchpad->name = name;
+
+	ret = input_mt_init_slots(sc->touchpad, touch_count, 0);
 	if (ret < 0)
-		return ret;
+		goto err;
+
+	/* We map the button underneath the touchpad to BTN_LEFT. */
+	__set_bit(EV_KEY, sc->touchpad->evbit);
+	__set_bit(BTN_LEFT, sc->touchpad->keybit);
+	__set_bit(INPUT_PROP_BUTTONPAD, sc->touchpad->propbit);
 
-	input_set_abs_params(input_dev, ABS_MT_POSITION_X, 0, w, 0, 0);
-	input_set_abs_params(input_dev, ABS_MT_POSITION_Y, 0, h, 0, 0);
+	input_set_abs_params(sc->touchpad, ABS_MT_POSITION_X, 0, w, 0, 0);
+	input_set_abs_params(sc->touchpad, ABS_MT_POSITION_Y, 0, h, 0, 0);
+
+	ret = input_register_device(sc->touchpad);
+	if (ret < 0)
+		goto err;
 
 	return 0;
+
+err:
+	kfree(sc->touchpad->name);
+	sc->touchpad->name = NULL;
+
+	input_free_device(sc->touchpad);
+	sc->touchpad = NULL;
+
+	return ret;
 }
 
+static void sony_unregister_touchpad(struct sony_sc *sc)
+{
+	if (!sc->touchpad)
+		return;
+
+	kfree(sc->touchpad->name);
+	sc->touchpad->name = NULL;
+
+	input_unregister_device(sc->touchpad);
+	sc->touchpad = NULL;
+}
 
 /*
  * Sending HID_REQ_GET_REPORT changes the operation mode of the ps3 controller
@@ -2422,7 +2482,7 @@ static int sony_input_configured(struct hid_device *hdev,
 		 * The Dualshock 4 touchpad supports 2 touches and has a
 		 * resolution of 1920x942 (44.86 dots/mm).
 		 */
-		ret = sony_register_touchpad(hidinput, 2, 1920, 942);
+		ret = sony_register_touchpad(sc, 2, 1920, 942);
 		if (ret) {
 			hid_err(sc->hdev,
 			"Unable to initialize multi-touch slots: %d\n",
@@ -2544,13 +2604,16 @@ static void sony_remove(struct hid_device *hdev)
 {
 	struct sony_sc *sc = hid_get_drvdata(hdev);
 
+	hid_hw_close(hdev);
+
 	if (sc->quirks & SONY_LED_SUPPORT)
 		sony_leds_remove(sc);
 
-	if (sc->quirks & SONY_BATTERY_SUPPORT) {
-		hid_hw_close(hdev);
+	if (sc->quirks & SONY_BATTERY_SUPPORT)
 		sony_battery_remove(sc);
-	}
+
+	if (sc->touchpad)
+		sony_unregister_touchpad(sc);
 
 	sony_cancel_work_sync(sc);
 
-- 
2.7.4


^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH 3/8] HID: sony: Comply to Linux gamepad spec for DS4
  2016-11-23 22:07 [PATCH 0/8] HID: sony: DS4 updates Roderick Colenbrander
  2016-11-23 22:07 ` [PATCH 1/8] HID: sony: Fix memory issue when connecting device using both Bluetooth and USB Roderick Colenbrander
  2016-11-23 22:07 ` [PATCH 2/8] HID: sony: Make the DS4 touchpad a separate device Roderick Colenbrander
@ 2016-11-23 22:07 ` Roderick Colenbrander
  2016-11-23 22:07 ` [PATCH 4/8] HID: sony: Report DS4 motion sensors through a separate device Roderick Colenbrander
                   ` (5 subsequent siblings)
  8 siblings, 0 replies; 21+ messages in thread
From: Roderick Colenbrander @ 2016-11-23 22:07 UTC (permalink / raw)
  To: linux-input
  Cc: Dmitry Torokhov, Jiri Kosina, Benjamin Tissoires, Simon Wood,
	Frank Praznik, Tim Bird, Roderick Colenbrander

From: Roderick Colenbrander <roderick.colenbrander@sony.com>

The DS4 side of hid-sony used the hid-core layer to assign buttons
and axes based on the HID report descriptors. The default mapping
was strange e.g. right stick using ABS_Z/ABS_RZ or the physical
'south button' being reported as BTN_EAST etcetera.

This patch makes the DS4 side ofi the hid-sony driver comply to
the Linux game controller spec as suggested in a discussion with
Dmitry on the linux-input list.

Currently the main user of the DS4 is the SDL2 library, which has
a mapping table using vendor/device/version as a key. In order to
not break SDL2 we discussed adjusting the version number, so it
can have both mappings. This was discust on linux-input and we
discussed privately with SDL2 developers.

Signed-off-by: Roderick Colenbrander <roderick.colenbrander@sony.com>
---
 drivers/hid/hid-sony.c | 70 ++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 70 insertions(+)

diff --git a/drivers/hid/hid-sony.c b/drivers/hid/hid-sony.c
index 995b5cf..d8889d6 100644
--- a/drivers/hid/hid-sony.c
+++ b/drivers/hid/hid-sony.c
@@ -977,6 +977,32 @@ static const unsigned int buzz_keymap[] = {
 	[20] = BTN_TRIGGER_HAPPY20,
 };
 
+static const unsigned int ds4_absmap[] = {
+	[0x30] = ABS_X,
+	[0x31] = ABS_Y,
+	[0x32] = ABS_RX, /* right stick X */
+	[0x33] = ABS_Z, /* L2 */
+	[0x34] = ABS_RZ, /* R2 */
+	[0x35] = ABS_RY, /* right stick Y */
+};
+
+static const unsigned int ds4_keymap[] = {
+	[0x1] = BTN_WEST, /* Square */
+	[0x2] = BTN_SOUTH, /* Cross */
+	[0x3] = BTN_EAST, /* Circle */
+	[0x4] = BTN_NORTH, /* Triangle */
+	[0x5] = BTN_TL, /* L1 */
+	[0x6] = BTN_TR, /* R1 */
+	[0x7] = BTN_TL2, /* L2 */
+	[0x8] = BTN_TR2, /* R2 */
+	[0x9] = BTN_SELECT, /* Share */
+	[0xa] = BTN_START, /* Options */
+	[0xb] = BTN_THUMBL, /* L3 */
+	[0xc] = BTN_THUMBR, /* R3 */
+	[0xd] = BTN_MODE, /* PS */
+};
+
+
 static enum power_supply_property sony_battery_props[] = {
 	POWER_SUPPLY_PROP_PRESENT,
 	POWER_SUPPLY_PROP_CAPACITY,
@@ -1143,6 +1169,37 @@ static int ps3remote_mapping(struct hid_device *hdev, struct hid_input *hi,
 	return 1;
 }
 
+static int ds4_mapping(struct hid_device *hdev, struct hid_input *hi,
+		       struct hid_field *field, struct hid_usage *usage,
+		       unsigned long **bit, int *max)
+{
+	if ((usage->hid & HID_USAGE_PAGE) == HID_UP_BUTTON) {
+		unsigned int key = usage->hid & HID_USAGE;
+
+		if (key >= ARRAY_SIZE(ds4_keymap))
+			return -1;
+
+		key = ds4_keymap[key];
+		hid_map_usage_clear(hi, usage, bit, max, EV_KEY, key);
+		return 1;
+	} else if ((usage->hid & HID_USAGE_PAGE) == HID_UP_GENDESK) {
+		unsigned int abs = usage->hid & HID_USAGE;
+
+		/* Let the HID parser deal with the HAT. */
+		if (usage->hid == HID_GD_HATSWITCH)
+			return 0;
+
+		if (abs >= ARRAY_SIZE(ds4_absmap))
+			return -1;
+
+		abs = ds4_absmap[abs];
+		hid_map_usage_clear(hi, usage, bit, max, EV_ABS, abs);
+		return 1;
+	}
+
+	return 0;
+}
+
 static u8 *sony_report_fixup(struct hid_device *hdev, u8 *rdesc,
 		unsigned int *rsize)
 {
@@ -1416,6 +1473,10 @@ static int sony_mapping(struct hid_device *hdev, struct hid_input *hi,
 	if (sc->quirks & PS3REMOTE)
 		return ps3remote_mapping(hdev, hi, field, usage, bit, max);
 
+
+	if (sc->quirks & DUALSHOCK4_CONTROLLER)
+		return ds4_mapping(hdev, hi, field, usage, bit, max);
+
 	/* Let hid-core decide for the others */
 	return 0;
 }
@@ -2578,6 +2639,15 @@ static int sony_probe(struct hid_device *hdev, const struct hid_device_id *id)
 	else if (sc->quirks & SIXAXIS_CONTROLLER)
 		connect_mask |= HID_CONNECT_HIDDEV_FORCE;
 
+	/* Patch the hw version on DS4 compatible devices, so applications can
+	 * distinguish between the default HID mappings and the mappings defined
+	 * by the Linux game controller spec. This is important for the SDL2
+	 * library, which has a game controller database, which uses device ids
+	 * in combination with version as a key.
+	 */
+	if (sc->quirks & DUALSHOCK4_CONTROLLER)
+		hdev->version |= 0x8000;
+
 	ret = hid_hw_start(hdev, connect_mask);
 	if (ret) {
 		hid_err(hdev, "hw start failed\n");
-- 
2.7.4


^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH 4/8] HID: sony: Report DS4 motion sensors through a separate device
  2016-11-23 22:07 [PATCH 0/8] HID: sony: DS4 updates Roderick Colenbrander
                   ` (2 preceding siblings ...)
  2016-11-23 22:07 ` [PATCH 3/8] HID: sony: Comply to Linux gamepad spec for DS4 Roderick Colenbrander
@ 2016-11-23 22:07 ` Roderick Colenbrander
  2016-11-23 23:17   ` Simon Wood
  2016-11-23 22:07 ` [PATCH 5/8] HID: sony: Use DS4 MAC address as unique identifier on USB Roderick Colenbrander
                   ` (4 subsequent siblings)
  8 siblings, 1 reply; 21+ messages in thread
From: Roderick Colenbrander @ 2016-11-23 22:07 UTC (permalink / raw)
  To: linux-input
  Cc: Dmitry Torokhov, Jiri Kosina, Benjamin Tissoires, Simon Wood,
	Frank Praznik, Tim Bird, Roderick Colenbrander

From: Roderick Colenbrander <roderick.colenbrander@sony.com>

The DS4 motion sensors are currently mapped by the hid-core driver
to non-existing axes in between ABS_MISC and ABS_MT_SLOT, because
the device already exhausted ABS_X-ABS_RZ. For a part the mapping
by hid-core is accomplished by a fixup in hid-sony as the motion
axes actually use vendor specific usage pages.

This patch makes the DS4 use a separate input device for the motion
sensors and reports acceleration data through ABS_X-ABS_Z and
gyroscope data through ABS_RX-ABS_RZ. In addition it extends the
event spec to allow gyroscope data through ABS_RX-ABS_RZ when
INPUT_PROP_ACCELEROMETER is set. This change was suggested by
Peter Hutterer during a discussion on linux-input.

Signed-off-by: Roderick Colenbrander <roderick.colenbrander@sony.com>
---
 Documentation/input/event-codes.txt |   5 +-
 drivers/hid/hid-sony.c              | 394 ++++++++++--------------------------
 include/uapi/linux/input.h          |  11 +-
 3 files changed, 114 insertions(+), 296 deletions(-)

diff --git a/Documentation/input/event-codes.txt b/Documentation/input/event-codes.txt
index 36ea940..575415f 100644
--- a/Documentation/input/event-codes.txt
+++ b/Documentation/input/event-codes.txt
@@ -301,7 +301,10 @@ them as any other INPUT_PROP_BUTTONPAD device.
 INPUT_PROP_ACCELEROMETER
 -------------------------
 Directional axes on this device (absolute and/or relative x, y, z) represent
-accelerometer data. All other axes retain their meaning. A device must not mix
+accelerometer data. Some devices also report gyroscope data, which devices
+can report through the rotational axes (absolute and/or relative rx, ry, rz).
+
+All other axes retain their meaning. A device must not mix
 regular directional axes and accelerometer axes on the same event node.
 
 Guidelines:
diff --git a/drivers/hid/hid-sony.c b/drivers/hid/hid-sony.c
index d8889d6..c391907 100644
--- a/drivers/hid/hid-sony.c
+++ b/drivers/hid/hid-sony.c
@@ -344,265 +344,6 @@ static u8 navigation_rdesc[] = {
 	0xC0                /*  End Collection                      */
 };
 
-/*
- * The default descriptor doesn't provide mapping for the accelerometers
- * or orientation sensors.  This fixed descriptor maps the accelerometers
- * to usage values 0x40, 0x41 and 0x42 and maps the orientation sensors
- * to usage values 0x43, 0x44 and 0x45.
- */
-static u8 dualshock4_usb_rdesc[] = {
-	0x05, 0x01,         /*  Usage Page (Desktop),               */
-	0x09, 0x05,         /*  Usage (Gamepad),                    */
-	0xA1, 0x01,         /*  Collection (Application),           */
-	0x85, 0x01,         /*      Report ID (1),                  */
-	0x09, 0x30,         /*      Usage (X),                      */
-	0x09, 0x31,         /*      Usage (Y),                      */
-	0x09, 0x32,         /*      Usage (Z),                      */
-	0x09, 0x35,         /*      Usage (Rz),                     */
-	0x15, 0x00,         /*      Logical Minimum (0),            */
-	0x26, 0xFF, 0x00,   /*      Logical Maximum (255),          */
-	0x75, 0x08,         /*      Report Size (8),                */
-	0x95, 0x04,         /*      Report Count (4),               */
-	0x81, 0x02,         /*      Input (Variable),               */
-	0x09, 0x39,         /*      Usage (Hat Switch),             */
-	0x15, 0x00,         /*      Logical Minimum (0),            */
-	0x25, 0x07,         /*      Logical Maximum (7),            */
-	0x35, 0x00,         /*      Physical Minimum (0),           */
-	0x46, 0x3B, 0x01,   /*      Physical Maximum (315),         */
-	0x65, 0x14,         /*      Unit (Degrees),                 */
-	0x75, 0x04,         /*      Report Size (4),                */
-	0x95, 0x01,         /*      Report Count (1),               */
-	0x81, 0x42,         /*      Input (Variable, Null State),   */
-	0x65, 0x00,         /*      Unit,                           */
-	0x05, 0x09,         /*      Usage Page (Button),            */
-	0x19, 0x01,         /*      Usage Minimum (01h),            */
-	0x29, 0x0D,         /*      Usage Maximum (0Dh),            */
-	0x15, 0x00,         /*      Logical Minimum (0),            */
-	0x25, 0x01,         /*      Logical Maximum (1),            */
-	0x75, 0x01,         /*      Report Size (1),                */
-	0x95, 0x0E,         /*      Report Count (14),              */
-	0x81, 0x02,         /*      Input (Variable),               */
-	0x06, 0x00, 0xFF,   /*      Usage Page (FF00h),             */
-	0x09, 0x20,         /*      Usage (20h),                    */
-	0x75, 0x06,         /*      Report Size (6),                */
-	0x95, 0x01,         /*      Report Count (1),               */
-	0x15, 0x00,         /*      Logical Minimum (0),            */
-	0x25, 0x3F,         /*      Logical Maximum (63),           */
-	0x81, 0x02,         /*      Input (Variable),               */
-	0x05, 0x01,         /*      Usage Page (Desktop),           */
-	0x09, 0x33,         /*      Usage (Rx),                     */
-	0x09, 0x34,         /*      Usage (Ry),                     */
-	0x15, 0x00,         /*      Logical Minimum (0),            */
-	0x26, 0xFF, 0x00,   /*      Logical Maximum (255),          */
-	0x75, 0x08,         /*      Report Size (8),                */
-	0x95, 0x02,         /*      Report Count (2),               */
-	0x81, 0x02,         /*      Input (Variable),               */
-	0x06, 0x00, 0xFF,   /*      Usage Page (FF00h),             */
-	0x09, 0x21,         /*      Usage (21h),                    */
-	0x95, 0x03,         /*      Report Count (3),               */
-	0x81, 0x02,         /*      Input (Variable),               */
-	0x05, 0x01,         /*      Usage Page (Desktop),           */
-	0x19, 0x40,         /*      Usage Minimum (40h),            */
-	0x29, 0x42,         /*      Usage Maximum (42h),            */
-	0x16, 0x00, 0x80,   /*      Logical Minimum (-32768),       */
-	0x26, 0xFF, 0x7F,   /*      Logical Maximum (32767),        */
-	0x75, 0x10,         /*      Report Size (16),               */
-	0x95, 0x03,         /*      Report Count (3),               */
-	0x81, 0x02,         /*      Input (Variable),               */
-	0x19, 0x43,         /*      Usage Minimum (43h),            */
-	0x29, 0x45,         /*      Usage Maximum (45h),            */
-	0x16, 0x00, 0x80,   /*      Logical Minimum (-32768),       */
-	0x26, 0xFF, 0x7F,   /*      Logical Maximum (32767),        */
-	0x95, 0x03,         /*      Report Count (3),               */
-	0x81, 0x02,         /*      Input (Variable),               */
-	0x06, 0x00, 0xFF,   /*      Usage Page (FF00h),             */
-	0x09, 0x21,         /*      Usage (21h),                    */
-	0x15, 0x00,         /*      Logical Minimum (0),            */
-	0x26, 0xFF, 0x00,   /*      Logical Maximum (255),          */
-	0x75, 0x08,         /*      Report Size (8),                */
-	0x95, 0x27,         /*      Report Count (39),              */
-	0x81, 0x02,         /*      Input (Variable),               */
-	0x85, 0x05,         /*      Report ID (5),                  */
-	0x09, 0x22,         /*      Usage (22h),                    */
-	0x95, 0x1F,         /*      Report Count (31),              */
-	0x91, 0x02,         /*      Output (Variable),              */
-	0x85, 0x04,         /*      Report ID (4),                  */
-	0x09, 0x23,         /*      Usage (23h),                    */
-	0x95, 0x24,         /*      Report Count (36),              */
-	0xB1, 0x02,         /*      Feature (Variable),             */
-	0x85, 0x02,         /*      Report ID (2),                  */
-	0x09, 0x24,         /*      Usage (24h),                    */
-	0x95, 0x24,         /*      Report Count (36),              */
-	0xB1, 0x02,         /*      Feature (Variable),             */
-	0x85, 0x08,         /*      Report ID (8),                  */
-	0x09, 0x25,         /*      Usage (25h),                    */
-	0x95, 0x03,         /*      Report Count (3),               */
-	0xB1, 0x02,         /*      Feature (Variable),             */
-	0x85, 0x10,         /*      Report ID (16),                 */
-	0x09, 0x26,         /*      Usage (26h),                    */
-	0x95, 0x04,         /*      Report Count (4),               */
-	0xB1, 0x02,         /*      Feature (Variable),             */
-	0x85, 0x11,         /*      Report ID (17),                 */
-	0x09, 0x27,         /*      Usage (27h),                    */
-	0x95, 0x02,         /*      Report Count (2),               */
-	0xB1, 0x02,         /*      Feature (Variable),             */
-	0x85, 0x12,         /*      Report ID (18),                 */
-	0x06, 0x02, 0xFF,   /*      Usage Page (FF02h),             */
-	0x09, 0x21,         /*      Usage (21h),                    */
-	0x95, 0x0F,         /*      Report Count (15),              */
-	0xB1, 0x02,         /*      Feature (Variable),             */
-	0x85, 0x13,         /*      Report ID (19),                 */
-	0x09, 0x22,         /*      Usage (22h),                    */
-	0x95, 0x16,         /*      Report Count (22),              */
-	0xB1, 0x02,         /*      Feature (Variable),             */
-	0x85, 0x14,         /*      Report ID (20),                 */
-	0x06, 0x05, 0xFF,   /*      Usage Page (FF05h),             */
-	0x09, 0x20,         /*      Usage (20h),                    */
-	0x95, 0x10,         /*      Report Count (16),              */
-	0xB1, 0x02,         /*      Feature (Variable),             */
-	0x85, 0x15,         /*      Report ID (21),                 */
-	0x09, 0x21,         /*      Usage (21h),                    */
-	0x95, 0x2C,         /*      Report Count (44),              */
-	0xB1, 0x02,         /*      Feature (Variable),             */
-	0x06, 0x80, 0xFF,   /*      Usage Page (FF80h),             */
-	0x85, 0x80,         /*      Report ID (128),                */
-	0x09, 0x20,         /*      Usage (20h),                    */
-	0x95, 0x06,         /*      Report Count (6),               */
-	0xB1, 0x02,         /*      Feature (Variable),             */
-	0x85, 0x81,         /*      Report ID (129),                */
-	0x09, 0x21,         /*      Usage (21h),                    */
-	0x95, 0x06,         /*      Report Count (6),               */
-	0xB1, 0x02,         /*      Feature (Variable),             */
-	0x85, 0x82,         /*      Report ID (130),                */
-	0x09, 0x22,         /*      Usage (22h),                    */
-	0x95, 0x05,         /*      Report Count (5),               */
-	0xB1, 0x02,         /*      Feature (Variable),             */
-	0x85, 0x83,         /*      Report ID (131),                */
-	0x09, 0x23,         /*      Usage (23h),                    */
-	0x95, 0x01,         /*      Report Count (1),               */
-	0xB1, 0x02,         /*      Feature (Variable),             */
-	0x85, 0x84,         /*      Report ID (132),                */
-	0x09, 0x24,         /*      Usage (24h),                    */
-	0x95, 0x04,         /*      Report Count (4),               */
-	0xB1, 0x02,         /*      Feature (Variable),             */
-	0x85, 0x85,         /*      Report ID (133),                */
-	0x09, 0x25,         /*      Usage (25h),                    */
-	0x95, 0x06,         /*      Report Count (6),               */
-	0xB1, 0x02,         /*      Feature (Variable),             */
-	0x85, 0x86,         /*      Report ID (134),                */
-	0x09, 0x26,         /*      Usage (26h),                    */
-	0x95, 0x06,         /*      Report Count (6),               */
-	0xB1, 0x02,         /*      Feature (Variable),             */
-	0x85, 0x87,         /*      Report ID (135),                */
-	0x09, 0x27,         /*      Usage (27h),                    */
-	0x95, 0x23,         /*      Report Count (35),              */
-	0xB1, 0x02,         /*      Feature (Variable),             */
-	0x85, 0x88,         /*      Report ID (136),                */
-	0x09, 0x28,         /*      Usage (28h),                    */
-	0x95, 0x22,         /*      Report Count (34),              */
-	0xB1, 0x02,         /*      Feature (Variable),             */
-	0x85, 0x89,         /*      Report ID (137),                */
-	0x09, 0x29,         /*      Usage (29h),                    */
-	0x95, 0x02,         /*      Report Count (2),               */
-	0xB1, 0x02,         /*      Feature (Variable),             */
-	0x85, 0x90,         /*      Report ID (144),                */
-	0x09, 0x30,         /*      Usage (30h),                    */
-	0x95, 0x05,         /*      Report Count (5),               */
-	0xB1, 0x02,         /*      Feature (Variable),             */
-	0x85, 0x91,         /*      Report ID (145),                */
-	0x09, 0x31,         /*      Usage (31h),                    */
-	0x95, 0x03,         /*      Report Count (3),               */
-	0xB1, 0x02,         /*      Feature (Variable),             */
-	0x85, 0x92,         /*      Report ID (146),                */
-	0x09, 0x32,         /*      Usage (32h),                    */
-	0x95, 0x03,         /*      Report Count (3),               */
-	0xB1, 0x02,         /*      Feature (Variable),             */
-	0x85, 0x93,         /*      Report ID (147),                */
-	0x09, 0x33,         /*      Usage (33h),                    */
-	0x95, 0x0C,         /*      Report Count (12),              */
-	0xB1, 0x02,         /*      Feature (Variable),             */
-	0x85, 0xA0,         /*      Report ID (160),                */
-	0x09, 0x40,         /*      Usage (40h),                    */
-	0x95, 0x06,         /*      Report Count (6),               */
-	0xB1, 0x02,         /*      Feature (Variable),             */
-	0x85, 0xA1,         /*      Report ID (161),                */
-	0x09, 0x41,         /*      Usage (41h),                    */
-	0x95, 0x01,         /*      Report Count (1),               */
-	0xB1, 0x02,         /*      Feature (Variable),             */
-	0x85, 0xA2,         /*      Report ID (162),                */
-	0x09, 0x42,         /*      Usage (42h),                    */
-	0x95, 0x01,         /*      Report Count (1),               */
-	0xB1, 0x02,         /*      Feature (Variable),             */
-	0x85, 0xA3,         /*      Report ID (163),                */
-	0x09, 0x43,         /*      Usage (43h),                    */
-	0x95, 0x30,         /*      Report Count (48),              */
-	0xB1, 0x02,         /*      Feature (Variable),             */
-	0x85, 0xA4,         /*      Report ID (164),                */
-	0x09, 0x44,         /*      Usage (44h),                    */
-	0x95, 0x0D,         /*      Report Count (13),              */
-	0xB1, 0x02,         /*      Feature (Variable),             */
-	0x85, 0xA5,         /*      Report ID (165),                */
-	0x09, 0x45,         /*      Usage (45h),                    */
-	0x95, 0x15,         /*      Report Count (21),              */
-	0xB1, 0x02,         /*      Feature (Variable),             */
-	0x85, 0xA6,         /*      Report ID (166),                */
-	0x09, 0x46,         /*      Usage (46h),                    */
-	0x95, 0x15,         /*      Report Count (21),              */
-	0xB1, 0x02,         /*      Feature (Variable),             */
-	0x85, 0xF0,         /*      Report ID (240),                */
-	0x09, 0x47,         /*      Usage (47h),                    */
-	0x95, 0x3F,         /*      Report Count (63),              */
-	0xB1, 0x02,         /*      Feature (Variable),             */
-	0x85, 0xF1,         /*      Report ID (241),                */
-	0x09, 0x48,         /*      Usage (48h),                    */
-	0x95, 0x3F,         /*      Report Count (63),              */
-	0xB1, 0x02,         /*      Feature (Variable),             */
-	0x85, 0xF2,         /*      Report ID (242),                */
-	0x09, 0x49,         /*      Usage (49h),                    */
-	0x95, 0x0F,         /*      Report Count (15),              */
-	0xB1, 0x02,         /*      Feature (Variable),             */
-	0x85, 0xA7,         /*      Report ID (167),                */
-	0x09, 0x4A,         /*      Usage (4Ah),                    */
-	0x95, 0x01,         /*      Report Count (1),               */
-	0xB1, 0x02,         /*      Feature (Variable),             */
-	0x85, 0xA8,         /*      Report ID (168),                */
-	0x09, 0x4B,         /*      Usage (4Bh),                    */
-	0x95, 0x01,         /*      Report Count (1),               */
-	0xB1, 0x02,         /*      Feature (Variable),             */
-	0x85, 0xA9,         /*      Report ID (169),                */
-	0x09, 0x4C,         /*      Usage (4Ch),                    */
-	0x95, 0x08,         /*      Report Count (8),               */
-	0xB1, 0x02,         /*      Feature (Variable),             */
-	0x85, 0xAA,         /*      Report ID (170),                */
-	0x09, 0x4E,         /*      Usage (4Eh),                    */
-	0x95, 0x01,         /*      Report Count (1),               */
-	0xB1, 0x02,         /*      Feature (Variable),             */
-	0x85, 0xAB,         /*      Report ID (171),                */
-	0x09, 0x4F,         /*      Usage (4Fh),                    */
-	0x95, 0x39,         /*      Report Count (57),              */
-	0xB1, 0x02,         /*      Feature (Variable),             */
-	0x85, 0xAC,         /*      Report ID (172),                */
-	0x09, 0x50,         /*      Usage (50h),                    */
-	0x95, 0x39,         /*      Report Count (57),              */
-	0xB1, 0x02,         /*      Feature (Variable),             */
-	0x85, 0xAD,         /*      Report ID (173),                */
-	0x09, 0x51,         /*      Usage (51h),                    */
-	0x95, 0x0B,         /*      Report Count (11),              */
-	0xB1, 0x02,         /*      Feature (Variable),             */
-	0x85, 0xAE,         /*      Report ID (174),                */
-	0x09, 0x52,         /*      Usage (52h),                    */
-	0x95, 0x01,         /*      Report Count (1),               */
-	0xB1, 0x02,         /*      Feature (Variable),             */
-	0x85, 0xAF,         /*      Report ID (175),                */
-	0x09, 0x53,         /*      Usage (53h),                    */
-	0x95, 0x02,         /*      Report Count (2),               */
-	0xB1, 0x02,         /*      Feature (Variable),             */
-	0x85, 0xB0,         /*      Report ID (176),                */
-	0x09, 0x54,         /*      Usage (54h),                    */
-	0x95, 0x3F,         /*      Report Count (63),              */
-	0xB1, 0x02,         /*      Feature (Variable),             */
-	0xC0                /*  End Collection                      */
-};
 
 /*
  * The default behavior of the Dualshock 4 is to send reports using report
@@ -706,31 +447,10 @@ static u8 dualshock4_bt_rdesc[] = {
 	0x75, 0x08,         /*      Report Size (8),                */
 	0x95, 0x02,         /*      Report Count (2),               */
 	0x81, 0x02,         /*      Input (Variable),               */
-	0x06, 0x00, 0xFF,   /*      Usage Page (FF00h),             */
-	0x09, 0x20,         /*      Usage (20h),                    */
-	0x95, 0x03,         /*      Report Count (3),               */
-	0x81, 0x02,         /*      Input (Variable),               */
-	0x05, 0x01,         /*      Usage Page (Desktop),           */
-	0x19, 0x40,         /*      Usage Minimum (40h),            */
-	0x29, 0x42,         /*      Usage Maximum (42h),            */
-	0x16, 0x00, 0x80,   /*      Logical Minimum (-32768),       */
-	0x26, 0xFF, 0x7F,   /*      Logical Maximum (32767),        */
-	0x75, 0x10,         /*      Report Size (16),               */
-	0x95, 0x03,         /*      Report Count (3),               */
-	0x81, 0x02,         /*      Input (Variable),               */
-	0x19, 0x43,         /*      Usage Minimum (43h),            */
-	0x29, 0x45,         /*      Usage Maximum (45h),            */
-	0x16, 0x00, 0x80,   /*      Logical Minimum (-32768),       */
-	0x26, 0xFF, 0x7F,   /*      Logical Maximum (32767),        */
-	0x95, 0x03,         /*      Report Count (3),               */
-	0x81, 0x02,         /*      Input (Variable),               */
-	0x06, 0x00, 0xFF,   /*      Usage Page (FF00h),             */
-	0x09, 0x20,         /*      Usage (20h),                    */
-	0x15, 0x00,         /*      Logical Minimum (0),            */
-	0x26, 0xFF, 0x00,   /*      Logical Maximum (255),          */
-	0x75, 0x08,         /*      Report Size (8),                */
-	0x95, 0x31,         /*      Report Count (51),              */
-	0x81, 0x02,         /*      Input (Variable),               */
+	0x06, 0x00, 0xFF,   /*      Usage Page (FF00h)              */
+	0x09, 0x21,         /*      Usage (0x21)                    */
+	0x95, 0x42,         /*      Report Count (66)               */
+	0x81, 0x02,         /*      Input (Variable)                */
 	0x09, 0x21,         /*      Usage (21h),                    */
 	0x75, 0x08,         /*      Report Size (8),                */
 	0x95, 0x4D,         /*      Report Count (77),              */
@@ -1060,9 +780,11 @@ struct motion_output_report_02 {
  * additional +2.
  */
 #define DS4_INPUT_REPORT_BUTTON_OFFSET    5
+#define DS4_INPUT_REPORT_GYRO_X_OFFSET   13
 #define DS4_INPUT_REPORT_BATTERY_OFFSET  30
 #define DS4_INPUT_REPORT_TOUCHPAD_OFFSET 33
 
+#define DS4_SENSOR_SUFFIX " Motion Sensors"
 #define DS4_TOUCHPAD_SUFFIX " Touchpad"
 
 static DEFINE_SPINLOCK(sony_dev_list_lock);
@@ -1074,6 +796,7 @@ struct sony_sc {
 	struct list_head list_node;
 	struct hid_device *hdev;
 	struct input_dev *touchpad;
+	struct input_dev *sensor_dev;
 	struct led_classdev *leds[MAX_LEDS];
 	unsigned long quirks;
 	struct work_struct state_worker;
@@ -1225,15 +948,11 @@ static u8 *sony_report_fixup(struct hid_device *hdev, u8 *rdesc,
 	}
 
 	/*
-	 * The default Dualshock 4 USB descriptor doesn't assign
-	 * the gyroscope values to corresponding axes so we need a
-	 * modified one.
+	 * The default Dualshock 4 BT descriptor doesn't describe report ID 17
+	 * which is most often used for input data. Add this mapping, so we
+	 * use the generic hid code for parsing the buttons and axes.
 	 */
-	if (sc->quirks & DUALSHOCK4_CONTROLLER_USB) {
-		hid_info(hdev, "Using modified Dualshock 4 report descriptor with gyroscope axes\n");
-		rdesc = dualshock4_usb_rdesc;
-		*rsize = sizeof(dualshock4_usb_rdesc);
-	} else if (sc->quirks & DUALSHOCK4_CONTROLLER_BT) {
+	if (sc->quirks & DUALSHOCK4_CONTROLLER_BT) {
 		hid_info(hdev, "Using modified Dualshock 4 Bluetooth report descriptor\n");
 		rdesc = dualshock4_bt_rdesc;
 		*rsize = sizeof(dualshock4_bt_rdesc);
@@ -1293,6 +1012,9 @@ static void dualshock4_parse_report(struct sony_sc *sc, u8 *rd, int size)
 	int n, m, offset, num_touch_data, max_touch_data;
 	u8 cable_state, battery_capacity, battery_charging;
 
+	/* Order of hw axes is gyro first, then accelerometer. */
+	int axes[6] = {ABS_RX, ABS_RY, ABS_RZ, ABS_X, ABS_Y, ABS_Z};
+
 	/* When using Bluetooth the header is 2 bytes longer, so skip these. */
 	int data_offset = (sc->quirks & DUALSHOCK4_CONTROLLER_USB) ? 0 : 2;
 
@@ -1300,6 +1022,14 @@ 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);
 
+	offset = data_offset + DS4_INPUT_REPORT_GYRO_X_OFFSET;
+	for (n = 0; n < 6; n++, offset += 2) {
+		short value = get_unaligned_le16(&rd[offset]);
+
+		input_report_abs(sc->sensor_dev, axes[n], value);
+	}
+	input_sync(sc->sensor_dev);
+
 	/*
 	 * The lower 4 bits of byte 30 (or 32 for BT) contain the battery level
 	 * and the 5th bit contains the USB cable state.
@@ -1553,6 +1283,76 @@ static void sony_unregister_touchpad(struct sony_sc *sc)
 	sc->touchpad = NULL;
 }
 
+static int sony_register_sensors(struct sony_sc *sc)
+{
+	size_t name_sz;
+	char *name;
+	int ret;
+
+	sc->sensor_dev = input_allocate_device();
+	if (!sc->sensor_dev)
+		return -ENOMEM;
+
+	input_set_drvdata(sc->sensor_dev, sc);
+	sc->sensor_dev->dev.parent = &sc->hdev->dev;
+	sc->sensor_dev->phys = sc->hdev->phys;
+	sc->sensor_dev->uniq = sc->hdev->uniq;
+	sc->sensor_dev->id.bustype = sc->hdev->bus;
+	sc->sensor_dev->id.vendor = sc->hdev->vendor;
+	sc->sensor_dev->id.product = sc->hdev->product;
+	sc->sensor_dev->id.version = sc->hdev->version;
+
+	/* Append a suffix to the controller name as there are various
+	 * DS4 compatible non-Sony devices with different names.
+	 */
+	name_sz = strlen(sc->hdev->name) + sizeof(DS4_SENSOR_SUFFIX);
+	name = kzalloc(name_sz, GFP_KERNEL);
+	if (!name) {
+		ret = -ENOMEM;
+		goto err;
+	}
+	snprintf(name, name_sz, "%s" DS4_SENSOR_SUFFIX, sc->hdev->name);
+	sc->sensor_dev->name = name;
+
+	input_set_abs_params(sc->sensor_dev, ABS_X, -32768, 32767, 0, 0);
+	input_set_abs_params(sc->sensor_dev, ABS_Y, -32768, 32767, 0, 0);
+	input_set_abs_params(sc->sensor_dev, ABS_Z, -32768, 32767, 0, 0);
+
+	input_set_abs_params(sc->sensor_dev, ABS_RX, -32768, 32767, 0, 0);
+	input_set_abs_params(sc->sensor_dev, ABS_RY, -32768, 32767, 0, 0);
+	input_set_abs_params(sc->sensor_dev, ABS_RZ, -32768, 32767, 0, 0);
+
+	__set_bit(INPUT_PROP_ACCELEROMETER, sc->sensor_dev->propbit);
+
+	ret = input_register_device(sc->sensor_dev);
+	if (ret < 0)
+		goto err;
+
+	return 0;
+
+err:
+	kfree(sc->sensor_dev->name);
+	sc->sensor_dev->name = NULL;
+
+	input_free_device(sc->sensor_dev);
+	sc->sensor_dev = NULL;
+
+	return ret;
+}
+
+static void sony_unregister_sensors(struct sony_sc *sc)
+{
+	if (!sc->sensor_dev)
+		return;
+
+	kfree(sc->sensor_dev->name);
+	sc->sensor_dev->name = NULL;
+
+	input_unregister_device(sc->sensor_dev);
+	sc->sensor_dev = NULL;
+}
+
+
 /*
  * Sending HID_REQ_GET_REPORT changes the operation mode of the ps3 controller
  * to "operational".  Without this, the ps3 controller will not report any
@@ -2551,6 +2351,13 @@ static int sony_input_configured(struct hid_device *hdev,
 			return ret;
 		}
 
+		ret = sony_register_sensors(sc);
+		if (ret) {
+			hid_err(sc->hdev,
+			"Unable to initialize motion sensors: %d\n", ret);
+			goto err_stop;
+		}
+
 		sony_init_output_report(sc, dualshock4_send_output_report);
 	} else if (sc->quirks & MOTION_CONTROLLER) {
 		sony_init_output_report(sc, motion_send_output_report);
@@ -2685,6 +2492,9 @@ static void sony_remove(struct hid_device *hdev)
 	if (sc->touchpad)
 		sony_unregister_touchpad(sc);
 
+	if (sc->sensor_dev)
+		sony_unregister_sensors(sc);
+
 	sony_cancel_work_sync(sc);
 
 	kfree(sc->output_report_dmabuf);
diff --git a/include/uapi/linux/input.h b/include/uapi/linux/input.h
index e794f7b..f561c0e 100644
--- a/include/uapi/linux/input.h
+++ b/include/uapi/linux/input.h
@@ -61,9 +61,14 @@ struct input_id {
  * Note that input core does not clamp reported values to the
  * [minimum, maximum] limits, such task is left to userspace.
  *
- * Resolution for main axes (ABS_X, ABS_Y, ABS_Z) is reported in
- * units per millimeter (units/mm), resolution for rotational axes
- * (ABS_RX, ABS_RY, ABS_RZ) is reported in units per radian.
+ * The default resolution for main axes (ABS_X, ABS_Y, ABS_Z)
+ * is reported in units per millimeter (units/mm), resolution
+ * for rotational axes (ABS_RX, ABS_RY, ABS_RZ) is reported
+ * in units per radian.
+ * When INPUT_PROP_ACCELEROMETER is set the resolution changes.
+ * The main axes (ABS_X, ABS_Y, ABS_Z) are then reported in
+ * in units per g (units/g) and in units per degree per second
+ * (units/deg/s) for rotational axes (ABS_RX, ABS_RY, ABS_RZ).
  */
 struct input_absinfo {
 	__s32 value;
-- 
2.7.4


^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH 5/8] HID: sony: Use DS4 MAC address as unique identifier on USB
  2016-11-23 22:07 [PATCH 0/8] HID: sony: DS4 updates Roderick Colenbrander
                   ` (3 preceding siblings ...)
  2016-11-23 22:07 ` [PATCH 4/8] HID: sony: Report DS4 motion sensors through a separate device Roderick Colenbrander
@ 2016-11-23 22:07 ` Roderick Colenbrander
  2016-11-23 22:07 ` [PATCH 6/8] HID: sony: Support DS4 dongle Roderick Colenbrander
                   ` (3 subsequent siblings)
  8 siblings, 0 replies; 21+ messages in thread
From: Roderick Colenbrander @ 2016-11-23 22:07 UTC (permalink / raw)
  To: linux-input
  Cc: Dmitry Torokhov, Jiri Kosina, Benjamin Tissoires, Simon Wood,
	Frank Praznik, Tim Bird, Roderick Colenbrander

From: Roderick Colenbrander <roderick.colenbrander@sony.com>

The DS4 MAC address is reported as a unique identified when
using Bluetooth. For USB there is no unique identifier reported
yet, so use the MAC address.

Signed-off-by: Roderick Colenbrander <roderick.colenbrander@sony.com>
---
 drivers/hid/hid-sony.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/drivers/hid/hid-sony.c b/drivers/hid/hid-sony.c
index c391907..ea5b045 100644
--- a/drivers/hid/hid-sony.c
+++ b/drivers/hid/hid-sony.c
@@ -2190,6 +2190,12 @@ static int sony_check_add(struct sony_sc *sc)
 		}
 
 		memcpy(sc->mac_address, &buf[1], sizeof(sc->mac_address));
+
+		snprintf(sc->hdev->uniq, sizeof(sc->hdev->uniq),
+			"%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx",
+			sc->mac_address[5], sc->mac_address[4],
+			sc->mac_address[3], sc->mac_address[2],
+			sc->mac_address[1], sc->mac_address[0]);
 	} else if ((sc->quirks & SIXAXIS_CONTROLLER_USB) ||
 			(sc->quirks & NAVIGATION_CONTROLLER_USB)) {
 		buf = kmalloc(SIXAXIS_REPORT_0xF2_SIZE, GFP_KERNEL);
-- 
2.7.4


^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH 6/8] HID: sony: Support DS4 dongle
  2016-11-23 22:07 [PATCH 0/8] HID: sony: DS4 updates Roderick Colenbrander
                   ` (4 preceding siblings ...)
  2016-11-23 22:07 ` [PATCH 5/8] HID: sony: Use DS4 MAC address as unique identifier on USB Roderick Colenbrander
@ 2016-11-23 22:07 ` Roderick Colenbrander
  2016-11-23 22:07 ` [PATCH 7/8] HID: sony: Calibrate DS4 motion sensors Roderick Colenbrander
                   ` (2 subsequent siblings)
  8 siblings, 0 replies; 21+ messages in thread
From: Roderick Colenbrander @ 2016-11-23 22:07 UTC (permalink / raw)
  To: linux-input
  Cc: Dmitry Torokhov, Jiri Kosina, Benjamin Tissoires, Simon Wood,
	Frank Praznik, Tim Bird, Roderick Colenbrander

From: Roderick Colenbrander <roderick.colenbrander@sony.com>

Add support for USB based DS4 dongle device, which allows connecting
a DS4 through Bluetooth, but hides Bluetooth from the host system.

Signed-off-by: Roderick Colenbrander <roderick.colenbrander@sony.com>
---
 drivers/hid/hid-core.c | 1 +
 drivers/hid/hid-ids.h  | 1 +
 drivers/hid/hid-sony.c | 2 ++
 3 files changed, 4 insertions(+)

diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c
index 4a5ce67..f468377 100644
--- a/drivers/hid/hid-core.c
+++ b/drivers/hid/hid-core.c
@@ -2064,6 +2064,7 @@ static const struct hid_device_id hid_have_special_driver[] = {
 	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS4_CONTROLLER) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS4_CONTROLLER_2) },
 	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS4_CONTROLLER_2) },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS4_CONTROLLER_DONGLE) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_VAIO_VGX_MOUSE) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_VAIO_VGP_MOUSE) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_SINO_LITE, USB_DEVICE_ID_SINO_LITE_CONTROLLER) },
diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h
index ef57825..a33e577 100644
--- a/drivers/hid/hid-ids.h
+++ b/drivers/hid/hid-ids.h
@@ -906,6 +906,7 @@
 #define USB_DEVICE_ID_SONY_PS3_CONTROLLER	0x0268
 #define USB_DEVICE_ID_SONY_PS4_CONTROLLER	0x05c4
 #define USB_DEVICE_ID_SONY_PS4_CONTROLLER_2	0x09cc
+#define USB_DEVICE_ID_SONY_PS4_CONTROLLER_DONGLE	0x0ba0
 #define USB_DEVICE_ID_SONY_MOTION_CONTROLLER	0x03d5
 #define USB_DEVICE_ID_SONY_NAVIGATION_CONTROLLER	0x042f
 #define USB_DEVICE_ID_SONY_BUZZ_CONTROLLER		0x0002
diff --git a/drivers/hid/hid-sony.c b/drivers/hid/hid-sony.c
index ea5b045..f27c9b8 100644
--- a/drivers/hid/hid-sony.c
+++ b/drivers/hid/hid-sony.c
@@ -2607,6 +2607,8 @@ static const struct hid_device_id sony_devices[] = {
 		.driver_data = DUALSHOCK4_CONTROLLER_USB },
 	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS4_CONTROLLER_2),
 		.driver_data = DUALSHOCK4_CONTROLLER_BT },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS4_CONTROLLER_DONGLE),
+		.driver_data = DUALSHOCK4_CONTROLLER_USB },
 	/* Nyko Core Controller for PS3 */
 	{ HID_USB_DEVICE(USB_VENDOR_ID_SINO_LITE, USB_DEVICE_ID_SINO_LITE_CONTROLLER),
 		.driver_data = SIXAXIS_CONTROLLER_USB | SINO_LITE_CONTROLLER },
-- 
2.7.4


^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH 7/8] HID: sony: Calibrate DS4 motion sensors
  2016-11-23 22:07 [PATCH 0/8] HID: sony: DS4 updates Roderick Colenbrander
                   ` (5 preceding siblings ...)
  2016-11-23 22:07 ` [PATCH 6/8] HID: sony: Support DS4 dongle Roderick Colenbrander
@ 2016-11-23 22:07 ` Roderick Colenbrander
  2016-11-23 22:07 ` [PATCH 8/8] HID: sony: Report hardware timestamp for DS4 sensor values Roderick Colenbrander
  2016-11-28 13:56 ` [PATCH 0/8] HID: sony: DS4 updates Jiri Kosina
  8 siblings, 0 replies; 21+ messages in thread
From: Roderick Colenbrander @ 2016-11-23 22:07 UTC (permalink / raw)
  To: linux-input
  Cc: Dmitry Torokhov, Jiri Kosina, Benjamin Tissoires, Simon Wood,
	Frank Praznik, Tim Bird, Roderick Colenbrander

From: Roderick Colenbrander <roderick.colenbrander@sony.com>

The DS4 motion sensors require calibration for accurate operation.
This patch adds calibration for both the accelerometer and the
gyroscope. Calibration requires reading device specific scaling
factors and offsets. For precision reasons we store these values
as a numerator and denominator and apply the values when processing
the data.

Signed-off-by: Roderick Colenbrander <roderick.colenbrander@sony.com>
---
 drivers/hid/hid-sony.c | 213 ++++++++++++++++++++++++++++++++++++++++++-------
 1 file changed, 185 insertions(+), 28 deletions(-)

diff --git a/drivers/hid/hid-sony.c b/drivers/hid/hid-sony.c
index f27c9b8..d9e5254 100644
--- a/drivers/hid/hid-sony.c
+++ b/drivers/hid/hid-sony.c
@@ -768,6 +768,7 @@ struct motion_output_report_02 {
 };
 
 #define DS4_FEATURE_REPORT_0x02_SIZE 37
+#define DS4_FEATURE_REPORT_0x05_SIZE 41
 #define DS4_FEATURE_REPORT_0x81_SIZE 7
 #define DS4_INPUT_REPORT_0x11_SIZE 78
 #define DS4_OUTPUT_REPORT_0x05_SIZE 32
@@ -787,10 +788,25 @@ struct motion_output_report_02 {
 #define DS4_SENSOR_SUFFIX " Motion Sensors"
 #define DS4_TOUCHPAD_SUFFIX " Touchpad"
 
+#define DS4_GYRO_RES_PER_DEG_S 1024
+#define DS4_ACC_RES_PER_G      8192
+
 static DEFINE_SPINLOCK(sony_dev_list_lock);
 static LIST_HEAD(sony_device_list);
 static DEFINE_IDA(sony_device_id_allocator);
 
+/* Used for calibration of DS4 accelerometer and gyro. */
+struct ds4_calibration_data {
+	int abs_code;
+	short bias;
+	/* Calibration requires scaling against a sensitivity value, which is a
+	 * float. Store sensitivity as a fraction to limit floating point
+	 * calculations until final calibration.
+	 */
+	int sens_numer;
+	int sens_denom;
+};
+
 struct sony_sc {
 	spinlock_t lock;
 	struct list_head list_node;
@@ -822,6 +838,9 @@ struct sony_sc {
 	u8 led_delay_on[MAX_LEDS];
 	u8 led_delay_off[MAX_LEDS];
 	u8 led_count;
+
+	/* DS4 calibration data */
+	struct ds4_calibration_data ds4_calib_data[6];
 };
 
 static inline void sony_schedule_work(struct sony_sc *sc)
@@ -1012,9 +1031,6 @@ static void dualshock4_parse_report(struct sony_sc *sc, u8 *rd, int size)
 	int n, m, offset, num_touch_data, max_touch_data;
 	u8 cable_state, battery_capacity, battery_charging;
 
-	/* Order of hw axes is gyro first, then accelerometer. */
-	int axes[6] = {ABS_RX, ABS_RY, ABS_RZ, ABS_X, ABS_Y, ABS_Z};
-
 	/* When using Bluetooth the header is 2 bytes longer, so skip these. */
 	int data_offset = (sc->quirks & DUALSHOCK4_CONTROLLER_USB) ? 0 : 2;
 
@@ -1023,10 +1039,22 @@ static void dualshock4_parse_report(struct sony_sc *sc, u8 *rd, int size)
 	input_report_key(sc->touchpad, BTN_LEFT, rd[offset+2] & 0x2);
 
 	offset = data_offset + DS4_INPUT_REPORT_GYRO_X_OFFSET;
-	for (n = 0; n < 6; n++, offset += 2) {
-		short value = get_unaligned_le16(&rd[offset]);
+	for (n = 0; n < 6; n++) {
+		/* Store data in int for more precision during mult_frac. */
+		int raw_data = (short)((rd[offset+1] << 8) | rd[offset]);
+		struct ds4_calibration_data *calib = &sc->ds4_calib_data[n];
+
+		/* High precision is needed during calibration, but the
+		 * calibrated values are within 32-bit.
+		 * Note: we swap numerator 'x' and 'numer' in mult_frac for
+		 *       precision reasons so we don't need 64-bit.
+		 */
+		int calib_data = mult_frac(calib->sens_numer,
+					   raw_data - calib->bias,
+					   calib->sens_denom);
 
-		input_report_abs(sc->sensor_dev, axes[n], value);
+		input_report_abs(sc->sensor_dev, calib->abs_code, calib_data);
+		offset += 2;
 	}
 	input_sync(sc->sensor_dev);
 
@@ -1288,6 +1316,7 @@ static int sony_register_sensors(struct sony_sc *sc)
 	size_t name_sz;
 	char *name;
 	int ret;
+	int range;
 
 	sc->sensor_dev = input_allocate_device();
 	if (!sc->sensor_dev)
@@ -1314,13 +1343,21 @@ static int sony_register_sensors(struct sony_sc *sc)
 	snprintf(name, name_sz, "%s" DS4_SENSOR_SUFFIX, sc->hdev->name);
 	sc->sensor_dev->name = name;
 
-	input_set_abs_params(sc->sensor_dev, ABS_X, -32768, 32767, 0, 0);
-	input_set_abs_params(sc->sensor_dev, ABS_Y, -32768, 32767, 0, 0);
-	input_set_abs_params(sc->sensor_dev, ABS_Z, -32768, 32767, 0, 0);
-
-	input_set_abs_params(sc->sensor_dev, ABS_RX, -32768, 32767, 0, 0);
-	input_set_abs_params(sc->sensor_dev, ABS_RY, -32768, 32767, 0, 0);
-	input_set_abs_params(sc->sensor_dev, ABS_RZ, -32768, 32767, 0, 0);
+	range = DS4_ACC_RES_PER_G*4;
+	input_set_abs_params(sc->sensor_dev, ABS_X, -range, range, 16, 0);
+	input_set_abs_params(sc->sensor_dev, ABS_Y, -range, range, 16, 0);
+	input_set_abs_params(sc->sensor_dev, ABS_Z, -range, range, 16, 0);
+	input_abs_set_res(sc->sensor_dev, ABS_X, DS4_ACC_RES_PER_G);
+	input_abs_set_res(sc->sensor_dev, ABS_Y, DS4_ACC_RES_PER_G);
+	input_abs_set_res(sc->sensor_dev, ABS_Z, DS4_ACC_RES_PER_G);
+
+	range = DS4_GYRO_RES_PER_DEG_S*2048;
+	input_set_abs_params(sc->sensor_dev, ABS_RX, -range, range, 16, 0);
+	input_set_abs_params(sc->sensor_dev, ABS_RY, -range, range, 16, 0);
+	input_set_abs_params(sc->sensor_dev, ABS_RZ, -range, range, 16, 0);
+	input_abs_set_res(sc->sensor_dev, ABS_RX, DS4_GYRO_RES_PER_DEG_S);
+	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(INPUT_PROP_ACCELEROMETER, sc->sensor_dev->propbit);
 
@@ -1418,23 +1455,145 @@ static int sixaxis_set_operational_bt(struct hid_device *hdev)
 }
 
 /*
- * Requesting feature report 0x02 in Bluetooth mode changes the state of the
- * controller so that it sends full input reports of type 0x11.
+ * Request DS4 calibration data for the motion sensors.
+ * For Bluetooth this also affects the operating mode (see below).
  */
-static int dualshock4_set_operational_bt(struct hid_device *hdev)
+static int dualshock4_get_calibration_data(struct sony_sc *sc)
 {
 	u8 *buf;
 	int ret;
+	short gyro_pitch_bias, gyro_pitch_plus, gyro_pitch_minus;
+	short gyro_yaw_bias, gyro_yaw_plus, gyro_yaw_minus;
+	short gyro_roll_bias, gyro_roll_plus, gyro_roll_minus;
+	short gyro_speed_plus, gyro_speed_minus;
+	short acc_x_plus, acc_x_minus;
+	short acc_y_plus, acc_y_minus;
+	short acc_z_plus, acc_z_minus;
+	int speed_2x;
+	int range_2g;
+
+	/* For Bluetooth we use a different request, which supports CRC.
+	 * Note: in Bluetooth mode feature report 0x02 also changes the state
+	 * of the controller, so that it sends input reports of type 0x11.
+	 */
+	if (sc->quirks & DUALSHOCK4_CONTROLLER_USB) {
+		buf = kmalloc(DS4_FEATURE_REPORT_0x02_SIZE, GFP_KERNEL);
+		if (!buf)
+			return -ENOMEM;
 
-	buf = kmalloc(DS4_FEATURE_REPORT_0x02_SIZE, GFP_KERNEL);
-	if (!buf)
-		return -ENOMEM;
+		ret = hid_hw_raw_request(sc->hdev, 0x02, buf,
+					 DS4_FEATURE_REPORT_0x02_SIZE,
+					 HID_FEATURE_REPORT,
+					 HID_REQ_GET_REPORT);
+		if (ret < 0)
+			goto err_stop;
+	} else {
+		u8 bthdr = 0xA3;
+		u32 crc;
+		u32 report_crc;
+		int retries;
 
-	ret = hid_hw_raw_request(hdev, 0x02, buf, DS4_FEATURE_REPORT_0x02_SIZE,
-				HID_FEATURE_REPORT, HID_REQ_GET_REPORT);
+		buf = kmalloc(DS4_FEATURE_REPORT_0x05_SIZE, GFP_KERNEL);
+		if (!buf)
+			return -ENOMEM;
 
-	kfree(buf);
+		for (retries = 0; retries < 3; retries++) {
+			ret = hid_hw_raw_request(sc->hdev, 0x05, buf,
+						 DS4_FEATURE_REPORT_0x05_SIZE,
+						 HID_FEATURE_REPORT,
+						 HID_REQ_GET_REPORT);
+			if (ret < 0)
+				goto err_stop;
 
+			/* CRC check */
+			crc = crc32_le(0xFFFFFFFF, &bthdr, 1);
+			crc = ~crc32_le(crc, buf, DS4_FEATURE_REPORT_0x05_SIZE-4);
+			report_crc = get_unaligned_le32(&buf[DS4_FEATURE_REPORT_0x05_SIZE-4]);
+			if (crc != report_crc) {
+				hid_warn(sc->hdev, "DualShock 4 calibration report's CRC check failed, received crc 0x%0x != 0x%0x\n",
+					report_crc, crc);
+				if (retries < 2) {
+					hid_warn(sc->hdev, "Retrying DualShock 4 get calibration report request\n");
+					continue;
+				} else {
+					ret = -EILSEQ;
+					goto err_stop;
+				}
+			} else {
+				break;
+			}
+		}
+	}
+
+	gyro_pitch_bias  = get_unaligned_le16(&buf[1]);
+	gyro_yaw_bias    = get_unaligned_le16(&buf[3]);
+	gyro_roll_bias   = get_unaligned_le16(&buf[5]);
+	if (sc->quirks & DUALSHOCK4_CONTROLLER_USB) {
+		gyro_pitch_plus  = get_unaligned_le16(&buf[7]);
+		gyro_pitch_minus = get_unaligned_le16(&buf[9]);
+		gyro_yaw_plus    = get_unaligned_le16(&buf[11]);
+		gyro_yaw_minus   = get_unaligned_le16(&buf[13]);
+		gyro_roll_plus   = get_unaligned_le16(&buf[15]);
+		gyro_roll_minus  = get_unaligned_le16(&buf[17]);
+	} else {
+		gyro_pitch_plus  = get_unaligned_le16(&buf[7]);
+		gyro_yaw_plus    = get_unaligned_le16(&buf[9]);
+		gyro_roll_plus   = get_unaligned_le16(&buf[11]);
+		gyro_pitch_minus = get_unaligned_le16(&buf[13]);
+		gyro_yaw_minus   = get_unaligned_le16(&buf[15]);
+		gyro_roll_minus  = get_unaligned_le16(&buf[17]);
+	}
+	gyro_speed_plus  = get_unaligned_le16(&buf[19]);
+	gyro_speed_minus = get_unaligned_le16(&buf[21]);
+	acc_x_plus       = get_unaligned_le16(&buf[23]);
+	acc_x_minus      = get_unaligned_le16(&buf[25]);
+	acc_y_plus       = get_unaligned_le16(&buf[27]);
+	acc_y_minus      = get_unaligned_le16(&buf[29]);
+	acc_z_plus       = get_unaligned_le16(&buf[31]);
+	acc_z_minus      = get_unaligned_le16(&buf[33]);
+
+	/* Set gyroscope calibration and normalization parameters.
+	 * Data values will be normalized to 1/DS4_GYRO_RES_PER_DEG_S degree/s.
+	 */
+	speed_2x = (gyro_speed_plus + gyro_speed_minus);
+	sc->ds4_calib_data[0].abs_code = ABS_RX;
+	sc->ds4_calib_data[0].bias = gyro_pitch_bias;
+	sc->ds4_calib_data[0].sens_numer = speed_2x*DS4_GYRO_RES_PER_DEG_S;
+	sc->ds4_calib_data[0].sens_denom = gyro_pitch_plus - gyro_pitch_minus;
+
+	sc->ds4_calib_data[1].abs_code = ABS_RY;
+	sc->ds4_calib_data[1].bias = gyro_yaw_bias;
+	sc->ds4_calib_data[1].sens_numer = speed_2x*DS4_GYRO_RES_PER_DEG_S;
+	sc->ds4_calib_data[1].sens_denom = gyro_yaw_plus - gyro_yaw_minus;
+
+	sc->ds4_calib_data[2].abs_code = ABS_RZ;
+	sc->ds4_calib_data[2].bias = gyro_roll_bias;
+	sc->ds4_calib_data[2].sens_numer = speed_2x*DS4_GYRO_RES_PER_DEG_S;
+	sc->ds4_calib_data[2].sens_denom = gyro_roll_plus - gyro_roll_minus;
+
+	/* Set accelerometer calibration and normalization parameters.
+	 * Data values will be normalized to 1/DS4_ACC_RES_PER_G G.
+	 */
+	range_2g = acc_x_plus - acc_x_minus;
+	sc->ds4_calib_data[3].abs_code = ABS_X;
+	sc->ds4_calib_data[3].bias = acc_x_plus - range_2g / 2;
+	sc->ds4_calib_data[3].sens_numer = 2*DS4_ACC_RES_PER_G;
+	sc->ds4_calib_data[3].sens_denom = range_2g;
+
+	range_2g = acc_y_plus - acc_y_minus;
+	sc->ds4_calib_data[4].abs_code = ABS_Y;
+	sc->ds4_calib_data[4].bias = acc_y_plus - range_2g / 2;
+	sc->ds4_calib_data[4].sens_numer = 2*DS4_ACC_RES_PER_G;
+	sc->ds4_calib_data[4].sens_denom = range_2g;
+
+	range_2g = acc_z_plus - acc_z_minus;
+	sc->ds4_calib_data[5].abs_code = ABS_Z;
+	sc->ds4_calib_data[5].bias = acc_z_plus - range_2g / 2;
+	sc->ds4_calib_data[5].sens_numer = 2*DS4_ACC_RES_PER_G;
+	sc->ds4_calib_data[5].sens_denom = range_2g;
+
+err_stop:
+	kfree(buf);
 	return ret;
 }
 
@@ -2337,12 +2496,10 @@ static int sony_input_configured(struct hid_device *hdev,
 		ret = sixaxis_set_operational_bt(hdev);
 		sony_init_output_report(sc, sixaxis_send_output_report);
 	} else if (sc->quirks & DUALSHOCK4_CONTROLLER) {
-		if (sc->quirks & DUALSHOCK4_CONTROLLER_BT) {
-			ret = dualshock4_set_operational_bt(hdev);
-			if (ret < 0) {
-				hid_err(hdev, "failed to set the Dualshock 4 operational mode\n");
-				goto err_stop;
-			}
+		ret = dualshock4_get_calibration_data(sc);
+		if (ret < 0) {
+			hid_err(hdev, "Failed to get calibration data from Dualshock 4\n");
+			goto err_stop;
 		}
 
 		/*
-- 
2.7.4


^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH 8/8] HID: sony: Report hardware timestamp for DS4 sensor values
  2016-11-23 22:07 [PATCH 0/8] HID: sony: DS4 updates Roderick Colenbrander
                   ` (6 preceding siblings ...)
  2016-11-23 22:07 ` [PATCH 7/8] HID: sony: Calibrate DS4 motion sensors Roderick Colenbrander
@ 2016-11-23 22:07 ` Roderick Colenbrander
  2016-11-28 13:56 ` [PATCH 0/8] HID: sony: DS4 updates Jiri Kosina
  8 siblings, 0 replies; 21+ messages in thread
From: Roderick Colenbrander @ 2016-11-23 22:07 UTC (permalink / raw)
  To: linux-input
  Cc: Dmitry Torokhov, Jiri Kosina, Benjamin Tissoires, Simon Wood,
	Frank Praznik, Tim Bird, Roderick Colenbrander

From: Roderick Colenbrander <roderick.colenbrander@sony.com>

Report the hardware timestamp inside each HID report through
MSC_TIMESTAMP for motion sensor values.

Signed-off-by: Roderick Colenbrander <roderick.colenbrander@sony.com>
---
 drivers/hid/hid-sony.c | 26 ++++++++++++++++++++++++++
 1 file changed, 26 insertions(+)

diff --git a/drivers/hid/hid-sony.c b/drivers/hid/hid-sony.c
index d9e5254..2127613 100644
--- a/drivers/hid/hid-sony.c
+++ b/drivers/hid/hid-sony.c
@@ -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
@@ -839,6 +840,10 @@ struct sony_sc {
 	u8 led_delay_off[MAX_LEDS];
 	u8 led_count;
 
+	bool timestamp_initialized;
+	u16 prev_timestamp;
+	unsigned int timestamp_us;
+
 	/* DS4 calibration data */
 	struct ds4_calibration_data ds4_calib_data[6];
 };
@@ -1030,6 +1035,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;
@@ -1038,6 +1044,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. */
@@ -1359,6 +1383,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);
-- 
2.7.4


^ permalink raw reply related	[flat|nested] 21+ messages in thread

* Re: [PATCH 4/8] HID: sony: Report DS4 motion sensors through a separate device
  2016-11-23 22:07 ` [PATCH 4/8] HID: sony: Report DS4 motion sensors through a separate device Roderick Colenbrander
@ 2016-11-23 23:17   ` Simon Wood
  2016-11-24  4:44     ` Roderick Colenbrander
  0 siblings, 1 reply; 21+ messages in thread
From: Simon Wood @ 2016-11-23 23:17 UTC (permalink / raw)
  To: Roderick Colenbrander
  Cc: linux-input, Dmitry Torokhov, Jiri Kosina, Benjamin Tissoires,
	Simon Wood, Frank Praznik, Tim Bird, Roderick Colenbrander

On Wed, November 23, 2016 3:07 pm, Roderick Colenbrander wrote:
> From: Roderick Colenbrander <roderick.colenbrander@sony.com>
>
>
> The DS4 motion sensors are currently mapped by the hid-core driver
> to non-existing axes in between ABS_MISC and ABS_MT_SLOT, because the
> device already exhausted ABS_X-ABS_RZ. For a part the mapping by hid-core
> is accomplished by a fixup in hid-sony as the motion axes actually use
> vendor specific usage pages.

We probably all agree that sending Acc/Gyro data across the joystick
interface is not the best thing in the world, so I would have some doubts
about whether spinning up another separate interface is quite the 'correct
thing' either.

A while back I did some 'tinkering' on the SixAxis to see if 'we' could
use the IIO interface to report accelerometer data.
https://patchwork.kernel.org/patch/6589061/

I think that the timestamps are critical to get correct interpretation of
the data, and note that PS Move and PS VR both return multiple sets of
acc/gyro data in a single HID report.

>
> This patch makes the DS4 use a separate input device for the motion
> sensors and reports acceleration data through ABS_X-ABS_Z and gyroscope
> data through ABS_RX-ABS_RZ. In addition it extends the event spec to allow
> gyroscope data through ABS_RX-ABS_RZ when INPUT_PROP_ACCELEROMETER is set.
> This change was suggested by
> Peter Hutterer during a discussion on linux-input.

Do you have a link?

Also, can you confirm whether this change would break '/dev/hidrawX', I
know a number of projects that read that directly to do their thing.

Thanks,
Simon.


^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH 4/8] HID: sony: Report DS4 motion sensors through a separate device
  2016-11-23 23:17   ` Simon Wood
@ 2016-11-24  4:44     ` Roderick Colenbrander
  2016-11-28 13:53       ` Jiri Kosina
  0 siblings, 1 reply; 21+ messages in thread
From: Roderick Colenbrander @ 2016-11-24  4:44 UTC (permalink / raw)
  To: Simon Wood
  Cc: linux-input, Dmitry Torokhov, Jiri Kosina, Benjamin Tissoires,
	Frank Praznik, Tim Bird, Roderick Colenbrander

On Wed, Nov 23, 2016 at 3:17 PM, Simon Wood <simon@mungewell.org> wrote:
>
> On Wed, November 23, 2016 3:07 pm, Roderick Colenbrander wrote:
> > From: Roderick Colenbrander <roderick.colenbrander@sony.com>
> >
> >
> > The DS4 motion sensors are currently mapped by the hid-core driver
> > to non-existing axes in between ABS_MISC and ABS_MT_SLOT, because the
> > device already exhausted ABS_X-ABS_RZ. For a part the mapping by hid-core
> > is accomplished by a fixup in hid-sony as the motion axes actually use
> > vendor specific usage pages.
>
> We probably all agree that sending Acc/Gyro data across the joystick
> interface is not the best thing in the world, so I would have some doubts
> about whether spinning up another separate interface is quite the 'correct
> thing' either.
>
> A while back I did some 'tinkering' on the SixAxis to see if 'we' could
> use the IIO interface to report accelerometer data.
> https://patchwork.kernel.org/patch/6589061/
>
> I think that the timestamps are critical to get correct interpretation of
> the data, and note that PS Move and PS VR both return multiple sets of
> acc/gyro data in a single HID report.

Timestamps are important. The last patch in this series reported them
through MSC_TIMESTAMP, which felt like a reasonable approach.

I'm not sure about the specifics of the other devices you mention. My
bet based on experience is that if there are multiple data points for
a given axis or touch point in a HID report (e.g. because the internal
device polling rate is high), there are likely multiple timestamps as
well. Multiple input_sync and multiple MSC_TIMESTAMPS could be an
option, similar like what was done for touch.

> >
> > This patch makes the DS4 use a separate input device for the motion
> > sensors and reports acceleration data through ABS_X-ABS_Z and gyroscope
> > data through ABS_RX-ABS_RZ. In addition it extends the event spec to allow
> > gyroscope data through ABS_RX-ABS_RZ when INPUT_PROP_ACCELEROMETER is set.
> > This change was suggested by
> > Peter Hutterer during a discussion on linux-input.
>
> Do you have a link?

There was a longer discussion when we tried to revive evdev patches on
adding additional ABS axes. This was kind of the last in that thread
in which we also discussed Wacom / Wii which are already handling some
of the stuff kind of.

https://lkml.org/lkml/2016/11/8/95

> Also, can you confirm whether this change would break '/dev/hidrawX', I
> know a number of projects that read that directly to do their thing.

We made the HID descriptor towards the end of report 17 look closely
like how the original report 1 looks like. To be honest as I mentioned
in 0/8, I'm not sure if we should even fixup the HID descriptors. For
example I'm aware of various cross platform projects (open and closed)
dealing with these devices and they are now seeing inconsistent views
between Windows, Linux and OSX, causing headaches. Some parse the
vendor specific bits as intended for example.

> Thanks,
> Simon.
>



-- 
Roderick Colenbrander
Senior Manager of Software Engineering
Gaikai, a Sony Interactive Entertainment Company
roderick@gaikai.com

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH 4/8] HID: sony: Report DS4 motion sensors through a separate device
  2016-11-24  4:44     ` Roderick Colenbrander
@ 2016-11-28 13:53       ` Jiri Kosina
  2016-11-29  6:32         ` Roderick Colenbrander
  0 siblings, 1 reply; 21+ messages in thread
From: Jiri Kosina @ 2016-11-28 13:53 UTC (permalink / raw)
  To: Roderick Colenbrander
  Cc: Simon Wood, linux-input, Dmitry Torokhov, Benjamin Tissoires,
	Frank Praznik, Tim Bird, Roderick Colenbrander

On Wed, 23 Nov 2016, Roderick Colenbrander wrote:

> > We probably all agree that sending Acc/Gyro data across the joystick
> > interface is not the best thing in the world, so I would have some doubts
> > about whether spinning up another separate interface is quite the 'correct
> > thing' either.
> >
> > A while back I did some 'tinkering' on the SixAxis to see if 'we' could
> > use the IIO interface to report accelerometer data.
> > https://patchwork.kernel.org/patch/6589061/

Roderick,

would you have any input on this aspect? I haven't really been actively 
involved in the discussion last year, but my gut feeling is that IIO would 
be the best suited interface for this.

Thanks,

-- 
Jiri Kosina
SUSE Labs


^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH 0/8] HID: sony: DS4 updates
  2016-11-23 22:07 [PATCH 0/8] HID: sony: DS4 updates Roderick Colenbrander
                   ` (7 preceding siblings ...)
  2016-11-23 22:07 ` [PATCH 8/8] HID: sony: Report hardware timestamp for DS4 sensor values Roderick Colenbrander
@ 2016-11-28 13:56 ` Jiri Kosina
  2016-11-29  2:36   ` Roderick Colenbrander
  8 siblings, 1 reply; 21+ messages in thread
From: Jiri Kosina @ 2016-11-28 13:56 UTC (permalink / raw)
  To: Roderick Colenbrander
  Cc: linux-input, Dmitry Torokhov, Benjamin Tissoires, Simon Wood,
	Frank Praznik, Tim Bird, Roderick Colenbrander

On Wed, 23 Nov 2016, Roderick Colenbrander wrote:

> I would like to share various updates to the DS4 driver. The first
> 4 patches are bug fixes and improvements discussed in various
> discussions on linux-input:
> - Fix issue when mixing USB and Bluetooth due to failure behind
>   the scens in sony_input_configured. Benjamin suggested the
>   fix we added.
> - The touchpad is a separate device to avoid touch influencing
>   the analog sticks, which happened due to use of input_mt_sync.
> - The DS4 code now complies to the Linux game controller spec.
>   We work with SDL2, the biggest DS4 user, to make sure it can
>   handle the different mappings. If desired we could make the DS3
>   comply as well and make similar changes.
> - Make DS4 motion sensors a separate device, so applications
>   don't have to use 'non-existing' axes. Updated the event code
>   specs to allow gyroscope data when INPUT_PROP_ACCELEROMETER is
>   set as suggested by Peter Hutterer.
> 
> The next 2 patches add the unique ID to the USB device and add
> support for a new DS4 device.
> 
> The last 2 patches add calibration and timestamp to the motion
> sensors, which finally makes the motion sensors usable.
> 
> As part of the changes we started to wonder if we should drop
> HID report fixups altogether for the DS4. It is used right now
> to have the hid-core layer be able to handle events for the
> 'misbehaving' report ID 17. I'm aware though of various cross
> platform libraries parsing DS4 HID reports, which are seeing
> inconsistent views per OS. Not sure what we should do, we could
> change this in a future patch. We would need to manually report
> buttons / axes when on Bluetooth for report ID 17.

I've now applied patches 1-3 to for-4.10/sony. For the rest, I'd like to 
still see the discussion of proper interface to take place.

Thanks,

-- 
Jiri Kosina
SUSE Labs


^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH 0/8] HID: sony: DS4 updates
  2016-11-28 13:56 ` [PATCH 0/8] HID: sony: DS4 updates Jiri Kosina
@ 2016-11-29  2:36   ` Roderick Colenbrander
  2016-11-29 13:33     ` Jiri Kosina
  0 siblings, 1 reply; 21+ messages in thread
From: Roderick Colenbrander @ 2016-11-29  2:36 UTC (permalink / raw)
  To: Jiri Kosina
  Cc: linux-input, Dmitry Torokhov, Benjamin Tissoires, Simon Wood,
	Frank Praznik, Tim Bird, Roderick Colenbrander

Hi Jiri,

Thanks for merging some of the patches. I will see where the other
discussion is going. Would you be able to merge patch 6 as well, it is
quite standalone adding a new product id?

Thanks,
Roderick

On Mon, Nov 28, 2016 at 5:56 AM, Jiri Kosina <jikos@kernel.org> wrote:
> On Wed, 23 Nov 2016, Roderick Colenbrander wrote:
>
>> I would like to share various updates to the DS4 driver. The first
>> 4 patches are bug fixes and improvements discussed in various
>> discussions on linux-input:
>> - Fix issue when mixing USB and Bluetooth due to failure behind
>>   the scens in sony_input_configured. Benjamin suggested the
>>   fix we added.
>> - The touchpad is a separate device to avoid touch influencing
>>   the analog sticks, which happened due to use of input_mt_sync.
>> - The DS4 code now complies to the Linux game controller spec.
>>   We work with SDL2, the biggest DS4 user, to make sure it can
>>   handle the different mappings. If desired we could make the DS3
>>   comply as well and make similar changes.
>> - Make DS4 motion sensors a separate device, so applications
>>   don't have to use 'non-existing' axes. Updated the event code
>>   specs to allow gyroscope data when INPUT_PROP_ACCELEROMETER is
>>   set as suggested by Peter Hutterer.
>>
>> The next 2 patches add the unique ID to the USB device and add
>> support for a new DS4 device.
>>
>> The last 2 patches add calibration and timestamp to the motion
>> sensors, which finally makes the motion sensors usable.
>>
>> As part of the changes we started to wonder if we should drop
>> HID report fixups altogether for the DS4. It is used right now
>> to have the hid-core layer be able to handle events for the
>> 'misbehaving' report ID 17. I'm aware though of various cross
>> platform libraries parsing DS4 HID reports, which are seeing
>> inconsistent views per OS. Not sure what we should do, we could
>> change this in a future patch. We would need to manually report
>> buttons / axes when on Bluetooth for report ID 17.
>
> I've now applied patches 1-3 to for-4.10/sony. For the rest, I'd like to
> still see the discussion of proper interface to take place.
>
> Thanks,
>
> --
> Jiri Kosina
> SUSE Labs
>



-- 
Roderick Colenbrander
Senior Manager of Software Engineering
Gaikai, a Sony Interactive Entertainment Company
roderick@gaikai.com

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH 4/8] HID: sony: Report DS4 motion sensors through a separate device
  2016-11-28 13:53       ` Jiri Kosina
@ 2016-11-29  6:32         ` Roderick Colenbrander
  2016-12-02 22:11           ` Roderick Colenbrander
  0 siblings, 1 reply; 21+ messages in thread
From: Roderick Colenbrander @ 2016-11-29  6:32 UTC (permalink / raw)
  To: Jiri Kosina
  Cc: Simon Wood, linux-input, Dmitry Torokhov, Benjamin Tissoires,
	Frank Praznik, Tim Bird, Roderick Colenbrander

On Mon, Nov 28, 2016 at 5:53 AM, Jiri Kosina <jikos@kernel.org> wrote:
> On Wed, 23 Nov 2016, Roderick Colenbrander wrote:
>
>> > We probably all agree that sending Acc/Gyro data across the joystick
>> > interface is not the best thing in the world, so I would have some doubts
>> > about whether spinning up another separate interface is quite the 'correct
>> > thing' either.
>> >
>> > A while back I did some 'tinkering' on the SixAxis to see if 'we' could
>> > use the IIO interface to report accelerometer data.
>> > https://patchwork.kernel.org/patch/6589061/
>
> Roderick,
>
> would you have any input on this aspect? I haven't really been actively
> involved in the discussion last year, but my gut feeling is that IIO would
> be the best suited interface for this.
>
> Thanks,
>
> --
> Jiri Kosina
> SUSE Labs
>

Hi Jiri,

Thanks for your response as well. From a technical side IIO is
promising and we experimented with it a bit as well. From a more
practical and business side I'm not the biggest fan. Let me explain a
bit and work out something which would ideally work for everyone
involved.

On the technical side, IIO was made for expressing many kinds of
sensors and our gamepads could be supported as well. The integration
with the HID side would be a bit tricky as the input report is shared
with general input data, so buffering, locks etcetera are needed, but
this is an implementation detail.

The main concern for us is software support in consumer platforms,
which we often deal with. These open or closed platforms have good
infrastructure for the Linux input frameworks, adding some other
system while of course technically feasible is just not possible in
practice. There is a strong preference there for standard evdev.
Some platforms use IIO behind the scenes for sensors e.g. Android.
Taking Android as example, it seems to access most sensors through a
vendor specific HAL implementation, which can bubble up
accelerometers, gyroscopes and many other kind of sensors. We looked
over public code for some of these devices and the sensor list
reported through this HAL seems to be static just based on what is
built-in into a particular device. For a gamepad hot-plugging is
common and at least on so wouldn't work (don't think the framework
handles this concept yet either), while this is handled fine for
evdev. I see similar challenges on other platforms we may potentially
deal with. Desktop Linux is probably the easiest, though libraries
like SDL2 and others need to gain support at some point.

I definitely see IIO as an interesting platform, but across platforms
the user space side is really not there even on a popular platform
like Android. As a company we may end up using this driver on on
various consumer devices (and older kernels), so I'm not a fan of IIO
for framework / legacy related reasons. We would like to maintain a
single code base, which is among the reasons we contribute to this
driver, wanting to avoid custom proprietary solutions, which don't
scale.

I'm not sure what the best path forward is. Maybe we could consider
supporting both e.g. through a kernel configuration option. This could
be forward and backwards compatible.

Thanks,

-- 
Roderick Colenbrander
Senior Manager of Software Engineering
Gaikai Inc, a Sony Interactive Entertainment Company

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH 0/8] HID: sony: DS4 updates
  2016-11-29  2:36   ` Roderick Colenbrander
@ 2016-11-29 13:33     ` Jiri Kosina
  0 siblings, 0 replies; 21+ messages in thread
From: Jiri Kosina @ 2016-11-29 13:33 UTC (permalink / raw)
  To: Roderick Colenbrander
  Cc: linux-input, Dmitry Torokhov, Benjamin Tissoires, Simon Wood,
	Frank Praznik, Tim Bird, Roderick Colenbrander

On Mon, 28 Nov 2016, Roderick Colenbrander wrote:

> Thanks for merging some of the patches. I will see where the other
> discussion is going. Would you be able to merge patch 6 as well, it is
> quite standalone adding a new product id?

Makes sense; pushed out for for-4.10/sony now.

-- 
Jiri Kosina
SUSE Labs


^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH 4/8] HID: sony: Report DS4 motion sensors through a separate device
  2016-11-29  6:32         ` Roderick Colenbrander
@ 2016-12-02 22:11           ` Roderick Colenbrander
  2016-12-05  9:44             ` Benjamin Tissoires
  0 siblings, 1 reply; 21+ messages in thread
From: Roderick Colenbrander @ 2016-12-02 22:11 UTC (permalink / raw)
  To: Jiri Kosina
  Cc: Simon Wood, linux-input, Dmitry Torokhov, Benjamin Tissoires,
	Frank Praznik, Tim Bird, Roderick Colenbrander

On Mon, Nov 28, 2016 at 10:32 PM, Roderick Colenbrander
<roderick@gaikai.com> wrote:
> On Mon, Nov 28, 2016 at 5:53 AM, Jiri Kosina <jikos@kernel.org> wrote:
>> On Wed, 23 Nov 2016, Roderick Colenbrander wrote:
>>
>>> > We probably all agree that sending Acc/Gyro data across the joystick
>>> > interface is not the best thing in the world, so I would have some doubts
>>> > about whether spinning up another separate interface is quite the 'correct
>>> > thing' either.
>>> >
>>> > A while back I did some 'tinkering' on the SixAxis to see if 'we' could
>>> > use the IIO interface to report accelerometer data.
>>> > https://patchwork.kernel.org/patch/6589061/
>>
>> Roderick,
>>
>> would you have any input on this aspect? I haven't really been actively
>> involved in the discussion last year, but my gut feeling is that IIO would
>> be the best suited interface for this.
>>
>> Thanks,
>>
>> --
>> Jiri Kosina
>> SUSE Labs
>>
>
> Hi Jiri,
>
> Thanks for your response as well. From a technical side IIO is
> promising and we experimented with it a bit as well. From a more
> practical and business side I'm not the biggest fan. Let me explain a
> bit and work out something which would ideally work for everyone
> involved.
>
> On the technical side, IIO was made for expressing many kinds of
> sensors and our gamepads could be supported as well. The integration
> with the HID side would be a bit tricky as the input report is shared
> with general input data, so buffering, locks etcetera are needed, but
> this is an implementation detail.
>
> The main concern for us is software support in consumer platforms,
> which we often deal with. These open or closed platforms have good
> infrastructure for the Linux input frameworks, adding some other
> system while of course technically feasible is just not possible in
> practice. There is a strong preference there for standard evdev.
> Some platforms use IIO behind the scenes for sensors e.g. Android.
> Taking Android as example, it seems to access most sensors through a
> vendor specific HAL implementation, which can bubble up
> accelerometers, gyroscopes and many other kind of sensors. We looked
> over public code for some of these devices and the sensor list
> reported through this HAL seems to be static just based on what is
> built-in into a particular device. For a gamepad hot-plugging is
> common and at least on so wouldn't work (don't think the framework
> handles this concept yet either), while this is handled fine for
> evdev. I see similar challenges on other platforms we may potentially
> deal with. Desktop Linux is probably the easiest, though libraries
> like SDL2 and others need to gain support at some point.
>
> I definitely see IIO as an interesting platform, but across platforms
> the user space side is really not there even on a popular platform
> like Android. As a company we may end up using this driver on on
> various consumer devices (and older kernels), so I'm not a fan of IIO
> for framework / legacy related reasons. We would like to maintain a
> single code base, which is among the reasons we contribute to this
> driver, wanting to avoid custom proprietary solutions, which don't
> scale.
>
> I'm not sure what the best path forward is. Maybe we could consider
> supporting both e.g. through a kernel configuration option. This could
> be forward and backwards compatible.
>
> Thanks,
>
> --
> Roderick Colenbrander
> Senior Manager of Software Engineering
> Gaikai Inc, a Sony Interactive Entertainment Company

Hi Jiri and others,

Any suggestions on how to move forward?

Thanks,
Roderick

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH 4/8] HID: sony: Report DS4 motion sensors through a separate device
  2016-12-02 22:11           ` Roderick Colenbrander
@ 2016-12-05  9:44             ` Benjamin Tissoires
  2017-01-13 20:25               ` Roderick Colenbrander
  2017-01-27 13:50               ` Jiri Kosina
  0 siblings, 2 replies; 21+ messages in thread
From: Benjamin Tissoires @ 2016-12-05  9:44 UTC (permalink / raw)
  To: Roderick Colenbrander
  Cc: Jiri Kosina, Simon Wood, linux-input, Dmitry Torokhov,
	Frank Praznik, Tim Bird, Roderick Colenbrander

On Dec 02 2016 or thereabouts, Roderick Colenbrander wrote:
> On Mon, Nov 28, 2016 at 10:32 PM, Roderick Colenbrander
> <roderick@gaikai.com> wrote:
> > On Mon, Nov 28, 2016 at 5:53 AM, Jiri Kosina <jikos@kernel.org> wrote:
> >> On Wed, 23 Nov 2016, Roderick Colenbrander wrote:
> >>
> >>> > We probably all agree that sending Acc/Gyro data across the joystick
> >>> > interface is not the best thing in the world, so I would have some doubts
> >>> > about whether spinning up another separate interface is quite the 'correct
> >>> > thing' either.
> >>> >
> >>> > A while back I did some 'tinkering' on the SixAxis to see if 'we' could
> >>> > use the IIO interface to report accelerometer data.
> >>> > https://patchwork.kernel.org/patch/6589061/
> >>
> >> Roderick,
> >>
> >> would you have any input on this aspect? I haven't really been actively
> >> involved in the discussion last year, but my gut feeling is that IIO would
> >> be the best suited interface for this.
> >>
> >> Thanks,
> >>
> >> --
> >> Jiri Kosina
> >> SUSE Labs
> >>
> >
> > Hi Jiri,
> >
> > Thanks for your response as well. From a technical side IIO is
> > promising and we experimented with it a bit as well. From a more
> > practical and business side I'm not the biggest fan. Let me explain a
> > bit and work out something which would ideally work for everyone
> > involved.
> >
> > On the technical side, IIO was made for expressing many kinds of
> > sensors and our gamepads could be supported as well. The integration
> > with the HID side would be a bit tricky as the input report is shared
> > with general input data, so buffering, locks etcetera are needed, but
> > this is an implementation detail.
> >
> > The main concern for us is software support in consumer platforms,
> > which we often deal with. These open or closed platforms have good
> > infrastructure for the Linux input frameworks, adding some other
> > system while of course technically feasible is just not possible in
> > practice. There is a strong preference there for standard evdev.
> > Some platforms use IIO behind the scenes for sensors e.g. Android.
> > Taking Android as example, it seems to access most sensors through a
> > vendor specific HAL implementation, which can bubble up
> > accelerometers, gyroscopes and many other kind of sensors. We looked
> > over public code for some of these devices and the sensor list
> > reported through this HAL seems to be static just based on what is
> > built-in into a particular device. For a gamepad hot-plugging is
> > common and at least on so wouldn't work (don't think the framework
> > handles this concept yet either), while this is handled fine for
> > evdev. I see similar challenges on other platforms we may potentially
> > deal with. Desktop Linux is probably the easiest, though libraries
> > like SDL2 and others need to gain support at some point.
> >
> > I definitely see IIO as an interesting platform, but across platforms
> > the user space side is really not there even on a popular platform
> > like Android. As a company we may end up using this driver on on
> > various consumer devices (and older kernels), so I'm not a fan of IIO
> > for framework / legacy related reasons. We would like to maintain a
> > single code base, which is among the reasons we contribute to this
> > driver, wanting to avoid custom proprietary solutions, which don't
> > scale.
> >
> > I'm not sure what the best path forward is. Maybe we could consider
> > supporting both e.g. through a kernel configuration option. This could
> > be forward and backwards compatible.
> >
> > Thanks,
> >
> > --
> > Roderick Colenbrander
> > Senior Manager of Software Engineering
> > Gaikai Inc, a Sony Interactive Entertainment Company
> 
> Hi Jiri and others,
> 
> Any suggestions on how to move forward?

Hi Roderick,

>From a personal perspective I must confess I dislike IIO too. I don't
like the way it was introduced and took over the existing subsystems to
replace existing sensors. It's clear there was caveats with the input
subsystem, but I was not so pleased with the fact that they wrote an
entirely new sysfs just for that. Not to mention that I don't think the
sysfs approach is the best way to handle input data.
On the other hand, IIO allows to set hysteresis and filters on the input
data, so this makes interesting for global system events and power
consumption.

In your case, I think using IIO is just non sense. The accelerometers
found on the DS4 are meant to be used as a stream of data, which is not
what IIO was made for. Plus, if you start exporting accelerometers as
IIO, how will the DE differentiate between the DS4 accelerometer and the
integrated one.

Anyway, that's just my personal opinion that might not matters much if
Dmitry and Jiri want to get rid of accelerometers from the input
subsystem. But I'd say your case should be still considered as an input
node, not as an IIO sensor.

Cheers,
Benjamin



^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH 4/8] HID: sony: Report DS4 motion sensors through a separate device
  2016-12-05  9:44             ` Benjamin Tissoires
@ 2017-01-13 20:25               ` Roderick Colenbrander
  2017-01-27 13:50               ` Jiri Kosina
  1 sibling, 0 replies; 21+ messages in thread
From: Roderick Colenbrander @ 2017-01-13 20:25 UTC (permalink / raw)
  To: Jiri Kosina, Dmitry Torokhov
  Cc: Simon Wood, Benjamin Tissoires, linux-input, Frank Praznik,
	Tim Bird, Roderick Colenbrander

Hi Dmitry and Jiri,

I would like to revive this thread since the holidays are over and
4.10 is well on its way now. Last week Jiri asked in another thread
about this patch series and was wondering about what the status from
the list was. There has been some discussion back and forth in this
thread, but your guidance is needed to see what the best path forward
is for the input framework. There will certainly more devices like the
Dualshock 4 needing this capability, just from press the newly
announced Nintendo Switch controllers would need it as well.

Thanks,
Roderick

On Mon, Dec 5, 2016 at 1:44 AM, Benjamin Tissoires
<benjamin.tissoires@redhat.com> wrote:
> On Dec 02 2016 or thereabouts, Roderick Colenbrander wrote:
>> On Mon, Nov 28, 2016 at 10:32 PM, Roderick Colenbrander
>> <roderick@gaikai.com> wrote:
>> > On Mon, Nov 28, 2016 at 5:53 AM, Jiri Kosina <jikos@kernel.org> wrote:
>> >> On Wed, 23 Nov 2016, Roderick Colenbrander wrote:
>> >>
>> >>> > We probably all agree that sending Acc/Gyro data across the joystick
>> >>> > interface is not the best thing in the world, so I would have some doubts
>> >>> > about whether spinning up another separate interface is quite the 'correct
>> >>> > thing' either.
>> >>> >
>> >>> > A while back I did some 'tinkering' on the SixAxis to see if 'we' could
>> >>> > use the IIO interface to report accelerometer data.
>> >>> > https://patchwork.kernel.org/patch/6589061/
>> >>
>> >> Roderick,
>> >>
>> >> would you have any input on this aspect? I haven't really been actively
>> >> involved in the discussion last year, but my gut feeling is that IIO would
>> >> be the best suited interface for this.
>> >>
>> >> Thanks,
>> >>
>> >> --
>> >> Jiri Kosina
>> >> SUSE Labs
>> >>
>> >
>> > Hi Jiri,
>> >
>> > Thanks for your response as well. From a technical side IIO is
>> > promising and we experimented with it a bit as well. From a more
>> > practical and business side I'm not the biggest fan. Let me explain a
>> > bit and work out something which would ideally work for everyone
>> > involved.
>> >
>> > On the technical side, IIO was made for expressing many kinds of
>> > sensors and our gamepads could be supported as well. The integration
>> > with the HID side would be a bit tricky as the input report is shared
>> > with general input data, so buffering, locks etcetera are needed, but
>> > this is an implementation detail.
>> >
>> > The main concern for us is software support in consumer platforms,
>> > which we often deal with. These open or closed platforms have good
>> > infrastructure for the Linux input frameworks, adding some other
>> > system while of course technically feasible is just not possible in
>> > practice. There is a strong preference there for standard evdev.
>> > Some platforms use IIO behind the scenes for sensors e.g. Android.
>> > Taking Android as example, it seems to access most sensors through a
>> > vendor specific HAL implementation, which can bubble up
>> > accelerometers, gyroscopes and many other kind of sensors. We looked
>> > over public code for some of these devices and the sensor list
>> > reported through this HAL seems to be static just based on what is
>> > built-in into a particular device. For a gamepad hot-plugging is
>> > common and at least on so wouldn't work (don't think the framework
>> > handles this concept yet either), while this is handled fine for
>> > evdev. I see similar challenges on other platforms we may potentially
>> > deal with. Desktop Linux is probably the easiest, though libraries
>> > like SDL2 and others need to gain support at some point.
>> >
>> > I definitely see IIO as an interesting platform, but across platforms
>> > the user space side is really not there even on a popular platform
>> > like Android. As a company we may end up using this driver on on
>> > various consumer devices (and older kernels), so I'm not a fan of IIO
>> > for framework / legacy related reasons. We would like to maintain a
>> > single code base, which is among the reasons we contribute to this
>> > driver, wanting to avoid custom proprietary solutions, which don't
>> > scale.
>> >
>> > I'm not sure what the best path forward is. Maybe we could consider
>> > supporting both e.g. through a kernel configuration option. This could
>> > be forward and backwards compatible.
>> >
>> > Thanks,
>> >
>> > --
>> > Roderick Colenbrander
>> > Senior Manager of Software Engineering
>> > Gaikai Inc, a Sony Interactive Entertainment Company
>>
>> Hi Jiri and others,
>>
>> Any suggestions on how to move forward?
>
> Hi Roderick,
>
> From a personal perspective I must confess I dislike IIO too. I don't
> like the way it was introduced and took over the existing subsystems to
> replace existing sensors. It's clear there was caveats with the input
> subsystem, but I was not so pleased with the fact that they wrote an
> entirely new sysfs just for that. Not to mention that I don't think the
> sysfs approach is the best way to handle input data.
> On the other hand, IIO allows to set hysteresis and filters on the input
> data, so this makes interesting for global system events and power
> consumption.
>
> In your case, I think using IIO is just non sense. The accelerometers
> found on the DS4 are meant to be used as a stream of data, which is not
> what IIO was made for. Plus, if you start exporting accelerometers as
> IIO, how will the DE differentiate between the DS4 accelerometer and the
> integrated one.
>
> Anyway, that's just my personal opinion that might not matters much if
> Dmitry and Jiri want to get rid of accelerometers from the input
> subsystem. But I'd say your case should be still considered as an input
> node, not as an IIO sensor.
>
> Cheers,
> Benjamin
>
>



-- 
Roderick Colenbrander
Senior Manager of Software Engineering
Gaikai, a Sony Interactive Entertainment Company
roderick@gaikai.com

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH 4/8] HID: sony: Report DS4 motion sensors through a separate device
  2016-12-05  9:44             ` Benjamin Tissoires
  2017-01-13 20:25               ` Roderick Colenbrander
@ 2017-01-27 13:50               ` Jiri Kosina
       [not found]                 ` <CANndSK=d=D0i2pJJqjpiSWJ9MJVKZOzF8LYF2kPU3sdmcR2Kng@mail.gmail.com>
  1 sibling, 1 reply; 21+ messages in thread
From: Jiri Kosina @ 2017-01-27 13:50 UTC (permalink / raw)
  To: Benjamin Tissoires
  Cc: Roderick Colenbrander, Simon Wood, linux-input, Dmitry Torokhov,
	Frank Praznik, Tim Bird, Roderick Colenbrander

On Mon, 5 Dec 2016, Benjamin Tissoires wrote:

> In your case, I think using IIO is just non sense. The accelerometers 
> found on the DS4 are meant to be used as a stream of data, which is not 
> what IIO was made for. Plus, if you start exporting accelerometers as 
> IIO, how will the DE differentiate between the DS4 accelerometer and the 
> integrated one.

Fair enough, after re-reading the whole thing, I agree that IIO is not the 
best aproach here. So let's just proceed as originally planned.

Thanks,

-- 
Jiri Kosina
SUSE Labs


^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH 4/8] HID: sony: Report DS4 motion sensors through a separate device
       [not found]                 ` <CANndSK=d=D0i2pJJqjpiSWJ9MJVKZOzF8LYF2kPU3sdmcR2Kng@mail.gmail.com>
@ 2017-01-28  3:19                   ` Roderick Colenbrander
  0 siblings, 0 replies; 21+ messages in thread
From: Roderick Colenbrander @ 2017-01-28  3:19 UTC (permalink / raw)
  To: Jiri Kosina
  Cc: Benjamin Tissoires, Simon Wood, linux-input, Dmitry Torokhov,
	Frank Praznik, Tim Bird, Roderick Colenbrander

On Fri, Jan 27, 2017 at 6:25 PM, Roderick Colenbrander
<roderick@gaikai.com> wrote:
> On Fri, Jan 27, 2017 at 5:50 AM, Jiri Kosina <jikos@kernel.org> wrote:
>>
>> On Mon, 5 Dec 2016, Benjamin Tissoires wrote:
>>
>> > In your case, I think using IIO is just non sense. The accelerometers
>> > found on the DS4 are meant to be used as a stream of data, which is not
>> > what IIO was made for. Plus, if you start exporting accelerometers as
>> > IIO, how will the DE differentiate between the DS4 accelerometer and the
>> > integrated one.
>>
>> Fair enough, after re-reading the whole thing, I agree that IIO is not the
>> best aproach here. So let's just proceed as originally planned.
>>
>> Thanks,
>>
>> --
>> Jiri Kosina
>> SUSE Labs
>>
>
> That's great news :) Do you want me to resend the patches? The series from
> December should still apply though. We may add another 1 or 2 patches later,
> but they will build on top of the ones sent so far.

(resubmit in plain form)

That's great news :) Do you want me to resend the patches? The series from
December should still apply though. We may add another 1 or 2 patches
later, but they will build on top of the ones sent so far.

^ permalink raw reply	[flat|nested] 21+ messages in thread

end of thread, other threads:[~2017-01-28  3:28 UTC | newest]

Thread overview: 21+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-11-23 22:07 [PATCH 0/8] HID: sony: DS4 updates Roderick Colenbrander
2016-11-23 22:07 ` [PATCH 1/8] HID: sony: Fix memory issue when connecting device using both Bluetooth and USB Roderick Colenbrander
2016-11-23 22:07 ` [PATCH 2/8] HID: sony: Make the DS4 touchpad a separate device Roderick Colenbrander
2016-11-23 22:07 ` [PATCH 3/8] HID: sony: Comply to Linux gamepad spec for DS4 Roderick Colenbrander
2016-11-23 22:07 ` [PATCH 4/8] HID: sony: Report DS4 motion sensors through a separate device Roderick Colenbrander
2016-11-23 23:17   ` Simon Wood
2016-11-24  4:44     ` Roderick Colenbrander
2016-11-28 13:53       ` Jiri Kosina
2016-11-29  6:32         ` Roderick Colenbrander
2016-12-02 22:11           ` Roderick Colenbrander
2016-12-05  9:44             ` Benjamin Tissoires
2017-01-13 20:25               ` Roderick Colenbrander
2017-01-27 13:50               ` Jiri Kosina
     [not found]                 ` <CANndSK=d=D0i2pJJqjpiSWJ9MJVKZOzF8LYF2kPU3sdmcR2Kng@mail.gmail.com>
2017-01-28  3:19                   ` Roderick Colenbrander
2016-11-23 22:07 ` [PATCH 5/8] HID: sony: Use DS4 MAC address as unique identifier on USB Roderick Colenbrander
2016-11-23 22:07 ` [PATCH 6/8] HID: sony: Support DS4 dongle Roderick Colenbrander
2016-11-23 22:07 ` [PATCH 7/8] HID: sony: Calibrate DS4 motion sensors Roderick Colenbrander
2016-11-23 22:07 ` [PATCH 8/8] HID: sony: Report hardware timestamp for DS4 sensor values Roderick Colenbrander
2016-11-28 13:56 ` [PATCH 0/8] HID: sony: DS4 updates Jiri Kosina
2016-11-29  2:36   ` Roderick Colenbrander
2016-11-29 13:33     ` Jiri Kosina

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.