linux-input.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v2 1/2] HID: sony: Add battery status reporting for the Sixaxis and Dualshock 4 controllers.
@ 2014-01-27 15:17 Frank Praznik
  2014-01-27 15:17 ` [PATCH v2 2/2] HID: sony: Add output events for the multi-touch pad on the Dualshock 4 Frank Praznik
  2014-01-28 19:39 ` [PATCH v2 1/2] HID: sony: Add battery status reporting for the Sixaxis and Dualshock 4 controllers Jiri Kosina
  0 siblings, 2 replies; 7+ messages in thread
From: Frank Praznik @ 2014-01-27 15:17 UTC (permalink / raw)
  To: linux-input; +Cc: jkosina, Frank Praznik

Add battery status reporting for the Sixaxis and Dualshock 4 controllers.

Signed-off-by: Frank Praznik <frank.praznik@oh.rr.com>
---

 v2 of the patch fixes a small logic error where the battery_charging flag was
 flipped on the Sixaxis.
 
 The line:  battery_charging = rd[30] & 0x01;
 should be: battery_charging = !(rd[30] & 0x01);
 
 since the low bit is 0 when charging and 1 when charging is complete.

 drivers/hid/hid-sony.c | 186 ++++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 185 insertions(+), 1 deletion(-)

diff --git a/drivers/hid/hid-sony.c b/drivers/hid/hid-sony.c
index 1235405..04fd611 100644
--- a/drivers/hid/hid-sony.c
+++ b/drivers/hid/hid-sony.c
@@ -30,6 +30,8 @@
 #include <linux/slab.h>
 #include <linux/usb.h>
 #include <linux/leds.h>
+#include <linux/power_supply.h>
+#include <linux/spinlock.h>
 
 #include "hid-ids.h"
 
@@ -42,6 +44,7 @@
 #define DUALSHOCK4_CONTROLLER_BT  BIT(6)
 
 #define SONY_LED_SUPPORT (SIXAXIS_CONTROLLER_USB | BUZZ_CONTROLLER | DUALSHOCK4_CONTROLLER_USB)
+#define SONY_BATTERY_SUPPORT (SIXAXIS_CONTROLLER_USB | SIXAXIS_CONTROLLER_BT | DUALSHOCK4_CONTROLLER_USB)
 
 #define MAX_LEDS 4
 
@@ -487,18 +490,30 @@ static const unsigned int buzz_keymap[] = {
 	[20] = BTN_TRIGGER_HAPPY20,
 };
 
+static enum power_supply_property sony_battery_props[] = {
+	POWER_SUPPLY_PROP_PRESENT,
+	POWER_SUPPLY_PROP_CAPACITY,
+	POWER_SUPPLY_PROP_SCOPE,
+	POWER_SUPPLY_PROP_STATUS,
+};
+
 struct sony_sc {
+	spinlock_t lock;
 	struct hid_device *hdev;
 	struct led_classdev *leds[MAX_LEDS];
 	struct hid_report *output_report;
 	unsigned long quirks;
 	struct work_struct state_worker;
+	struct power_supply battery;
 
 #ifdef CONFIG_SONY_FF
 	__u8 left;
 	__u8 right;
 #endif
 
+	__u8 cable_state;
+	__u8 battery_charging;
+	__u8 battery_capacity;
 	__u8 led_state[MAX_LEDS];
 	__u8 led_count;
 };
@@ -599,6 +614,63 @@ static __u8 *sony_report_fixup(struct hid_device *hdev, __u8 *rdesc,
 	return rdesc;
 }
 
