All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/8] HID: wacom: Support second generation Intuos Pro
@ 2017-01-25 20:08 Aaron Armstrong Skomra
  2017-01-25 20:08 ` [PATCH 1/8] HID: wacom: Enable HID_GENERIC codepath for Bluetooth devices Aaron Armstrong Skomra
                   ` (9 more replies)
  0 siblings, 10 replies; 11+ messages in thread
From: Aaron Armstrong Skomra @ 2017-01-25 20:08 UTC (permalink / raw)
  To: linux-input, jkosina, benjamin.tissoires, pinglinux, killertofu
  Cc: Aaron Armstrong Skomra

Patches 1-3 add Bluetooth support for the 2nd-gen Intuos Pro. Its
Bluetooth report lacks a proper report descriptor so we must add
explicit support for the device here.

Patches 4-8 add USB support for this device via the Wacom driver's
generic code path.

Best,
Aaron

Aaron Armstrong Skomra (5):
  HID: wacom: generic: remove input_event_flag
  HID: wacom: generic: add support for touchring
  HID: wacom: generic: add vendor defined touch
  HID: wacom: generic: support generic touch switch
  HID: wacom: generic: support LEDs

Jason Gerecke (3):
  HID: wacom: Enable HID_GENERIC codepath for Bluetooth devices
  HID: wacom: Move WAC_CMD_* into wacom_wac.h
  HID: wacom: Support 2nd-gen Intuos Pro's Bluetooth classic interface

 drivers/hid/wacom.h     |   3 +
 drivers/hid/wacom_sys.c | 111 +++++++++++++++----
 drivers/hid/wacom_wac.c | 279 +++++++++++++++++++++++++++++++++++++++++++++---
 drivers/hid/wacom_wac.h |  37 ++++++-
 4 files changed, 389 insertions(+), 41 deletions(-)

-- 
2.7.4


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

* [PATCH 1/8] HID: wacom: Enable HID_GENERIC codepath for Bluetooth devices
  2017-01-25 20:08 [PATCH 0/8] HID: wacom: Support second generation Intuos Pro Aaron Armstrong Skomra
@ 2017-01-25 20:08 ` Aaron Armstrong Skomra
  2017-01-25 20:08 ` [PATCH 2/8] HID: wacom: Move WAC_CMD_* into wacom_wac.h Aaron Armstrong Skomra
                   ` (8 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: Aaron Armstrong Skomra @ 2017-01-25 20:08 UTC (permalink / raw)
  To: linux-input, jkosina, benjamin.tissoires, pinglinux, killertofu
  Cc: Jason Gerecke

From: Jason Gerecke <killertofu@gmail.com>

There no reason a Bluetooth device with the appropriate HID descriptor
couldn't be used through the HID_GENERIC codepath in the future. Ensure
that the driver attempts to bind to these devices.

Signed-off-by: Jason Gerecke <jason.gerecke@wacom.com>
---
 drivers/hid/wacom_wac.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c
index 0884dc9..a23b736 100644
--- a/drivers/hid/wacom_wac.c
+++ b/drivers/hid/wacom_wac.c
@@ -4121,6 +4121,7 @@ const struct hid_device_id wacom_ids[] = {
 
 	{ USB_DEVICE_WACOM(HID_ANY_ID) },
 	{ I2C_DEVICE_WACOM(HID_ANY_ID) },
+	{ BT_DEVICE_WACOM(HID_ANY_ID) },
 	{ }
 };
 MODULE_DEVICE_TABLE(hid, wacom_ids);
-- 
2.7.4


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

* [PATCH 2/8] HID: wacom: Move WAC_CMD_* into wacom_wac.h
  2017-01-25 20:08 [PATCH 0/8] HID: wacom: Support second generation Intuos Pro Aaron Armstrong Skomra
  2017-01-25 20:08 ` [PATCH 1/8] HID: wacom: Enable HID_GENERIC codepath for Bluetooth devices Aaron Armstrong Skomra
@ 2017-01-25 20:08 ` Aaron Armstrong Skomra
  2017-01-25 20:08 ` [PATCH 3/8] HID: wacom: Support 2nd-gen Intuos Pro's Bluetooth classic interface Aaron Armstrong Skomra
                   ` (7 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: Aaron Armstrong Skomra @ 2017-01-25 20:08 UTC (permalink / raw)
  To: linux-input, jkosina, benjamin.tissoires, pinglinux, killertofu
  Cc: Jason Gerecke

From: Jason Gerecke <killertofu@gmail.com>

Centralize our definition of report IDs by moving those for device commands
into wacom_wac.h alongside those for input reports.

Signed-off-by: Jason Gerecke <jason.gerecke@wacom.com>
---
 drivers/hid/wacom_sys.c | 8 --------
 drivers/hid/wacom_wac.h | 9 +++++++++
 2 files changed, 9 insertions(+), 8 deletions(-)

diff --git a/drivers/hid/wacom_sys.c b/drivers/hid/wacom_sys.c
index e1aa51a..4dd7b80 100644
--- a/drivers/hid/wacom_sys.c
+++ b/drivers/hid/wacom_sys.c
@@ -16,15 +16,7 @@
 #include <linux/input/mt.h>
 
 #define WAC_MSG_RETRIES		5
-
-#define WAC_CMD_WL_LED_CONTROL	0x03
-#define WAC_CMD_LED_CONTROL	0x20
-#define WAC_CMD_ICON_START	0x21
-#define WAC_CMD_ICON_XFER	0x23
-#define WAC_CMD_ICON_BT_XFER	0x26
 #define WAC_CMD_RETRIES		10
-#define WAC_CMD_DELETE_PAIRING	0x20
-#define WAC_CMD_UNPAIR_ALL	0xFF
 
 #define DEV_ATTR_RW_PERM (S_IRUGO | S_IWUSR | S_IWGRP)
 #define DEV_ATTR_WO_PERM (S_IWUSR | S_IWGRP)
diff --git a/drivers/hid/wacom_wac.h b/drivers/hid/wacom_wac.h
index fb0e50a..804fda3 100644
--- a/drivers/hid/wacom_wac.h
+++ b/drivers/hid/wacom_wac.h
@@ -72,6 +72,15 @@
 #define WACOM_REPORT_REMOTE		17
 #define WACOM_REPORT_INTUOSHT2_ID	8
 
+/* wacom command report ids */
+#define WAC_CMD_WL_LED_CONTROL          0x03
+#define WAC_CMD_LED_CONTROL             0x20
+#define WAC_CMD_ICON_START              0x21
+#define WAC_CMD_ICON_XFER               0x23
+#define WAC_CMD_ICON_BT_XFER            0x26
+#define WAC_CMD_DELETE_PAIRING          0x20
+#define WAC_CMD_UNPAIR_ALL              0xFF
+
 /* device quirks */
 #define WACOM_QUIRK_BBTOUCH_LOWRES	0x0001
 #define WACOM_QUIRK_SENSE		0x0002
-- 
2.7.4


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

* [PATCH 3/8] HID: wacom: Support 2nd-gen Intuos Pro's Bluetooth classic interface
  2017-01-25 20:08 [PATCH 0/8] HID: wacom: Support second generation Intuos Pro Aaron Armstrong Skomra
  2017-01-25 20:08 ` [PATCH 1/8] HID: wacom: Enable HID_GENERIC codepath for Bluetooth devices Aaron Armstrong Skomra
  2017-01-25 20:08 ` [PATCH 2/8] HID: wacom: Move WAC_CMD_* into wacom_wac.h Aaron Armstrong Skomra
@ 2017-01-25 20:08 ` Aaron Armstrong Skomra
  2017-01-25 20:08 ` [PATCH 4/8] HID: wacom: generic: remove input_event_flag Aaron Armstrong Skomra
                   ` (6 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: Aaron Armstrong Skomra @ 2017-01-25 20:08 UTC (permalink / raw)
  To: linux-input, jkosina, benjamin.tissoires, pinglinux, killertofu
  Cc: Jason Gerecke

From: Jason Gerecke <killertofu@gmail.com>

In addition to its USB interface, the second-generation Intuos Pro
includes a Bluetooth radio that offers two pairing interfaces: classic
and low-energy. The classic interface functions just like the earlier
Bluetooth-enabled Intuos4 and Graphire4 tablets, appearing as a HID device
that our driver can work with. The low-energy interface is intented to
be used by userspace applications that make use of its paper-to-digital
capabilities.

Despite the USB interface using Wacom's new vendor-defined HID usages,
the Bluetooth interface provides us with useless black-box "blob"
report descriptors like past devices. We thus have to explicitly add
support for the PIDs and reports used.

These devices pack a /lot/ of information into a single Bluetooth
input report. Each report contains up to seven snapshots of the pen
state, four snapshots of the touch state (of five touches each), pad
state, and battery data. Thankfully this isn't too hard for the driver
to report -- it just takes a fair amount of code to extract!

Signed-off-by: Jason Gerecke <jason.gerecke@wacom.com>
---
 drivers/hid/wacom_sys.c |  25 ++++++
 drivers/hid/wacom_wac.c | 197 ++++++++++++++++++++++++++++++++++++++++++++++++
 drivers/hid/wacom_wac.h |   6 +-
 3 files changed, 226 insertions(+), 2 deletions(-)

diff --git a/drivers/hid/wacom_sys.c b/drivers/hid/wacom_sys.c
index 4dd7b80..4a70783 100644
--- a/drivers/hid/wacom_sys.c
+++ b/drivers/hid/wacom_sys.c
@@ -756,6 +756,10 @@ static int wacom_led_control(struct wacom *wacom)
 		report_id = WAC_CMD_WL_LED_CONTROL;
 		buf_size = 13;
 	}
