2012-02-04 16:09:07

by Benjamin Tissoires

[permalink] [raw]
Subject: [patch v3 0/3] Support of Perixx Peripad 701 for hid-multitouch

Hi Guys,

This is the v3 of the support of Perixx Peripad 701.

I included the changes asked by Henrik & Dmitry:
- code = ((usage->hid - 1) & HID_USAGE) + BTN_MOUSE;
+ code = BTN_MOUSE + ((usage->hid - 1) & HID_USAGE);
use of min;
remove remove the call to input_mt_report_finger_count;
remove debug information;
some cosmetic changes (parenthesis, typos)

Cheers,
Benjamin


2012-02-04 16:09:09

by Benjamin Tissoires

[permalink] [raw]
Subject: [PATCH v3 2/3] HID: multitouch: add control of the feature "Maximum Contact Number"

From: Benjamin Tissoires <[email protected]>

Some devices, like Perixx Peripad 701 do not work if the feature
"Maximum Contact Number" is not set to the right value.
This patch allows hid-multitouch to control this feature.

If the programmer fills the field maxcontacts in the mt_class,
then the driver will set the feature to this value. It is safe
for current drivers as the feature is read/write in the HID norm
and all devices should implement the norm.

Signed-off-by: Benjamin Tissoires <[email protected]>
---
drivers/hid/hid-multitouch.c | 32 ++++++++++++++++++++++++++++++++
1 files changed, 32 insertions(+), 0 deletions(-)

diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c
index 4c69749..825759e 100644
--- a/drivers/hid/hid-multitouch.c
+++ b/drivers/hid/hid-multitouch.c
@@ -77,6 +77,8 @@ struct mt_device {
unsigned last_slot_field; /* the last field of a slot */
int last_mt_collection; /* last known mt-related collection */
__s8 inputmode; /* InputMode HID feature, -1 if non-existent */
+ __s8 maxcontact_report_id; /* Maximum Contact Number HID feature,
+ -1 if non-existent */
__u8 num_received; /* how many contacts we received */
__u8 num_expected; /* expected last contact index */
__u8 maxcontacts;
@@ -242,6 +244,7 @@ static void mt_feature_mapping(struct hid_device *hdev,
td->inputmode = field->report->id;
break;
case HID_DG_CONTACTMAX:
+ td->maxcontact_report_id = field->report->id;
td->maxcontacts = field->value[0];
if (td->mtclass.maxcontacts)
/* check if the maxcontacts is given by the class */
@@ -606,6 +609,32 @@ static void mt_set_input_mode(struct hid_device *hdev)
}
}

+static void mt_set_maxcontacts(struct hid_device *hdev)
+{
+ struct mt_device *td = hid_get_drvdata(hdev);
+ struct hid_report *r;
+ struct hid_report_enum *re;
+ int fieldmax, max;
+
+ if (td->maxcontact_report_id < 0)
+ return;
+
+ if (!td->mtclass.maxcontacts)
+ return;
+
+ re = &hdev->report_enum[HID_FEATURE_REPORT];
+ r = re->report_id_hash[td->maxcontact_report_id];
+ if (r) {
+ max = td->mtclass.maxcontacts;
+ fieldmax = r->field[0]->logical_maximum;
+ max = min(fieldmax, max);
+ if (r->field[0]->value[0] != max) {
+ r->field[0]->value[0] = max;
+ usbhid_submit_report(hdev, r, USB_DIR_OUT);
+ }
+ }
+}
+
static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id)
{
int ret, i;
@@ -631,6 +660,7 @@ static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id)
}
td->mtclass = *mtclass;
td->inputmode = -1;
+ td->maxcontact_report_id = -1;
td->last_mt_collection = -1;
hid_set_drvdata(hdev, td);

@@ -653,6 +683,7 @@ static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id)

ret = sysfs_create_group(&hdev->dev.kobj, &mt_attribute_group);

+ mt_set_maxcontacts(hdev);
mt_set_input_mode(hdev);

return 0;
@@ -665,6 +696,7 @@ fail:
#ifdef CONFIG_PM
static int mt_reset_resume(struct hid_device *hdev)
{
+ mt_set_maxcontacts(hdev);
mt_set_input_mode(hdev);
return 0;
}
--
1.7.7.6

2012-02-04 16:09:13

by Benjamin Tissoires

[permalink] [raw]
Subject: [PATCH v3 3/3] HID: multitouch: support Perixx PERIPAD 701

From: Benjamin Tissoires <[email protected]>

Perixx Peripad 701 is an hybrid device which presents a touchpad and
a keyboard on the same surface. The switch between the two is controlled
by a physical switch, and the firmware sends the events on the right
interface (mouse, keyboard or multitouch).
This patch enables the multitouch interface of this device to work.