+static void sixaxis_parse_report(struct sony_sc *sc, __u8 *rd, int size)
+{
+	static const __u8 sixaxis_battery_capacity[] = { 0, 1, 25, 50, 75, 100 };
+	unsigned long flags;
+	__u8 cable_state, battery_capacity, battery_charging;
+
+	/* The sixaxis is charging if the battery value is 0xee
+	 * and it is fully charged if the value is 0xef.
+	 * It does not report the actual level while charging so it
+	 * is set to 100% while charging is in progress.
+	 */
+	if (rd[30] >= 0xee) {
+		battery_capacity = 100;
+		battery_charging = rd[30] & 0x01;
+	} else {
+		battery_capacity = sixaxis_battery_capacity[rd[30]];
+		battery_charging = 0;
+	}
+	cable_state = (rd[31] >> 4) & 0x01;
+
+	spin_lock_irqsave(&sc->lock, flags);
+	sc->cable_state = cable_state;
+	sc->battery_capacity = battery_capacity;
+	sc->battery_charging = battery_charging;
+	spin_unlock_irqrestore(&sc->lock, flags);
+}
+
+static void dualshock4_parse_report(struct sony_sc *sc, __u8 *rd, int size)
+{
+	unsigned long flags;
+	__u8 cable_state, battery_capacity, battery_charging;
+
+	/* The lower 4 bits of byte 30 contain the battery level
+	 * and the 5th bit contains the USB cable state.
+	 */
+	cable_state = (rd[30] >> 4) & 0x01;
+	battery_capacity = rd[30] & 0x0F;
+
+	/* On USB the Dualshock 4 battery level goes from 0 to 11.
+	 * A battery level of 11 means fully charged.
+	 */
+	if (cable_state && battery_capacity == 11)
+		battery_charging = 0;
+	else
+		battery_charging = 1;
+
+	if (battery_capacity > 10)
+		battery_capacity--;
+	battery_capacity *= 10;
+
+	spin_lock_irqsave(&sc->lock, flags);
+	sc->cable_state = cable_state;
+	sc->battery_capacity = battery_capacity;
+	sc->battery_charging = battery_charging;
+	spin_unlock_irqrestore(&sc->lock, flags);
+}
+
 static int sony_raw_event(struct hid_device *hdev, struct hid_report *report,
 		__u8 *rd, int size)
 {
@@ -613,6 +685,11 @@ static int sony_raw_event(struct hid_device *hdev, struct hid_report *report,
 		swap(rd[43], rd[44]);
 		swap(rd[45], rd[46]);
 		swap(rd[47], rd[48]);
+
+		sixaxis_parse_report(sc, rd, size);
+	} else if ((sc->quirks & DUALSHOCK4_CONTROLLER_USB) && rd[0] == 0x01 &&
+			size == 64) {
+		dualshock4_parse_report(sc, rd, size);
 	}
 
 	return 0;
@@ -1011,6 +1088,91 @@ static void sony_destroy_ff(struct hid_device *hdev)
 }
 #endif
 