+	else if (wacom->wacom_wac.features.type == INTUOSP2_BT) {
+		report_id = WAC_CMD_WL_INTUOSP2;
+		buf_size = 51;
+	}
 	buf = kzalloc(buf_size, GFP_KERNEL);
 	if (!buf)
 		return -ENOMEM;
@@ -781,6 +785,16 @@ static int wacom_led_control(struct wacom *wacom)
 		} else
 			buf[1] = led_bits;
 	}
+	else if (wacom->wacom_wac.features.type == INTUOSP2_BT) {
+		buf[0] = report_id;
+		buf[4] = 100; // Power Connection LED (ORANGE)
+		buf[5] = 100; // BT Connection LED (BLUE)
+		buf[6] = 100; // Paper Mode (RED?)
+		buf[7] = 100; // Paper Mode (GREEN?)
+		buf[8] = 100; // Paper Mode (BLUE?)
+		buf[9] = wacom->led.llv;
+		buf[10] = wacom->led.groups[0].select & 0x03;
+	}
 	else {
 		int led = wacom->led.groups[0].select | 0x4;
 
@@ -1409,6 +1423,17 @@ static int wacom_initialize_leds(struct wacom *wacom)
 						      &intuos5_led_attr_group);
 		break;
 
+	case INTUOSP2_BT:
+		wacom->led.llv = 50;
+		wacom->led.max_llv = 100;
+		error = wacom_leds_alloc_and_register(wacom, 1, 4, false);
+		if (error) {
+			hid_err(wacom->hdev,
+				"cannot create leds err: %d\n", error);
+			return error;
+		}
+		return 0;
+
 	case REMOTE:
 		wacom->led.llv = 255;
 		wacom->led.max_llv = 255;
diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c
index a23b736..ef29f7a 100644
--- a/drivers/hid/wacom_wac.c
+++ b/drivers/hid/wacom_wac.c
@@ -1190,6 +1190,161 @@ static int wacom_wac_finger_count_touches(struct wacom_wac *wacom)
 	return count;
 }
 
