linux-input.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v2 0/7] HID: multitouch: support of hybrid finger/pen devices
@ 2013-03-22 17:38 Benjamin Tissoires
  2013-03-22 17:38 ` [PATCH v2 1/7] HID: input: don't register unmapped input devices Benjamin Tissoires
                   ` (7 more replies)
  0 siblings, 8 replies; 9+ messages in thread
From: Benjamin Tissoires @ 2013-03-22 17:38 UTC (permalink / raw)
  To: Henrik Rydberg, Jiri Kosina, Stephane Chatty, linux-input,
	linux-kernel

Hi Guys,

this is the second iteration of the support of dual sensors (pen + touch)
devices.

There has not been a lot of changes since v1:
- use " |= " instead of " = r || " in patch 1
- introduce a factorization of input_configured() in patch 2 (which makes more sense
IMO)
- patch 4 is new, but the change is quite small (again, tested on my database)
- patch 6 has been reworked, though it's not clear if it's better
- patch 7 has been reworked, the set_bit occurs now in input_configured()

Cheers,
Benjamin

Benjamin Tissoires (7):
  HID: input: don't register unmapped input devices
  HID: multitouch: breaks out touch handling in specific functions
  HID: multitouch: do not map usage from non used reports
  HID: multitouch: change touch sensor detection in
    mt_input_configured()
  HID: multitouch: add handling for pen in dual-sensors device
  HID: multitouch: append " Pen" to the name of the stylus input
  HID: multitouch: force BTN_STYLUS for pen devices

 drivers/hid/hid-input.c      |  77 +++++++++++++++
 drivers/hid/hid-multitouch.c | 216 ++++++++++++++++++++++++++++++++++---------
 include/linux/hid.h          |   1 +
 3 files changed, 251 insertions(+), 43 deletions(-)

-- 
1.8.1.4

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

* [PATCH v2 1/7] HID: input: don't register unmapped input devices
  2013-03-22 17:38 [PATCH v2 0/7] HID: multitouch: support of hybrid finger/pen devices Benjamin Tissoires
