From patchwork Fri Oct 26 08:44:25 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Benjamin Tissoires X-Patchwork-Id: 1650271 X-Patchwork-Delegate: jikos@jikos.cz Return-Path: X-Original-To: patchwork-linux-input@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork2.kernel.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by patchwork2.kernel.org (Postfix) with ESMTP id BBF01DF2F6 for ; Fri, 26 Oct 2012 08:48:07 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1757491Ab2JZIpE (ORCPT ); Fri, 26 Oct 2012 04:45:04 -0400 Received: from mail-wi0-f172.google.com ([209.85.212.172]:64066 "EHLO mail-wi0-f172.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1757420Ab2JZIos (ORCPT ); Fri, 26 Oct 2012 04:44:48 -0400 Received: by mail-wi0-f172.google.com with SMTP id hq12so225506wib.1 for ; Fri, 26 Oct 2012 01:44:47 -0700 (PDT) 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=gBqpmWKCB9kTfzCDNX9zspl6hk+Y55EElqTcntTtQxg=; b=FNMc0DnlLyy5r/Ryc7JxrFJtbufEiPzIdIVGVSXwZLdufYdbuArpUUzJ7f2P9dhVBO VZMnf1oA6I/jCRHQKIaXisUz3zQGfMQaQUsxhS6hrLMvu5wCEivtW72p/OnEKdffatJJ rtz8Hl/laqv7Gn4hgt5PT2QXttX87Y3enPkJ+15Vi8hEWbV649WvPV4PneIhbNfLylQ9 RzhKjzDULA3uFY5C5o3GqvZ94yHzaz3Tn7P1Yx0kJqQwedhnpffrtVw564XKYq9VIdo2 DdcQktyOLTBaB1zasM3dHKNjXQ5KbMlBdzFMl7LVYLpzEnAy96dyjq6fVg/ReJJSm03u 8EZQ== Received: by 10.180.104.97 with SMTP id gd1mr3596609wib.4.1351241087867; Fri, 26 Oct 2012 01:44:47 -0700 (PDT) Received: from miniplouf.lan (lan31-8-82-247-176-67.fbx.proxad.net. [82.247.176.67]) by mx.google.com with ESMTPS id dq6sm14151586wib.5.2012.10.26.01.44.46 (version=TLSv1/SSLv3 cipher=OTHER); Fri, 26 Oct 2012 01:44:47 -0700 (PDT) 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 v2 09/11] HID: hid-multitouch: support for hovering devices Date: Fri, 26 Oct 2012 10:44:25 +0200 Message-Id: <1351241067-9521-10-git-send-email-benjamin.tissoires@gmail.com> X-Mailer: git-send-email 1.7.11.7 In-Reply-To: <1351241067-9521-1-git-send-email-benjamin.tissoires@gmail.com> References: <1351241067-9521-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 | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c index bd23f19..c0ab1c6 100644 --- a/drivers/hid/hid-multitouch.c +++ b/drivers/hid/hid-multitouch.c @@ -55,7 +55,7 @@ MODULE_LICENSE("GPL"); #define MT_QUIRK_WIN_8_CERTIFIED (1 << 10) struct mt_slot { - __s32 x, y, cx, cy, p, w, h; + __s32 x, y, cx, cy, z, p, w, h; __s32 contactid; /* the device ContactID assigned to this slot */ bool touch_state; /* is the touch valid? */ }; @@ -394,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_WIN_8_CERTIFIED) { + 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; @@ -511,6 +517,11 @@ static void mt_complete_slot(struct mt_device *td, struct input_dev *input) struct mt_slot *s = &td->curdata; if (td->mtclass.quirks & MT_QUIRK_WIN_8_CERTIFIED && + !test_bit(ABS_MT_DISTANCE, input->absbit)) + /* If InRange is not present, rely on TipSwitch */ + s->touch_state = !s->z; + + if (td->mtclass.quirks & MT_QUIRK_WIN_8_CERTIFIED && !s->touch_state) { struct input_mt_slot *slot = &input->mt->slots[slotnum]; int prv_x = input_mt_get_value(slot, ABS_MT_POSITION_X); @@ -543,6 +554,7 @@ static void mt_complete_slot(struct mt_device *td, struct input_dev *input) input_event(input, EV_ABS, ABS_MT_TOOL_Y, s->cy); } + input_event(input, EV_ABS, ABS_MT_DISTANCE, s->z); 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); @@ -575,11 +587,16 @@ 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_WIN_8_CERTIFIED) + td->curdata.touch_state = value; break; case HID_DG_TIPSWITCH: if (quirks & MT_QUIRK_NOT_SEEN_MEANS_UP) td->curvalid = value; - td->curdata.touch_state = value; + if (quirks & MT_QUIRK_WIN_8_CERTIFIED) + td->curdata.z = !value; + else + td->curdata.touch_state = value; break; case HID_DG_CONFIDENCE: if (quirks & MT_QUIRK_VALID_IS_CONFIDENCE)