From patchwork Wed Nov 14 15:59:24 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Benjamin Tissoires X-Patchwork-Id: 1742161 X-Patchwork-Delegate: jikos@jikos.cz Return-Path: X-Original-To: patchwork-linux-input@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork1.kernel.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by patchwork1.kernel.org (Postfix) with ESMTP id 434693FE20 for ; Wed, 14 Nov 2012 16:00:50 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1423069Ab2KNQAB (ORCPT ); Wed, 14 Nov 2012 11:00:01 -0500 Received: from mail-wi0-f172.google.com ([209.85.212.172]:38882 "EHLO mail-wi0-f172.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1423059Ab2KNP77 (ORCPT ); Wed, 14 Nov 2012 10:59:59 -0500 Received: by mail-wi0-f172.google.com with SMTP id hj6so622577wib.1 for ; Wed, 14 Nov 2012 07:59:58 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=from:to:subject:date:message-id:x-mailer:in-reply-to:references; bh=GI1RakNWhpanh41Bj4P4RR8s/ee2i2XltJNQ+BTfTaw=; b=meZHOpVrTwl4GTNHMh9sS+zT+xazhheDTstlFDDx3PWVBbK7Wekgb/spTHQ7+fTGRW ny+m2p3tWyFmcKbeAgRDN0mNRHWnRrJDA8cIKcK2kWdixwaiwlxwOSpgcXkbAXPArgjh kpnkm6eL4gqn8iwtMRh7gJ+Dv2QHMz10gM0SZBdSC5yqLIyRAPHooVGqQNF67a1gOv7E 14UYRCvp9ldVko4wgaJ5NsNWzGaG+3193iIKElEN+0baGJaHxXILfnzBBvxXdO+P7IU4 ujSnZbBkC3IDhmix2cZYiVQkz0+hL3urIFsn6YyzEOfebObs7rEEX0r8XbbsBm/2GNKE tzVQ== Received: by 10.180.94.169 with SMTP id dd9mr26773557wib.14.1352908798470; Wed, 14 Nov 2012 07:59:58 -0800 (PST) Received: from localhost.localdomain.com (lan31-8-82-247-176-67.fbx.proxad.net. [82.247.176.67]) by mx.google.com with ESMTPS id r10sm3050116wiz.0.2012.11.14.07.59.56 (version=TLSv1/SSLv3 cipher=OTHER); Wed, 14 Nov 2012 07:59:57 -0800 (PST) From: Benjamin Tissoires To: "benjamin.tissoires" , Dmitry Torokhov , Henrik Rydberg , Jiri Kosina , Stephane Chatty , linux-input@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v4 12/14] HID: hid-multitouch: support for hovering devices Date: Wed, 14 Nov 2012 16:59:24 +0100 Message-Id: <1352908766-4492-13-git-send-email-benjamin.tissoires@gmail.com> X-Mailer: git-send-email 1.8.0 In-Reply-To: <1352908766-4492-1-git-send-email-benjamin.tissoires@gmail.com> References: <1352908766-4492-1-git-send-email-benjamin.tissoires@gmail.com> Sender: linux-input-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-input@vger.kernel.org Win8 devices supporting hovering must provides InRange HID field. The information that the finger is here but is not touching the surface is sent to the user space through ABS_MT_DISTANCE as required by the multitouch protocol. Signed-off-by: Benjamin Tissoires --- drivers/hid/hid-multitouch.c | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c index c5b81a7..5f26b2f 100644 --- a/drivers/hid/hid-multitouch.c +++ b/drivers/hid/hid-multitouch.c @@ -53,11 +53,13 @@ MODULE_LICENSE("GPL"); #define MT_QUIRK_SLOT_IS_CONTACTID_MINUS_ONE (1 << 8) #define MT_QUIRK_NO_AREA (1 << 9) #define MT_QUIRK_IGNORE_DUPLICATES (1 << 10) +#define MT_QUIRK_HOVERING (1 << 11) struct mt_slot { __s32 x, y, cx, cy, p, w, h; __s32 contactid; /* the device ContactID assigned to this slot */ bool touch_state; /* is the touch valid? */ + bool inrange_state; /* is the finger in proximity of the sensor? */ }; struct mt_class { @@ -392,6 +394,12 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi, case HID_UP_DIGITIZER: switch (usage->hid) { case HID_DG_INRANGE: + if (cls->quirks & MT_QUIRK_HOVERING) { + hid_map_usage(hi, usage, bit, max, + EV_ABS, ABS_MT_DISTANCE); + input_set_abs_params(hi->input, + ABS_MT_DISTANCE, 0, 1, 0, 0); + } mt_store_field(usage, td, hi); td->last_field_index = field->index; return 1; @@ -521,9 +529,9 @@ static void mt_complete_slot(struct mt_device *td, struct input_dev *input) input_mt_slot(input, slotnum); input_mt_report_slot_state(input, MT_TOOL_FINGER, - s->touch_state); - if (s->touch_state) { - /* this finger is on the screen */ + s->touch_state || s->inrange_state); + if (s->touch_state || s->inrange_state) { + /* this finger is in proximity of the sensor */ int wide = (s->w > s->h); /* divided by two to match visual scale of touch */ int major = max(s->w, s->h) >> 1; @@ -533,6 +541,8 @@ static void mt_complete_slot(struct mt_device *td, struct input_dev *input) input_event(input, EV_ABS, ABS_MT_POSITION_Y, s->y); input_event(input, EV_ABS, ABS_MT_TOOL_X, s->cx); input_event(input, EV_ABS, ABS_MT_TOOL_Y, s->cy); + input_event(input, EV_ABS, ABS_MT_DISTANCE, + !s->touch_state); input_event(input, EV_ABS, ABS_MT_ORIENTATION, wide); input_event(input, EV_ABS, ABS_MT_PRESSURE, s->p); input_event(input, EV_ABS, ABS_MT_TOUCH_MAJOR, major); @@ -565,6 +575,8 @@ static int mt_event(struct hid_device *hid, struct hid_field *field, case HID_DG_INRANGE: if (quirks & MT_QUIRK_VALID_IS_INRANGE) td->curvalid = value; + if (quirks & MT_QUIRK_HOVERING) + td->curdata.inrange_state = value; break; case HID_DG_TIPSWITCH: if (quirks & MT_QUIRK_NOT_SEEN_MEANS_UP)