@ 2013-03-22 17:38 ` Benjamin Tissoires
  2013-03-22 17:38 ` [PATCH v2 2/7] HID: multitouch: breaks out touch handling in specific functions Benjamin Tissoires
                   ` (6 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Benjamin Tissoires @ 2013-03-22 17:38 UTC (permalink / raw)
  To: Henrik Rydberg, Jiri Kosina, Stephane Chatty, linux-input,
	linux-kernel

There is no need to register an input device containing no events.
This allows drivers using the quirk MULTI_INPUT to register one input
per report effectively used.

For backward compatibility, we need to add a quirk to request
this behavior.

Signed-off-by: Benjamin Tissoires <benjamin.tissoires@redhat.com>
---
 drivers/hid/hid-input.c | 77 +++++++++++++++++++++++++++++++++++++++++++++++++
 include/linux/hid.h     |  1 +
 2 files changed, 78 insertions(+)

diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c
index 21b196c..945b815 100644
--- a/drivers/hid/hid-input.c
+++ b/drivers/hid/hid-input.c
@@ -1198,6 +1198,67 @@ static struct hid_input *hidinput_allocate(struct hid_device *hid)
 	return hidinput;
 }
 
+static bool hidinput_has_been_populated(struct hid_input *hidinput)
+{
+	int i;
+	unsigned long r = 0;
+
+	for (i = 0; i < BITS_TO_LONGS(EV_CNT); i++)
+		r |= hidinput->input->evbit[i];
+
+	for (i = 0; i < BITS_TO_LONGS(KEY_CNT); i++)
+		r |= hidinput->input->keybit[i];
+
+	for (i = 0; i < BITS_TO_LONGS(REL_CNT); i++)
+		r |= hidinput->input->relbit[i];
+
+	for (i = 0; i < BITS_TO_LONGS(ABS_CNT); i++)
+		r |= hidinput->input->absbit[i];
+
+	for (i = 0; i < BITS_TO_LONGS(MSC_CNT); i++)
+		r |= hidinput->input->mscbit[i];
+
+	for (i = 0; i < BITS_TO_LONGS(LED_CNT); i++)
+		r |= hidinput->input->ledbit[i];
+
+	for (i = 0; i < BITS_TO_LONGS(SND_CNT); i++)
+		r |= hidinput->input->sndbit[i];
+
+	for (i = 0; i < BITS_TO_LONGS(FF_CNT); i++)
+		r |= hidinput->input->ffbit[i];
+
+	for (i = 0; i < BITS_TO_LONGS(SW_CNT); i++)
+		r |= hidinput->input->swbit[i];
+
+	return !!r;
+}
+
+static void hidinput_cleanup_hidinput(struct hid_device *hid,
+		struct hid_input *hidinput)
+{
+	struct hid_report *report;
+	int i, k;
+
+	list_del(&hidinput->list);
+	input_free_device(hidinput->input);
+
+	for (k = HID_INPUT_REPORT; k <= HID_OUTPUT_REPORT; k++) {
+		if (k == HID_OUTPUT_REPORT &&
+			hid->quirks & HID_QUIRK_SKIP_OUTPUT_REPORTS)
+			continue;
+
+		list_for_each_entry(report, &hid->report_enum[k].report_list,
+				    list) {
+
+			for (i = 0; i < report->maxfield; i++)
+				if (report->field[i]->hidinput == hidinput)
+					report->field[i]->hidinput = NULL;
+		}
+	}
+
+	kfree(hidinput);
+}
+
 /*
  * Register the input device; print a message.
  * Configure the input layer interface
@@ -1249,6 +1310,10 @@ int hidinput_connect(struct hid_device *hid, unsigned int force)
 					hidinput_configure_usage(hidinput, report->field[i],
 								 report->field[i]->usage + j);
 
+			if ((hid->quirks & HID_QUIRK_NO_EMPTY_INPUT) &&
+			    !hidinput_has_been_populated(hidinput))
+				continue;
+
 			if (hid->quirks & HID_QUIRK_MULTI_INPUT) {
 				/* This will leave hidinput NULL, so that it
 				 * allocates another one if we have more inputs on
@@ -1265,6 +1330,18 @@ int hidinput_connect(struct hid_device *hid, unsigned int force)
 		}
 	}
 
+	if (hidinput && (hid->quirks & HID_QUIRK_NO_EMPTY_INPUT) &&
+	    !hidinput_has_been_populated(hidinput)) {
+		/* no need to register an input device not populated */
+		hidinput_cleanup_hidinput(hid, hidinput);
+		hidinput = NULL;
+	}
+
+	if (list_empty(&hid->inputs)) {
+		hid_err(hid, "No inputs registered, leaving\n");
+		goto out_unwind;
+	}
+
 	if (hidinput) {
 		if (drv->input_configured)
 			drv->input_configured(hid, hidinput);
diff --git a/include/linux/hid.h b/include/linux/hid.h
index 19357f6..b7b5ff2 100644
--- a/include/linux/hid.h
+++ b/include/linux/hid.h
@@ -282,6 +282,7 @@ struct hid_item {
 #define HID_QUIRK_BADPAD			0x00000020
 #define HID_QUIRK_MULTI_INPUT			0x00000040
 #define HID_QUIRK_HIDINPUT_FORCE		0x00000080
+#define HID_QUIRK_NO_EMPTY_INPUT		0x00000100
 #define HID_QUIRK_SKIP_OUTPUT_REPORTS		0x00010000
 #define HID_QUIRK_FULLSPEED_INTERVAL		0x10000000
 #define HID_QUIRK_NO_INIT_REPORTS		0x20000000
-- 
1.8.1.4


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

* [PATCH v2 2/7] HID: multitouch: breaks out touch handling in specific functions
  2013-03-22 17:38 [PATCH v2 0/7] HID: multitouch: support of hybrid finger/pen devices Benjamin Tissoires
  2013-03-22 17:38 ` [PATCH v2 1/7] HID: input: don't register unmapped input devices Benjamin Tissoires
