From patchwork Tue Oct 10 04:16:31 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Wei-Ning Huang X-Patchwork-Id: 9995005 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id BD3E6603FF for ; Tue, 10 Oct 2017 04:16:51 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id A03362656B for ; Tue, 10 Oct 2017 04:16:51 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 93E772684F; Tue, 10 Oct 2017 04:16:51 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.3 required=2.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_HI, RCVD_IN_SORBS_SPAM, T_DKIM_INVALID autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id E43FF1FEBB for ; Tue, 10 Oct 2017 04:16:50 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751596AbdJJEQs (ORCPT ); Tue, 10 Oct 2017 00:16:48 -0400 Received: from mail-pf0-f171.google.com ([209.85.192.171]:52332 "EHLO mail-pf0-f171.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751321AbdJJEQq (ORCPT ); Tue, 10 Oct 2017 00:16:46 -0400 Received: by mail-pf0-f171.google.com with SMTP id a1so12696789pfj.9 for ; Mon, 09 Oct 2017 21:16:46 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=from:to:cc:subject:date:message-id; bh=QI3UTK0x7H7gi4DiCERCVbmB+QdHEuIF8Tx5LClBOjA=; b=IEAelrZbKqKgZGCZt3+QOrAi9wLe/wT9IHHMV0vV2SYEUzw2ioK4TN9n6Fa/ck2ZET Y0aA0IavIeFafX2k95gV7q8uaQfOoA3g9TosI0AYAxsHPtihKpw3Thv2VLoYSWy5aAhx GT0tJIqIcqDKGR7RwqWpoiuk4aQXfp3kBMk34= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id; bh=QI3UTK0x7H7gi4DiCERCVbmB+QdHEuIF8Tx5LClBOjA=; b=SrI2rzWuZLxV2Ta9PJOe3WGIcG97zFmmjw38ERNfe7X0Qzac3pkBo0dLwoypLZkP4r 12aRya1wLhyXZMNhhl3/ytBft7QI5ZLr3FA6MO2Br5PqKf8WRi7JJVWpUDlJJo1dB9nQ 36xf83Xuly0IH3tOCa6CRblWpn9UzBVPg8Fpb7kC700pE/tyPAs0RNvbtU/DpzFo7n40 WW1VbfZlr/hsmcjjjVAEtggj/1FNNFQVcYOQ6EFmY+LsDXvW6CDSKYu4CdPNrvNq30+l k+syNLu8mFguFE2m030ioN4FDnVs2fEn96m9VwQMjVss+IAMMt4mswSYPDPf2WLkH1SK +KGg== X-Gm-Message-State: AMCzsaVDjc1on169q1RyF4vakVflAsDZndXX5Zc5EOszBagrj2JyiyKb LdICzLXA7G0ZpstV8N5ElLbHrQ== X-Google-Smtp-Source: AOwi7QCULtFbOaKQLysQ7btPVb9AteKqwotE08SjaT5zR05JwmPUS/kL+JDKbyCxLLwMHpIDI2pvTQ== X-Received: by 10.98.74.23 with SMTP id x23mr12169161pfa.205.1507609006077; Mon, 09 Oct 2017 21:16:46 -0700 (PDT) Received: from wnhuang0.tpe.corp.google.com ([2401:fa00:1:b:d826:2c5f:5c68:68b1]) by smtp.gmail.com with ESMTPSA id k11sm18272801pfh.134.2017.10.09.21.16.43 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 09 Oct 2017 21:16:45 -0700 (PDT) From: Wei-Ning Huang X-Google-Original-From: Wei-Ning Huang To: LKML , Linux Input Cc: Dmitry Torokhov , Jiri Kosina , Benjamin Tissoires , Wei-Ning Huang , Henrik Rydberg Subject: [PATCH v4] HID: hid-multitouch: support fine-grain orientation reporting Date: Tue, 10 Oct 2017 12:16:31 +0800 Message-Id: <20171010041631.22093-1-wnhuang@google.com> X-Mailer: git-send-email 2.12.2 Sender: linux-input-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-input@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Wei-Ning Huang The current hid-multitouch driver only allow the report of two orientations, vertical and horizontal. We use the Azimuth orientation usage 0x3F under the Digitizer usage page to report orientation if the device supports it. Changelog: v1 -> v2: - Fix commit message. - Remove resolution reporting for ABS_MT_ORIENTATION. v2 -> v3: - Fix commit message. v3 -> v4: - Fix ABS_MT_ORIENTATION ABS param range. - Don't set ABS_MT_ORIENTATION in ABS_DG_HEIGHT when it is already set by ABS_DG_AZIMUTH. Signed-off-by: Wei-Ning Huang Reviewed-by: Dmitry Torokhov Acked-by: Henrik Rydberg Reviewed-by: Benjamin Tissoires --- drivers/hid/hid-multitouch.c | 52 ++++++++++++++++++++++++++++++++++++++++---- include/linux/hid.h | 1 + 2 files changed, 49 insertions(+), 4 deletions(-) diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c index 440b999304a5..3317dae64ef7 100644 --- a/drivers/hid/hid-multitouch.c +++ b/drivers/hid/hid-multitouch.c @@ -84,11 +84,12 @@ MODULE_LICENSE("GPL"); #define MT_IO_FLAGS_PENDING_SLOTS 2 struct mt_slot { - __s32 x, y, cx, cy, p, w, h; + __s32 x, y, cx, cy, p, w, h, a; __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? */ bool confidence_state; /* is the touch made by a finger? */ + bool has_azimuth; /* the contact reports azimuth */ }; struct mt_class { @@ -571,8 +572,15 @@ static int mt_touch_input_mapping(struct hid_device *hdev, struct hid_input *hi, if (!(cls->quirks & MT_QUIRK_NO_AREA)) { set_abs(hi->input, ABS_MT_TOUCH_MINOR, field, cls->sn_height); - input_set_abs_params(hi->input, - ABS_MT_ORIENTATION, 0, 1, 0, 0); + + /* + * Only set ABS_MT_ORIENTATION if it is not + * already set by the HID_DG_AZIMUTH usage. + */ + if (!test_bit(ABS_MT_ORIENTATION, + hi->input->absbit)) + input_set_abs_params(hi->input, + ABS_MT_ORIENTATION, 0, 1, 0, 0); } mt_store_field(usage, td, hi); return 1; @@ -591,6 +599,21 @@ static int mt_touch_input_mapping(struct hid_device *hdev, struct hid_input *hi, td->cc_index = field->index; td->cc_value_index = usage->usage_index; return 1; + case HID_DG_AZIMUTH: + hid_map_usage(hi, usage, bit, max, + EV_ABS, ABS_MT_ORIENTATION); + /* + * Azimuth has the range of [0, MAX) representing a full + * revolution. Set ABS_MT_ORIENTATION to a quarter of + * MAX according the definition of ABS_MT_ORIENTATION + */ + input_set_abs_params(hi->input, ABS_MT_ORIENTATION, + -field->logical_maximum / 4, + field->logical_maximum / 4, + cls->sn_move ? + field->logical_maximum / cls->sn_move : 0, 0); + mt_store_field(usage, td, hi); + return 1; case HID_DG_CONTACTMAX: /* we don't set td->last_slot_field as contactcount and * contact max are global to the report */ @@ -683,6 +706,10 @@ static void mt_complete_slot(struct mt_device *td, struct input_dev *input) int wide = (s->w > s->h); int major = max(s->w, s->h); int minor = min(s->w, s->h); + int orientation = wide; + + if (s->has_azimuth) + orientation = s->a; /* * divided by two to match visual scale of touch @@ -699,7 +726,8 @@ 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->touch_state); - input_event(input, EV_ABS, ABS_MT_ORIENTATION, wide); + input_event(input, EV_ABS, ABS_MT_ORIENTATION, + orientation); input_event(input, EV_ABS, ABS_MT_PRESSURE, s->p); input_event(input, EV_ABS, ABS_MT_TOUCH_MAJOR, major); input_event(input, EV_ABS, ABS_MT_TOUCH_MINOR, minor); @@ -789,6 +817,22 @@ static void mt_process_mt_event(struct hid_device *hid, struct hid_field *field, break; case HID_DG_CONTACTCOUNT: break; + case HID_DG_AZIMUTH: + /* + * Azimuth is counter-clockwise and ranges from [0, MAX) + * (a full revolution). Convert it to clockwise ranging + * [-MAX/2, MAX/2]. + * + * Note that ABS_MT_ORIENTATION require us to report + * the limit of [-MAX/4, MAX/4], but the value can go + * out of range to [-MAX/2, MAX/2] to report an upside + * down ellipsis. + */ + if (value > field->logical_maximum / 2) + value -= field->logical_maximum; + td->curdata.a = -value; + td->curdata.has_azimuth = true; + break; case HID_DG_TOUCH: /* do nothing */ break; diff --git a/include/linux/hid.h b/include/linux/hid.h index ab05a86269dc..d81b9b6fd83a 100644 --- a/include/linux/hid.h +++ b/include/linux/hid.h @@ -281,6 +281,7 @@ struct hid_item { #define HID_DG_DEVICECONFIG 0x000d000e #define HID_DG_DEVICESETTINGS 0x000d0023 +#define HID_DG_AZIMUTH 0x000d003f #define HID_DG_CONFIDENCE 0x000d0047 #define HID_DG_WIDTH 0x000d0048 #define HID_DG_HEIGHT 0x000d0049