+static int sony_battery_get_property(struct power_supply *psy,
+				     enum power_supply_property psp,
+				     union power_supply_propval *val)
+{
+	struct sony_sc *sc = container_of(psy, struct sony_sc, battery);
+	unsigned long flags;
+	int ret = 0;
+	u8 battery_charging, battery_capacity, cable_state;
+
+	spin_lock_irqsave(&sc->lock, flags);
+	battery_charging = sc->battery_charging;
+	battery_capacity = sc->battery_capacity;
+	cable_state = sc->cable_state;
+	spin_unlock_irqrestore(&sc->lock, flags);
+
+	switch (psp) {
+	case POWER_SUPPLY_PROP_PRESENT:
+		val->intval = 1;
+		break;
+	case POWER_SUPPLY_PROP_SCOPE:
+		val->intval = POWER_SUPPLY_SCOPE_DEVICE;
+		break;
+	case POWER_SUPPLY_PROP_CAPACITY:
+		val->intval = battery_capacity;
+		break;
+	case POWER_SUPPLY_PROP_STATUS:
+		if (battery_charging)
+			val->intval = POWER_SUPPLY_STATUS_CHARGING;
+		else
+			if (battery_capacity == 100 && cable_state)
+				val->intval = POWER_SUPPLY_STATUS_FULL;
+			else
+				val->intval = POWER_SUPPLY_STATUS_DISCHARGING;
+		break;
+	default:
+		ret = -EINVAL;
+		break;
+	}
+	return ret;
+}
+
+static int sony_battery_probe(struct sony_sc *sc)
+{
+	static atomic_t power_id_seq = ATOMIC_INIT(0);
+	unsigned long power_id;
+	struct hid_device *hdev = sc->hdev;
+	int ret;
+
+	power_id = (unsigned long)atomic_inc_return(&power_id_seq);
+
+	sc->battery.properties = sony_battery_props;
+	sc->battery.num_properties = ARRAY_SIZE(sony_battery_props);
+	sc->battery.get_property = sony_battery_get_property;
+	sc->battery.type = POWER_SUPPLY_TYPE_BATTERY;
+	sc->battery.use_for_apm = 0;
+	sc->battery.name = kasprintf(GFP_KERNEL, "sony_controller_battery_%lu",
+				     power_id);
+	if (!sc->battery.name)
+		return -ENOMEM;
+
+	ret = power_supply_register(&hdev->dev, &sc->battery);
+	if (ret) {
+		hid_err(hdev, "Unable to register battery device\n");
+		goto err_free;
+	}
+
+	power_supply_powers(&sc->battery, &hdev->dev);
+	return 0;
+
+err_free:
+	kfree(sc->battery.name);
+	sc->battery.name = NULL;
+	return ret;
+}
+
+static void sony_battery_remove(struct sony_sc *sc)
+{
+	if (!sc->battery.name)
+		return;
+
+	power_supply_unregister(&sc->battery);
+	kfree(sc->battery.name);
+	sc->battery.name = NULL;
+}
+
 static int sony_set_output_report(struct sony_sc *sc, int req_id, int req_size)
 {
 	struct list_head *head, *list;
@@ -1101,14 +1263,31 @@ static int sony_probe(struct hid_device *hdev, const struct hid_device_id *id)
 			goto err_stop;
 	}
 
+	if (sc->quirks & SONY_BATTERY_SUPPORT) {
+		ret = sony_battery_probe(sc);
+		if (ret < 0)
+			goto err_stop;
+
+		/* Open the device to receive reports with battery info */
+		ret = hid_hw_open(hdev);
+		if (ret < 0) {
+			hid_err(hdev, "hw open failed\n");
+			goto err_stop;
+		}
+	}
+
 	ret = sony_init_ff(hdev);
 	if (ret < 0)
-		goto err_stop;
+		goto err_close;
 
 	return 0;
+err_close:
+	hid_hw_close(hdev);
 err_stop:
 	if (sc->quirks & SONY_LED_SUPPORT)
 		sony_leds_remove(hdev);
+	if (sc->quirks & SONY_BATTERY_SUPPORT)
+		sony_battery_remove(sc);
 	hid_hw_stop(hdev);
 	return ret;
 }
@@ -1120,6 +1299,11 @@ static void sony_remove(struct hid_device *hdev)
 	if (sc->quirks & SONY_LED_SUPPORT)
 		sony_leds_remove(hdev);
 
+	if (sc->quirks & SONY_BATTERY_SUPPORT) {
+		hid_hw_close(hdev);
+		sony_battery_remove(sc);
+	}
+
 	sony_destroy_ff(hdev);
 
 	hid_hw_stop(hdev);
-- 
1.8.3.2


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

* [PATCH v2 2/2] HID: sony: Add output events for the multi-touch pad on the Dualshock 4.
  2014-01-27 15:17 [PATCH v2 1/2] HID: sony: Add battery status reporting for the Sixaxis and Dualshock 4 controllers Frank Praznik
@ 2014-01-27 15:17 ` Frank Praznik
  2014-01-27 17:47   ` simon
  2014-01-27 20:40   ` simon
  2014-01-28 19:39 ` [PATCH v2 1/2] HID: sony: Add battery status reporting for the Sixaxis and Dualshock 4 controllers Jiri Kosina
  1 sibling, 2 replies; 7+ messages in thread