@ 2013-03-22 17:38 ` Benjamin Tissoires
  2013-03-22 17:38 ` [PATCH v2 3/7] HID: multitouch: do not map usage from non used reports Benjamin Tissoires
                   ` (5 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Benjamin Tissoires @ 2013-03-22 17:38 UTC (permalink / raw)
  To: Henrik Rydberg, Jiri Kosina, Stephane Chatty, linux-input,
	linux-kernel

This will allow easier integration of hybrid pen and touch devices.

Signed-off-by: Benjamin Tissoires <benjamin.tissoires@redhat.com>
---
 drivers/hid/hid-multitouch.c | 123 +++++++++++++++++++++++++++++--------------
 1 file changed, 83 insertions(+), 40 deletions(-)

diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c
index 1f544a4..35b6025 100644
--- a/drivers/hid/hid-multitouch.c
+++ b/drivers/hid/hid-multitouch.c
@@ -114,6 +114,9 @@ struct mt_device {
 	unsigned mt_flags;	/* flags to pass to input-mt */
 };
 
+static void mt_post_parse_default_settings(struct mt_device *td);
+static void mt_post_parse(struct mt_device *td);
+
 /* classes of device behavior */
 #define MT_CLS_DEFAULT				0x0001
 
@@ -364,7 +367,7 @@ static void mt_store_field(struct hid_usage *usage, struct mt_device *td,
 	f->usages[f->length++] = usage->hid;
 }
 
-static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi,
+static int mt_touch_input_mapping(struct hid_device *hdev, struct hid_input *hi,
 		struct hid_field *field, struct hid_usage *usage,
 		unsigned long **bit, int *max)
 {
@@ -373,13 +376,8 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi,
 	int code;
 	struct hid_usage *prev_usage = NULL;
 
-	/* Only map fields from TouchScreen or TouchPad collections.
-	* We need to ignore fields that belong to other collections
-	* such as Mouse that might have the same GenericDesktop usages. */
 	if (field->application == HID_DG_TOUCHSCREEN)
 		td->mt_flags |= INPUT_MT_DIRECT;
-	else if (field->application != HID_DG_TOUCHPAD)
-		return 0;
 
 	/*
 	 * Model touchscreens providing buttons as touchpads.
@@ -388,12 +386,6 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi,
 	    (usage->hid & HID_USAGE_PAGE) == HID_UP_BUTTON)
 		td->mt_flags |= INPUT_MT_POINTER;
 
-	/* eGalax devices provide a Digitizer.Stylus input which overrides
-	 * the correct Digitizers.Finger X/Y ranges.
-	 * Let's just ignore this input. */
-	if (field->physical == HID_DG_STYLUS)
-		return -1;
-
 	if (usage->usage_index)
 		prev_usage = &field->usage[usage->usage_index - 1];
 
@@ -514,7 +506,7 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi,
 	return 0;
 }
 
-static int mt_input_mapped(struct hid_device *hdev, struct hid_input *hi,
+static int mt_touch_input_mapped(struct hid_device *hdev, struct hid_input *hi,
 		struct hid_field *field, struct hid_usage *usage,
 		unsigned long **bit, int *max)
 {
@@ -605,7 +597,7 @@ static void mt_sync_frame(struct mt_device *td, struct input_dev *input)
 	td->num_received = 0;
 }
 
-static int mt_event(struct hid_device *hid, struct hid_field *field,
+static int mt_touch_event(struct hid_device *hid, struct hid_field *field,
 				struct hid_usage *usage, __s32 value)
 {
 	/* we will handle the hidinput part later, now remains hiddev */
@@ -681,19 +673,13 @@ static void mt_process_mt_event(struct hid_device *hid, struct hid_field *field,
 	}
 }
 
-static void mt_report(struct hid_device *hid, struct hid_report *report)
+static void mt_touch_report(struct hid_device *hid, struct hid_report *report)
 {
 	struct mt_device *td = hid_get_drvdata(hid);
 	struct hid_field *field;
 	unsigned count;
 	int r, n;
 
-	if (report->id != td->mt_report_id)
-		return;
-
-	if (!(hid->claimed & HID_CLAIMED_INPUT))
-		return;
-
 	/*
 	 * Includes multi-packet support where subsequent
 	 * packets are sent with zero contactcount.
@@ -721,6 +707,81 @@ static void mt_report(struct hid_device *hid, struct hid_report *report)
 		mt_sync_frame(td, report->field[0]->hidinput->input);
 }
 
+static void mt_touch_input_configured(struct hid_device *hdev,
+					struct hid_input *hi)
+{
+	struct mt_device *td = hid_get_drvdata(hdev);
+	struct mt_class *cls = &td->mtclass;
+	struct input_dev *input = hi->input;
+
+	if (!td->maxcontacts)
+		td->maxcontacts = MT_DEFAULT_MAXCONTACT;
+
+	mt_post_parse(td);
+	if (td->serial_maybe)
+		mt_post_parse_default_settings(td);
+
+	if (cls->is_indirect)
+		td->mt_flags |= INPUT_MT_POINTER;
+
+	if (cls->quirks & MT_QUIRK_NOT_SEEN_MEANS_UP)
+		td->mt_flags |= INPUT_MT_DROP_UNUSED;
+
+	input_mt_init_slots(input, td->maxcontacts, td->mt_flags);
+
+	td->mt_flags = 0;
+}
+
+static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi,
+		struct hid_field *field, struct hid_usage *usage,
+		unsigned long **bit, int *max)
+{
+	/* Only map fields from TouchScreen or TouchPad collections.
+	* We need to ignore fields that belong to other collections
+	* such as Mouse that might have the same GenericDesktop usages. */
+	if (field->application != HID_DG_TOUCHSCREEN &&
+	    field->application != HID_DG_TOUCHPAD)
+		return 0;
+
+	/* eGalax devices provide a Digitizer.Stylus input which overrides
+	 * the correct Digitizers.Finger X/Y ranges.
+	 * Let's just ignore this input. */
+	if (field->physical == HID_DG_STYLUS)
+		return -1;
+
+	return mt_touch_input_mapping(hdev, hi, field, usage, bit, max);
+}
+
+static int mt_input_mapped(struct hid_device *hdev, struct hid_input *hi,
+		struct hid_field *field, struct hid_usage *usage,
+		unsigned long **bit, int *max)
+{
+	return mt_touch_input_mapped(hdev, hi, field, usage, bit, max);
+}
+
+static int mt_event(struct hid_device *hid, struct hid_field *field,
+				struct hid_usage *usage, __s32 value)
+{
+	struct mt_device *td = hid_get_drvdata(hid);
+
+	if (field->report->id == td->mt_report_id)
+		return mt_touch_event(hid, field, usage, value);
+
+	/* ignore other reports */
+	return 1;
+}
+
+static void mt_report(struct hid_device *hid, struct hid_report *report)
+{
+	struct mt_device *td = hid_get_drvdata(hid);
+
+	if (!(hid->claimed & HID_CLAIMED_INPUT))
+		return;
+
+	if (report->id == td->mt_report_id)
+		mt_touch_report(hid, report);
+}
+
 static void mt_set_input_mode(struct hid_device *hdev)
 {
 	struct mt_device *td = hid_get_drvdata(hdev);
@@ -795,32 +856,14 @@ static void mt_post_parse(struct mt_device *td)
 }
 
 static void mt_input_configured(struct hid_device *hdev, struct hid_input *hi)
-
 {
-	struct mt_device *td = hid_get_drvdata(hdev);
-	struct mt_class *cls = &td->mtclass;
 	struct input_dev *input = hi->input;
 
 	/* Only initialize slots for MT input devices */
 	if (!test_bit(ABS_MT_POSITION_X, input->absbit))
 		return;
 
-	if (!td->maxcontacts)
-		td->maxcontacts = MT_DEFAULT_MAXCONTACT;
-
-	mt_post_parse(td);
-	if (td->serial_maybe)
-		mt_post_parse_default_settings(td);
-
-	if (cls->is_indirect)
-		td->mt_flags |= INPUT_MT_POINTER;
-
-	if (cls->quirks & MT_QUIRK_NOT_SEEN_MEANS_UP)
-		td->mt_flags |= INPUT_MT_DROP_UNUSED;
-
-	input_mt_init_slots(input, td->maxcontacts, td->mt_flags);
-
-	td->mt_flags = 0;
+	mt_touch_input_configured(hdev, hi);
 }
 
 static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id)
-- 
1.8.1.4


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

* [PATCH v2 3/7] HID: multitouch: do not map usage from non used reports
  2013-03-22 17:38 [PATCH v2 0/7] HID: multitouch: support of hybrid finger/pen devices Benjamin Tissoires
  2013-03-22 17:38 ` [PATCH v2 1/7] HID: input: don't register unmapped input devices Benjamin Tissoires
  2013-03-22 17:38 ` [PATCH v2 2/7] HID: multitouch: breaks out touch handling in specific functions Benjamin Tissoires
@ 2013-03-22 17:38 ` Benjamin Tissoires
  2013-03-22 17:38 ` [PATCH v2 4/7] HID: multitouch: change touch sensor detection in mt_input_configured() Benjamin Tissoires
                   ` (4 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Benjamin Tissoires @ 2013-03-22 17:38 UTC (permalink / raw)
  To: Henrik Rydberg, Jiri Kosina, Stephane Chatty, linux-input,
	linux-kernel

hid-multitouch only handles touch events, so there is no point in
mapping other kind of events.

Signed-off-by: Benjamin Tissoires <benjamin.tissoires@redhat.com>
---
 drivers/hid/hid-multitouch.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c
index 35b6025..611c88cb 100644
--- a/drivers/hid/hid-multitouch.c
+++ b/drivers/hid/hid-multitouch.c
@@ -741,7 +741,7 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi,
 	* such as Mouse that might have the same GenericDesktop usages. */
 	if (field->application != HID_DG_TOUCHSCREEN &&
 	    field->application != HID_DG_TOUCHPAD)
-		return 0;
+		return -1;
 
 	/* eGalax devices provide a Digitizer.Stylus input which overrides
 	 * the correct Digitizers.Finger X/Y ranges.
-- 
1.8.1.4

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

* [PATCH v2 4/7] HID: multitouch: change touch sensor detection in mt_input_configured()
  2013-03-22 17:38 [PATCH v2 0/7] HID: multitouch: support of hybrid finger/pen devices Benjamin Tissoires
                   ` (2 preceding siblings ...)
  2013-03-22 17:38 ` [PATCH v2 3/7] HID: multitouch: do not map usage from non used reports Benjamin Tissoires
@ 2013-03-22 17:38 ` Benjamin Tissoires
  2013-03-22 17:38 ` [PATCH v2 5/7] HID: multitouch: add handling for pen in dual-sensors device Benjamin Tissoires
                   ` (3 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Benjamin Tissoires @ 2013-03-22 17:38 UTC (permalink / raw)
  To: Henrik Rydberg, Jiri Kosina, Stephane Chatty, linux-input,
	linux-kernel

To implement different methods for pen and touch, the previous
implementation has to be reworked.

This detection of the input attached to the touch sensor is the same
than the one used in mt_report().

Signed-off-by: Benjamin Tissoires <benjamin.tissoires@redhat.com>
---
 drivers/hid/hid-multitouch.c | 9 +++------
 1 file changed, 3 insertions(+), 6 deletions(-)

diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c
index 611c88cb..6a934de 100644
--- a/drivers/hid/hid-multitouch.c
+++ b/drivers/hid/hid-multitouch.c
@@ -857,13 +857,10 @@ static void mt_post_parse(struct mt_device *td)
 
 static void mt_input_configured(struct hid_device *hdev, struct hid_input *hi)
 {
-	struct input_dev *input = hi->input;
-
-	/* Only initialize slots for MT input devices */
-	if (!test_bit(ABS_MT_POSITION_X, input->absbit))
-		return;
+	struct mt_device *td = hid_get_drvdata(hdev);
 
-	mt_touch_input_configured(hdev, hi);
+	if (hi->report->id == td->mt_report_id)
+		mt_touch_input_configured(hdev, hi);
 }
 
 static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id)