We need to manually set the device as a trackpad (we cannot infer it
from the reports descriptors as the device works under Windows, a system
that does not allow multitouch touchpad).
We also need to set the hid feature MAX CONTACT NUMBER to 2 or the device
stops sending events once it has been pressed by two touches.

Signed-off-by: Benjamin Tissoires <[email protected]>
---
drivers/hid/Kconfig | 1 +
drivers/hid/hid-ids.h | 1 +
drivers/hid/hid-multitouch.c | 11 +++++++++++
3 files changed, 13 insertions(+), 0 deletions(-)

diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig
index a421abd..f7c43b6 100644
--- a/drivers/hid/Kconfig
+++ b/drivers/hid/Kconfig
@@ -355,6 +355,7 @@ config HID_MULTITOUCH
- Lumio CrystalTouch panels
- MosArt dual-touch panels
- PenMount dual touch panels
+ - Perixx Peripad 701 touchpad
- PixArt optical touch screen
- Pixcir dual touch panels
- Quanta panels
diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h
index fb9e61f..de89df5 100644
--- a/drivers/hid/hid-ids.h
+++ b/drivers/hid/hid-ids.h
@@ -660,6 +660,7 @@

#define USB_VENDOR_ID_TOPSEED2 0x1784
#define USB_DEVICE_ID_TOPSEED2_RF_COMBO 0x0004
+#define USB_DEVICE_ID_TOPSEED2_PERIPAD_701 0x0016

#define USB_VENDOR_ID_TOPMAX 0x0663
#define USB_DEVICE_ID_TOPMAX_COBRAPAD 0x0103
diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c
index 825759e..443e0a9 100644
--- a/drivers/hid/hid-multitouch.c
+++ b/drivers/hid/hid-multitouch.c
@@ -103,6 +103,7 @@ struct mt_device {
#define MT_CLS_CYPRESS 0x0102
#define MT_CLS_EGALAX 0x0103
#define MT_CLS_EGALAX_SERIAL 0x0104
+#define MT_CLS_TOPSEED 0x0105

#define MT_DEFAULT_MAXCONTACT 10

@@ -192,6 +193,11 @@ static struct mt_class mt_classes[] = {
.sn_move = 4096,
.sn_pressure = 32,
},
+ { .name = MT_CLS_TOPSEED,
+ .quirks = MT_QUIRK_ALWAYS_VALID,
+ .is_indirect = true,
+ .maxcontacts = 2,
+ },

{ }
};
@@ -897,6 +903,11 @@ static const struct hid_device_id mt_devices[] = {
HID_USB_DEVICE(USB_VENDOR_ID_STANTUM_SITRONIX,
USB_DEVICE_ID_MTP_SITRONIX)},