From: Frank Praznik @ 2014-01-27 15:17 UTC (permalink / raw)
  To: linux-input; +Cc: jkosina, Frank Praznik

Add output events for the multi-touch pad on the Dualshock 4.

The touchpad has a resolution of 1920x940 and is capable of 2 simultaneous
touches. A 'Type B' stateful slot protocol is implemented as defined in
Documentation/input/multi-touch-protocol.txt

Applications can use the touchpad data by processing the ABS_MT_SLOT,
ABS_MT_TRACKING_ID, ABS_MT_POSITION_X and ABS_MT_POSITION_Y events.

Signed-off-by: Frank Praznik <frank.praznik@oh.rr.com>
---
 drivers/hid/hid-sony.c | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 54 insertions(+)

diff --git a/drivers/hid/hid-sony.c b/drivers/hid/hid-sony.c
index 04fd611..2bd3f13 100644
--- a/drivers/hid/hid-sony.c
+++ b/drivers/hid/hid-sony.c
@@ -32,6 +32,7 @@
 #include <linux/leds.h>
 #include <linux/power_supply.h>
 #include <linux/spinlock.h>
+#include <linux/input/mt.h>
 
 #include "hid-ids.h"
 
@@ -643,7 +644,11 @@ 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, offset = 35;
 	__u8 cable_state, battery_capacity, battery_charging;
 
 	/* The lower 4 bits of byte 30 contain the battery level
@@ -669,6 +674,28 @@ static void dualshock4_parse_report(struct sony_sc *sc, __u8 *rd, int size)
 	sc->battery_capacity = battery_capacity;
 	sc->battery_charging = battery_charging;
 	spin_unlock_irqrestore(&sc->lock, flags);
+
+	/* The Dualshock 4 multi-touch trackpad data starts at offset 35 on USB.
+	 * The first 7 bits of the first byte is a counter and bit 8 is a touch
+	 * indicator that is 0 when pressed and 1 when not pressed.
+	 * The next 3 bytes are two 12 bit touch coordinates, X and Y.
+	 * The data for the second touch is in the same format and immediatly
+	 * follows the data for the first.
+	 */
+	for (n = 0; n < 2; n++) {
+		__u16 x, y;
+
+		x = rd[offset+1] | ((rd[offset+2] & 0xF) << 8);
+		y = ((rd[offset+2] & 0xF0) >> 4) | (rd[offset+3] << 4);
+
+		input_mt_slot(input_dev, n);
+		input_mt_report_slot_state(input_dev, MT_TOOL_FINGER,
+					!(rd[offset] >> 7));
+		input_report_abs(input_dev, ABS_MT_POSITION_X, x);
+		input_report_abs(input_dev, ABS_MT_POSITION_Y, y);
+
+		offset += 4;
+	}
 }
 
 static int sony_raw_event(struct hid_device *hdev, struct hid_report *report,
@@ -1200,6 +1227,26 @@ static int sony_set_output_report(struct sony_sc *sc, int req_id, int req_size)
 	return -EINVAL;
 }
 