-- 
1.8.1.4

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

* [PATCH v2 5/7] HID: multitouch: add handling for pen in dual-sensors device
  2013-03-22 17:38 [PATCH v2 0/7] HID: multitouch: support of hybrid finger/pen devices Benjamin Tissoires
                   ` (3 preceding siblings ...)
  2013-03-22 17:38 ` [PATCH v2 4/7] HID: multitouch: change touch sensor detection in mt_input_configured() Benjamin Tissoires
@ 2013-03-22 17:38 ` Benjamin Tissoires
  2013-03-22 17:38 ` [PATCH v2 6/7] HID: multitouch: append " Pen" to the name of the stylus input Benjamin Tissoires
                   ` (2 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Benjamin Tissoires @ 2013-03-22 17:38 UTC (permalink / raw)
  To: Henrik Rydberg, Jiri Kosina, Stephane Chatty, linux-input,
	linux-kernel

Dual sensors devices reports pen and touch on two different reports.
Using the quirk HID_QUIRK_MULTI_INPUT allows us to create a new input
device to forward pen events.

The quirk HID_QUIRK_NO_EMPTY_INPUT avoids the creation of input devices
for the not used mouse emulation present on Win7 certified devices.

Since hid-multitouch sets the quirk HID_QUIRK_NO_INPUT_SYNC, we need
to manually send SYN events for pen report too.

Signed-off-by: Benjamin Tissoires <benjamin.tissoires@redhat.com>
---
 drivers/hid/hid-multitouch.c | 66 +++++++++++++++++++++++++++++++++++++++++---
 1 file changed, 62 insertions(+), 4 deletions(-)

diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c
index 6a934de..099a7ad 100644
--- a/drivers/hid/hid-multitouch.c
+++ b/drivers/hid/hid-multitouch.c
@@ -99,6 +99,7 @@ struct mt_device {
 	int cc_value_index;	/* contact count value index in the field */
 	unsigned last_slot_field;	/* the last field of a slot */
 	unsigned mt_report_id;	/* the report ID of the multitouch device */
+	unsigned pen_report_id;	/* the report ID of the pen device */
 	__s8 inputmode;		/* InputMode HID feature, -1 if non-existent */
 	__s8 inputmode_index;	/* InputMode HID feature index in the report */
 	__s8 maxcontact_report_id;	/* Maximum Contact Number HID feature,
@@ -367,6 +368,43 @@ static void mt_store_field(struct hid_usage *usage, struct mt_device *td,
 	f->usages[f->length++] = usage->hid;
 }
 
+static int mt_pen_input_mapping(struct hid_device *hdev, struct hid_input *hi,
+		struct hid_field *field, struct hid_usage *usage,
+		unsigned long **bit, int *max)
+{
+	struct mt_device *td = hid_get_drvdata(hdev);
+
+	td->pen_report_id = field->report->id;
+
+	return 0;
+}
+
+static int mt_pen_input_mapped(struct hid_device *hdev, struct hid_input *hi,
+		struct hid_field *field, struct hid_usage *usage,
+		unsigned long **bit, int *max)
+{
+	return 0;
+}
+
+static int mt_pen_event(struct hid_device *hid, struct hid_field *field,
+				struct hid_usage *usage, __s32 value)
+{
+	/* let hid-input handle it */
+	return 0;
+}
+
+static void mt_pen_report(struct hid_device *hid, struct hid_report *report)
+{
+	struct hid_field *field = report->field[0];
+
+	input_sync(field->hidinput->input);
+}
+
+static void mt_pen_input_configured(struct hid_device *hdev,
+					struct hid_input *hi)
+{
+}
+
 static int mt_touch_input_mapping(struct hid_device *hdev, struct hid_input *hi,
 		struct hid_field *field, struct hid_usage *usage,
 		unsigned long **bit, int *max)
@@ -740,14 +778,12 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi,
 	* We need to ignore fields that belong to other collections
 	* such as Mouse that might have the same GenericDesktop usages. */
 	if (field->application != HID_DG_TOUCHSCREEN &&
+	    field->application != HID_DG_PEN &&
 	    field->application != HID_DG_TOUCHPAD)
 		return -1;
 
-	/* eGalax devices provide a Digitizer.Stylus input which overrides
-	 * the correct Digitizers.Finger X/Y ranges.
-	 * Let's just ignore this input. */
 	if (field->physical == HID_DG_STYLUS)
-		return -1;
+		return mt_pen_input_mapping(hdev, hi, field, usage, bit, max);
 
 	return mt_touch_input_mapping(hdev, hi, field, usage, bit, max);
 }
@@ -756,6 +792,9 @@ static int mt_input_mapped(struct hid_device *hdev, struct hid_input *hi,
 		struct hid_field *field, struct hid_usage *usage,
 		unsigned long **bit, int *max)
 {
+	if (field->physical == HID_DG_STYLUS)
+		return mt_pen_input_mapped(hdev, hi, field, usage, bit, max);
+
 	return mt_touch_input_mapped(hdev, hi, field, usage, bit, max);
 }
 
@@ -767,6 +806,9 @@ static int mt_event(struct hid_device *hid, struct hid_field *field,
 	if (field->report->id == td->mt_report_id)
 		return mt_touch_event(hid, field, usage, value);
 
+	if (field->report->id == td->pen_report_id)
+		return mt_pen_event(hid, field, usage, value);
+
 	/* ignore other reports */
 	return 1;
 }
@@ -780,6 +822,9 @@ static void mt_report(struct hid_device *hid, struct hid_report *report)
 
 	if (report->id == td->mt_report_id)
 		mt_touch_report(hid, report);
+
+	if (report->id == td->pen_report_id)
+		mt_pen_report(hid, report);
 }
 
 static void mt_set_input_mode(struct hid_device *hdev)
@@ -861,6 +906,9 @@ static void mt_input_configured(struct hid_device *hdev, struct hid_input *hi)
 
 	if (hi->report->id == td->mt_report_id)
 		mt_touch_input_configured(hdev, hi);
+
+	if (hi->report->id == td->pen_report_id)
+		mt_pen_input_configured(hdev, hi);
 }
 
 static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id)
@@ -881,6 +929,14 @@ static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id)
 	 */
 	hdev->quirks |= HID_QUIRK_NO_INPUT_SYNC;
 
+	/*
+	 * This allows the driver to handle different input sensors
+	 * that emits events through different reports on the same HID
+	 * device.
+	 */
+	hdev->quirks |= HID_QUIRK_MULTI_INPUT;
+	hdev->quirks |= HID_QUIRK_NO_EMPTY_INPUT;
+
 	td = kzalloc(sizeof(struct mt_device), GFP_KERNEL);
 	if (!td) {
 		dev_err(&hdev->dev, "cannot allocate multitouch data\n");
@@ -890,6 +946,8 @@ static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id)
 	td->inputmode = -1;
 	td->maxcontact_report_id = -1;
 	td->cc_index = -1;
+	td->mt_report_id = -1;
+	td->pen_report_id = -1;
 	hid_set_drvdata(hdev, td);
 
 	td->fields = kzalloc(sizeof(struct mt_fields), GFP_KERNEL);
-- 
1.8.1.4

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

* [PATCH v2 6/7] HID: multitouch: append " Pen" to the name of the stylus input
  2013-03-22 17:38 [PATCH v2 0/7] HID: multitouch: support of hybrid finger/pen devices Benjamin Tissoires
                   ` (4 preceding siblings ...)
  2013-03-22 17:38 ` [PATCH v2 5/7] HID: multitouch: add handling for pen in dual-sensors device Benjamin Tissoires
@ 2013-03-22 17:38 ` Benjamin Tissoires
  2013-03-22 17:38 ` [PATCH v2 7/7] HID: multitouch: force BTN_STYLUS for pen devices Benjamin Tissoires
  2013-03-27 13:04 ` [PATCH v2 0/7] HID: multitouch: support of hybrid finger/pen devices Jiri Kosina
  7 siblings, 0 replies; 9+ messages in thread