+static void wacom_intuos_pro2_bt_pen(struct wacom_wac *wacom)
+{
+	const int pen_frame_len = 14;
+	const int pen_frames = 7;
+
+	struct input_dev *pen_input = wacom->pen_input;
+	unsigned char *data = wacom->data;
+	int i;
+
+	wacom->serial[0] = get_unaligned_le64(&data[99]);
+	wacom->id[0]     = get_unaligned_le16(&data[107]);
+	if (wacom->serial[0] >> 52 == 1) {
+		/* Add back in missing bits of ID for non-USI pens */
+		wacom->id[0] |= (wacom->serial[0] >> 32) & 0xFFFFF;
+	}
+	wacom->tool[0]   = wacom_intuos_get_tool_type(wacom_intuos_id_mangle(wacom->id[0]));
+
+	for (i = 0; i < pen_frames; i++) {
+		unsigned char *frame = &data[i*pen_frame_len + 1];
+
+		if (!(frame[0] & 0x80))
+			continue;
+
+		input_report_abs(pen_input, ABS_X, get_unaligned_le16(&frame[1]));
+		input_report_abs(pen_input, ABS_Y, get_unaligned_le16(&frame[3]));
+		input_report_abs(pen_input, ABS_PRESSURE, get_unaligned_le16(&frame[5]));
+		input_report_abs(pen_input, ABS_TILT_X, frame[7]);
+		input_report_abs(pen_input, ABS_TILT_Y, frame[8]);
+		input_report_abs(pen_input, ABS_Z, get_unaligned_le16(&frame[9]));
+		input_report_abs(pen_input, ABS_WHEEL, get_unaligned_le16(&frame[11]));
+		input_report_abs(pen_input, ABS_DISTANCE, frame[13]);
+
+		input_report_key(pen_input, BTN_TOUCH, frame[0] & 0x01);
+		input_report_key(pen_input, BTN_STYLUS, frame[0] & 0x02);
+		input_report_key(pen_input, BTN_STYLUS2, frame[0] & 0x04);
+
+		input_report_key(pen_input, wacom->tool[0], 1);
+		input_event(pen_input, EV_MSC, MSC_SERIAL, wacom->serial[0]);
+		input_report_abs(pen_input, ABS_MISC,
+				 wacom_intuos_id_mangle(wacom->id[0])); /* report tool id */
+
+		wacom->shared->stylus_in_proximity = frame[0] & 0x40;
+
+		input_sync(pen_input);
+	}
+}
+
+static void wacom_intuos_pro2_bt_touch(struct wacom_wac *wacom)
+{
+	const int finger_touch_len = 8;
+	const int finger_frames = 4;
+	const int finger_frame_len = 43;
+
+	struct input_dev *touch_input = wacom->touch_input;
+	unsigned char *data = wacom->data;
+	int num_contacts_left = 5;
+	int i, j;
+
+	for (i = 0; i < finger_frames; i++) {
+		unsigned char *frame = &data[i*finger_frame_len + 109];
+		int current_num_contacts = frame[0] & 0x7F;
+		int contacts_to_send;
+
+		if (!(frame[0] & 0x80))
+			continue;
+
+		/*
+		 * First packet resets the counter since only the first
+		 * packet in series will have non-zero current_num_contacts.
+		 */
+		if (current_num_contacts)
+			wacom->num_contacts_left = current_num_contacts;
+
+		contacts_to_send = min(num_contacts_left, wacom->num_contacts_left);
+
+		for (j = 0; j < contacts_to_send; j++) {
+			unsigned char *touch = &frame[j*finger_touch_len + 1];
+			int slot = input_mt_get_slot_by_key(touch_input, touch[0]);
+			int x = get_unaligned_le16(&touch[2]);
+			int y = get_unaligned_le16(&touch[4]);
+			int w = touch[6] * input_abs_get_res(touch_input, ABS_MT_POSITION_X);
+			int h = touch[7] * input_abs_get_res(touch_input, ABS_MT_POSITION_Y);
+
+			if (slot < 0)
+				continue;
+
+			input_mt_slot(touch_input, slot);
+			input_mt_report_slot_state(touch_input, MT_TOOL_FINGER, touch[1] & 0x01);
+			input_report_abs(touch_input, ABS_MT_POSITION_X, x);
+			input_report_abs(touch_input, ABS_MT_POSITION_Y, y);
+			input_report_abs(touch_input, ABS_MT_TOUCH_MAJOR, max(w, h));
+			input_report_abs(touch_input, ABS_MT_TOUCH_MINOR, min(w, h));
+			input_report_abs(touch_input, ABS_MT_ORIENTATION, w > h);
+		}
+
+		input_mt_sync_frame(touch_input);
+
+		wacom->num_contacts_left -= contacts_to_send;
+		if (wacom->num_contacts_left <= 0) {
+			wacom->num_contacts_left = 0;
+			wacom->shared->touch_down = wacom_wac_finger_count_touches(wacom);
+		}
+	}
+
+	input_report_switch(touch_input, SW_MUTE_DEVICE, !(data[281] >> 7));
+	input_sync(touch_input);
+}
+
+static void wacom_intuos_pro2_bt_pad(struct wacom_wac *wacom)
+{
+	struct input_dev *pad_input = wacom->pad_input;
+	unsigned char *data = wacom->data;
+
+	int buttons = (data[282] << 1) | ((data[281] >> 6) & 0x01);
+	int ring = data[285];
+	int prox = buttons | (ring & 0x80);
+
+	wacom_report_numbered_buttons(pad_input, 9, buttons);
+
+	input_report_abs(pad_input, ABS_WHEEL, (ring & 0x80) ? (ring & 0x7f) : 0);
+
+	input_report_key(pad_input, wacom->tool[1], prox ? 1 : 0);
+	input_report_abs(pad_input, ABS_MISC, prox ? PAD_DEVICE_ID : 0);
+	input_event(pad_input, EV_MSC, MSC_SERIAL, 0xffffffff);
+
+	input_sync(pad_input);
+}
+
+static void wacom_intuos_pro2_bt_battery(struct wacom_wac *wacom)
+{
+	unsigned char *data = wacom->data;
+
+	bool chg = data[284] & 0x80;
+	int battery_status = data[284] & 0x7F;
+
+	wacom_notify_battery(wacom, battery_status, chg, 1, chg);
+}
+
+static int wacom_intuos_pro2_bt_irq(struct wacom_wac *wacom, size_t len)
+{
+	unsigned char *data = wacom->data;
+
+	if (data[0] != 0x80) {
+		dev_dbg(wacom->pen_input->dev.parent,
+			"%s: received unknown report #%d\n", __func__, data[0]);
+		return 0;
+	}
+
+	wacom_intuos_pro2_bt_pen(wacom);
+	wacom_intuos_pro2_bt_touch(wacom);
+	wacom_intuos_pro2_bt_pad(wacom);
+	wacom_intuos_pro2_bt_battery(wacom);
+	return 0;
+}
+
 static int wacom_24hdt_irq(struct wacom_wac *wacom)
 {
 	struct input_dev *input = wacom->touch_input;
@@ -2667,6 +2822,10 @@ void wacom_wac_irq(struct wacom_wac *wacom_wac, size_t len)
 			sync = wacom_intuos_irq(wacom_wac);
 		break;
 
+	case INTUOSP2_BT:
+		sync = wacom_intuos_pro2_bt_irq(wacom_wac, len);
+		break;
+
 	case TABLETPC:
 	case TABLETPCE:
 	case TABLETPC2FG:
@@ -2838,6 +2997,13 @@ void wacom_setup_device_quirks(struct wacom *wacom)
 	if (features->type == REMOTE)
 		features->device_type = WACOM_DEVICETYPE_PAD;
 
+	if (features->type == INTUOSP2_BT) {
+		features->device_type |= WACOM_DEVICETYPE_PEN |
+					 WACOM_DEVICETYPE_PAD |
+					 WACOM_DEVICETYPE_TOUCH;
+		features->quirks |= WACOM_QUIRK_BATTERY;
+	}
+
 	switch (features->type) {
 	case PL:
 	case DTU:
@@ -2984,6 +3150,7 @@ int wacom_setup_pen_input_capabilities(struct input_dev *input_dev,
 	case INTUOSPL:
 	case INTUOS5S:
 	case INTUOSPS:
+	case INTUOSP2_BT:
 		input_set_abs_params(input_dev, ABS_DISTANCE, 0,
 				      features->distance_max,
 				      features->distance_fuzz, 0);
@@ -3092,6 +3259,27 @@ int wacom_setup_touch_input_capabilities(struct input_dev *input_dev,
 	}
 
 	switch (features->type) {
+	case INTUOSP2_BT:
+		input_dev->evbit[0] |= BIT_MASK(EV_SW);
+		__set_bit(SW_MUTE_DEVICE, input_dev->swbit);
+
+		if (wacom_wac->shared->touch->product == 0x361) {
+			input_set_abs_params(input_dev, ABS_MT_POSITION_X,
+					     0, 12440, 4, 0);
+			input_set_abs_params(input_dev, ABS_MT_POSITION_Y,
+					     0, 8640, 4, 0);
+		}
+		else if (wacom_wac->shared->touch->product == 0x360) {
+			input_set_abs_params(input_dev, ABS_MT_POSITION_X,
+					     0, 8960, 4, 0);
+			input_set_abs_params(input_dev, ABS_MT_POSITION_Y,
+					     0, 5920, 4, 0);
+		}
+		input_abs_set_res(input_dev, ABS_MT_POSITION_X, 40);
+		input_abs_set_res(input_dev, ABS_MT_POSITION_X, 40);
+
+		/* fall through */
+
 	case INTUOS5:
 	case INTUOS5L:
 	case INTUOSPM:
@@ -3389,6 +3577,7 @@ int wacom_setup_pad_input_capabilities(struct input_dev *input_dev,
 	case INTUOSPL:
 	case INTUOS5S:
 	case INTUOSPS:
+	case INTUOSP2_BT:
 		input_set_abs_params(input_dev, ABS_WHEEL, 0, 71, 0, 0);
 		break;
 
@@ -3947,6 +4136,12 @@ static const struct wacom_features wacom_features_0x343 =
 	  DTUS, WACOM_INTUOS_RES, WACOM_INTUOS_RES, 4,
 	  WACOM_DTU_OFFSET, WACOM_DTU_OFFSET,
 	  WACOM_DTU_OFFSET, WACOM_DTU_OFFSET };
+static const struct wacom_features wacom_features_0x360 =
+	{ "Wacom Intuos Pro M", 44800, 29600, 8191, 63,
+	  INTUOSP2_BT, WACOM_INTUOS_RES, WACOM_INTUOS_RES, 9, .touch_max = 10 };
+static const struct wacom_features wacom_features_0x361 =
+	{ "Wacom Intuos Pro L", 62200, 43200, 8191, 63,
+	  INTUOSP2_BT, WACOM_INTUOS_RES, WACOM_INTUOS_RES, 9, .touch_max = 10 };
 
 static const struct wacom_features wacom_features_HID_ANY_ID =
 	{ "Wacom HID", .type = HID_GENERIC, .oVid = HID_ANY_ID, .oPid = HID_ANY_ID };
@@ -4113,6 +4308,8 @@ const struct hid_device_id wacom_ids[] = {
 	{ USB_DEVICE_WACOM(0x33D) },
 	{ USB_DEVICE_WACOM(0x33E) },
 	{ USB_DEVICE_WACOM(0x343) },
+	{ BT_DEVICE_WACOM(0x360) },
+	{ BT_DEVICE_WACOM(0x361) },
 	{ USB_DEVICE_WACOM(0x4001) },
 	{ USB_DEVICE_WACOM(0x4004) },
 	{ USB_DEVICE_WACOM(0x5000) },
diff --git a/drivers/hid/wacom_wac.h b/drivers/hid/wacom_wac.h
index 804fda3..d3482de 100644
--- a/drivers/hid/wacom_wac.h
+++ b/drivers/hid/wacom_wac.h
@@ -12,8 +12,8 @@
 #include <linux/types.h>
 #include <linux/hid.h>
 
-/* maximum packet length for USB devices */
-#define WACOM_PKGLEN_MAX	192
+/* maximum packet length for USB/BT devices */
+#define WACOM_PKGLEN_MAX	361
 
 #define WACOM_NAME_MAX		64
 #define WACOM_MAX_REMOTES	5
@@ -80,6 +80,7 @@
 #define WAC_CMD_ICON_BT_XFER            0x26
 #define WAC_CMD_DELETE_PAIRING          0x20
 #define WAC_CMD_UNPAIR_ALL              0xFF
+#define WAC_CMD_WL_INTUOSP2             0x82
 
 /* device quirks */
 #define WACOM_QUIRK_BBTOUCH_LOWRES	0x0001
@@ -179,6 +180,7 @@ enum {
 	INTUOSPS,
 	INTUOSPM,
 	INTUOSPL,
+	INTUOSP2_BT,
 	WACOM_21UX2,
 	WACOM_22HD,
 	DTK,
-- 
2.7.4


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

* [PATCH 4/8] HID: wacom: generic: remove input_event_flag
  2017-01-25 20:08 [PATCH 0/8] HID: wacom: Support second generation Intuos Pro Aaron Armstrong Skomra
                   ` (2 preceding siblings ...)
  2017-01-25 20:08 ` [PATCH 3/8] HID: wacom: Support 2nd-gen Intuos Pro's Bluetooth classic interface Aaron Armstrong Skomra
@ 2017-01-25 20:08 ` Aaron Armstrong Skomra
  2017-01-25 20:08 ` [PATCH 5/8] HID: wacom: generic: add support for touchring Aaron Armstrong Skomra
                   ` (5 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: Aaron Armstrong Skomra @ 2017-01-25 20:08 UTC (permalink / raw)
  To: linux-input, jkosina, benjamin.tissoires, pinglinux, killertofu
  Cc: Aaron Armstrong Skomra, Aaron Skomra

Input_event_flag duplicates the information we track
in wacom_wac->hid_data.inrange_state for the pad.

Signed-off-by: Aaron Skomra <aaron.skomra@wacom.com>
---
 drivers/hid/wacom_wac.c | 9 +--------
 drivers/hid/wacom_wac.h | 1 -
 2 files changed, 1 insertion(+), 9 deletions(-)

diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c
index ef29f7a..f6825d2 100644
--- a/drivers/hid/wacom_wac.c
+++ b/drivers/hid/wacom_wac.c
@@ -1773,7 +1773,6 @@ static void wacom_wac_pad_event(struct hid_device *hdev, struct hid_field *field
 	struct wacom *wacom = hid_get_drvdata(hdev);
 	struct wacom_wac *wacom_wac = &wacom->wacom_wac;
 	struct input_dev *input = wacom_wac->pad_input;
-	struct wacom_features *features = &wacom_wac->features;
 	unsigned equivalent_usage = wacom_equivalent_usage(usage->hid);
 
 	if (wacom_equivalent_usage(field->physical) == HID_DG_TABLETFUNCTIONKEY) {
@@ -1785,7 +1784,6 @@ static void wacom_wac_pad_event(struct hid_device *hdev, struct hid_field *field
 		break;
 
 	default:
-		features->input_event_flag = true;
 		input_event(input, usage->type, usage->code, value);
 		break;
 	}
@@ -1823,20 +1821,15 @@ static void wacom_wac_pad_report(struct hid_device *hdev,
 {
 	struct wacom *wacom = hid_get_drvdata(hdev);
 	struct wacom_wac *wacom_wac = &wacom->wacom_wac;
-	struct wacom_features *features = &wacom_wac->features;
 	struct input_dev *input = wacom_wac->pad_input;
 	bool active = wacom_wac->hid_data.inrange_state != 0;
 
 	/* report prox for expresskey events */
 	if (wacom_equivalent_usage(report->field[0]->physical) == HID_DG_TABLETFUNCTIONKEY) {
-		features->input_event_flag = true;
 		input_event(input, EV_ABS, ABS_MISC, active ? PAD_DEVICE_ID : 0);
-	}
-
-	if (features->input_event_flag) {
-		features->input_event_flag = false;
 		input_sync(input);
 	}
+
 }
 
 static void wacom_wac_pen_usage_mapping(struct hid_device *hdev,
diff --git a/drivers/hid/wacom_wac.h b/drivers/hid/wacom_wac.h
index d3482de..dac95ba 100644
--- a/drivers/hid/wacom_wac.h
+++ b/drivers/hid/wacom_wac.h
@@ -243,7 +243,6 @@ struct wacom_features {
 	int pktlen;
 	bool check_for_hid_type;
 	int hid_type;
-	bool input_event_flag;
 };
 
 struct wacom_shared {
-- 
2.7.4


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

* [PATCH 5/8] HID: wacom: generic: add support for touchring
  2017-01-25 20:08 [PATCH 0/8] HID: wacom: Support second generation Intuos Pro Aaron Armstrong Skomra
                   ` (3 preceding siblings ...)
  2017-01-25 20:08 ` [PATCH 4/8] HID: wacom: generic: remove input_event_flag Aaron Armstrong Skomra
@ 2017-01-25 20:08 ` Aaron Armstrong Skomra
  2017-01-25 20:08 ` [PATCH 6/8] HID: wacom: generic: add vendor defined touch Aaron Armstrong Skomra
                   ` (4 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: Aaron Armstrong Skomra @ 2017-01-25 20:08 UTC (permalink / raw)
  To: linux-input, jkosina, benjamin.tissoires, pinglinux, killertofu
  Cc: Aaron Armstrong Skomra, Aaron Skomra

Add support for the touchring to the generic code path in
support of the second generation Intuos Pro.

We also add checks for usage->type to ensure that we
handle the usage before we report it, or change the
inrange_state based on it.

Signed-off-by: Aaron Skomra <aaron.skomra@wacom.com>
---
 drivers/hid/wacom_wac.c | 19 ++++++++++++++++++-
 1 file changed, 18 insertions(+), 1 deletion(-)

diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c
index f6825d2..636c4a1 100644
--- a/drivers/hid/wacom_wac.c
+++ b/drivers/hid/wacom_wac.c
@@ -1733,6 +1733,10 @@ static void wacom_wac_pad_usage_mapping(struct hid_device *hdev,
 		wacom_map_usage(input, usage, field, EV_ABS, ABS_WHEEL, 0);
 		features->device_type |= WACOM_DEVICETYPE_PAD;
 		break;
+	case WACOM_HID_WD_TOUCHRINGSTATUS:
+		wacom_map_usage(input, usage, field, EV_ABS, ABS_WHEEL, 0);
+		features->device_type |= WACOM_DEVICETYPE_PAD;
+		break;
 	}
 
 	switch (equivalent_usage & 0xfffffff0) {
@@ -1775,12 +1779,22 @@ static void wacom_wac_pad_event(struct hid_device *hdev, struct hid_field *field
 	struct input_dev *input = wacom_wac->pad_input;
 	unsigned equivalent_usage = wacom_equivalent_usage(usage->hid);
 
+	/*
+	 * Avoid reporting this event and setting inrange_state if this usage
+	 * hasn't been mapped.
+	 */
+	if (!usage->type)
+		return;
+
 	if (wacom_equivalent_usage(field->physical) == HID_DG_TABLETFUNCTIONKEY) {
-		wacom_wac->hid_data.inrange_state |= value;
+		if (usage->hid != WACOM_HID_WD_TOUCHRING)
+			wacom_wac->hid_data.inrange_state |= value;
 	}
 
 	switch (equivalent_usage) {
 	case WACOM_HID_WD_TOUCHRINGSTATUS:
+		if (!value)
+			input_event(input, usage->type, usage->code, 0);
 		break;
 
 	default:
@@ -2288,6 +2302,9 @@ void wacom_wac_event(struct hid_device *hdev, struct hid_field *field,
 	if (wacom->wacom_wac.features.type != HID_GENERIC)
 		return;
 
+	if (value > field->logical_maximum || value < field->logical_minimum)
+		return;
+
 	if (WACOM_PAD_FIELD(field)) {
 		wacom_wac_pad_battery_event(hdev, field, usage, value);
 		if (wacom->wacom_wac.pad_input)
-- 
2.7.4


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

* [PATCH 6/8] HID: wacom: generic: add vendor defined touch
  2017-01-25 20:08 [PATCH 0/8] HID: wacom: Support second generation Intuos Pro Aaron Armstrong Skomra
                   ` (4 preceding siblings ...)
  2017-01-25 20:08 ` [PATCH 5/8] HID: wacom: generic: add support for touchring Aaron Armstrong Skomra
@ 2017-01-25 20:08 ` Aaron Armstrong Skomra
  2017-01-25 20:08 ` [PATCH 7/8] HID: wacom: generic: support generic touch switch Aaron Armstrong Skomra
                   ` (3 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: Aaron Armstrong Skomra @ 2017-01-25 20:08 UTC (permalink / raw)
  To: linux-input, jkosina, benjamin.tissoires, pinglinux, killertofu
  Cc: Aaron Armstrong Skomra, Aaron Skomra

Add vendor defined touch to support the second generation
Intuos Pro. Previously all generic Wacom devices used
true HID to report their touch.

Signed-off-by: Aaron Skomra <aaron.skomra@wacom.com>
---
 drivers/hid/wacom.h     |  1 +
 drivers/hid/wacom_sys.c | 13 ++++++++++---
 drivers/hid/wacom_wac.c | 22 +++++++++++++++++-----
 drivers/hid/wacom_wac.h | 16 +++++++++++++++-
 4 files changed, 43 insertions(+), 9 deletions(-)

diff --git a/drivers/hid/wacom.h b/drivers/hid/wacom.h
index 8d8fe30..0e7b840 100644
--- a/drivers/hid/wacom.h
+++ b/drivers/hid/wacom.h
@@ -219,4 +219,5 @@ enum led_brightness wacom_leds_brightness_get(struct wacom_led *led);
 struct wacom_led *wacom_led_find(struct wacom *wacom, unsigned int group,
 				 unsigned int id);
 struct wacom_led *wacom_led_next(struct wacom *wacom, struct wacom_led *cur);
+int wacom_equivalent_usage(int usage);
 #endif
diff --git a/drivers/hid/wacom_sys.c b/drivers/hid/wacom_sys.c
index 4a70783..a4884e7 100644
--- a/drivers/hid/wacom_sys.c
+++ b/drivers/hid/wacom_sys.c
@@ -112,11 +112,12 @@ static void wacom_feature_mapping(struct hid_device *hdev,
 	struct wacom *wacom = hid_get_drvdata(hdev);
 	struct wacom_features *features = &wacom->wacom_wac.features;
 	struct hid_data *hid_data = &wacom->wacom_wac.hid_data;
+	unsigned int equivalent_usage = wacom_equivalent_usage(usage->hid);
 	u8 *data;
 	int ret;
 	int n;
 
-	switch (usage->hid) {
+	switch (equivalent_usage) {
 	case HID_DG_CONTACTMAX:
 		/* leave touch_max as is if predefined */
 		if (!features->touch_max) {
@@ -325,8 +326,14 @@ static void wacom_post_parse_hid(struct hid_device *hdev,
 	if (features->type == HID_GENERIC) {
 		/* Any last-minute generic device setup */
 		if (features->touch_max > 1) {
-			input_mt_init_slots(wacom_wac->touch_input, wacom_wac->features.touch_max,
-				    INPUT_MT_DIRECT);
+			if (features->device_type & WACOM_DEVICETYPE_DIRECT)
+				input_mt_init_slots(wacom_wac->touch_input,
+						    wacom_wac->features.touch_max,
+						    INPUT_MT_DIRECT);
+			else
+				input_mt_init_slots(wacom_wac->touch_input,
+						    wacom_wac->features.touch_max,
+						    INPUT_MT_POINTER);
 		}
 	}
 }
diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c
index 636c4a1..2eeaa05 100644
--- a/drivers/hid/wacom_wac.c
+++ b/drivers/hid/wacom_wac.c
@@ -1599,7 +1599,7 @@ static int wacom_tpc_irq(struct wacom_wac *wacom, size_t len)
 	return 0;
 }
 
-static int wacom_equivalent_usage(int usage)
+int wacom_equivalent_usage(int usage)
 {
 	if ((usage & HID_USAGE_PAGE) == WACOM_HID_UP_WACOMDIGITIZER) {
 		int subpage = (usage & 0xFF00) << 8;
@@ -1626,6 +1626,16 @@ static int wacom_equivalent_usage(int usage)
 		return subpage | subusage;
 	}
 
+	if ((usage & HID_USAGE_PAGE) == WACOM_HID_UP_WACOMTOUCH) {
+		int subpage = (usage & 0xFF00) << 8;
+		int subusage = (usage & 0xFF);
+
+		if (subpage == HID_UP_UNDEFINED)
+			subpage = WACOM_HID_SP_DIGITIZER;
+
+		return subpage | subusage;
+	}
+
 	return usage;
 }
 
@@ -2218,8 +2228,10 @@ static void wacom_wac_finger_pre_report(struct hid_device *hdev,
 
 		for (j = 0; j < field->maxusage; j++) {
 			struct hid_usage *usage = &field->usage[j];
+			unsigned int equivalent_usage =
+				wacom_equivalent_usage(usage->hid);
 
-			switch (usage->hid) {
+			switch (equivalent_usage) {
 			case HID_GD_X:
 			case HID_GD_Y:
 			case HID_DG_WIDTH:
@@ -2228,7 +2240,7 @@ static void wacom_wac_finger_pre_report(struct hid_device *hdev,
 			case HID_DG_INRANGE:
 			case HID_DG_INVERT:
 			case HID_DG_TIPSWITCH:
-				hid_data->last_slot_field = usage->hid;
+				hid_data->last_slot_field = equivalent_usage;
 				break;
 			case HID_DG_CONTACTCOUNT:
 				hid_data->cc_report = report->id;
@@ -2283,8 +2295,8 @@ void wacom_wac_usage_mapping(struct hid_device *hdev,
 	struct wacom_wac *wacom_wac = &wacom->wacom_wac;
 	struct wacom_features *features = &wacom_wac->features;
 
-	/* currently, only direct devices have proper hid report descriptors */
-	features->device_type |= WACOM_DEVICETYPE_DIRECT;
+	if (WACOM_DIRECT_DEVICE(field))
+		features->device_type |= WACOM_DEVICETYPE_DIRECT;
 
 	if (WACOM_PAD_FIELD(field))
 		wacom_wac_pad_usage_mapping(hdev, field, usage);
diff --git a/drivers/hid/wacom_wac.h b/drivers/hid/wacom_wac.h
index dac95ba..da38f77 100644
--- a/drivers/hid/wacom_wac.h
+++ b/drivers/hid/wacom_wac.h
@@ -101,6 +101,7 @@
 #define WACOM_HID_SP_DIGITIZER          0x000d0000
 #define WACOM_HID_SP_DIGITIZERINFO      0x00100000
 #define WACOM_HID_WD_DIGITIZER          (WACOM_HID_UP_WACOMDIGITIZER | 0x01)
+#define WACOM_HID_WD_PEN                (WACOM_HID_UP_WACOMDIGITIZER | 0x02)
 #define WACOM_HID_WD_SENSE              (WACOM_HID_UP_WACOMDIGITIZER | 0x36)
 #define WACOM_HID_WD_DIGITIZERFNKEYS    (WACOM_HID_UP_WACOMDIGITIZER | 0x39)
 #define WACOM_HID_WD_SERIALHI           (WACOM_HID_UP_WACOMDIGITIZER | 0x5c)
@@ -137,6 +138,12 @@
 #define WACOM_HID_UP_G11                0xff110000
 #define WACOM_HID_G11_PEN               (WACOM_HID_UP_G11 | 0x02)
 #define WACOM_HID_G11_TOUCHSCREEN       (WACOM_HID_UP_G11 | 0x11)
+#define WACOM_HID_UP_WACOMTOUCH         0xff000000
+#define WACOM_HID_WT_TOUCHSCREEN        (WACOM_HID_UP_WACOMTOUCH | 0x04)
+#define WACOM_HID_WT_TOUCHPAD           (WACOM_HID_UP_WACOMTOUCH | 0x05)
+#define WACOM_HID_WT_CONTACTMAX         (WACOM_HID_UP_WACOMTOUCH | 0x55)
+#define WACOM_HID_WT_X                  (WACOM_HID_UP_WACOMTOUCH | 0x130)
+#define WACOM_HID_WT_Y                  (WACOM_HID_UP_WACOMTOUCH | 0x131)
 
 #define WACOM_PAD_FIELD(f)	(((f)->physical == HID_DG_TABLETFUNCTIONKEY) || \
 				 ((f)->physical == WACOM_HID_WD_DIGITIZERFNKEYS) || \
@@ -154,7 +161,14 @@
 				 ((f)->physical == HID_DG_FINGER) || \
 				 ((f)->application == HID_DG_TOUCHSCREEN) || \
 				 ((f)->application == WACOM_HID_G9_TOUCHSCREEN) || \
-				 ((f)->application == WACOM_HID_G11_TOUCHSCREEN))
+				 ((f)->application == WACOM_HID_G11_TOUCHSCREEN) || \
+				 ((f)->application == WACOM_HID_WT_TOUCHPAD) || \
+				 ((f)->application == HID_DG_TOUCHPAD))
+
+#define WACOM_DIRECT_DEVICE(f)	(((f)->application == HID_DG_TOUCHSCREEN) || \
+				 ((f)->application == WACOM_HID_WT_TOUCHSCREEN) || \
+				 ((f)->application == HID_DG_PEN) || \
+				 ((f)->application == WACOM_HID_WD_PEN))
 
 enum {
 	PENPARTNER = 0,
-- 
2.7.4


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

* [PATCH 7/8] HID: wacom: generic: support generic touch switch
  2017-01-25 20:08 [PATCH 0/8] HID: wacom: Support second generation Intuos Pro Aaron Armstrong Skomra
                   ` (5 preceding siblings ...)
  2017-01-25 20:08 ` [PATCH 6/8] HID: wacom: generic: add vendor defined touch Aaron Armstrong Skomra
@ 2017-01-25 20:08 ` Aaron Armstrong Skomra
  2017-01-25 20:08 ` [PATCH 8/8] HID: wacom: generic: support LEDs Aaron Armstrong Skomra
                   ` (2 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: Aaron Armstrong Skomra @ 2017-01-25 20:08 UTC (permalink / raw)
  To: linux-input, jkosina, benjamin.tissoires, pinglinux, killertofu
  Cc: Aaron Armstrong Skomra, Aaron Skomra

The second generation Intuos Pro is the first device
in the generic codepath which has a touchswitch. We
utilize a flag in wacom_shared in order to report
this switch event received from the pad on the touch
input.

Signed-off-by: Aaron Skomra <aaron.skomra@wacom.com>
---
 drivers/hid/wacom_sys.c | 26 +++++++++++++++++++-------
 drivers/hid/wacom_wac.c | 19 ++++++++++++++++++-
 drivers/hid/wacom_wac.h |  4 +++-
 3 files changed, 40 insertions(+), 9 deletions(-)

diff --git a/drivers/hid/wacom_sys.c b/drivers/hid/wacom_sys.c
index a4884e7..a8e68dc 100644
--- a/drivers/hid/wacom_sys.c
+++ b/drivers/hid/wacom_sys.c
@@ -2053,6 +2053,24 @@ static void wacom_release_resources(struct wacom *wacom)
 	wacom->wacom_wac.pad_input = NULL;
 }
 
+static void wacom_set_shared_values(struct wacom_wac *wacom_wac)
+{
+	if (wacom_wac->features.device_type & WACOM_DEVICETYPE_TOUCH) {
+		wacom_wac->shared->type = wacom_wac->features.type;
+		wacom_wac->shared->touch_input = wacom_wac->touch_input;
+	}
+
+	if (wacom_wac->has_mute_touch_switch)
+		wacom_wac->shared->has_mute_touch_switch = true;
+
+	if (wacom_wac->shared->has_mute_touch_switch &&
+	    wacom_wac->shared->touch_input) {
+		set_bit(EV_SW, wacom_wac->shared->touch_input->evbit);
+		input_set_capability(wacom_wac->shared->touch_input, EV_SW,
+				     SW_MUTE_DEVICE);
+	}
+}
+
 static int wacom_parse_and_register(struct wacom *wacom, bool wireless)
 {
 	struct wacom_wac *wacom_wac = &wacom->wacom_wac;
@@ -2172,13 +2190,7 @@ static int wacom_parse_and_register(struct wacom *wacom, bool wireless)
 	if (features->device_type & WACOM_DEVICETYPE_WL_MONITOR)
 		error = hid_hw_open(hdev);
 
-	if ((wacom_wac->features.type == INTUOSHT ||
-	     wacom_wac->features.type == INTUOSHT2) &&
-	    (wacom_wac->features.device_type & WACOM_DEVICETYPE_TOUCH)) {
-		wacom_wac->shared->type = wacom_wac->features.type;
-		wacom_wac->shared->touch_input = wacom_wac->touch_input;
-	}
-
+	wacom_set_shared_values(wacom_wac);
 	devres_close_group(&hdev->dev, wacom);
 
 	return 0;
diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c
index 2eeaa05..06d152a 100644
--- a/drivers/hid/wacom_wac.c
+++ b/drivers/hid/wacom_wac.c
@@ -1728,7 +1728,17 @@ static void wacom_wac_pad_usage_mapping(struct hid_device *hdev,
 		features->device_type |= WACOM_DEVICETYPE_PAD;
 		break;
 	case WACOM_HID_WD_TOUCHONOFF:
-		wacom_map_usage(input, usage, field, EV_SW, SW_MUTE_DEVICE, 0);
+		/*
+		 * This usage, which is used to mute touch events, comes
+		 * from the pad packet, but is reported on the touch
+		 * interface. Because the touch interface may not have
+		 * been created yet, we cannot call wacom_map_usage(). In
+		 * order to process this usage when we receive it, we set
+		 * the usage type and code directly.
+		 */
+		wacom_wac->has_mute_touch_switch = true;
+		usage->type = EV_SW;
+		usage->code = SW_MUTE_DEVICE;
 		features->device_type |= WACOM_DEVICETYPE_PAD;
 		break;
 	case WACOM_HID_WD_TOUCHSTRIP:
@@ -1807,6 +1817,13 @@ static void wacom_wac_pad_event(struct hid_device *hdev, struct hid_field *field
 			input_event(input, usage->type, usage->code, 0);
 		break;
 
+	case WACOM_HID_WD_TOUCHONOFF:
+		if (wacom_wac->shared->touch_input) {
+			input_report_switch(wacom_wac->shared->touch_input,
+					    SW_MUTE_DEVICE, !value);
+			input_sync(wacom_wac->shared->touch_input);
+		}
+		break;
 	default:
 		input_event(input, usage->type, usage->code, value);
 		break;
diff --git a/drivers/hid/wacom_wac.h b/drivers/hid/wacom_wac.h
index da38f77..4feaf94 100644
--- a/drivers/hid/wacom_wac.h
+++ b/drivers/hid/wacom_wac.h
@@ -115,6 +115,7 @@
 #define WACOM_HID_WD_ACCELEROMETER_Y    (WACOM_HID_UP_WACOMDIGITIZER | 0x0402)
 #define WACOM_HID_WD_ACCELEROMETER_Z    (WACOM_HID_UP_WACOMDIGITIZER | 0x0403)
 #define WACOM_HID_WD_BATTERY_CHARGING   (WACOM_HID_UP_WACOMDIGITIZER | 0x0404)
+#define WACOM_HID_WD_TOUCHONOFF         (WACOM_HID_UP_WACOMDIGITIZER | 0x0454)
 #define WACOM_HID_WD_BATTERY_LEVEL      (WACOM_HID_UP_WACOMDIGITIZER | 0x043b)
 #define WACOM_HID_WD_EXPRESSKEY00       (WACOM_HID_UP_WACOMDIGITIZER | 0x0910)
 #define WACOM_HID_WD_EXPRESSKEYCAP00    (WACOM_HID_UP_WACOMDIGITIZER | 0x0950)
@@ -124,7 +125,6 @@
 #define WACOM_HID_WD_BUTTONLEFT         (WACOM_HID_UP_WACOMDIGITIZER | 0x0993)
 #define WACOM_HID_WD_BUTTONRIGHT        (WACOM_HID_UP_WACOMDIGITIZER | 0x0994)
 #define WACOM_HID_WD_BUTTONCENTER       (WACOM_HID_UP_WACOMDIGITIZER | 0x0995)
-#define WACOM_HID_WD_TOUCHONOFF         (WACOM_HID_UP_WACOMDIGITIZER | 0x0996)
 #define WACOM_HID_WD_FINGERWHEEL        (WACOM_HID_UP_WACOMDIGITIZER | 0x0d03)
 #define WACOM_HID_WD_OFFSETLEFT         (WACOM_HID_UP_WACOMDIGITIZER | 0x0d30)
 #define WACOM_HID_WD_OFFSETTOP          (WACOM_HID_UP_WACOMDIGITIZER | 0x0d31)
@@ -268,6 +268,7 @@ struct wacom_shared {
 	struct input_dev *touch_input;
 	struct hid_device *pen;
 	struct hid_device *touch;
+	bool has_mute_touch_switch;
 };
 
 struct hid_data {
@@ -324,6 +325,7 @@ struct wacom_wac {
 	int mode_report;
 	int mode_value;
 	struct hid_data hid_data;
+	bool has_mute_touch_switch;
 };
 
 #endif
-- 
2.7.4


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

* [PATCH 8/8] HID: wacom: generic: support LEDs
  2017-01-25 20:08 [PATCH 0/8] HID: wacom: Support second generation Intuos Pro Aaron Armstrong Skomra
                   ` (6 preceding siblings ...)
  2017-01-25 20:08 ` [PATCH 7/8] HID: wacom: generic: support generic touch switch Aaron Armstrong Skomra
@ 2017-01-25 20:08 ` Aaron Armstrong Skomra
  2017-01-26 20:39 ` [PATCH 0/8] HID: wacom: Support second generation Intuos Pro Ping Cheng
  2017-01-26 20:48 ` Jiri Kosina
  9 siblings, 0 replies; 11+ messages in thread
From: Aaron Armstrong Skomra @ 2017-01-25 20:08 UTC (permalink / raw)
  To: linux-input, jkosina, benjamin.tissoires, pinglinux, killertofu
  Cc: Aaron Armstrong Skomra, Aaron Skomra

Add support for the LEDs around the mode switch to the
generic code path in support of the second generation
Intuos Pro.

Signed-off-by: Aaron Skomra <aaron.skomra@wacom.com>
---
 drivers/hid/wacom.h     |  2 ++
 drivers/hid/wacom_sys.c | 39 ++++++++++++++++++++++++++++++++++++---
 drivers/hid/wacom_wac.c | 14 +++++++++++++-
 drivers/hid/wacom_wac.h |  1 +
 4 files changed, 52 insertions(+), 4 deletions(-)

diff --git a/drivers/hid/wacom.h b/drivers/hid/wacom.h
index 0e7b840..d0d7dc1 100644
--- a/drivers/hid/wacom.h
+++ b/drivers/hid/wacom.h
@@ -168,6 +168,7 @@ struct wacom {
 	struct work_struct remote_work;
 	struct delayed_work init_work;
 	struct wacom_remote *remote;
+	bool generic_has_leds;
 	struct wacom_leds {
 		struct wacom_group_leds *groups;
 		unsigned int count;
@@ -220,4 +221,5 @@ struct wacom_led *wacom_led_find(struct wacom *wacom, unsigned int group,
 				 unsigned int id);
 struct wacom_led *wacom_led_next(struct wacom *wacom, struct wacom_led *cur);
 int wacom_equivalent_usage(int usage);
+int wacom_initialize_leds(struct wacom *wacom);
 #endif
diff --git a/drivers/hid/wacom_sys.c b/drivers/hid/wacom_sys.c
index a8e68dc..3586acb 100644
--- a/drivers/hid/wacom_sys.c
+++ b/drivers/hid/wacom_sys.c
@@ -771,8 +771,13 @@ static int wacom_led_control(struct wacom *wacom)
 	if (!buf)
 		return -ENOMEM;
 
-	if (wacom->wacom_wac.features.type >= INTUOS5S &&
-	    wacom->wacom_wac.features.type <= INTUOSPL) {
+	if (wacom->wacom_wac.features.type == HID_GENERIC) {
+		buf[0] = WAC_CMD_LED_CONTROL_GENERIC;
+		buf[1] = wacom->led.llv;
+		buf[2] = wacom->led.groups[0].select & 0x03;
+
+	} else if ((wacom->wacom_wac.features.type >= INTUOS5S &&
+	    wacom->wacom_wac.features.type <= INTUOSPL)) {
 		/*
 		 * Touch Ring and crop mark LED luminance may take on
 		 * one of four values:
@@ -1042,6 +1047,17 @@ static struct attribute_group intuos5_led_attr_group = {
 	.attrs = intuos5_led_attrs,
 };
 
+static struct attribute *generic_led_attrs[] = {
+	&dev_attr_status0_luminance.attr,
+	&dev_attr_status_led0_select.attr,
+	NULL
+};
+
+static struct attribute_group generic_led_attr_group = {
+	.name = "wacom_led",
+	.attrs = generic_led_attrs,
+};
+
 struct wacom_sysfs_group_devres {
 	struct attribute_group *group;
 	struct kobject *root;
@@ -1363,7 +1379,7 @@ static int wacom_leds_alloc_and_register(struct wacom *wacom, int group_count,
 	return 0;
 }
 
-static int wacom_initialize_leds(struct wacom *wacom)
+int wacom_initialize_leds(struct wacom *wacom)
 {
 	int error;
 
@@ -1372,6 +1388,23 @@ static int wacom_initialize_leds(struct wacom *wacom)
 
 	/* Initialize default values */
 	switch (wacom->wacom_wac.features.type) {
+	case HID_GENERIC:
+		if (!wacom->generic_has_leds)
+			return 0;
+		wacom->led.llv = 100;
+		wacom->led.max_llv = 100;
+
+		error = wacom_leds_alloc_and_register(wacom, 1, 4, false);
+		if (error) {
+			hid_err(wacom->hdev,
+				"cannot create leds err: %d\n", error);
+			return error;
+		}
+
+		error = wacom_devm_sysfs_create_group(wacom,
+						      &generic_led_attr_group);
+		break;
+
 	case INTUOS4S:
 	case INTUOS4:
 	case INTUOS4WL:
diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c
index 06d152a..0dad786 100644
--- a/drivers/hid/wacom_wac.c
+++ b/drivers/hid/wacom_wac.c
@@ -43,6 +43,8 @@ static void wacom_report_numbered_buttons(struct input_dev *input_dev,
 
 static int wacom_numbered_button_to_key(int n);
 
+static void wacom_update_led(struct wacom *wacom, int button_count, int mask,
+			     int group);
 /*
  * Percent of battery capacity for Graphire.
  * 8th value means AC online and show 100% capacity.
@@ -1715,12 +1717,14 @@ static void wacom_wac_pad_usage_mapping(struct hid_device *hdev,
 		wacom_map_usage(input, usage, field, EV_ABS, ABS_Z, 0);
 		features->device_type |= WACOM_DEVICETYPE_PAD;
 		break;
+	case WACOM_HID_WD_BUTTONCENTER:
+		wacom->generic_has_leds = true;
+		/* fall through */
 	case WACOM_HID_WD_BUTTONHOME:
 	case WACOM_HID_WD_BUTTONUP:
 	case WACOM_HID_WD_BUTTONDOWN:
 	case WACOM_HID_WD_BUTTONLEFT:
 	case WACOM_HID_WD_BUTTONRIGHT:
-	case WACOM_HID_WD_BUTTONCENTER:
 		wacom_map_usage(input, usage, field, EV_KEY,
 				wacom_numbered_button_to_key(features->numbered_buttons),
 				0);
@@ -1797,7 +1801,9 @@ static void wacom_wac_pad_event(struct hid_device *hdev, struct hid_field *field
 	struct wacom *wacom = hid_get_drvdata(hdev);
 	struct wacom_wac *wacom_wac = &wacom->wacom_wac;
 	struct input_dev *input = wacom_wac->pad_input;
+	struct wacom_features *features = &wacom_wac->features;
 	unsigned equivalent_usage = wacom_equivalent_usage(usage->hid);
+	int i;
 
 	/*
 	 * Avoid reporting this event and setting inrange_state if this usage
@@ -1824,6 +1830,12 @@ static void wacom_wac_pad_event(struct hid_device *hdev, struct hid_field *field
 			input_sync(wacom_wac->shared->touch_input);
 		}
 		break;
+
+	case WACOM_HID_WD_BUTTONCENTER:
+		for (i = 0; i < wacom->led.count; i++)
+			wacom_update_led(wacom, features->numbered_buttons,
+					 value, i);
+		 /* fall through*/
 	default:
 		input_event(input, usage->type, usage->code, value);
 		break;
diff --git a/drivers/hid/wacom_wac.h b/drivers/hid/wacom_wac.h
index 4feaf94..857ccee 100644
--- a/drivers/hid/wacom_wac.h
+++ b/drivers/hid/wacom_wac.h
@@ -79,6 +79,7 @@
 #define WAC_CMD_ICON_XFER               0x23
 #define WAC_CMD_ICON_BT_XFER            0x26
 #define WAC_CMD_DELETE_PAIRING          0x20
+#define WAC_CMD_LED_CONTROL_GENERIC     0x32
 #define WAC_CMD_UNPAIR_ALL              0xFF
 #define WAC_CMD_WL_INTUOSP2             0x82
 
-- 
2.7.4


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

* Re: [PATCH 0/8] HID: wacom: Support second generation Intuos Pro
  2017-01-25 20:08 [PATCH 0/8] HID: wacom: Support second generation Intuos Pro Aaron Armstrong Skomra
                   ` (7 preceding siblings ...)
  2017-01-25 20:08 ` [PATCH 8/8] HID: wacom: generic: support LEDs Aaron Armstrong Skomra
@ 2017-01-26 20:39 ` Ping Cheng
  2017-01-26 20:48 ` Jiri Kosina
  9 siblings, 0 replies; 11+ messages in thread
From: Ping Cheng @ 2017-01-26 20:39 UTC (permalink / raw)
  To: Aaron Armstrong Skomra
  Cc: linux-input, Jiri Kosina, Benjamin Tissoires, Jason Gerecke

On Wed, Jan 25, 2017 at 12:08 PM, Aaron Armstrong Skomra
<skomra@gmail.com> wrote:
>
> Patches 1-3 add Bluetooth support for the 2nd-gen Intuos Pro. Its
> Bluetooth report lacks a proper report descriptor so we must add
> explicit support for the device here.
>
> Patches 4-8 add USB support for this device via the Wacom driver's
> generic code path.
>
> Best,
> Aaron
>
> Aaron Armstrong Skomra (5):
>   HID: wacom: generic: remove input_event_flag
>   HID: wacom: generic: add support for touchring
>   HID: wacom: generic: add vendor defined touch
>   HID: wacom: generic: support generic touch switch
>   HID: wacom: generic: support LEDs
>
> Jason Gerecke (3):
>   HID: wacom: Enable HID_GENERIC codepath for Bluetooth devices
>   HID: wacom: Move WAC_CMD_* into wacom_wac.h
>   HID: wacom: Support 2nd-gen Intuos Pro's Bluetooth classic interface

This whole set is reviewed-by: Ping Cheng <pingc@wacom.com>

Thank you Aaron and Jason for your effort.

Cheers,
Ping

>
>  drivers/hid/wacom.h     |   3 +
>  drivers/hid/wacom_sys.c | 111 +++++++++++++++----
>  drivers/hid/wacom_wac.c | 279 +++++++++++++++++++++++++++++++++++++++++++++---
>  drivers/hid/wacom_wac.h |  37 ++++++-
>  4 files changed, 389 insertions(+), 41 deletions(-)
>
> --
> 2.7.4
>

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

* Re: [PATCH 0/8] HID: wacom: Support second generation Intuos Pro
  2017-01-25 20:08 [PATCH 0/8] HID: wacom: Support second generation Intuos Pro Aaron Armstrong Skomra
                   ` (8 preceding siblings ...)
  2017-01-26 20:39 ` [PATCH 0/8] HID: wacom: Support second generation Intuos Pro Ping Cheng
@ 2017-01-26 20:48 ` Jiri Kosina
  9 siblings, 0 replies; 11+ messages in thread
From: Jiri Kosina @ 2017-01-26 20:48 UTC (permalink / raw)
  To: Aaron Armstrong Skomra
  Cc: linux-input, benjamin.tissoires, pinglinux, killertofu

On Wed, 25 Jan 2017, Aaron Armstrong Skomra wrote:

> Patches 1-3 add Bluetooth support for the 2nd-gen Intuos Pro. Its
> Bluetooth report lacks a proper report descriptor so we must add
> explicit support for the device here.
> 
> Patches 4-8 add USB support for this device via the Wacom driver's
> generic code path.
> 
> Best,
> Aaron
> 
> Aaron Armstrong Skomra (5):
>   HID: wacom: generic: remove input_event_flag
>   HID: wacom: generic: add support for touchring
>   HID: wacom: generic: add vendor defined touch
>   HID: wacom: generic: support generic touch switch
>   HID: wacom: generic: support LEDs
> 
> Jason Gerecke (3):
>   HID: wacom: Enable HID_GENERIC codepath for Bluetooth devices
>   HID: wacom: Move WAC_CMD_* into wacom_wac.h
>   HID: wacom: Support 2nd-gen Intuos Pro's Bluetooth classic interface
> 
>  drivers/hid/wacom.h     |   3 +
>  drivers/hid/wacom_sys.c | 111 +++++++++++++++----
>  drivers/hid/wacom_wac.c | 279 +++++++++++++++++++++++++++++++++++++++++++++---
>  drivers/hid/wacom_wac.h |  37 ++++++-
>  4 files changed, 389 insertions(+), 41 deletions(-)

Applied to hid.git#for-4.11/wacom, thanks.

-- 
Jiri Kosina
SUSE Labs


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

end of thread, other threads:[~2017-01-26 20:48 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-01-25 20:08 [PATCH 0/8] HID: wacom: Support second generation Intuos Pro Aaron Armstrong Skomra
2017-01-25 20:08 ` [PATCH 1/8] HID: wacom: Enable HID_GENERIC codepath for Bluetooth devices Aaron Armstrong Skomra
2017-01-25 20:08 ` [PATCH 2/8] HID: wacom: Move WAC_CMD_* into wacom_wac.h Aaron Armstrong Skomra
2017-01-25 20:08 ` [PATCH 3/8] HID: wacom: Support 2nd-gen Intuos Pro's Bluetooth classic interface Aaron Armstrong Skomra
2017-01-25 20:08 ` [PATCH 4/8] HID: wacom: generic: remove input_event_flag Aaron Armstrong Skomra
2017-01-25 20:08 ` [PATCH 5/8] HID: wacom: generic: add support for touchring Aaron Armstrong Skomra
2017-01-25 20:08 ` [PATCH 6/8] HID: wacom: generic: add vendor defined touch Aaron Armstrong Skomra
2017-01-25 20:08 ` [PATCH 7/8] HID: wacom: generic: support generic touch switch Aaron Armstrong Skomra
2017-01-25 20:08 ` [PATCH 8/8] HID: wacom: generic: support LEDs Aaron Armstrong Skomra
2017-01-26 20:39 ` [PATCH 0/8] HID: wacom: Support second generation Intuos Pro Ping Cheng
2017-01-26 20:48 ` 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.