+static int sony_register_touchpad(struct sony_sc *sc, int touch_count,
+					int w, int h)
+{
+	struct hid_input *hidinput = list_entry(sc->hdev->inputs.next,
+						struct hid_input, list);
+	struct input_dev *input_dev = hidinput->input;
+	int ret;
+
+	ret = input_mt_init_slots(input_dev, touch_count, 0);
+	if (ret < 0) {
+		hid_err(sc->hdev, "Unable to initialize multi-touch slots\n");
+		return ret;
+	}
+
+	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);
+
+	return 0;
+}
+
 static int sony_probe(struct hid_device *hdev, const struct hid_device_id *id)
 {
 	int ret;
@@ -1249,6 +1296,13 @@ static int sony_probe(struct hid_device *hdev, const struct hid_device_id *id)
 		if (ret < 0)
 			goto err_stop;
 
+		/* The Dualshock 4 touchpad supports 2 touches and has a
+		 * resolution of 1920x940.
+		 */
+		ret = sony_register_touchpad(sc, 2, 1920, 940);
+		if (ret < 0)
+			goto err_stop;
+
 		INIT_WORK(&sc->state_worker, dualshock4_state_worker);
 	} else {
 		ret = 0;
-- 
1.8.3.2


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

* Re: [PATCH v2 2/2] HID: sony: Add output events for the multi-touch pad on the Dualshock 4.
  2014-01-27 15:17 ` [PATCH v2 2/2] HID: sony: Add output events for the multi-touch pad on the Dualshock 4 Frank Praznik
@ 2014-01-27 17:47   ` simon
  2014-01-27 21:28     ` Frank Praznik
  2014-01-27 20:40   ` simon
  1 sibling, 1 reply; 7+ messages in thread
From: simon @ 2014-01-27 17:47 UTC (permalink / raw)
  Cc: linux-input, jkosina, Frank Praznik


> +
> +	/* The Dualshock 4 multi-touch trackpad data starts at offset 35 on USB.
> +	 * The first 7 bits of the first byte is a counter and bit 8 is a touch
> +	 * indicator that is 0 when pressed and 1 when not pressed.
> +	 * The next 3 bytes are two 12 bit touch coordinates, X and Y.
> +	 * The data for the second touch is in the same format and immediatly
> +	 * follows the data for the first.
> +	 */

Hi Frank,
I don't know if it helps multitouch, but there is a second set of data in
the HID stream, that is present when a figure is moving/swiping on the
touchpad. This gives us a 'vector' rather than a 'point'.

I previously attempted to describe the format here:
http://www.spinics.net/lists/linux-input/msg28525.html

Ahead of the 'event counter' is a 'point or vector' byte and what might be
a 'pressure' measurement (couldn't really tell).

Interspersed with the data you mention is a second set of X1/Y1/X2/Y2 
containing the starting position of the swipe/vector. These are
differentiated with '02' (rather than '01') in the 34'th byte.

1 finger swipe left to right
--
# cat /dev/hidraw0 | hexdump -v -e '64/1 "%02x " "\n"' | cut -d ' ' -f
34-52 | grep -e '^02'
02 01 34 93 90 1d 9e bd e0 23 06 34 94 90 1d 9e bd e0 23
02 1f 34 a5 90 1d 9e bd e0 23 22 34 aa 90 1d 9e bd e0 23
02 3c 34 c3 90 1d 9e bd e0 23 41 34 ca 90 1d 9e bd e0 23
02 7c 34 37 c1 1c 9e bd e0 23 81 34 47 c1 1c 9e bd e0 23
02 bd 34 23 e2 1b 9e bd e0 23 c2 34 3a e2 1b 9e bd e0 23
02 d4 34 8e 82 1b 9e bd e0 23 d9 34 ad 72 1b 9e bd e0 23
02 f8 34 3d 23 1b 9e bd e0 23 fb 34 55 13 1b 9e bd e0 23
02 14 34 a5 e3 1a 9e bd e0 23 1a 34 b6 d3 1a 9e bd e0 23
02 2e 34 f3 b3 1a 9e bd e0 23 31 34 01 a4 1a 9e bd e0 23
02 55 34 40 a4 1a 9e bd e0 23 5a 34 47 a4 1a 9e bd e0 23
02 95 34 71 a4 1a 9e bd e0 23 9a 34 73 a4 1a 9e bd e0 23
02 ad 34 78 a4 1a 9e bd e0 23 b2 34 7a a4 1a 9e bd e0 23
      [ data you use....... ]    [ start of swipe....  ]
--

2 finger swipe top to bottom
--
# cat /dev/hidraw0 | hexdump -v -e '64/1 "%02x " "\n"' | cut -d ' ' -f
34-52 | grep -e '^02'
02 26 37 4a b6 04 9e bd e0 23 2b 37 4a c6 04 9e bd e0 23
02 5b 37 43 96 05 38 64 80 0b 60 37 43 d6 05 38 64 80 0b
02 84 37 3f 56 08 38 6c b0 0c 89 37 3f e6 08 38 6e 00 0d
02 a7 37 38 86 0d 38 80 c0 0f ad 37 37 b6 0e 38 85 80 10
02 d0 37 32 b6 16 38 bc d0 16 d5 37 32 a6 17 38 c5 c0 17
02 f4 37 32 16 1b 38 e7 00 1b f9 37 32 86 1b 38 eb 50 1b
02 17 37 32 f6 1c 38 f5 70 1c 1c 37 32 26 1d 38 f6 90 1c
02 40 37 32 36 1e 38 fd 40 1d 44 37 32 56 1e 38 fd 50 1d
02 63 37 32 c6 1e 38 00 91 1d 68 37 32 e6 1e 38 00 a1 1d
02 86 37 32 46 1f 38 03 d1 1d 8b 37 32 56 1f 38 03 e1 1d
02 af 37 32 b6 1f 38 06 11 1e b3 37 32 c6 1f 38 06 11 1e
02 3b 37 32 96 20 38 0b 81 1e 41 37 32 96 20 38 0b 91 1e
02 82 37 32 e6 20 38 0c c1 1e 87 37 32 e6 20 38 0c c1 1e
02 a5 37 32 16 21 38 0c 01 1f aa 37 32 26 21 38 0c 01 1f
--

Also note that there are seperate event counters for 1st and 2nd fingers,
which mean that the 2nd finger can remain pressed whilst the 1st is
pressed/released.
--
# cat /dev/hidraw0 | hexdump -v -e '64/1 "%02x " "\n"' | cut -d ' ' -f
34-52 | grep -e '^02'
02 a6>42<16 b1 19 c1 58 21 15 ab 42 16 b1 19 c1 58 21 15 <- 1st press
02 15 42 26 b1 19 c1 58 21 15 1b 42 27 b1 19 c1 58 21 15
02 50 42 2d b1 19 c1 58 21 15 55 42 2e b1 19 c1 58 21 15
02 b6 42 41 b1 19 c3 e2 c6 12 bb 42 41 b1 19 44 b5 96 14
02 01 42 43 b1 19>44<a4 96 14 06 42 43 b1 19 44 a3 96 14 <- 2nd press
02 1f 42 43 b1 19 44 9d 96 14 24 42 43 b1 19 44 9c 96 14
02 6b 42 44 b1 19 44 8e 96 14 70 42 45 b1 19 44 8d 96 14
02 cf 42 46 b1 19 44 81 c6 13 d4 42 46 b1 19 44 80 c6 13
02 38 42 47 b1 19 44 78 a6 13 3d 42 47 b1 19 44 77 a6 13
02 3a 42 48 b1 19 44 6b 56 13 3f 42 48 b1 19 44 6b 56 13
02 f5 42 48 d1 1a 44 67 f6 12 fa 42 48 11 1b 44 67 e6 12
02 18 42 49 d1 1c 44 67 d6 12 1d 42 4a 41 1d 44 67 d6 12
02 47 42 53 81 21 44 66 c6 12 4c 42 54 41 22 44 66 c6 12
02 70 42 5d 01 28 44 66 b6 12 75 42 5f e1 28 44 66 b6 12
02 99 42 65 e1 2d 44 66 a6 12 9e 42 66 91 2e 44 66 a6 12
02 bd 42 68 61 31 44 65 96 12 c2 42 68 d1 31 44 65 96 12
02 0e>c2<6d d1 34 44 64 86 12 13 c2 6d d1 34 44 64 86 12 <- 1st release
02 26 c2 6d d1 34 44 64 86 12 2b c2 6d d1 34 44 64 86 12
02 68 c2 6d d1 34 44 62 76 12 6d c2 6d d1 34 44 62 76 12
02 07>45<52 71 08 44 62 76 12 0c 45 52 d1 08 44 62 76 12 <- 1st press
02 30 45 56 41 0c 44 62 76 12 34 45 57 d1 0c 44 62 76 12
02 58 45 5a 51 10 44 62 76 12 5d 45 5a d1 10 44 62 76 12
02 7b 45 5c f1 12 44 62 76 12 80 45 5d 51 13 44 62 76 12
02 ce 45 64 71 1a 44 62 76 12 d3 45 65 01 1b 44 62 76 12
02 f1 45 67 91 1d 44 62 66 12 f6 45 68 21 1e 44 62 66 12
02 3d 45 6f e1 22 44 62 66 12 42 45 6f 01 23 44 62 66 12
02 60 45 70 b1 23 44 62 66 12 65 45 70 c1 23 44 62 66 12
02 3a>c5<73 41 25 44 7a 56 12 3d c5 73 41 25 44 7d b6 12 <- 1st release
02 57 c5 73 41 25 44 87 f6 12 5c c5 73 41 25 44 8a 06 13
--

Simon.



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

* Re: [PATCH v2 2/2] HID: sony: Add output events for the multi-touch pad on the Dualshock 4.
  2014-01-27 15:17 ` [PATCH v2 2/2] HID: sony: Add output events for the multi-touch pad on the Dualshock 4 Frank Praznik
  2014-01-27 17:47   ` simon
@ 2014-01-27 20:40   ` simon
  2014-01-27 21:02     ` Frank Praznik
  1 sibling, 1 reply; 7+ messages in thread
From: simon @ 2014-01-27 20:40 UTC (permalink / raw)
  Cc: linux-input, jkosina, Frank Praznik


> +	for (n = 0; n < 2; n++) {
> +		__u16 x, y;
> +
> +		x = rd[offset+1] | ((rd[offset+2] & 0xF) << 8);
> +		y = ((rd[offset+2] & 0xF0) >> 4) | (rd[offset+3] << 4);
> +
> +		input_mt_slot(input_dev, n);
> +		input_mt_report_slot_state(input_dev, MT_TOOL_FINGER,
> +					!(rd[offset] >> 7));
> +		input_report_abs(input_dev, ABS_MT_POSITION_X, x);
> +		input_report_abs(input_dev, ABS_MT_POSITION_Y, y);
> +
> +		offset += 4;
> +	}

Sorry I have another point/question....

Doesn't this 'spam' the Multitouch interface every incoming report,
regardless on whether anything has actually change? ie. Should HID-Sony
track the values, and only send when it detects a change...

Simon


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

* Re: [PATCH v2 2/2] HID: sony: Add output events for the multi-touch pad on the Dualshock 4.
  2014-01-27 20:40   ` simon
@ 2014-01-27 21:02     ` Frank Praznik
  0 siblings, 0 replies; 7+ messages in thread
From: Frank Praznik @ 2014-01-27 21:02 UTC (permalink / raw)
  To: simon, Frank Praznik; +Cc: linux-input, jkosina

On 1/27/2014 15:40, simon@mungewell.org wrote:
>> +	for (n = 0; n < 2; n++) {
>> +		__u16 x, y;
>> +
>> +		x = rd[offset+1] | ((rd[offset+2] & 0xF) << 8);
>> +		y = ((rd[offset+2] & 0xF0) >> 4) | (rd[offset+3] << 4);
>> +
>> +		input_mt_slot(input_dev, n);
>> +		input_mt_report_slot_state(input_dev, MT_TOOL_FINGER,
>> +					!(rd[offset] >> 7));
>> +		input_report_abs(input_dev, ABS_MT_POSITION_X, x);
>> +		input_report_abs(input_dev, ABS_MT_POSITION_Y, y);
>> +
>> +		offset += 4;
>> +	}
> Sorry I have another point/question....
>
> Doesn't this 'spam' the Multitouch interface every incoming report,
> regardless on whether anything has actually change? ie. Should HID-Sony
> track the values, and only send when it detects a change...
>
> Simon
>
No, the HID layer tracks the current state and only sends events when 
something changes so there is no need to shadow it again.  If you watch 
the output in evtest, events are only sent when something changes.  All 
this does is manually parse the touch data for the HID layer.

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

* Re: [PATCH v2 2/2] HID: sony: Add output events for the multi-touch pad on the Dualshock 4.
  2014-01-27 17:47   ` simon
@ 2014-01-27 21:28     ` Frank Praznik
  0 siblings, 0 replies; 7+ messages in thread
From: Frank Praznik @ 2014-01-27 21:28 UTC (permalink / raw)
  To: simon, Frank Praznik; +Cc: linux-input, jkosina

On 1/27/2014 12:47, simon@mungewell.org wrote:
>> +
>> +	/* The Dualshock 4 multi-touch trackpad data starts at offset 35 on USB.
>> +	 * The first 7 bits of the first byte is a counter and bit 8 is a touch
>> +	 * indicator that is 0 when pressed and 1 when not pressed.
>> +	 * The next 3 bytes are two 12 bit touch coordinates, X and Y.
>> +	 * The data for the second touch is in the same format and immediatly
>> +	 * follows the data for the first.
>> +	 */
> Hi Frank,
> I don't know if it helps multitouch, but there is a second set of data in
> the HID stream, that is present when a figure is moving/swiping on the
> touchpad. This gives us a 'vector' rather than a 'point'.
>
> I previously attempted to describe the format here:
> http://www.spinics.net/lists/linux-input/msg28525.html
>
> Ahead of the 'event counter' is a 'point or vector' byte and what might be
> a 'pressure' measurement (couldn't really tell).
>
> Interspersed with the data you mention is a second set of X1/Y1/X2/Y2
> containing the starting position of the swipe/vector. These are
> differentiated with '02' (rather than '01') in the 34'th byte.
>
> Simon.
>
All the device driver is concerned with is the sending the 'raw' touch 
points to the HID layer (ie. point 1/2 is up/down at position X and Y).  
The HID layer then tracks the IDs for each contact point and sends the 
appropriate events to the user application.  It's then up to the 
application software to track and interpret it.

See this document for information on the multi-touch protocol:
https://www.kernel.org/doc/Documentation/input/multi-touch-protocol.txt

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

* Re: [PATCH v2 1/2] HID: sony: Add battery status reporting for the Sixaxis and Dualshock 4 controllers.
  2014-01-27 15:17 [PATCH v2 1/2] HID: sony: Add battery status reporting for the Sixaxis and Dualshock 4 controllers Frank Praznik
  2014-01-27 15:17 ` [PATCH v2 2/2] HID: sony: Add output events for the multi-touch pad on the Dualshock 4 Frank Praznik
@ 2014-01-28 19:39 ` Jiri Kosina
  1 sibling, 0 replies; 7+ messages in thread
From: Jiri Kosina @ 2014-01-28 19:39 UTC (permalink / raw)
  To: Frank Praznik; +Cc: linux-input

On Mon, 27 Jan 2014, Frank Praznik wrote:

> Add battery status reporting for the Sixaxis and Dualshock 4 controllers.

I have applied both patches, thanks Frank.

-- 
Jiri Kosina
SUSE Labs

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

end of thread, other threads:[~2014-01-28 19:39 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-01-27 15:17 [PATCH v2 1/2] HID: sony: Add battery status reporting for the Sixaxis and Dualshock 4 controllers Frank Praznik
2014-01-27 15:17 ` [PATCH v2 2/2] HID: sony: Add output events for the multi-touch pad on the Dualshock 4 Frank Praznik
2014-01-27 17:47   ` simon
2014-01-27 21:28     ` Frank Praznik
2014-01-27 20:40   ` simon
2014-01-27 21:02     ` Frank Praznik
2014-01-28 19:39 ` [PATCH v2 1/2] HID: sony: Add battery status reporting for the Sixaxis and Dualshock 4 controllers Jiri Kosina

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).