From: Benjamin Tissoires @ 2013-03-22 17:38 UTC (permalink / raw)
  To: Henrik Rydberg, Jiri Kosina, Stephane Chatty, linux-input,
	linux-kernel

This is not just cosmetics, it can help to write udev and X.org
rules.

Signed-off-by: Benjamin Tissoires <benjamin.tissoires@redhat.com>
---
 drivers/hid/hid-multitouch.c | 31 ++++++++++++++++++++++++++++++-
 1 file changed, 30 insertions(+), 1 deletion(-)

diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c
index 099a7ad..5555174 100644
--- a/drivers/hid/hid-multitouch.c
+++ b/drivers/hid/hid-multitouch.c
@@ -44,6 +44,7 @@
 #include <linux/slab.h>
 #include <linux/usb.h>
 #include <linux/input/mt.h>
+#include <linux/string.h>
 
 
 MODULE_AUTHOR("Stephane Chatty <chatty@enac.fr>");
@@ -260,6 +261,14 @@ static struct mt_class mt_classes[] = {
 	{ }
 };
 
+static void mt_free_input_name(struct hid_input *hi)
+{
+	struct hid_device *hdev = hi->report->device;
+
+	if (hi->input->name != hdev->name)
+		kfree(hi->input->name);
+}
+
 static ssize_t mt_show_quirks(struct device *dev,
 			   struct device_attribute *attr,
 			   char *buf)
