From patchwork Sat Oct 9 11:43:10 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alistair Francis X-Patchwork-Id: 12547525 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 95151C433F5 for ; Sat, 9 Oct 2021 11:45:32 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 5F6E260F38 for ; Sat, 9 Oct 2021 11:45:32 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org 5F6E260F38 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=alistair23.me Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:Message-Id:Date:Subject:Cc :To:From:Reply-To:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:In-Reply-To:References: List-Owner; bh=9ZKpVmsygirJREdWXCJ/qeRrYJWBHOctB7w38EeWirA=; b=3dsVAPzKHe7m/G N4ceMIHXWNs3oHsvLRza4dxKhsOgpFH6J6xkEkw1qKkQ9w9TAu+Yrqiccf6SiWDGSsd+wkw0pDWYR JZX+dn8tlm1GfEKxuv548lx7ttxSrvutXB2Zxbqoz6Krpe0KgVZzgR3ruURbnphNhGD5fzviX/UTn xhMmDAMr19UJfwq3s3IgyKKqGy+6kBxSB9N05bo1bXdyCKwqx6d6d249k6O1W6wUf0jLwBLJETtbY LTHATMa4x9odHWwspf2DpFdryw7adgJzy5AbbiWz/VXxXIi+msX7ZJLqOei/hISB53a8p3/+gHCf2 WrgB9DP7oJC1DH+Axn5Q==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1mZAlL-005UIX-Ig; Sat, 09 Oct 2021 11:43:35 +0000 Received: from new3-smtp.messagingengine.com ([66.111.4.229]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1mZAlH-005UHg-LQ for linux-arm-kernel@lists.infradead.org; Sat, 09 Oct 2021 11:43:33 +0000 Received: from compute6.internal (compute6.nyi.internal [10.202.2.46]) by mailnew.nyi.internal (Postfix) with ESMTP id CAC1C580542; Sat, 9 Oct 2021 07:43:28 -0400 (EDT) Received: from mailfrontend1 ([10.202.2.162]) by compute6.internal (MEProxy); Sat, 09 Oct 2021 07:43:28 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=alistair23.me; h=from:to:cc:subject:date:message-id:mime-version :content-transfer-encoding; s=fm2; bh=qaUqksoNnwhMxXafs7u0XKkHPB HK7yNaTZWp2E6vOls=; b=kyQ/cjvn6eLjCAl6YrSnePFJgYbrpUPjRkXwz/0QKE sztVjBCw1CCdcgEuGmqgf0ykBpxu3Jhdann+bf1hDd24o0tfC+chWvb/rNUWTBto VnTt4PH6WuqXMrWTug71fkTIXGv7wzl0q6aJyIbEv4wFwozr+/JhpWS3SmM81AAi 072O26LosPXvflS94e7H5c7xei0i87aIKkh6Ke7WMMBisBIWLOxzL9X8SF1RNNxK 7NBsAnRnbeh8tWkbQhktZ4ZbaqZKg/na/0Nf1mqwq8SMT93CWQf0A9MHOl0l90VT q5Zb30k1wMMl8EzPvG7P1H7EQAwIhL2BEcux5jf2Ypsw== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:content-transfer-encoding:date:from :message-id:mime-version:subject:to:x-me-proxy:x-me-proxy :x-me-sender:x-me-sender:x-sasl-enc; s=fm1; bh=qaUqksoNnwhMxXafs 7u0XKkHPBHK7yNaTZWp2E6vOls=; b=EffMQS3TXAU6XNrR4+YDXk8+T15LrU5Dl ocwDQZimm5fHy9yM2N9d7xuwkGt0cQArlV51XuR4fXjZEJicCqL2Gbc4ciug66Bl Q0BLiIbkCBAES8KRZtSAITz87ReO5YR+FWfy5JbZWksPa8GxAnaw9DOawxiGchCP rRv12f8aB9Uqm234sVi5oCnepzA72nfOlItGNZStZhhyheZKIDTaF0JmkK5pjmXE J7GHaitYYNwXlvCllRf0kuS/5CeChIOcT2Ib+HzURekcvb4yIQ0AEJiD5XMPQXme MJnv14x1aMrny8zp/WV1hCnnH+mCl+0n3BEr4z/3osiSRbxiNfpJQ== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgedvtddrvddtvddggedvucetufdoteggodetrfdotf fvucfrrhhofhhilhgvmecuhfgrshhtofgrihhlpdfqfgfvpdfurfetoffkrfgpnffqhgen uceurghilhhouhhtmecufedttdenucenucfjughrpefhvffufffkofgggfestdekredtre dttdenucfhrhhomheptehlihhsthgrihhrucfhrhgrnhgtihhsuceorghlihhsthgrihhr segrlhhishhtrghirhdvfedrmhgvqeenucggtffrrghtthgvrhhnpeejleeihfdvtefgtd ethfdtgefftdeiffefjeeiffefveeuleejheejvefhffeukeenucevlhhushhtvghrufhi iigvpedtnecurfgrrhgrmhepmhgrihhlfhhrohhmpegrlhhishhtrghirhesrghlihhsth grihhrvdefrdhmvg X-ME-Proxy: Received: by mail.messagingengine.com (Postfix) with ESMTPA; Sat, 9 Oct 2021 07:43:24 -0400 (EDT) From: Alistair Francis To: dmitry.torokhov@gmail.com, shawnguo@kernel.org, s.hauer@pengutronix.de Cc: linux-imx@nxp.com, jikos@kernel.org, benjamin.tissoires@redhat.com, linux-input@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, alistair23@gmail.com, Alistair Francis Subject: [PATCH v11 1/4] HID: wacom_sys: Add support for flipping the data values Date: Sat, 9 Oct 2021 21:43:10 +1000 Message-Id: <20211009114313.17967-1-alistair@alistair23.me> X-Mailer: git-send-email 2.31.1 MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20211009_044331_815314_11C94B5B X-CRM114-Status: GOOD ( 17.94 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org Add support to the Wacom HID device for flipping the values based on device tree settings. This allows us to support devices where the panel is installed in a different orientation, such as the reMarkable2. Signed-off-by: Alistair Francis Reviewed-by: Rob Herring --- .../bindings/input/hid-over-i2c.txt | 20 ++++++ drivers/hid/wacom_sys.c | 25 ++++++++ drivers/hid/wacom_wac.c | 61 +++++++++++++++++++ drivers/hid/wacom_wac.h | 13 ++++ 4 files changed, 119 insertions(+) diff --git a/Documentation/devicetree/bindings/input/hid-over-i2c.txt b/Documentation/devicetree/bindings/input/hid-over-i2c.txt index c76bafaf98d2..16ebd7c46049 100644 --- a/Documentation/devicetree/bindings/input/hid-over-i2c.txt +++ b/Documentation/devicetree/bindings/input/hid-over-i2c.txt @@ -33,6 +33,26 @@ device-specific compatible properties, which should be used in addition to the - post-power-on-delay-ms: time required by the device after enabling its regulators or powering it on, before it is ready for communication. + flip-tilt-x: + type: boolean + description: Flip the tilt X values read from device + + flip-tilt-y: + type: boolean + description: Flip the tilt Y values read from device + + flip-pos-x: + type: boolean + description: Flip the X position values read from device + + flip-pos-y: + type: boolean + description: Flip the Y position values read from device + + flip-distance: + type: boolean + description: Flip the distance values read from device + Example: i2c-hid-dev@2c { diff --git a/drivers/hid/wacom_sys.c b/drivers/hid/wacom_sys.c index 93f49b766376..47d9590b10bd 100644 --- a/drivers/hid/wacom_sys.c +++ b/drivers/hid/wacom_sys.c @@ -10,6 +10,7 @@ #include "wacom_wac.h" #include "wacom.h" +#include #include #define WAC_MSG_RETRIES 5 @@ -2730,6 +2731,28 @@ static void wacom_mode_change_work(struct work_struct *work) return; } +static void wacom_of_read(struct hid_device *hdev, struct wacom_wac *wacom_wac) +{ + if (IS_ENABLED(CONFIG_OF)) { + wacom_wac->flip_tilt_x = of_property_read_bool(hdev->dev.parent->of_node, + "flip-tilt-x"); + wacom_wac->flip_tilt_y = of_property_read_bool(hdev->dev.parent->of_node, + "flip-tilt-y"); + wacom_wac->flip_pos_x = of_property_read_bool(hdev->dev.parent->of_node, + "flip-pos-x"); + wacom_wac->flip_pos_y = of_property_read_bool(hdev->dev.parent->of_node, + "flip-pos-y"); + wacom_wac->flip_distance = of_property_read_bool(hdev->dev.parent->of_node, + "flip-distance"); + } else { + wacom_wac->flip_tilt_x = false; + wacom_wac->flip_tilt_y = false; + wacom_wac->flip_pos_x = false; + wacom_wac->flip_pos_y = false; + wacom_wac->flip_distance = false; + } +} + static int wacom_probe(struct hid_device *hdev, const struct hid_device_id *id) { @@ -2797,6 +2820,8 @@ static int wacom_probe(struct hid_device *hdev, error); } + wacom_of_read(hdev, wacom_wac); + wacom_wac->probe_complete = true; return 0; } diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c index 33a6908995b1..c01f683e23fa 100644 --- a/drivers/hid/wacom_wac.c +++ b/drivers/hid/wacom_wac.c @@ -3261,6 +3261,63 @@ static int wacom_status_irq(struct wacom_wac *wacom_wac, size_t len) return 0; } +static int wacom_of_irq(struct wacom_wac *wacom_wac, size_t len) +{ + const struct wacom_features *features = &wacom_wac->features; + unsigned char *data = wacom_wac->data; + struct input_dev *input = wacom_wac->pen_input; + unsigned int x, y, pressure; + unsigned char tsw, f1, f2, ers; + short tilt_x, tilt_y, distance; + + if (!IS_ENABLED(CONFIG_OF)) + return 0; + + tsw = data[1] & WACOM_TIP_SWITCH_bm; + ers = data[1] & WACOM_ERASER_bm; + f1 = data[1] & WACOM_BARREL_SWITCH_bm; + f2 = data[1] & WACOM_BARREL_SWITCH_2_bm; + x = le16_to_cpup((__le16 *)&data[2]); + y = le16_to_cpup((__le16 *)&data[4]); + pressure = le16_to_cpup((__le16 *)&data[6]); + + /* Signed */ + tilt_x = get_unaligned_le16(&data[9]); + tilt_y = get_unaligned_le16(&data[11]); + + distance = get_unaligned_le16(&data[13]); + + /* keep touch state for pen events */ + if (!wacom_wac->shared->touch_down) + wacom_wac->tool[0] = (data[1] & 0x0c) ? + BTN_TOOL_RUBBER : BTN_TOOL_PEN; + + wacom_wac->shared->touch_down = data[1] & 0x20; + + // Flip the values based on properties from the device tree + + // Default to a negative value for distance as HID compliant Wacom + // devices generally specify the hovering distance as negative. + distance = wacom_wac->flip_distance ? distance : -distance; + x = wacom_wac->flip_pos_x ? (features->x_max - x) : x; + y = wacom_wac->flip_pos_y ? (features->y_max - y) : y; + tilt_x = wacom_wac->flip_tilt_x ? -tilt_x : tilt_x; + tilt_y = wacom_wac->flip_tilt_y ? -tilt_y : tilt_y; + + input_report_key(input, BTN_TOUCH, tsw || ers); + input_report_key(input, wacom_wac->tool[0], wacom_wac->shared->touch_down); + input_report_key(input, BTN_STYLUS, f1); + input_report_key(input, BTN_STYLUS2, f2); + input_report_abs(input, ABS_X, x); + input_report_abs(input, ABS_Y, y); + input_report_abs(input, ABS_PRESSURE, pressure); + input_report_abs(input, ABS_DISTANCE, distance); + input_report_abs(input, ABS_TILT_X, tilt_x); + input_report_abs(input, ABS_TILT_Y, tilt_y); + + return 1; +} + void wacom_wac_irq(struct wacom_wac *wacom_wac, size_t len) { bool sync; @@ -3379,6 +3436,10 @@ void wacom_wac_irq(struct wacom_wac *wacom_wac, size_t len) sync = wacom_remote_irq(wacom_wac, len); break; + case HID_GENERIC: + sync = wacom_of_irq(wacom_wac, len); + break; + default: sync = false; break; diff --git a/drivers/hid/wacom_wac.h b/drivers/hid/wacom_wac.h index 8b2d4e5b2303..4dd5a56bf347 100644 --- a/drivers/hid/wacom_wac.h +++ b/drivers/hid/wacom_wac.h @@ -157,6 +157,14 @@ #define WACOM_HID_WT_Y (WACOM_HID_UP_WACOMTOUCH | 0x131) #define WACOM_HID_WT_REPORT_VALID (WACOM_HID_UP_WACOMTOUCH | 0x1d0) +// Bitmasks (for data[3]) +#define WACOM_TIP_SWITCH_bm (1 << 0) +#define WACOM_BARREL_SWITCH_bm (1 << 1) +#define WACOM_ERASER_bm (1 << 2) +#define WACOM_INVERT_bm (1 << 3) +#define WACOM_BARREL_SWITCH_2_bm (1 << 4) +#define WACOM_IN_RANGE_bm (1 << 5) + #define WACOM_BATTERY_USAGE(f) (((f)->hid == HID_DG_BATTERYSTRENGTH) || \ ((f)->hid == WACOM_HID_WD_BATTERY_CHARGING) || \ ((f)->hid == WACOM_HID_WD_BATTERY_LEVEL)) @@ -357,6 +365,11 @@ struct wacom_wac { bool has_mode_change; bool is_direct_mode; bool is_invalid_bt_frame; + bool flip_tilt_x; + bool flip_tilt_y; + bool flip_pos_x; + bool flip_pos_y; + bool flip_distance; }; #endif