+ /* TopSeed panels */
+ { .driver_data = MT_CLS_TOPSEED,
+ HID_USB_DEVICE(USB_VENDOR_ID_TOPSEED2,
+ USB_DEVICE_ID_TOPSEED2_PERIPAD_701) },
+
/* Touch International panels */
{ .driver_data = MT_CLS_DEFAULT,
HID_USB_DEVICE(USB_VENDOR_ID_TOUCH_INTL,
--
1.7.7.6

2012-02-04 16:09:46

by Benjamin Tissoires

[permalink] [raw]
Subject: [PATCH v3 1/3] HID: multitouch: add support for trackpads

From: Benjamin Tissoires <[email protected]>

* some multitouch trackpads present the touch usage. This needs to be
filtered as it will conflict with mt-implementation.
* trackpads send BTN_TOOL_* to notify how many fingers are present
(this is used by xorg to use synaptics instead of generic evdev)
* trackpads like Perixx 701 are not different from a hid point of view
from a touchscreen, and we need to manually set them as touchpad.

Signed-off-by: Benjamin Tissoires <[email protected]>
---
drivers/hid/hid-multitouch.c | 40 ++++++++++++++++++++++++++++++++++------
1 files changed, 34 insertions(+), 6 deletions(-)

diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c
index 24fc442..4c69749 100644
--- a/drivers/hid/hid-multitouch.c
+++ b/drivers/hid/hid-multitouch.c
@@ -1,9 +1,9 @@
/*
* HID driver for multitouch panels
*
- * Copyright (c) 2010-2011 Stephane Chatty <[email protected]>
- * Copyright (c) 2010-2011 Benjamin Tissoires <[email protected]>
- * Copyright (c) 2010-2011 Ecole Nationale de l'Aviation Civile, France
+ * Copyright (c) 2010-2012 Stephane Chatty <[email protected]>
+ * Copyright (c) 2010-2012 Benjamin Tissoires <[email protected]>
+ * Copyright (c) 2010-2012 Ecole Nationale de l'Aviation Civile, France
*
* This code is partly based on hid-egalax.c:
*
@@ -67,6 +67,7 @@ struct mt_class {
__s32 sn_height; /* Signal/noise ratio for height events */
__s32 sn_pressure; /* Signal/noise ratio for pressure events */
__u8 maxcontacts;
+ bool is_indirect; /* true for touchpads */
};

struct mt_device {
@@ -265,17 +266,31 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi,
{
struct mt_device *td = hid_get_drvdata(hdev);
struct mt_class *cls = &td->mtclass;
+ int code;

/* 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)
set_bit(INPUT_PROP_DIRECT, hi->input->propbit);
- else if (field->application == HID_DG_TOUCHPAD)
- set_bit(INPUT_PROP_POINTER, hi->input->propbit);
- else
+ else if (field->application != HID_DG_TOUCHPAD)
return 0;

+ /* In case of an indirect device (touchpad), we need to add
+ * specific BTN_TOOL_* to be handled by the synaptics xorg
+ * driver.
+ * We also consider that touchscreens providing buttons are touchpads.
+ */
+ if (field->application == HID_DG_TOUCHPAD ||
+ (usage->hid & HID_USAGE_PAGE) == HID_UP_BUTTON ||
+ cls->is_indirect) {
+ set_bit(INPUT_PROP_POINTER, hi->input->propbit);
+ set_bit(BTN_TOOL_FINGER, hi->input->keybit);
+ set_bit(BTN_TOOL_DOUBLETAP, hi->input->keybit);
+ set_bit(BTN_TOOL_TRIPLETAP, hi->input->keybit);
+ set_bit(BTN_TOOL_QUADTAP, hi->input->keybit);
+ }
+
/* eGalax devices provide a Digitizer.Stylus input which overrides
* the correct Digitizers.Finger X/Y ranges.
* Let's just ignore this input. */
@@ -389,9 +404,19 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi,
td->last_field_index = field->index;
return -1;
}
+ case HID_DG_TOUCH:
+ /* Legacy devices use TIPSWITCH and not TOUCH.
+ * Let's just ignore this field. */
+ return -1;
/* let hid-input decide for the others */
return 0;

+ case HID_UP_BUTTON:
+ code = BTN_MOUSE + ((usage->hid - 1) & HID_USAGE);
+ hid_map_usage(hi, usage, bit, max, EV_KEY, code);
+ input_set_capability(hi->input, EV_KEY, code);
+ return 1;
+
case 0xff000000:
/* we do not want to map these: no input-oriented meaning */
return -1;
@@ -538,6 +563,9 @@ static int mt_event(struct hid_device *hid, struct hid_field *field,
if (value)
td->num_expected = value;
break;
+ case HID_DG_TOUCH:
+ /* do nothing */
+ break;

default:
/* fallback to the generic hidinput handling */
--
1.7.7.6

2012-02-06 08:37:56

by Henrik Rydberg

[permalink] [raw]
Subject: Re: [patch v3 0/3] Support of Perixx Peripad 701 for hid-multitouch

Hi Benjamin,

> This is the v3 of the support of Perixx Peripad 701.
>
> I included the changes asked by Henrik & Dmitry:
> - code = ((usage->hid - 1) & HID_USAGE) + BTN_MOUSE;
> + code = BTN_MOUSE + ((usage->hid - 1) & HID_USAGE);
> use of min;
> remove remove the call to input_mt_report_finger_count;
> remove debug information;
> some cosmetic changes (parenthesis, typos)

Looking good now, thanks.

Acked-by: Henrik Rydberg <[email protected]>

Henrik

2012-02-06 12:24:05

by Jiri Kosina

[permalink] [raw]
Subject: Re: [patch v3 0/3] Support of Perixx Peripad 701 for hid-multitouch

On Mon, 6 Feb 2012, Henrik Rydberg wrote:

> > This is the v3 of the support of Perixx Peripad 701.
> >
> > I included the changes asked by Henrik & Dmitry:
> > - code = ((usage->hid - 1) & HID_USAGE) + BTN_MOUSE;
> > + code = BTN_MOUSE + ((usage->hid - 1) & HID_USAGE);
> > use of min;
> > remove remove the call to input_mt_report_finger_count;
> > remove debug information;
> > some cosmetic changes (parenthesis, typos)
>
> Looking good now, thanks.
>
> Acked-by: Henrik Rydberg <[email protected]>

I have now applied the patchset. Thanks everybody.

--
Jiri Kosina
SUSE Labs