@@ -403,6 +412,12 @@ static void mt_pen_report(struct hid_device *hid, struct hid_report *report)
 static void mt_pen_input_configured(struct hid_device *hdev,
 					struct hid_input *hi)
 {
+	char *name = kzalloc(strlen(hi->input->name) + 5, GFP_KERNEL);
+	if (name) {
+		sprintf(name, "%s Pen", hi->input->name);
+		mt_free_input_name(hi);
+		hi->input->name = name;
+	}
 }
 
 static int mt_touch_input_mapping(struct hid_device *hdev, struct hid_input *hi,
@@ -903,6 +918,10 @@ static void mt_post_parse(struct mt_device *td)
 static void mt_input_configured(struct hid_device *hdev, struct hid_input *hi)
 {
 	struct mt_device *td = hid_get_drvdata(hdev);
+	char *name = kstrdup(hdev->name, GFP_KERNEL);
+
+	if (name)
+		hi->input->name = name;
 
 	if (hi->report->id == td->mt_report_id)
 		mt_touch_input_configured(hdev, hi);
@@ -916,6 +935,7 @@ static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id)
 	int ret, i;
 	struct mt_device *td;
 	struct mt_class *mtclass = mt_classes; /* MT_CLS_DEFAULT */
+	struct hid_input *hi;
 
 	for (i = 0; mt_classes[i].name ; i++) {
 		if (id->driver_data == mt_classes[i].name) {
@@ -966,7 +986,7 @@ static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id)
 
 	ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT);
 	if (ret)
-		goto fail;
+		goto hid_fail;
 
 	ret = sysfs_create_group(&hdev->dev.kobj, &mt_attribute_group);
 
@@ -978,6 +998,9 @@ static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id)
 
 	return 0;
 
+hid_fail:
+	list_for_each_entry(hi, &hdev->inputs, list)
+		mt_free_input_name(hi);
 fail:
 	kfree(td->fields);
 	kfree(td);
@@ -1007,8 +1030,14 @@ static int mt_resume(struct hid_device *hdev)
 static void mt_remove(struct hid_device *hdev)
 {
 	struct mt_device *td = hid_get_drvdata(hdev);
+	struct hid_input *hi;
+
 	sysfs_remove_group(&hdev->dev.kobj, &mt_attribute_group);
 	hid_hw_stop(hdev);
+
+	list_for_each_entry(hi, &hdev->inputs, list)
+		mt_free_input_name(hi);
+
 	kfree(td);
 	hid_set_drvdata(hdev, NULL);
 }
-- 
1.8.1.4

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

* [PATCH v2 7/7] HID: multitouch: force BTN_STYLUS for pen devices
  2013-03-22 17:38 [PATCH v2 0/7] HID: multitouch: support of hybrid finger/pen devices Benjamin Tissoires
                   ` (5 preceding siblings ...)
  2013-03-22 17:38 ` [PATCH v2 6/7] HID: multitouch: append " Pen" to the name of the stylus input Benjamin Tissoires
@ 2013-03-22 17:38 ` Benjamin Tissoires
  2013-03-27 13:04 ` [PATCH v2 0/7] HID: multitouch: support of hybrid finger/pen devices Jiri Kosina
  7 siblings, 0 replies; 9+ messages in thread
From: Benjamin Tissoires @ 2013-03-22 17:38 UTC (permalink / raw)
  To: Henrik Rydberg, Jiri Kosina, Stephane Chatty, linux-input,
	linux-kernel

The "tablet" udev rule relies on BTN_STYLUS to be set.

Signed-off-by: Benjamin Tissoires <benjamin.tissoires@redhat.com>
---
 drivers/hid/hid-multitouch.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c
index 5555174..aceaf6c 100644
--- a/drivers/hid/hid-multitouch.c
+++ b/drivers/hid/hid-multitouch.c
@@ -418,6 +418,9 @@ static void mt_pen_input_configured(struct hid_device *hdev,
 		mt_free_input_name(hi);
 		hi->input->name = name;
 	}
+
+	/* force BTN_STYLUS to allow tablet matching in udev */
+	__set_bit(BTN_STYLUS, hi->input->keybit);
 }
 
 static int mt_touch_input_mapping(struct hid_device *hdev, struct hid_input *hi,
-- 
1.8.1.4

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

* Re: [PATCH v2 0/7] HID: multitouch: support of hybrid finger/pen devices
  2013-03-22 17:38 [PATCH v2 0/7] HID: multitouch: support of hybrid finger/pen devices Benjamin Tissoires
                   ` (6 preceding siblings ...)
  2013-03-22 17:38 ` [PATCH v2 7/7] HID: multitouch: force BTN_STYLUS for pen devices Benjamin Tissoires
@ 2013-03-27 13:04 ` Jiri Kosina
  7 siblings, 0 replies; 9+ messages in thread
From: Jiri Kosina @ 2013-03-27 13:04 UTC (permalink / raw)
  To: Benjamin Tissoires
  Cc: Henrik Rydberg, Stephane Chatty, linux-input, linux-kernel

On Fri, 22 Mar 2013, Benjamin Tissoires wrote:

> Hi Guys,
> 
> this is the second iteration of the support of dual sensors (pen + touch)
> devices.
> 
> There has not been a lot of changes since v1:
> - use " |= " instead of " = r || " in patch 1
> - introduce a factorization of input_configured() in patch 2 (which makes more sense
> IMO)
> - patch 4 is new, but the change is quite small (again, tested on my database)
> - patch 6 has been reworked, though it's not clear if it's better
> - patch 7 has been reworked, the set_bit occurs now in input_configured()

I have now applied the series for 3.10. Thanks.

-- 
Jiri Kosina
SUSE Labs

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

end of thread, other threads:[~2013-03-27 13:04 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-03-22 17:38 [PATCH v2 0/7] HID: multitouch: support of hybrid finger/pen devices Benjamin Tissoires
2013-03-22 17:38 ` [PATCH v2 1/7] HID: input: don't register unmapped input devices Benjamin Tissoires
2013-03-22 17:38 ` [PATCH v2 2/7] HID: multitouch: breaks out touch handling in specific functions Benjamin Tissoires
2013-03-22 17:38 ` [PATCH v2 3/7] HID: multitouch: do not map usage from non used reports Benjamin Tissoires
2013-03-22 17:38 ` [PATCH v2 4/7] HID: multitouch: change touch sensor detection in mt_input_configured() Benjamin Tissoires
2013-03-22 17:38 ` [PATCH v2 5/7] HID: multitouch: add handling for pen in dual-sensors device Benjamin Tissoires
2013-03-22 17:38 ` [PATCH v2 6/7] HID: multitouch: append " Pen" to the name of the stylus input Benjamin Tissoires
2013-03-22 17:38 ` [PATCH v2 7/7] HID: multitouch: force BTN_STYLUS for pen devices Benjamin Tissoires
2013-03-27 13:04 ` [PATCH v2 0/7] HID: multitouch: support of hybrid finger/pen devices 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).