From patchwork Tue Dec 21 19:17:26 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Angela Czubak X-Patchwork-Id: 12690439 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 vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 8DEDCC433FE for ; Tue, 21 Dec 2021 19:17:50 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S241720AbhLUTRu (ORCPT ); Tue, 21 Dec 2021 14:17:50 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:57832 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229436AbhLUTRt (ORCPT ); Tue, 21 Dec 2021 14:17:49 -0500 Received: from mail-wr1-x430.google.com (mail-wr1-x430.google.com [IPv6:2a00:1450:4864:20::430]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 721B8C06173F for ; Tue, 21 Dec 2021 11:17:49 -0800 (PST) Received: by mail-wr1-x430.google.com with SMTP id c4so26506wrd.9 for ; Tue, 21 Dec 2021 11:17:49 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=semihalf-com.20210112.gappssmtp.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=dFKe64RHn+wfMjnj0soDOjBJv32ROQQmXkTlTsTSnnA=; b=BScRZICxkSWZm8rKyB6dB9mtpKEjfKFX2gMG4w1gQDx4WsjLnPXNMlQCWN+aoPdNG2 SjRYgeSy/Zz/fV1IG6rVeFOAz82D3u629kz2l9WnE7gn1droxzVhMbQqiobPxP58DEv4 SP5/H4OcXSfKLMBFcxemv4jtL7dXthMfhZ7THP60i2NDCcemnNRpqaCkdzNCyOGemFHC 5gIYPJ2t+SO4Mk2i6/4arwoxQ+rlk/JZkdDNl9zKGRAmtdRkEcEe5jqiWVfziQ6sJIkC ltjMIrIQO+dnOjhjSZpSiXRCDm2AERXqCunJftEH8zJDs8W1bKTfdcTZs39sep7sf3Et bo6g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=dFKe64RHn+wfMjnj0soDOjBJv32ROQQmXkTlTsTSnnA=; b=afHCceMfLwXxLCNEm1v1+t0aqm3hFCgIGezMi2vAH2EkPPokbXlBY+6/nfvrIHZ/UE rPw4GU6Ug+Uu4ppC1iNeUZon6H1m8B8TGdaW5XDanGecteAiROfGejmU6hzT9PpwfnPH PakqymvkCbaClMoqrwWFJiDPOt9s62EAoIHWrnFFRLfw+zhojUxh9k+jZFCAYf/IJH8Q BchdVA55PWs+PLn3NIzdnriMAQN87AgzGE02lPhB7twsz4iy1SuWBITJ0nrodkY55+Qr UoJbrETA/kOXVddbA4PCT2Evq2UtTXxv2+B3IOl3IcrRZUGAFpUl/gkMGw5yJGc0tOZa 9y+g== X-Gm-Message-State: AOAM532nFpIzVR2M+Uvb/CaknHTHURdG+GDU6imAbb6quzPd0CoYjdZO QPSLrK5A5w3wOOnCQAr7B1bAYTSrBW2OWT9Bn2E= X-Google-Smtp-Source: ABdhPJyJovZQf7ZtOfG85bG5HDLw5Bzct2ZGl60DQzN3WOw61tNEHYWxVAManOb+XX0LNyp4l+63fA== X-Received: by 2002:a05:6000:108a:: with SMTP id y10mr1014072wrw.335.1640114268029; Tue, 21 Dec 2021 11:17:48 -0800 (PST) Received: from aczubak.c.googlers.com.com (109.36.187.35.bc.googleusercontent.com. [35.187.36.109]) by smtp.gmail.com with ESMTPSA id t8sm3994846wmq.32.2021.12.21.11.17.47 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 21 Dec 2021 11:17:47 -0800 (PST) From: Angela Czubak To: linux-input@vger.kernel.org Cc: upstream@semihalf.com, dmitry.torokhov@gmail.com, Angela Czubak Subject: [PATCH 01/18] HID: add haptics page defines Date: Tue, 21 Dec 2021 19:17:26 +0000 Message-Id: <20211221191743.1893185-2-acz@semihalf.com> X-Mailer: git-send-email 2.34.1.307.g9b7440fafd-goog In-Reply-To: <20211221191743.1893185-1-acz@semihalf.com> References: <20211221191743.1893185-1-acz@semihalf.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-input@vger.kernel.org Introduce haptic usages as defined in HID Usage Tables specification. Signed-off-by: Angela Czubak Reviewed-by: Dmitry Torokhov --- include/linux/hid.h | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/include/linux/hid.h b/include/linux/hid.h index f453be385bd4..70679bf820ce 100644 --- a/include/linux/hid.h +++ b/include/linux/hid.h @@ -153,6 +153,7 @@ struct hid_item { #define HID_UP_TELEPHONY 0x000b0000 #define HID_UP_CONSUMER 0x000c0000 #define HID_UP_DIGITIZER 0x000d0000 +#define HID_UP_HAPTIC 0x000e0000 #define HID_UP_PID 0x000f0000 #define HID_UP_BATTERY 0x00850000 #define HID_UP_HPVENDOR 0xff7f0000 @@ -301,6 +302,28 @@ struct hid_item { #define HID_DG_TOOLSERIALNUMBER 0x000d005b #define HID_DG_LATENCYMODE 0x000d0060 +#define HID_HP_SIMPLECONTROLLER 0x000e0001 +#define HID_HP_WAVEFORMLIST 0x000e0010 +#define HID_HP_DURATIONLIST 0x000e0011 +#define HID_HP_AUTOTRIGGER 0x000e0020 +#define HID_HP_MANUALTRIGGER 0x000e0021 +#define HID_HP_AUTOTRIGGERASSOCIATEDCONTROL 0x000e0022 +#define HID_HP_INTENSITY 0x000e0023 +#define HID_HP_REPEATCOUNT 0x000e0024 +#define HID_HP_RETRIGGERPERIOD 0x000e0025 +#define HID_HP_WAVEFORMVENDORPAGE 0x000e0026 +#define HID_HP_WAVEFORMVENDORID 0x000e0027 +#define HID_HP_WAVEFORMCUTOFFTIME 0x000e0028 +#define HID_HP_WAVEFORMNONE 0x000e1001 +#define HID_HP_WAVEFORMSTOP 0x000e1002 +#define HID_HP_WAVEFORMCLICK 0x000e1003 +#define HID_HP_WAVEFORMBUZZCONTINUOUS 0x000e1004 +#define HID_HP_WAVEFORMRUMBLECONTINUOUS 0x000e1005 +#define HID_HP_WAVEFORMPRESS 0x000e1006 +#define HID_HP_WAVEFORMRELEASE 0x000e1007 +#define HID_HP_VENDORWAVEFORMMIN 0x000e2001 +#define HID_HP_VENDORWAVEFORMMAX 0x000e2fff + #define HID_BAT_ABSOLUTESTATEOFCHARGE 0x00850065 #define HID_VD_ASUS_CUSTOM_MEDIA_KEYS 0xff310076 From patchwork Tue Dec 21 19:17:27 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Angela Czubak X-Patchwork-Id: 12690443 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 vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 61A8CC433EF for ; Tue, 21 Dec 2021 19:17:51 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S241721AbhLUTRv (ORCPT ); Tue, 21 Dec 2021 14:17:51 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:57838 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229436AbhLUTRu (ORCPT ); Tue, 21 Dec 2021 14:17:50 -0500 Received: from mail-wr1-x42a.google.com (mail-wr1-x42a.google.com [IPv6:2a00:1450:4864:20::42a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 4E952C061574 for ; Tue, 21 Dec 2021 11:17:50 -0800 (PST) Received: by mail-wr1-x42a.google.com with SMTP id a9so35983wrr.8 for ; Tue, 21 Dec 2021 11:17:50 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=semihalf-com.20210112.gappssmtp.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=z4kqxZftMv6A3T258Gb1J2+2xP5Vkofn4t2RzIfnSy8=; b=vWGs6hmKsDVYa1V9SAmwXeuvlScoZ/Nn9pRTK26NEScWU12ea5l+N3PXAFkCVEkShT DO/plGb+fRHctJ958FH9bJHWrW6Ql8i0Iy7PZjgWwtJADUP20ndUwBi8uc3PlKO6B74D i7SmRpcF0oKPgj763ooGn9zbkWb1EsdJRaoxpxctqZdGlExAklk4NQKLixqOlsrChT0k r8E/NFMd/VtdawQF4ruqSlCz+EihMwa5kvnUrjNbsgron6WW8bTVmQcPU2JXNd+cwxKT Q2vMjJ8Kc0Vtxi2DLkdWFqO3hDS2OFXLMWuoSypn+xeRyvc8T9gBOJ/vSAs5/ylCQD09 u/5g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=z4kqxZftMv6A3T258Gb1J2+2xP5Vkofn4t2RzIfnSy8=; b=ksB0budGsXaBaW3wcwSl6YBFWGP+PJVKk2UoHZbvT1wivj7PabSYDaUETU/SxH5kMK DyZncdVfXWxuVXmJ+cccHDYU24ome3GlvVDWI8G0fqf0YuwQ7VUFVqRWF1PpSJryf1BP 8NGkVjtdi4UHLC3qEpjdbR7YRZGnH596YfrPMeNsc3o4R6LFGbYiYbj1vrGuUyFH/bQ/ IoLXacgyMudapZRUH4SkEzBj8aTC9K8ldQi2UVksnnxHx+GSLV6pvBJih4wtWPG3Nckw WU/NaLX7ggLUGdOXQlHPaUiFJT4ZjNgskz2Nu9St6Y84sOLMherq3c6+jEsFOYN5082D oCfw== X-Gm-Message-State: AOAM533D7Jp933LBEbaihnNaCpvPkyZf2T2AaSFRHbQktvaOtET/AhIV 2id+3OXsiLx+sIqeO1h9KqN+KBcP4DF9Eptp4A8= X-Google-Smtp-Source: ABdhPJwlOdiY5JOlQuHZt+zo8RMFYlWw9nkgNtxuYU0pmvDN+H/MXygWq6iBbKiLJK7B1BzLLKoOdA== X-Received: by 2002:adf:f252:: with SMTP id b18mr3862936wrp.341.1640114268946; Tue, 21 Dec 2021 11:17:48 -0800 (PST) Received: from aczubak.c.googlers.com.com (109.36.187.35.bc.googleusercontent.com. [35.187.36.109]) by smtp.gmail.com with ESMTPSA id t8sm3994846wmq.32.2021.12.21.11.17.48 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 21 Dec 2021 11:17:48 -0800 (PST) From: Angela Czubak To: linux-input@vger.kernel.org Cc: upstream@semihalf.com, dmitry.torokhov@gmail.com, Angela Czubak Subject: [PATCH 02/18] Input: add FF_HID effect type Date: Tue, 21 Dec 2021 19:17:27 +0000 Message-Id: <20211221191743.1893185-3-acz@semihalf.com> X-Mailer: git-send-email 2.34.1.307.g9b7440fafd-goog In-Reply-To: <20211221191743.1893185-1-acz@semihalf.com> References: <20211221191743.1893185-1-acz@semihalf.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-input@vger.kernel.org FF_HID effect type can be used to trigger haptic feedback with HID simple haptic usages. Signed-off-by: Angela Czubak --- include/uapi/linux/input.h | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/include/uapi/linux/input.h b/include/uapi/linux/input.h index ee3127461ee0..0d4d426cf75a 100644 --- a/include/uapi/linux/input.h +++ b/include/uapi/linux/input.h @@ -424,6 +424,24 @@ struct ff_rumble_effect { __u16 weak_magnitude; }; +/** + * struct ff_hid_effect + * @hid_usage: hid_usage according to Haptics page (WAVEFORM_CLICK, etc.) + * @vendor_id: the waveform vendor ID if hid_usage is in the vendor-defined range + * @vendor_id: the vendor waveform page if hid_usage is in the vendor-defined range + * @intensity: strength of the effect as percentage + * @repeat_count: number of times to retrigger effect + * @retrigger_period: time before effect is retriggered (in ms) + */ +struct ff_hid_effect { + __u16 hid_usage; + __u16 vendor_id; + __u8 vendor_waveform_page; + __u16 intensity; + __u16 repeat_count; + __u16 retrigger_period; +}; + /** * struct ff_effect - defines force feedback effect * @type: type of the effect (FF_CONSTANT, FF_PERIODIC, FF_RAMP, FF_SPRING, @@ -460,6 +478,7 @@ struct ff_effect { struct ff_periodic_effect periodic; struct ff_condition_effect condition[2]; /* One for each axis */ struct ff_rumble_effect rumble; + struct ff_hid_effect hid; } u; }; @@ -467,6 +486,7 @@ struct ff_effect { * Force feedback effect types */ +#define FF_HID 0x4f #define FF_RUMBLE 0x50 #define FF_PERIODIC 0x51 #define FF_CONSTANT 0x52 @@ -476,7 +496,7 @@ struct ff_effect { #define FF_INERTIA 0x56 #define FF_RAMP 0x57 -#define FF_EFFECT_MIN FF_RUMBLE +#define FF_EFFECT_MIN FF_HID #define FF_EFFECT_MAX FF_RAMP /* From patchwork Tue Dec 21 19:17:28 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Angela Czubak X-Patchwork-Id: 12690441 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 vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id D9F18C4332F for ; Tue, 21 Dec 2021 19:17:51 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229436AbhLUTRv (ORCPT ); Tue, 21 Dec 2021 14:17:51 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:57840 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S241729AbhLUTRv (ORCPT ); Tue, 21 Dec 2021 14:17:51 -0500 Received: from mail-wr1-x42e.google.com (mail-wr1-x42e.google.com [IPv6:2a00:1450:4864:20::42e]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id B1C6DC06173F for ; Tue, 21 Dec 2021 11:17:50 -0800 (PST) Received: by mail-wr1-x42e.google.com with SMTP id e5so60342wrc.5 for ; Tue, 21 Dec 2021 11:17:50 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=semihalf-com.20210112.gappssmtp.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=KUy4u4/fllLjqTaoSYHcRo6aZSM05/Tqo7d9/i38GsM=; b=mVCS7gzy//josiO9WrCr/f074SLOb/Wm8Y9DgBz0lIb/EUURBPouk2Z9blaSLC7XNj aF0CptxB6wdog31sXXK6ollyfpaTpzlqaE7Cmlh+dEXifDvSx1ESznGk7waOCW6Vz2BB bS8AXRhwIExv2iNZXF7LXznu6XYBgZGeLzKtO0iDbomLcK5z1adu0g5FUR94twPNUR0c +5+pTUxU9dfcVpQU2w8VItG6xheqHgI4a2i2fgs9MXURBLPpmowp/349g9k5Ok//aEli 3WiTh5Dwq6g0ww5aTLjynkxiPAhCWBR+8/OKFSPPkI5f8bQ2SfOBn+9FauBcsnWJFGS5 gG4w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=KUy4u4/fllLjqTaoSYHcRo6aZSM05/Tqo7d9/i38GsM=; b=0S/u0P2pS63i9XaRlHjeCKmu2z/6EFENduReAyt5cMXC9KdfK4jDEHqKbHwLmj2XRW J9dV8wpyZ42YuyaQVv4QXXWpG8PHAXgDt1UEz/Eiy8+5A1p94RyX+Rpz5SgLec2yxJi/ Xs/CJn/B+JnlbwQcix8WVEvQeNWNkHP9J8do6GAFxLNtO9k08a0ld03xvAGIgx56Yymq BCJDkOK3QldDiotTmO7tGhwc72Xed9LXW7M1ybpKGAN45ccfDjdS60SDGvKeXg/x3+BK gqsYgOmLzAGqRsxuuKBesKrSRBH5L8r2yTcOyo/+VDJKZT0DT1Pwqf7tymHpkUQxKBat rDiA== X-Gm-Message-State: AOAM532PH51x7RWSS/9ar+G9ru5HwmWgjlt/q6RcfN7+3qOelsym6nZK V/4k98R3rlAUh6IlyReIFhUbZlX1Qr8w9Phm7VA= X-Google-Smtp-Source: ABdhPJyD8JxqKj61KGmKzpj8jCyPpUPNZp6E5+O53hkOQ/VSiFEef+b3EQZcIxdFyfJ6iqp7/FeU2g== X-Received: by 2002:adf:d841:: with SMTP id k1mr3976074wrl.396.1640114269365; Tue, 21 Dec 2021 11:17:49 -0800 (PST) Received: from aczubak.c.googlers.com.com (109.36.187.35.bc.googleusercontent.com. [35.187.36.109]) by smtp.gmail.com with ESMTPSA id t8sm3994846wmq.32.2021.12.21.11.17.48 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 21 Dec 2021 11:17:49 -0800 (PST) From: Angela Czubak To: linux-input@vger.kernel.org Cc: upstream@semihalf.com, dmitry.torokhov@gmail.com, Angela Czubak Subject: [PATCH 03/18] Input: add INPUT_PROP_HAPTIC_TOUCHPAD Date: Tue, 21 Dec 2021 19:17:28 +0000 Message-Id: <20211221191743.1893185-4-acz@semihalf.com> X-Mailer: git-send-email 2.34.1.307.g9b7440fafd-goog In-Reply-To: <20211221191743.1893185-1-acz@semihalf.com> References: <20211221191743.1893185-1-acz@semihalf.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-input@vger.kernel.org INPUT_PROP_HAPTIC_TOUCHPAD property is to be set for a device with simple haptic capabilities. Signed-off-by: Angela Czubak --- include/uapi/linux/input-event-codes.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/uapi/linux/input-event-codes.h b/include/uapi/linux/input-event-codes.h index 225ec87d4f22..df2ba5da4eaa 100644 --- a/include/uapi/linux/input-event-codes.h +++ b/include/uapi/linux/input-event-codes.h @@ -27,6 +27,7 @@ #define INPUT_PROP_TOPBUTTONPAD 0x04 /* softbuttons at top of pad */ #define INPUT_PROP_POINTING_STICK 0x05 /* is a pointing stick */ #define INPUT_PROP_ACCELEROMETER 0x06 /* has accelerometer */ +#define INPUT_PROP_HAPTIC_TOUCHPAD 0x07 /* is a haptic touchpad */ #define INPUT_PROP_MAX 0x1f #define INPUT_PROP_CNT (INPUT_PROP_MAX + 1) From patchwork Tue Dec 21 19:17:29 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Angela Czubak X-Patchwork-Id: 12690445 X-Patchwork-Delegate: jikos@jikos.cz 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 vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 76CDCC433F5 for ; Tue, 21 Dec 2021 19:17:52 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S241737AbhLUTRw (ORCPT ); Tue, 21 Dec 2021 14:17:52 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:57846 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S241729AbhLUTRv (ORCPT ); Tue, 21 Dec 2021 14:17:51 -0500 Received: from mail-wm1-x330.google.com (mail-wm1-x330.google.com [IPv6:2a00:1450:4864:20::330]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 482BAC061574 for ; Tue, 21 Dec 2021 11:17:51 -0800 (PST) Received: by mail-wm1-x330.google.com with SMTP id l4so66463wmq.3 for ; Tue, 21 Dec 2021 11:17:51 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=semihalf-com.20210112.gappssmtp.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=WUQOlH+CRkkd1Psuoq24m4twbzqmWsxWeJKyPpr5VA8=; b=ddW495LtvWG5dVnbSwkTiSF/FvEQGpPQtAWyyzmDevmEjPzNLSLwnxlz84s7+x7o8F gQ5WT/XIxf4fYX8GUnRI5TdduYAvBTnbcjC0B/xT0BWknWQA68E8QeTMrnRjZ4eKcQyb HTsp/R5U9bP4jTHZbyojE5KO1DTr74byysI4yzAw4Ng4TxARNQYPwxCFEuv3YCKatdSE htF+EsQm3ExjEI5Hdr1VLTV0gBx5M5K/hHASbsU1Y/yfZOXb4A0/TZUPaLuEk9XDiWCg nfowI7Vqkz5KDQbEEkmi+MFfQ27FDA8fAewFmSZLjaZnL5EHZHqsEvJEETAdAOwXNedd polg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=WUQOlH+CRkkd1Psuoq24m4twbzqmWsxWeJKyPpr5VA8=; b=aZW5wV14jDKMk/aqsS3e+t1bDqiUPqqB6HkjXTWqBJmpKKh5MaejS6BDbDbAIECYmw zRutd8BYfjY1riJq470HeqANWOUq0kn+UVvx4lYHBeK/aaIcp62DZYHG4gbeqCYAb8jB QSfsNZN6xMG9uVu80s1ZXj+vFDzqi5pAOAbZcOSbYkj/HGnf2xUNY+gamLvDCNvTlBNI O/dHJZQ2KeZLk5UoXR0bogMGta2u8eLgV1H6IO/mmeBPAUlnFK2OHnQKo+5dqXrhGX7t Nix/wkVlX6cvsuM4MR0e6SuW7mb/75GAQaoFEXaDYIpuL6ZbRCZW/agLobwQ6wfTmR4S DTDA== X-Gm-Message-State: AOAM533/daTfPpWX37Xw1ALznt3m7WVAboIxXJ3q2cFts5D6nqxCFbmv WLs/VHcllQ4sBBhBnlIIxj0jcSNjXlCfNkOPwOI= X-Google-Smtp-Source: ABdhPJwIuu+MXLH4Djnn+GcalfdxeSyVSpvrwz0cPiRaMacIh8QI+ZoLRj7MBFLGxM+Uc1S1bRSDKA== X-Received: by 2002:a7b:c3cc:: with SMTP id t12mr3932741wmj.168.1640114269850; Tue, 21 Dec 2021 11:17:49 -0800 (PST) Received: from aczubak.c.googlers.com.com (109.36.187.35.bc.googleusercontent.com. [35.187.36.109]) by smtp.gmail.com with ESMTPSA id t8sm3994846wmq.32.2021.12.21.11.17.49 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 21 Dec 2021 11:17:49 -0800 (PST) From: Angela Czubak To: linux-input@vger.kernel.org Cc: upstream@semihalf.com, dmitry.torokhov@gmail.com, Angela Czubak Subject: [PATCH 04/18] HID: haptic: introduce hid_haptic_device Date: Tue, 21 Dec 2021 19:17:29 +0000 Message-Id: <20211221191743.1893185-5-acz@semihalf.com> X-Mailer: git-send-email 2.34.1.307.g9b7440fafd-goog In-Reply-To: <20211221191743.1893185-1-acz@semihalf.com> References: <20211221191743.1893185-1-acz@semihalf.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-input@vger.kernel.org Define a new structure that contains simple haptic device configuration as well as current state. Signed-off-by: Angela Czubak --- drivers/hid/Kconfig | 4 +++ drivers/hid/Makefile | 1 + drivers/hid/hid-haptic.c | 10 ++++++ drivers/hid/hid-haptic.h | 68 ++++++++++++++++++++++++++++++++++++++++ 4 files changed, 83 insertions(+) create mode 100644 drivers/hid/hid-haptic.c create mode 100644 drivers/hid/hid-haptic.h diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig index a7c78ac96270..8d1eb4491a7f 100644 --- a/drivers/hid/Kconfig +++ b/drivers/hid/Kconfig @@ -89,6 +89,10 @@ config HID_GENERIC If unsure, say Y. +config HID_HAPTIC + bool + default n + menu "Special HID drivers" depends on HID diff --git a/drivers/hid/Makefile b/drivers/hid/Makefile index 55a6fa3eca5a..65d54ccd4574 100644 --- a/drivers/hid/Makefile +++ b/drivers/hid/Makefile @@ -4,6 +4,7 @@ # hid-y := hid-core.o hid-input.o hid-quirks.o hid-$(CONFIG_DEBUG_FS) += hid-debug.o +hid-$(CONFIG_HID_HAPTIC) += hid-haptic.o obj-$(CONFIG_HID) += hid.o obj-$(CONFIG_UHID) += uhid.o diff --git a/drivers/hid/hid-haptic.c b/drivers/hid/hid-haptic.c new file mode 100644 index 000000000000..0910d8af9f38 --- /dev/null +++ b/drivers/hid/hid-haptic.c @@ -0,0 +1,10 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * HID Haptic support for Linux + * + * Copyright (c) 2021 Angela Czubak + */ + +/* + */ +#include "hid-haptic.h" diff --git a/drivers/hid/hid-haptic.h b/drivers/hid/hid-haptic.h new file mode 100644 index 000000000000..41f19cd22f75 --- /dev/null +++ b/drivers/hid/hid-haptic.h @@ -0,0 +1,68 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * HID Haptic support for Linux + * + * Copyright (c) 2021 Angela Czubak + */ + +/* + */ + + +#include + +#define HID_HAPTIC_ORDINAL_WAVEFORMNONE 1 +#define HID_HAPTIC_ORDINAL_WAVEFORMSTOP 2 + +#define HID_HAPTIC_PRESS_THRESH 200 +#define HID_HAPTIC_RELEASE_THRESH 180 + +#define HID_HAPTIC_MODE_DEVICE 0 +#define HID_HAPTIC_MODE_KERNEL 1 + +struct hid_haptic_effect { + __u8 *report_buf; + struct input_dev *input_dev; + struct work_struct work; + struct list_head control; + struct mutex control_mutex; +}; + +struct hid_haptic_effect_node { + struct list_head node; + struct file *file; +}; + +struct hid_haptic_device { + struct input_dev *input_dev; + struct hid_device *hdev; + struct hid_report *auto_trigger_report; + struct mutex auto_trigger_mutex; + struct workqueue_struct *wq; + struct hid_report *manual_trigger_report; + struct mutex manual_trigger_mutex; + size_t manual_trigger_report_len; + int pressed_state; + __s32 pressure_sum; + __s32 force_logical_minimum; + __s32 force_physical_minimum; + __s32 force_resolution; + __u32 press_threshold; + __u32 release_threshold; + __u32 mode; + __u32 default_auto_trigger; + __u32 vendor_page; + __u32 vendor_id; + __u32 max_waveform_id; + __u32 max_duration_id; + __u16 *hid_usage_map; + __u32 *duration_map; + __u16 press_ordinal_orig; + __u16 press_ordinal_cur; + __u16 release_ordinal_orig; + __u16 release_ordinal_cur; +#define HID_HAPTIC_RELEASE_EFFECT_ID 0 +#define HID_HAPTIC_PRESS_EFFECT_ID 1 + struct hid_haptic_effect *effect; + struct hid_haptic_effect stop_effect; +}; From patchwork Tue Dec 21 19:17:30 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Angela Czubak X-Patchwork-Id: 12690447 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 vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 0DDCFC433FE for ; Tue, 21 Dec 2021 19:17:53 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S241729AbhLUTRw (ORCPT ); Tue, 21 Dec 2021 14:17:52 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:57850 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S241739AbhLUTRw (ORCPT ); Tue, 21 Dec 2021 14:17:52 -0500 Received: from mail-wr1-x431.google.com (mail-wr1-x431.google.com [IPv6:2a00:1450:4864:20::431]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id BBD4FC06173F for ; Tue, 21 Dec 2021 11:17:51 -0800 (PST) Received: by mail-wr1-x431.google.com with SMTP id j18so85870wrd.2 for ; Tue, 21 Dec 2021 11:17:51 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=semihalf-com.20210112.gappssmtp.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=tDE1yTTX0Xg5vz7Ch8EMZhldmZR/CGhGbu900yOBjHM=; b=dnjOPZw/mZxEaYHGWhjKq6ejI1iD7UPs7IV3Drau+05Uy7wC+NROv8KUpcSJzHWbTe kLdmBGrI3kiMi6BB1O0jFxRDs8PVIG2ZHkrNuZDKiP9WuHnXtSNzF7qGmpNAUprZzNyM rppbZ2nJ5Obc8s74d8F27xMkjXKgM1WSkbxlwN5D3ZF/zj32zugDIELfppnOdMQQBx7j KlLfWNwZT5yTwRdU3lPwB4Z3qU+HZvcMUvbbA56myUr3FIQjTD0+mBZeb1FXuM3GmJ/S UQ8nJEcegI8eSdPj+3ORsq4+ANYJB58TNooDKwQTA259jasV/pNnL2WHiXOOda5EJqrf tKqQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=tDE1yTTX0Xg5vz7Ch8EMZhldmZR/CGhGbu900yOBjHM=; b=mMeJ654Ny478WNkNaxg2AFts9rwU/IUXwhVxiAwqLgyQQhueAyym3ptyok4TkPmoq0 esY0PshMsUTSlpDAev8n/6F1Zt+CeETO9NEidC6clab8j6nIzhq9ezFZ0PAPI5NcP9BP Gxc491KdRvZwv/+5FRuenScIQdbxVI52L9QNeutB0VubuH7hdMG0b3eNdUqeHXDvDfk0 bdL8eLsU2VJfyKG7AnrkaEysCMhjt0VgqsNoolHDG0S83pBvLHQZH5ZBZ5m6GQH4agwU zvRGnS1q9gSPGupk0pRBclfyYTEkt89hwlQB5R5CjWXDQsK6bNYD5y5P0/QiE01YcoCT hcYQ== X-Gm-Message-State: AOAM5334Wo8RRVD3Nr9oSVL12g/Rl1hMOpQGxlSrsDr5Vh2GD4vDpWsz SQ3RYBX2uPYhIUizY3QGkXZGSPp8qpTv04TmRzQ= X-Google-Smtp-Source: ABdhPJwt5Wx+UShrK0N34AbzkpCCQf8RxIX1csIUhXcUpedeibrOSn8RJvr3w/1ILs66zF0gADCwzw== X-Received: by 2002:a5d:42d2:: with SMTP id t18mr3701915wrr.271.1640114270383; Tue, 21 Dec 2021 11:17:50 -0800 (PST) Received: from aczubak.c.googlers.com.com (109.36.187.35.bc.googleusercontent.com. [35.187.36.109]) by smtp.gmail.com with ESMTPSA id t8sm3994846wmq.32.2021.12.21.11.17.49 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 21 Dec 2021 11:17:50 -0800 (PST) From: Angela Czubak To: linux-input@vger.kernel.org Cc: upstream@semihalf.com, dmitry.torokhov@gmail.com, Angela Czubak Subject: [PATCH 05/18] HID: introduce hid_get_feature Date: Tue, 21 Dec 2021 19:17:30 +0000 Message-Id: <20211221191743.1893185-6-acz@semihalf.com> X-Mailer: git-send-email 2.34.1.307.g9b7440fafd-goog In-Reply-To: <20211221191743.1893185-1-acz@semihalf.com> References: <20211221191743.1893185-1-acz@semihalf.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-input@vger.kernel.org Move mt_get_feature from hid-multitouch to hid-core as it is a generic function that can be used by other drivers as well. Signed-off-by: Angela Czubak --- drivers/hid/hid-core.c | 39 ++++++++++++++++++++++++++++++++++++ drivers/hid/hid-multitouch.c | 38 +++-------------------------------- include/linux/hid.h | 1 + 3 files changed, 43 insertions(+), 35 deletions(-) diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index dbed2524fd47..c11cb7324157 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c @@ -1796,6 +1796,45 @@ int hid_report_raw_event(struct hid_device *hid, int type, u8 *data, u32 size, } EXPORT_SYMBOL_GPL(hid_report_raw_event); +/** + * hid_get_feature - retrieve feature report from device + * + * @hdev: hid device + * @report: hid report to retrieve + */ +void hid_get_feature(struct hid_device *hdev, struct hid_report *report) +{ + int ret; + u32 size = hid_report_len(report); + u8 *buf; + + /* + * Do not fetch the feature report if the device has been explicitly + * marked as non-capable. + */ + if (hdev->quirks & HID_QUIRK_NO_INIT_REPORTS) + return; + + buf = hid_alloc_report_buf(report, GFP_KERNEL); + if (!buf) + return; + + ret = hid_hw_raw_request(hdev, report->id, buf, size, + HID_FEATURE_REPORT, HID_REQ_GET_REPORT); + if (ret < 0) { + dev_warn(&hdev->dev, "failed to fetch feature %d\n", + report->id); + } else { + ret = hid_report_raw_event(hdev, HID_FEATURE_REPORT, buf, + size, 0); + if (ret) + dev_warn(&hdev->dev, "failed to report feature\n"); + } + + kfree(buf); +} +EXPORT_SYMBOL_GPL(hid_get_feature); + /** * hid_input_report - report data from lower layer (usb, bt...) * diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c index 082376a6cb3d..7beb3dfc3e67 100644 --- a/drivers/hid/hid-multitouch.c +++ b/drivers/hid/hid-multitouch.c @@ -434,38 +434,6 @@ static const struct attribute_group mt_attribute_group = { .attrs = sysfs_attrs }; -static void mt_get_feature(struct hid_device *hdev, struct hid_report *report) -{ - int ret; - u32 size = hid_report_len(report); - u8 *buf; - - /* - * Do not fetch the feature report if the device has been explicitly - * marked as non-capable. - */ - if (hdev->quirks & HID_QUIRK_NO_INIT_REPORTS) - return; - - buf = hid_alloc_report_buf(report, GFP_KERNEL); - if (!buf) - return; - - ret = hid_hw_raw_request(hdev, report->id, buf, size, - HID_FEATURE_REPORT, HID_REQ_GET_REPORT); - if (ret < 0) { - dev_warn(&hdev->dev, "failed to fetch feature %d\n", - report->id); - } else { - ret = hid_report_raw_event(hdev, HID_FEATURE_REPORT, buf, - size, 0); - if (ret) - dev_warn(&hdev->dev, "failed to report feature\n"); - } - - kfree(buf); -} - static void mt_feature_mapping(struct hid_device *hdev, struct hid_field *field, struct hid_usage *usage) { @@ -473,7 +441,7 @@ static void mt_feature_mapping(struct hid_device *hdev, switch (usage->hid) { case HID_DG_CONTACTMAX: - mt_get_feature(hdev, field->report); + hid_get_feature(hdev, field->report); td->maxcontacts = field->value[0]; if (!td->maxcontacts && @@ -490,7 +458,7 @@ static void mt_feature_mapping(struct hid_device *hdev, break; } - mt_get_feature(hdev, field->report); + hid_get_feature(hdev, field->report); if (field->value[usage->usage_index] == MT_BUTTONTYPE_CLICKPAD) td->is_buttonpad = true; @@ -498,7 +466,7 @@ static void mt_feature_mapping(struct hid_device *hdev, case 0xff0000c5: /* Retrieve the Win8 blob once to enable some devices */ if (usage->usage_index == 0) - mt_get_feature(hdev, field->report); + hid_get_feature(hdev, field->report); break; } } diff --git a/include/linux/hid.h b/include/linux/hid.h index 70679bf820ce..fce7966234de 100644 --- a/include/linux/hid.h +++ b/include/linux/hid.h @@ -1219,6 +1219,7 @@ static inline u32 hid_report_len(struct hid_report *report) int hid_report_raw_event(struct hid_device *hid, int type, u8 *data, u32 size, int interrupt); +void hid_get_feature(struct hid_device *hdev, struct hid_report *report); /* HID quirks API */ unsigned long hid_lookup_quirk(const struct hid_device *hdev); From patchwork Tue Dec 21 19:17:31 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Angela Czubak X-Patchwork-Id: 12690449 X-Patchwork-Delegate: jikos@jikos.cz 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 vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 62866C43217 for ; Tue, 21 Dec 2021 19:17:53 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S241739AbhLUTRw (ORCPT ); Tue, 21 Dec 2021 14:17:52 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:57852 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S241742AbhLUTRw (ORCPT ); Tue, 21 Dec 2021 14:17:52 -0500 Received: from mail-wm1-x32e.google.com (mail-wm1-x32e.google.com [IPv6:2a00:1450:4864:20::32e]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 3B2F6C061574 for ; Tue, 21 Dec 2021 11:17:52 -0800 (PST) Received: by mail-wm1-x32e.google.com with SMTP id b73so100682wmd.0 for ; Tue, 21 Dec 2021 11:17:52 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=semihalf-com.20210112.gappssmtp.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=xSCw5K4AnkP2An+YATsjN2i5JFyLHn8xlnkNkxCanGA=; b=J7fGzlAeoSFT67ygCKFecvdBTuM+JU5wD00x2R7n9owvMbhLo5HexyruYcIbBvjUUj ybZvyGQvTN1rLOT3OMABeqMYJVY2L/K5h2fYt+mRUA+NaPf1I/vhnj9LwxmNQ3RGbMd+ scXlIeHV7TSsHI/aQ+JH/EMYCdW8u3wQUqPQVIR0V3FS1k7EYU87IE4GJ8z34b30KhHm 3EKA+jljIO/geEwtFbyy1I6DfaXRZD0MsrljmlGz/b3SdOtprs02Vfa1SgSbHa3Ybqid sS86JAfeYgzdkYTH2YHgBmUIB8Op4ubP7vL7Ier6RsAL/6vVgduE5Pkfyj0PLo/xOZUk LZeg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=xSCw5K4AnkP2An+YATsjN2i5JFyLHn8xlnkNkxCanGA=; b=0DNAs568p7MKHUX9X7pQXsfiGE3Z2AxPcm38PueuXB9a5KZQIDPaMoB6ldViXTr3AA tHBOdWrDOky9d2soXGrFmBx4yaCsL6c2ockfGXemrhAS6yICtoidSFNvCvIes+TJK5HD ddydZmuYgJU1zZ65m10KJOLNqD0rAhFnKfPyvWmfF+bPFwAsm3zTIWNFJi3M5dkLi8pC Om3VDCRs5pridm/G7GCP+GbtMWxyQXCzNRw+U4dqoOKbna/Zgdt/hJdCmJaoNvognLjk bQp/t6CqCr4flida61ymWilDha088Ad5JXBkuE8aU7OOVc87tCMPmpmUyw1IIX5L1D5M FIjw== X-Gm-Message-State: AOAM5328FAVNizPF1Km9nk4SmlKIp3YEZqmk94EiDz0TNM7QaxpHhKpj mQ0kwRPZi2/gNPDwLz8Exmynse4gspDcNHRmB/M= X-Google-Smtp-Source: ABdhPJxpdp9dZhqS7QyPYkgwk9nJEvyQEQhuEEjSLMm6jcREYBBvR+Nb1h/oo2ualxCZjOAFZKOMcg== X-Received: by 2002:a05:600c:4e8d:: with SMTP id f13mr3939161wmq.7.1640114270817; Tue, 21 Dec 2021 11:17:50 -0800 (PST) Received: from aczubak.c.googlers.com.com (109.36.187.35.bc.googleusercontent.com. [35.187.36.109]) by smtp.gmail.com with ESMTPSA id t8sm3994846wmq.32.2021.12.21.11.17.50 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 21 Dec 2021 11:17:50 -0800 (PST) From: Angela Czubak To: linux-input@vger.kernel.org Cc: upstream@semihalf.com, dmitry.torokhov@gmail.com, Angela Czubak Subject: [PATCH 06/18] HID: haptic: add functions for mapping and configuration Date: Tue, 21 Dec 2021 19:17:31 +0000 Message-Id: <20211221191743.1893185-7-acz@semihalf.com> X-Mailer: git-send-email 2.34.1.307.g9b7440fafd-goog In-Reply-To: <20211221191743.1893185-1-acz@semihalf.com> References: <20211221191743.1893185-1-acz@semihalf.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-input@vger.kernel.org Add functions that recognize auto trigger and manual trigger reports as well as save their addresses. Verify that the pressure unit is either grams or newtons. Mark the input device as a haptic touchpad if the unit is correct and the reports are found. Signed-off-by: Angela Czubak --- drivers/hid/hid-haptic.c | 63 ++++++++++++++++++++++++++++++++++++++++ drivers/hid/hid-haptic.h | 46 +++++++++++++++++++++++++++++ 2 files changed, 109 insertions(+) diff --git a/drivers/hid/hid-haptic.c b/drivers/hid/hid-haptic.c index 0910d8af9f38..f130ec96a240 100644 --- a/drivers/hid/hid-haptic.c +++ b/drivers/hid/hid-haptic.c @@ -7,4 +7,67 @@ /* */ + #include "hid-haptic.h" + +void hid_haptic_feature_mapping(struct hid_device *hdev, + struct hid_haptic_device *haptic, + struct hid_field *field, struct hid_usage *usage) +{ + if (usage->hid == HID_HP_AUTOTRIGGER) { + if (usage->usage_index >= field->report_count) { + dev_err(&hdev->dev, + "HID_HP_AUTOTRIGGER out of range\n"); + return; + } + + hid_get_feature(hdev, field->report); + haptic->default_auto_trigger = + field->value[usage->usage_index]; + haptic->auto_trigger_report = field->report; + } +} +EXPORT_SYMBOL_GPL(hid_haptic_feature_mapping); + +bool hid_haptic_check_pressure_unit(struct hid_haptic_device *haptic, + struct hid_input *hi, struct hid_field *field) +{ + /* Accepted units are either grams or newtons. */ + if (field->unit == 0x0101 || field->unit == 0xe111) + return true; + return false; +} +EXPORT_SYMBOL_GPL(hid_haptic_check_pressure_unit); + +int hid_haptic_input_mapping(struct hid_device *hdev, + struct hid_haptic_device *haptic, + struct hid_input *hi, + struct hid_field *field, struct hid_usage *usage, + unsigned long **bit, int *max) +{ + if (usage->hid == HID_HP_MANUALTRIGGER) { + haptic->manual_trigger_report = field->report; + /* we don't really want to map these fields */ + return -1; + } + + return 0; +} +EXPORT_SYMBOL_GPL(hid_haptic_input_mapping); + +int hid_haptic_input_configured(struct hid_device *hdev, + struct hid_haptic_device *haptic, + struct hid_input *hi) +{ + + if (hi->application == HID_DG_TOUCHPAD) { + if (haptic->auto_trigger_report && + haptic->manual_trigger_report) { + __set_bit(INPUT_PROP_HAPTIC_TOUCHPAD, hi->input->propbit); + return 1; + } + return 0; + } + return -1; +} +EXPORT_SYMBOL_GPL(hid_haptic_input_configured); diff --git a/drivers/hid/hid-haptic.h b/drivers/hid/hid-haptic.h index 41f19cd22f75..4645d6cfd55a 100644 --- a/drivers/hid/hid-haptic.h +++ b/drivers/hid/hid-haptic.h @@ -66,3 +66,49 @@ struct hid_haptic_device { struct hid_haptic_effect *effect; struct hid_haptic_effect stop_effect; }; + +#ifdef CONFIG_MULTITOUCH_HAPTIC +void hid_haptic_feature_mapping(struct hid_device *hdev, + struct hid_haptic_device *haptic, + struct hid_field *field, struct hid_usage + *usage); +bool hid_haptic_check_pressure_unit(struct hid_haptic_device *haptic, + struct hid_input *hi, struct hid_field *field); +int hid_haptic_input_mapping(struct hid_device *hdev, + struct hid_haptic_device *haptic, + struct hid_input *hi, + struct hid_field *field, struct hid_usage *usage, + unsigned long **bit, int *max); +int hid_haptic_input_configured(struct hid_device *hdev, + struct hid_haptic_device *haptic, + struct hid_input *hi); +#else +static inline +void hid_haptic_feature_mapping(struct hid_device *hdev, + struct hid_haptic_device *haptic, + struct hid_field *field, struct hid_usage + *usage) +{} +static inline +bool hid_haptic_check_pressure_unit(struct hid_haptic_device *haptic, + struct hid_input *hi, struct hid_field *field) +{ + return false; +} +static inline +int hid_haptic_input_mapping(struct hid_device *hdev, + struct hid_haptic_device *haptic, + struct hid_input *hi, + struct hid_field *field, struct hid_usage *usage, + unsigned long **bit, int *max) +{ + return 0; +} +static inline +int hid_haptic_input_configured(struct hid_device *hdev, + struct hid_haptic_device *haptic, + struct hid_input *hi) +{ + return 0; +} +#endif From patchwork Tue Dec 21 19:17:32 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Angela Czubak X-Patchwork-Id: 12690451 X-Patchwork-Delegate: jikos@jikos.cz 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 vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 10C6CC433EF for ; Tue, 21 Dec 2021 19:17:54 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S241742AbhLUTRx (ORCPT ); Tue, 21 Dec 2021 14:17:53 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:57854 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S241744AbhLUTRx (ORCPT ); Tue, 21 Dec 2021 14:17:53 -0500 Received: from mail-wr1-x435.google.com (mail-wr1-x435.google.com [IPv6:2a00:1450:4864:20::435]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id A0149C06173F for ; Tue, 21 Dec 2021 11:17:52 -0800 (PST) Received: by mail-wr1-x435.google.com with SMTP id v7so21605738wrv.12 for ; Tue, 21 Dec 2021 11:17:52 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=semihalf-com.20210112.gappssmtp.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=lMBsWcSJgb9i8qVTJYXW8mi34u0001qEof9Eg4CN2wo=; b=GU/0Uh223BuhV47IeS7prq9ccAttcAf8W0xnzcDu8EzdbfaAV7SeMOUbI5z2E1pP9e 8TJy7mls6RD/8H+dWBy77IrCYZvNF1HKcZhGk30DKmEuv9ZmREci95rekuzoGV6yhc3k F/yoIbfNmhteBDaOD+gCRGORW7L6hgs8irwCzz8BCaQCPRDUaKkYFBggiCC8Pfm++Pam W2lBbRVZqjzZdpgYVXEquiYz8USTCb7UnAlEH5uVazrvqZo5taW+6BKAAPPwKbrSGng1 J/3bMZMkgVpr2ObUoXLlLNZo1PYzbSp9Cxsyk8nMPPI8C0mSNbZz3WrLiciKQ47Cl5lc CuHg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=lMBsWcSJgb9i8qVTJYXW8mi34u0001qEof9Eg4CN2wo=; b=fN/ENoIsr9hpYvuhXTJyIRLjmKo+9LCJQ4UjRzXa2L5JQ+d8hwiPe1rRsf+RIM3uVV /EMdIja2Tj2YVlGc3P/tBVfGb/gjiPd2rnclTU/Hhz32U6zFOVd3fegD5aBlRny0SAcw NInHV+ZgmQTCZ8gC8A8jy+UMSNx9Ev2KTEaI6FcyBWN+XN0vV0liFJkLlDvH0sFpR2cZ jmhknvQ1AcWqoZjTgS0by2v/9W+ASujT9CE+pNRI4Y6/DUsc9RZ+Tm3ol1rwbIE9z4CR I1YqFKRph3wMXgyfKSnj+5T96pkeTXTuZZ95Oxk9R6V6IoMhjvUqmXdBWp+sfsWMj0k8 XKJQ== X-Gm-Message-State: AOAM532vdaW2ItQ16Oz5t4NIlzobj1kYulnX5PYDsRqbm7eIOvSAEv14 qJewU1N48GyGJOpnYBZ4L5x/j2fw/wChSeux6/o= X-Google-Smtp-Source: ABdhPJzWAJvxrBBIhlt/mDRRTm/ZiXJ6WWfJh/CoYy9ntU7rm06IakF4I0fxRYre5bc6sBOSzIJu8Q== X-Received: by 2002:a5d:51d2:: with SMTP id n18mr3699215wrv.83.1640114271241; Tue, 21 Dec 2021 11:17:51 -0800 (PST) Received: from aczubak.c.googlers.com.com (109.36.187.35.bc.googleusercontent.com. [35.187.36.109]) by smtp.gmail.com with ESMTPSA id t8sm3994846wmq.32.2021.12.21.11.17.50 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 21 Dec 2021 11:17:50 -0800 (PST) From: Angela Czubak To: linux-input@vger.kernel.org Cc: upstream@semihalf.com, dmitry.torokhov@gmail.com, Angela Czubak Subject: [PATCH 07/18] HID: input: allow mapping of haptic output Date: Tue, 21 Dec 2021 19:17:32 +0000 Message-Id: <20211221191743.1893185-8-acz@semihalf.com> X-Mailer: git-send-email 2.34.1.307.g9b7440fafd-goog In-Reply-To: <20211221191743.1893185-1-acz@semihalf.com> References: <20211221191743.1893185-1-acz@semihalf.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-input@vger.kernel.org This change makes it possible to parse output reports by input mapping functions by HID drivers. Signed-off-by: Angela Czubak Reviewed-by: Dmitry Torokhov --- drivers/hid/hid-input.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c index 03f994541981..81eb277dee91 100644 --- a/drivers/hid/hid-input.c +++ b/drivers/hid/hid-input.c @@ -599,9 +599,10 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel if (field->report_count < 1) goto ignore; - /* only LED usages are supported in output fields */ + /* only LED and HAPTIC usages are supported in output fields */ if (field->report_type == HID_OUTPUT_REPORT && - (usage->hid & HID_USAGE_PAGE) != HID_UP_LED) { + (usage->hid & HID_USAGE_PAGE) != HID_UP_LED && + (usage->hid & HID_USAGE_PAGE) != HID_UP_HAPTIC) { goto ignore; } From patchwork Tue Dec 21 19:17:33 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Angela Czubak X-Patchwork-Id: 12690453 X-Patchwork-Delegate: jikos@jikos.cz 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 vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 5A82EC433F5 for ; Tue, 21 Dec 2021 19:17:54 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S241744AbhLUTRx (ORCPT ); Tue, 21 Dec 2021 14:17:53 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:57860 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S241746AbhLUTRx (ORCPT ); Tue, 21 Dec 2021 14:17:53 -0500 Received: from mail-wm1-x332.google.com (mail-wm1-x332.google.com [IPv6:2a00:1450:4864:20::332]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 3A413C061574 for ; Tue, 21 Dec 2021 11:17:53 -0800 (PST) Received: by mail-wm1-x332.google.com with SMTP id g132so77475wmg.2 for ; Tue, 21 Dec 2021 11:17:53 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=semihalf-com.20210112.gappssmtp.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=Ev2sZ7oE+x7h39+b3vSh344SBuXP/y6vNWeQ9ZHs/jg=; b=lolj1jLA41ETxNfWP32IIPMycTwfurdXH/ieAedFyM4SQ7Q5rq1lDGoXW3lxmW5/Dt fgURVJxBIW5qF0PazUvwgF3s8IoQ0jABxgGhNxf2lTXUI5FxVvAad65929UIkrj0DZDj q038aRi/q4sDrf2/LG12ddni0u5sKYnnF+JWeOeRW4zHD9ZARyaKathti/MZnZosYOlT xfqh54lK+4721oqi2jVDWj4iFHbXVrrL1sY0P7q4/kJNytcghqPOzP4wIrSddbJA9VZ4 TdyScTEIxwi5zwrTMWZdRa68sZSjSHhXo9Rtx+C+qkneytde35ByqT4z7nwLBErhzKyR 4/yw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=Ev2sZ7oE+x7h39+b3vSh344SBuXP/y6vNWeQ9ZHs/jg=; b=p5cMkWnPMz0xL3amCR5g1bcgjS+Sm2NMUTB7xUBW/K3L9mju3VpoPTnnq6YpUmRKDx +taUF2KX6D8Z5ybwOJJDTrlPDSRRdD6GBAC7T5mBapMCbBXHnz/h7wBVgqSmNcuExajU 8B2gvcQSBFuQI99aLnbG4ClrvilT4Xd5fq37ncKs1Y1KrlE42F/2mUymBjmm2ron7u/V ewkohg7NwQp0jQAWhYB4mfaoBZ7lUsKa0u8H54UXKMzZs51q9AwMlz71499vWhgtTTyQ OK8tWv5SGWVKKOXG088TQuuqLTnGLm7iJq5KTB2KoWE8+Pj2Bb8SkzRYYkJY46er5qN3 rL7g== X-Gm-Message-State: AOAM531ute4Fj2SAEU2hiQdQt2X2IjZXjccSi4P5O/ZbkYCaJeo/q0UG dR5ZoNvVJJ9sSTPSMROGp1IcHv84qyk+pR25dlw= X-Google-Smtp-Source: ABdhPJwPKxF3wLDLlFH1yMsZHaW7+NGn7VIObvgqDWe0rlz0VZLQVSsTn8caEPDgnrc7sT7POEHKyg== X-Received: by 2002:a05:600c:3acd:: with SMTP id d13mr4058163wms.37.1640114271786; Tue, 21 Dec 2021 11:17:51 -0800 (PST) Received: from aczubak.c.googlers.com.com (109.36.187.35.bc.googleusercontent.com. [35.187.36.109]) by smtp.gmail.com with ESMTPSA id t8sm3994846wmq.32.2021.12.21.11.17.51 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 21 Dec 2021 11:17:51 -0800 (PST) From: Angela Czubak To: linux-input@vger.kernel.org Cc: upstream@semihalf.com, dmitry.torokhov@gmail.com, Angela Czubak Subject: [PATCH 08/18] HID: haptic: initialize haptic device Date: Tue, 21 Dec 2021 19:17:33 +0000 Message-Id: <20211221191743.1893185-9-acz@semihalf.com> X-Mailer: git-send-email 2.34.1.307.g9b7440fafd-goog In-Reply-To: <20211221191743.1893185-1-acz@semihalf.com> References: <20211221191743.1893185-1-acz@semihalf.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-input@vger.kernel.org Add hid_haptic_init(). Parse autotrigger report to retrieve ordinals for press and release waveforms. Implement force feedback functions. Signed-off-by: Angela Czubak --- drivers/hid/hid-haptic.c | 445 +++++++++++++++++++++++++++++++++++++++ drivers/hid/hid-haptic.h | 6 + 2 files changed, 451 insertions(+) diff --git a/drivers/hid/hid-haptic.c b/drivers/hid/hid-haptic.c index f130ec96a240..b66bde7475e4 100644 --- a/drivers/hid/hid-haptic.c +++ b/drivers/hid/hid-haptic.c @@ -8,12 +8,16 @@ /* */ +#include + #include "hid-haptic.h" void hid_haptic_feature_mapping(struct hid_device *hdev, struct hid_haptic_device *haptic, struct hid_field *field, struct hid_usage *usage) { + u16 usage_hid; + if (usage->hid == HID_HP_AUTOTRIGGER) { if (usage->usage_index >= field->report_count) { dev_err(&hdev->dev, @@ -25,6 +29,20 @@ void hid_haptic_feature_mapping(struct hid_device *hdev, haptic->default_auto_trigger = field->value[usage->usage_index]; haptic->auto_trigger_report = field->report; + } else if ((usage->hid & HID_USAGE_PAGE) == HID_UP_ORDINAL) { + usage_hid = usage->hid & HID_USAGE; + switch (field->logical) { + case HID_HP_WAVEFORMLIST: + if (usage_hid > haptic->max_waveform_id) + haptic->max_waveform_id = usage_hid; + break; + case HID_HP_DURATIONLIST: + if (usage_hid > haptic->max_duration_id) + haptic->max_duration_id = usage_hid; + break; + default: + break; + } } } EXPORT_SYMBOL_GPL(hid_haptic_feature_mapping); @@ -71,3 +89,430 @@ int hid_haptic_input_configured(struct hid_device *hdev, return -1; } EXPORT_SYMBOL_GPL(hid_haptic_input_configured); + +static void parse_auto_trigger_field(struct hid_haptic_device *haptic, + struct hid_field *field) +{ + int count = field->report_count; + int n; + u16 usage_hid; + + for (n = 0; n < count; n++) { + switch (field->usage[n].hid & HID_USAGE_PAGE) { + case HID_UP_ORDINAL: + usage_hid = field->usage[n].hid & HID_USAGE; + switch (field->logical) { + case HID_HP_WAVEFORMLIST: + haptic->hid_usage_map[usage_hid] = field->value[n]; + if (field->value[n] == + (HID_HP_WAVEFORMPRESS & HID_USAGE)) { + haptic->press_ordinal_orig = usage_hid; + haptic->press_ordinal_cur = usage_hid; + } else if (field->value[n] == + (HID_HP_WAVEFORMRELEASE & HID_USAGE)) { + haptic->release_ordinal_orig = usage_hid; + haptic->release_ordinal_cur = usage_hid; + } + break; + case HID_HP_DURATIONLIST: + haptic->duration_map[usage_hid] = + field->value[n]; + break; + default: + break; + } + break; + case HID_UP_HAPTIC: + switch (field->usage[n].hid) { + case HID_HP_WAVEFORMVENDORID: + haptic->vendor_id = field->value[n]; + break; + case HID_HP_WAVEFORMVENDORPAGE: + haptic->vendor_page = field->value[n]; + break; + default: + break; + } + break; + default: + /* Should not really happen */ + break; + } + } +} + +static void fill_effect_buf(struct hid_haptic_device *haptic, + struct ff_hid_effect *effect, + struct hid_haptic_effect *haptic_effect, + int waveform_ordinal) +{ + struct hid_report *rep = haptic->manual_trigger_report; + struct hid_usage *usage; + struct hid_field *field; + s32 value; + int i, j; + u8 *buf = haptic_effect->report_buf; + + mutex_lock(&haptic->manual_trigger_mutex); + for (i = 0; i < rep->maxfield; i++) { + field = rep->field[i]; + /* Ignore if report count is out of bounds. */ + if (field->report_count < 1) + continue; + + for (j = 0; j < field->maxusage; j++) { + usage = &field->usage[j]; + + switch (usage->hid) { + case HID_HP_INTENSITY: + if (effect->intensity > 100) { + value = field->logical_maximum; + } else { + value = field->logical_minimum + + effect->intensity * + (field->logical_maximum - + field->logical_minimum) / 100; + } + break; + case HID_HP_REPEATCOUNT: + value = effect->repeat_count; + break; + case HID_HP_RETRIGGERPERIOD: + value = effect->retrigger_period; + break; + case HID_HP_MANUALTRIGGER: + value = waveform_ordinal; + break; + default: + break; + } + + field->value[j] = value; + } + } + + hid_output_report(rep, buf); + mutex_unlock(&haptic->manual_trigger_mutex); +} + +static int hid_haptic_upload_effect(struct input_dev *dev, struct ff_effect *effect, + struct ff_effect *old) +{ + struct ff_device *ff = dev->ff; + struct hid_haptic_device *haptic = ff->private; + int i, ordinal = 0; + + /* If vendor range, check vendor id and page */ + if (effect->u.hid.hid_usage >= (HID_HP_VENDORWAVEFORMMIN & HID_USAGE) && + effect->u.hid.hid_usage <= (HID_HP_VENDORWAVEFORMMAX & HID_USAGE) && + (effect->u.hid.vendor_id != haptic->vendor_id || + effect->u.hid.vendor_waveform_page != haptic->vendor_page)) + return -EINVAL; + + /* Check hid_usage */ + for (i = 1; i < haptic->max_waveform_id; i++) { + if (haptic->hid_usage_map[i] == effect->u.hid.hid_usage) { + ordinal = i; + break; + } + } + if (ordinal < 1) + return -EINVAL; + + /* Fill the buffer for the efect id */ + fill_effect_buf(haptic, &effect->u.hid, &haptic->effect[effect->id], + ordinal); + + return 0; +} + +static int play_effect(struct hid_device *hdev, struct hid_haptic_device *haptic, + struct hid_haptic_effect *effect) +{ + int ret; + + ret = hid_hw_output_report(hdev, effect->report_buf, + haptic->manual_trigger_report_len); + if (ret < 0) { + ret = hid_hw_raw_request(hdev, + haptic->manual_trigger_report->id, + effect->report_buf, + haptic->manual_trigger_report_len, + HID_OUTPUT_REPORT, HID_REQ_SET_REPORT); + + } + + return ret; +} + +static void haptic_work_handler(struct work_struct *work) +{ + + struct hid_haptic_effect *effect = container_of(work, + struct hid_haptic_effect, + work); + struct input_dev *dev = effect->input_dev; + struct hid_device *hdev = input_get_drvdata(dev); + struct hid_haptic_device *haptic = dev->ff->private; + + mutex_lock(&haptic->manual_trigger_mutex); + if (effect != &haptic->stop_effect) + play_effect(hdev, haptic, &haptic->stop_effect); + + play_effect(hdev, haptic, effect); + mutex_unlock(&haptic->manual_trigger_mutex); + +} + +static int hid_haptic_playback(struct input_dev *dev, int effect_id, int value) +{ + struct hid_haptic_device *haptic = dev->ff->private; + + if (value) + queue_work(haptic->wq, &haptic->effect[effect_id].work); + else + queue_work(haptic->wq, &haptic->stop_effect.work); + + return 0; +} + +static void effect_set_default(struct ff_effect *effect) +{ + effect->type = FF_HID; + effect->id = -1; + effect->u.hid.hid_usage = HID_HP_WAVEFORMNONE & HID_USAGE; + effect->u.hid.intensity = 100; + effect->u.hid.retrigger_period = 0; + effect->u.hid.repeat_count = 0; +} + +static int hid_haptic_erase(struct input_dev *dev, int effect_id) +{ + struct hid_haptic_device *haptic = dev->ff->private; + struct ff_effect effect; + int ordinal; + + effect_set_default(&effect); + switch (effect_id) { + case HID_HAPTIC_RELEASE_EFFECT_ID: + ordinal = haptic->release_ordinal_orig; + if (!ordinal) + ordinal = HID_HAPTIC_ORDINAL_WAVEFORMNONE; + else + effect.u.hid.hid_usage = HID_HP_WAVEFORMRELEASE & + HID_USAGE; + fill_effect_buf(haptic, &effect.u.hid, &haptic->effect[effect_id], + ordinal); + break; + case HID_HAPTIC_PRESS_EFFECT_ID: + ordinal = haptic->press_ordinal_orig; + if (!ordinal) + ordinal = HID_HAPTIC_ORDINAL_WAVEFORMNONE; + else + effect.u.hid.hid_usage = HID_HP_WAVEFORMPRESS & + HID_USAGE; + fill_effect_buf(haptic, &effect.u.hid, &haptic->effect[effect_id], + ordinal); + break; + default: + break; + } + + return 0; +} + +static void hid_haptic_destroy(struct ff_device *ff) +{ + struct hid_haptic_device *haptic = ff->private; + struct hid_device *hdev = haptic->hdev; + int r; + + if (hdev) + put_device(&hdev->dev); + + kfree(haptic->stop_effect.report_buf); + haptic->stop_effect.report_buf = NULL; + + if (haptic->effect) { + for (r = 0; r < ff->max_effects; r++) + kfree(haptic->effect[r].report_buf); + kfree(haptic->effect); + } + haptic->effect = NULL; + + destroy_workqueue(haptic->wq); + haptic->wq = NULL; + + kfree(haptic->duration_map); + haptic->duration_map = NULL; + + kfree(haptic->hid_usage_map); + haptic->hid_usage_map = NULL; + + module_put(THIS_MODULE); +} + +int hid_haptic_init(struct hid_device *hdev, + struct hid_haptic_device **haptic_ptr) +{ + struct hid_haptic_device *haptic = *haptic_ptr; + struct input_dev *dev = NULL; + struct hid_input *hidinput; + struct ff_device *ff; + int ret = 0, r; + struct ff_hid_effect stop_effect = { + .hid_usage = HID_HP_WAVEFORMSTOP & HID_USAGE, + }; + const char *prefix = "hid-haptic"; + char *name; + int (*flush)(struct input_dev *dev, struct file *file); + int (*event)(struct input_dev *dev, unsigned int type, unsigned int code, int value); + + haptic->hdev = hdev; + haptic->max_waveform_id = max(2u, haptic->max_waveform_id); + haptic->max_duration_id = max(2u, haptic->max_duration_id); + + haptic->hid_usage_map = kcalloc(haptic->max_waveform_id + 1, + sizeof(__u16), GFP_KERNEL); + if (!haptic->hid_usage_map) { + ret = -ENOMEM; + goto exit; + } + haptic->duration_map = kcalloc(haptic->max_duration_id + 1, + sizeof(__u32), GFP_KERNEL); + if (!haptic->duration_map) { + ret = -ENOMEM; + goto usage_map; + } + + if (haptic->max_waveform_id != haptic->max_duration_id) + dev_warn(&hdev->dev, + "Haptic duration and waveform lists have different max id (%u and %u).\n", + haptic->max_duration_id, haptic->max_waveform_id); + + haptic->hid_usage_map[HID_HAPTIC_ORDINAL_WAVEFORMNONE] = + HID_HP_WAVEFORMNONE & HID_USAGE; + haptic->hid_usage_map[HID_HAPTIC_ORDINAL_WAVEFORMSTOP] = + HID_HP_WAVEFORMSTOP & HID_USAGE; + + for (r = 0; r < haptic->auto_trigger_report->maxfield; r++) + parse_auto_trigger_field(haptic, haptic->auto_trigger_report->field[r]); + + list_for_each_entry(hidinput, &hdev->inputs, list) { + if (hidinput->application == HID_DG_TOUCHPAD) { + dev = hidinput->input; + break; + } + } + + if (!dev) { + dev_err(&hdev->dev, "Failed to find the input device\n"); + ret = -ENODEV; + goto duration_map; + } + + haptic->input_dev = dev; + haptic->manual_trigger_report_len = + hid_report_len(haptic->manual_trigger_report); + mutex_init(&haptic->manual_trigger_mutex); + name = kmalloc(strlen(prefix) + strlen(hdev->name) + 2, GFP_KERNEL); + if (name) { + sprintf(name, "%s %s", prefix, hdev->name); + haptic->wq = create_singlethread_workqueue(name); + kfree(name); + } + if (!haptic->wq) { + ret = -ENOMEM; + goto duration_map; + } + haptic->effect = kcalloc(FF_MAX_EFFECTS, + sizeof(struct hid_haptic_effect), GFP_KERNEL); + if (!haptic->effect) { + ret = -ENOMEM; + goto output_queue; + } + for (r = 0; r < FF_MAX_EFFECTS; r++) { + haptic->effect[r].report_buf = + hid_alloc_report_buf(haptic->manual_trigger_report, + GFP_KERNEL); + if (!haptic->effect[r].report_buf) { + dev_err(&hdev->dev, + "Failed to allocate a buffer for an effect.\n"); + ret = -ENOMEM; + goto buffer_free; + } + haptic->effect[r].input_dev = dev; + INIT_WORK(&haptic->effect[r].work, haptic_work_handler); + } + haptic->stop_effect.report_buf = + hid_alloc_report_buf(haptic->manual_trigger_report, + GFP_KERNEL); + if (!haptic->stop_effect.report_buf) { + dev_err(&hdev->dev, + "Failed to allocate a buffer for stop effect.\n"); + ret = -ENOMEM; + goto buffer_free; + } + haptic->stop_effect.input_dev = dev; + INIT_WORK(&haptic->stop_effect.work, haptic_work_handler); + fill_effect_buf(haptic, &stop_effect, &haptic->stop_effect, + HID_HAPTIC_ORDINAL_WAVEFORMSTOP); + + input_set_capability(dev, EV_FF, FF_HID); + + flush = dev->flush; + event = dev->event; + ret = input_ff_create(dev, FF_MAX_EFFECTS); + if (ret) { + dev_err(&hdev->dev, "Failed to create ff device.\n"); + goto stop_buffer_free; + } + + ff = dev->ff; + ff->private = haptic; + ff->upload = hid_haptic_upload_effect; + ff->playback = hid_haptic_playback; + ff->erase = hid_haptic_erase; + ff->destroy = hid_haptic_destroy; + if (!try_module_get(THIS_MODULE)) { + dev_err(&hdev->dev, "Failed to increase module count.\n"); + goto input_free; + } + if (!get_device(&hdev->dev)) { + dev_err(&hdev->dev, "Failed to get hdev device.\n"); + module_put(THIS_MODULE); + goto input_free; + } + return 0; + +input_free: + input_ff_destroy(dev); + /* Do not let double free happen, input_ff_destroy will call + * hid_haptic_destroy. + */ + *haptic_ptr = NULL; + /* Restore dev flush and event */ + dev->flush = flush; + dev->event = event; + return ret; +stop_buffer_free: + kfree(haptic->stop_effect.report_buf); + haptic->stop_effect.report_buf = NULL; +buffer_free: + while (--r >= 0) + kfree(haptic->effect[r].report_buf); + kfree(haptic->effect); + haptic->effect = NULL; +output_queue: + destroy_workqueue(haptic->wq); + haptic->wq = NULL; +duration_map: + kfree(haptic->duration_map); + haptic->duration_map = NULL; +usage_map: + kfree(haptic->hid_usage_map); + haptic->hid_usage_map = NULL; +exit: + return ret; +} +EXPORT_SYMBOL_GPL(hid_haptic_init); diff --git a/drivers/hid/hid-haptic.h b/drivers/hid/hid-haptic.h index 4645d6cfd55a..2581833125dd 100644 --- a/drivers/hid/hid-haptic.h +++ b/drivers/hid/hid-haptic.h @@ -82,6 +82,7 @@ int hid_haptic_input_mapping(struct hid_device *hdev, int hid_haptic_input_configured(struct hid_device *hdev, struct hid_haptic_device *haptic, struct hid_input *hi); +int hid_haptic_init(struct hid_device *hdev, struct hid_haptic_device **haptic_ptr); #else static inline void hid_haptic_feature_mapping(struct hid_device *hdev, @@ -111,4 +112,9 @@ int hid_haptic_input_configured(struct hid_device *hdev, { return 0; } +static inline +int hid_haptic_init(struct hid_device *hdev, struct hid_haptic_device **haptic_ptr) +{ + return 0; +} #endif From patchwork Tue Dec 21 19:17:34 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Angela Czubak X-Patchwork-Id: 12690455 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 vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id D4B3CC4332F for ; Tue, 21 Dec 2021 19:17:54 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S241747AbhLUTRy (ORCPT ); Tue, 21 Dec 2021 14:17:54 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:57862 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S241746AbhLUTRy (ORCPT ); Tue, 21 Dec 2021 14:17:54 -0500 Received: from mail-wm1-x32c.google.com (mail-wm1-x32c.google.com [IPv6:2a00:1450:4864:20::32c]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id AF2F9C06173F for ; Tue, 21 Dec 2021 11:17:53 -0800 (PST) Received: by mail-wm1-x32c.google.com with SMTP id 203-20020a1c01d4000000b00345bf98da86so1161824wmb.3 for ; Tue, 21 Dec 2021 11:17:53 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=semihalf-com.20210112.gappssmtp.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=GdaWpy//TX5tfDTh/jiXY1Aj27hl0tvdjm01dm25ifs=; b=XVVArxziePNps6R3J26WCHcOcKZJQnAWH5bNbHHUjDNlM0gRNT9Q74hEr2mosRhi84 uJKD126MaeLEolivnzYD5QimXNiAtn7AyfuPaaJpgMB/zvz0I4EcakAEgaTbXLh4YlZA wMvyhM4ATiX8BgCA/RKh7w1A5I3xdQLkl82YuzO7PWXQdcASymFSQCndwfv+IuDIHm3U 4g2+yhaLHbS7M+eocLhTevuvjJV5zfWTOv9RZuijwUtr+SyW9q3y0M1HS573L/FI5k8K FCH9lLdlvhQxLY/D5qfnmmzrsWGlhE9ho7TETlRZ/QqQBPow6Sn2MfDz6s7/iOQu3ULA fF7Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=GdaWpy//TX5tfDTh/jiXY1Aj27hl0tvdjm01dm25ifs=; b=2X4cD73/w+W3oPBztWRUVtbE2Er0ptqexL+NGhBVtZY0UJqhH1eh8RgcRzrbVbKayi KtnK8LZt1Hvy8Tn9wqUGwsz1INmYjWgSmgcPpgzU0WbBT5iuIitmoZUdvZ8IntLqhx3m Pg210d8sRAl+JjUL6eoN1EBwe/v0qNJhWEqZ3R/wp3/3X+MGmyNJ8ZTX7hQSxWwjyTTa BIHhLEbp6rg7EDbjjKju4BDznaQuJuUgLd6fudU98OUgDD7cZjk0kxQ55ZP+PvOZX0Qy 3TkGewz58eyJ8+C/4aUqyau2tmnEASU7Yp07PTO7mfeo+uXLwsdo5r3hBMTDgdjeoYno J3sA== X-Gm-Message-State: AOAM530vY5Pl9trd+SWpJQrPvNRPVS24sr9jQqDdzt2+MWJVgcOiS5nV x1Tsi8OrtxeEU4UNkGq6I7L9j0lrqDXuQD64W68= X-Google-Smtp-Source: ABdhPJw0iP9OXM0sT7Zlj3dfG1T/AeZsazBQmXXNWy9N4psZBPZlLC2jAH7CkYhPGcXzSvl1F7bolQ== X-Received: by 2002:a7b:c745:: with SMTP id w5mr3849880wmk.167.1640114272282; Tue, 21 Dec 2021 11:17:52 -0800 (PST) Received: from aczubak.c.googlers.com.com (109.36.187.35.bc.googleusercontent.com. [35.187.36.109]) by smtp.gmail.com with ESMTPSA id t8sm3994846wmq.32.2021.12.21.11.17.51 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 21 Dec 2021 11:17:52 -0800 (PST) From: Angela Czubak To: linux-input@vger.kernel.org Cc: upstream@semihalf.com, dmitry.torokhov@gmail.com, Angela Czubak Subject: [PATCH 09/18] Input: add shared effects Date: Tue, 21 Dec 2021 19:17:34 +0000 Message-Id: <20211221191743.1893185-10-acz@semihalf.com> X-Mailer: git-send-email 2.34.1.307.g9b7440fafd-goog In-Reply-To: <20211221191743.1893185-1-acz@semihalf.com> References: <20211221191743.1893185-1-acz@semihalf.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-input@vger.kernel.org If an effect is uploaded with file handle equal UINTPTR_MAX assume this effect should be shared and so may be modified using different file handles. Signed-off-by: Angela Czubak --- drivers/input/ff-core.c | 40 ++++++++++++++++++++++++++++++++++------ 1 file changed, 34 insertions(+), 6 deletions(-) diff --git a/drivers/input/ff-core.c b/drivers/input/ff-core.c index 1cf5deda06e1..960ae0e29348 100644 --- a/drivers/input/ff-core.c +++ b/drivers/input/ff-core.c @@ -34,6 +34,23 @@ static int check_effect_access(struct ff_device *ff, int effect_id, return 0; } +/* + * Check that the effect_id is a valid effect and whether the effect + * is shared + */ +static int check_effect_shared(struct ff_device *ff, int effect_id) +{ + if (effect_id < 0 || effect_id >= ff->max_effects || + !ff->effect_owners[effect_id]) + return -EINVAL; + + /* Shared effect */ + if (ff->effect_owners[effect_id] == (struct file *)UINTPTR_MAX) + return 0; + + return -EACCES; +} + /* * Checks whether 2 effects can be combined together */ @@ -139,8 +156,11 @@ int input_ff_upload(struct input_dev *dev, struct ff_effect *effect, id = effect->id; ret = check_effect_access(ff, id, file); - if (ret) - goto out; + if (ret) { + ret = check_effect_shared(ff, id); + if (ret) + goto out; + } old = &ff->effects[id]; @@ -174,21 +194,29 @@ static int erase_effect(struct input_dev *dev, int effect_id, { struct ff_device *ff = dev->ff; int error; + bool shared = false; error = check_effect_access(ff, effect_id, file); - if (error) - return error; + if (error) { + error = check_effect_shared(ff, effect_id); + if (!error) + shared = true; + else + return error; + } spin_lock_irq(&dev->event_lock); ff->playback(dev, effect_id, 0); - ff->effect_owners[effect_id] = NULL; + if (!shared) + ff->effect_owners[effect_id] = NULL; spin_unlock_irq(&dev->event_lock); if (ff->erase) { error = ff->erase(dev, effect_id); if (error) { spin_lock_irq(&dev->event_lock); - ff->effect_owners[effect_id] = file; + if (!shared) + ff->effect_owners[effect_id] = file; spin_unlock_irq(&dev->event_lock); return error; From patchwork Tue Dec 21 19:17:35 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Angela Czubak X-Patchwork-Id: 12690457 X-Patchwork-Delegate: jikos@jikos.cz 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 vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 51D25C43217 for ; Tue, 21 Dec 2021 19:17:55 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S241750AbhLUTRy (ORCPT ); Tue, 21 Dec 2021 14:17:54 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:57868 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S241748AbhLUTRy (ORCPT ); Tue, 21 Dec 2021 14:17:54 -0500 Received: from mail-wm1-x334.google.com (mail-wm1-x334.google.com [IPv6:2a00:1450:4864:20::334]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 22D7BC061574 for ; Tue, 21 Dec 2021 11:17:54 -0800 (PST) Received: by mail-wm1-x334.google.com with SMTP id g132so77489wmg.2 for ; Tue, 21 Dec 2021 11:17:54 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=semihalf-com.20210112.gappssmtp.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=LR8/5fV9qusZx/QgD/+UbqkCnKskxPPI5tV0mku1W8U=; b=XcTc3ZHKrx1l48StSfvrGfu8RdKkH65zG0Hv6EaYBF5d4n8hWLCGCVcqPKJcmmtueI BMDDZ0aPMv3sTuCMg+LBQL5D8JTz01anT/AOZgN9syC1y4MXFm9LTQDqraJMjbZnPzc0 8pq3G2zjBwUqyF2pmqcU95a6xhqd7e47ai50S14PATQXtq003Qjq4INBe8ZfRIwSlHr4 uwb0xgkZuLGot5UK0OJEULGFJFXNRZI9pNSWiMGdDGOj8eY4633L5QbFICeV7y2LvV2v w0UnLKSz3Jg+hUq127KkCnRmyp8/Y6zXjwRZL1HfGwelfOCZCigenPkNbbgEJMFmoGZP 8c1w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=LR8/5fV9qusZx/QgD/+UbqkCnKskxPPI5tV0mku1W8U=; b=cYm5DAHQEoV5W1bn0wBKEUsz6JHQ68mCbwPyK79cG6CJYjSHPFsUZxiY2B+ninNktX PUTiXxxCuVbtep8ewSGVFQwS6zGaFrcsV6h/ZgK8aQc1RqInVezHe2vJ5Xw6zgqkNSdA j+YDCIBlaiDDtRC3A4JDd2uI6bcaZyum6jsQaEc9++pn1vu9qj4SnpMcDiUYr4d4XyKh 7imam3SMkPKgd75kn6Q9SkJsvQRmO1GcyxorEhBAzwWMnp3X/ikvGlq0xWkEa7/m7gzI i3+zAxvFr4aI17FNx09SVvFDrERQHtUzVte2wei8aTIwSg0vERL+8wMKCme/TfG0Wu74 g77g== X-Gm-Message-State: AOAM530vSBM7//kOOWHYGr1JCZdWky6Bomg/CSFvUlQmdfrvgLddpR+B 7X7IANvNyto0gJOn/Fixbbxl5aUXcTAnFLPw0f8= X-Google-Smtp-Source: ABdhPJy4MMSHr6NH/2oKfdCaPgENUlB8S3OWaxVGPsFLUb8KAYXSZMFf4HbNQfogLL6wzhKknQiayQ== X-Received: by 2002:a05:600c:4e91:: with SMTP id f17mr3983501wmq.195.1640114272770; Tue, 21 Dec 2021 11:17:52 -0800 (PST) Received: from aczubak.c.googlers.com.com (109.36.187.35.bc.googleusercontent.com. [35.187.36.109]) by smtp.gmail.com with ESMTPSA id t8sm3994846wmq.32.2021.12.21.11.17.52 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 21 Dec 2021 11:17:52 -0800 (PST) From: Angela Czubak To: linux-input@vger.kernel.org Cc: upstream@semihalf.com, dmitry.torokhov@gmail.com, Angela Czubak Subject: [PATCH 10/18] HID: haptic: implement release and press effects Date: Tue, 21 Dec 2021 19:17:35 +0000 Message-Id: <20211221191743.1893185-11-acz@semihalf.com> X-Mailer: git-send-email 2.34.1.307.g9b7440fafd-goog In-Reply-To: <20211221191743.1893185-1-acz@semihalf.com> References: <20211221191743.1893185-1-acz@semihalf.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-input@vger.kernel.org Upload shared haptic affects for release and press waveforms if a device exposes them. Signed-off-by: Angela Czubak --- drivers/hid/hid-haptic.c | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/drivers/hid/hid-haptic.c b/drivers/hid/hid-haptic.c index b66bde7475e4..ad458bc7d4c5 100644 --- a/drivers/hid/hid-haptic.c +++ b/drivers/hid/hid-haptic.c @@ -367,6 +367,7 @@ int hid_haptic_init(struct hid_device *hdev, char *name; int (*flush)(struct input_dev *dev, struct file *file); int (*event)(struct input_dev *dev, unsigned int type, unsigned int code, int value); + struct ff_effect release_effect, press_effect; haptic->hdev = hdev; haptic->max_waveform_id = max(2u, haptic->max_waveform_id); @@ -483,8 +484,41 @@ int hid_haptic_init(struct hid_device *hdev, module_put(THIS_MODULE); goto input_free; } + + effect_set_default(&release_effect); + if (haptic->release_ordinal_orig) + release_effect.u.hid.hid_usage = HID_HP_WAVEFORMRELEASE & + HID_USAGE; + ret = input_ff_upload(dev, &release_effect, (struct file *)UINTPTR_MAX); + if (ret || release_effect.id != HID_HAPTIC_RELEASE_EFFECT_ID) { + if (!ret) { + ret = -EBUSY; + input_ff_erase(dev, release_effect.id, + (struct file *)UINTPTR_MAX); + } + dev_err(&hdev->dev, + "Failed to allocate id 0 for release effect.\n"); + goto input_free; + } + effect_set_default(&press_effect); + if (haptic->press_ordinal_orig) + press_effect.u.hid.hid_usage = HID_HP_WAVEFORMPRESS & HID_USAGE; + ret = input_ff_upload(dev, &press_effect, (struct file *)UINTPTR_MAX); + if (ret || press_effect.id != HID_HAPTIC_PRESS_EFFECT_ID) { + if (!ret) { + ret = -EBUSY; + input_ff_erase(dev, press_effect.id, + (struct file *)UINTPTR_MAX); + } + dev_err(&hdev->dev, + "Failed to allocate id 1 for press effect.\n"); + goto release_free; + } + return 0; +release_free: + input_ff_erase(dev, release_effect.id, (struct file *)UINTPTR_MAX); input_free: input_ff_destroy(dev); /* Do not let double free happen, input_ff_destroy will call From patchwork Tue Dec 21 19:17:36 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Angela Czubak X-Patchwork-Id: 12690459 X-Patchwork-Delegate: jikos@jikos.cz 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 vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id AE92CC433FE for ; Tue, 21 Dec 2021 19:17:55 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S241748AbhLUTRz (ORCPT ); Tue, 21 Dec 2021 14:17:55 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:57870 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S241746AbhLUTRy (ORCPT ); Tue, 21 Dec 2021 14:17:54 -0500 Received: from mail-wm1-x32d.google.com (mail-wm1-x32d.google.com [IPv6:2a00:1450:4864:20::32d]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 8EA96C06173F for ; Tue, 21 Dec 2021 11:17:54 -0800 (PST) Received: by mail-wm1-x32d.google.com with SMTP id 203-20020a1c01d4000000b00345bf98da86so1161845wmb.3 for ; Tue, 21 Dec 2021 11:17:54 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=semihalf-com.20210112.gappssmtp.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=IEKdHvS3R1CuQNg6dXHvgBGNaaT106e2VaSGqBlDdrQ=; b=Zzhmtw1oYWgp24QKj8JQV+cno+Gr+7Vg++EK0uDApRWJjBxLvtBANNWWEiCxgSjlU4 OxnI4N7HBIAYmdJQxKKjAdFth9Dy2B64tuB4aYDx1kOpmzIG6vVg8ygdUwE4pbW0d5Wc atCgve9lVP/6ONPNKlsP136YSMp2S7JsxhiUfvDG7nV1lTlZ7mKsC+4eoMawBpAzT5UK sbAY+7P+ZpEOXiCYc9AX0LOA+qmFDfS+a2HoQwAYrMcM9iIPKXuFULvNO8izCOOJ/MDw NlBi6h2Bz8QeiaNuM8K0RezTxj+JaHfSeqvf3px5br3/GDNHVK3ZTGExo2HaVfel0Jmo AGxQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=IEKdHvS3R1CuQNg6dXHvgBGNaaT106e2VaSGqBlDdrQ=; b=TRRL2yek3/8FdtKs8Qlkp0twIFDdW4Bd1yVJdyUJbnxYx0kbarC2qO25n2HsBZrNfF exAf6mrs5/X2jYVXpxmtuLSUEYtL8seVYQmSzUh7HyBydUoATOm+T8h4K4eaEfdgOBYE +Dh38R8T9J8lsKoi215bOQi+Qo/56hPXYb1Ip+6dQHMMbNHpGgFdg6Xr93foYPKBail3 WQNwOBGsHJj5wmRdFgW67gORgLN5yQs/5bZBcR3ISSik6YdjYXis+J8eJkBt4XgLV9pO sNhvJdu9EU/YA6bI+iBzBtTlu0kNC9fsaWMr/oD0ChMEvwLmdeyxPMO3vaVLX9Racwn6 rA/g== X-Gm-Message-State: AOAM532qNVzDRRy2oqaCgwrnZ82nHYp5ddsnT+pEeJTdRmBxQphi7yqW rXBSVWVvmGG8Wk15DklELv5X9PDa/v+N7sD9VU0= X-Google-Smtp-Source: ABdhPJyffexhJzp2fjaOWx3XKP26SmEALIOqY9EeqsY7wSDuXc/IsGZrRUi6GDrZkNyGDmngC3y4WA== X-Received: by 2002:a1c:f608:: with SMTP id w8mr4156435wmc.50.1640114273191; Tue, 21 Dec 2021 11:17:53 -0800 (PST) Received: from aczubak.c.googlers.com.com (109.36.187.35.bc.googleusercontent.com. [35.187.36.109]) by smtp.gmail.com with ESMTPSA id t8sm3994846wmq.32.2021.12.21.11.17.52 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 21 Dec 2021 11:17:52 -0800 (PST) From: Angela Czubak To: linux-input@vger.kernel.org Cc: upstream@semihalf.com, dmitry.torokhov@gmail.com, Angela Czubak Subject: [PATCH 11/18] HID: input: calculate resolution for pressure Date: Tue, 21 Dec 2021 19:17:36 +0000 Message-Id: <20211221191743.1893185-12-acz@semihalf.com> X-Mailer: git-send-email 2.34.1.307.g9b7440fafd-goog In-Reply-To: <20211221191743.1893185-1-acz@semihalf.com> References: <20211221191743.1893185-1-acz@semihalf.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-input@vger.kernel.org Assume that if the pressure is given in newtons it should be normalized to grams. If the pressure has no unit do not calculate resolution. Signed-off-by: Angela Czubak --- drivers/hid/hid-input.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c index 81eb277dee91..b680641a30c0 100644 --- a/drivers/hid/hid-input.c +++ b/drivers/hid/hid-input.c @@ -257,6 +257,19 @@ __s32 hidinput_calc_abs_res(const struct hid_field *field, __u16 code) } break; + case ABS_PRESSURE: + case ABS_MT_PRESSURE: + if (field->unit == 0xe111) { /* If newtons */ + /* Convert to grams */ + prev = physical_extents; + physical_extents *= 10197; + if (physical_extents < prev) + return 0; + unit_exponent -= 2; + } else if (field->unit != 0x101) { /* If not grams */ + return 0; + } + break; default: return 0; } From patchwork Tue Dec 21 19:17:37 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Angela Czubak X-Patchwork-Id: 12690461 X-Patchwork-Delegate: jikos@jikos.cz 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 vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 3793BC43219 for ; Tue, 21 Dec 2021 19:17:56 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S241752AbhLUTRz (ORCPT ); Tue, 21 Dec 2021 14:17:55 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:57876 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S241746AbhLUTRz (ORCPT ); Tue, 21 Dec 2021 14:17:55 -0500 Received: from mail-wm1-x32e.google.com (mail-wm1-x32e.google.com [IPv6:2a00:1450:4864:20::32e]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 054CCC061574 for ; Tue, 21 Dec 2021 11:17:55 -0800 (PST) Received: by mail-wm1-x32e.google.com with SMTP id 203-20020a1c01d4000000b00345bf98da86so1161856wmb.3 for ; Tue, 21 Dec 2021 11:17:54 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=semihalf-com.20210112.gappssmtp.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=rbHTAoCtRAdudEsITz3WZkrHYqvrwmEh06T/gjLvpRk=; b=gN+ndH2d4QS3MC6v3wck1U4EpnounPoiDmS5KPhC3uZwb3R0Cw6pAGFX2fjlnQNtid npKqh9o2+cfdTwlTTQOiS5HTfIn4shua5XQfFaaQseEqsbTzknz6nrI+2dBTEcEO8G15 8B3fSjwb8vUd+GF9knz9EXJLlgKFPVrEBxDWkq3Q7ZJs7vP0T4M3ylx97N9uXEMCHDUl MnMrbnQ1fSrCmP4Qwj5BvmCx5VB8PqMlnsah8L8Yw0UZeJLmzSrRtygLtqmBiTRn4VFp af1k+DF/dBbFc2jrB3ogCS+oCpkQW0MSvsNmNsiYgkp81Br21TRduRmnyVqumsmFFth6 +JWw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=rbHTAoCtRAdudEsITz3WZkrHYqvrwmEh06T/gjLvpRk=; b=O/dbutZ1gx4ICLbGdflQ5JzJ8VbD1VP+bdwyOTqu2AbKtwRUXYO7G96ujRKAK0KkR6 EUTpsNcOYp05y9Ep+sGPHzVJ16EVEdn4/Hdgw4V1zPjLlpt1fDrbT11BplTo9IqnEQeD KbjQllhdu2yKiizRHfC+BG1qEvuvk3KtYYREbpsxUaFpDFD2b2uHwXtCyG+9xKOsTtGx oLY4EQqxPZQ2yweLySt1JrhDo/vDSuSqn3A86YJJ2eT8ahCKjTzBlYt9EAyD+XGqn0kb q5MZX1+yx2wSbSr6MyxWy96pB38s2lWpWz2f3V046tiE11WUSQccht9x+lbgI0NAc3CD GYmw== X-Gm-Message-State: AOAM533q5vwHZmxWAmhIGrCJ1R4cCZNMSf39Phgs0rILLgyN71DSQXej mGcFmuz8gjk2PP+UjvafWJ3AJjnZdyvGxGrNqGc= X-Google-Smtp-Source: ABdhPJycfHcBpQz4OnU2TbkkYyw/n0Kw71KAyzsDxUdOc0wAFu4cMbWNxf1R8eC4hKBId/626DD4AA== X-Received: by 2002:a7b:c08e:: with SMTP id r14mr3923328wmh.68.1640114273621; Tue, 21 Dec 2021 11:17:53 -0800 (PST) Received: from aczubak.c.googlers.com.com (109.36.187.35.bc.googleusercontent.com. [35.187.36.109]) by smtp.gmail.com with ESMTPSA id t8sm3994846wmq.32.2021.12.21.11.17.53 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 21 Dec 2021 11:17:53 -0800 (PST) From: Angela Czubak To: linux-input@vger.kernel.org Cc: upstream@semihalf.com, dmitry.torokhov@gmail.com, Angela Czubak Subject: [PATCH 12/18] HID: haptic: add functions handling events Date: Tue, 21 Dec 2021 19:17:37 +0000 Message-Id: <20211221191743.1893185-13-acz@semihalf.com> X-Mailer: git-send-email 2.34.1.307.g9b7440fafd-goog In-Reply-To: <20211221191743.1893185-1-acz@semihalf.com> References: <20211221191743.1893185-1-acz@semihalf.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-input@vger.kernel.org Implement hid_haptic_handle_press_release() which generates haptic feedback as well as saves the pressed state of the haptic device. Function hid_haptic_handle_input() inserts BTN_LEFT and ABS_PRESSURE events if the device is in kernel mode. Add functions to increase and reset the state of the pressure detected by the device. Signed-off-by: Angela Czubak --- drivers/hid/hid-haptic.c | 72 +++++++++++++++++++++++++++++++++++++++- drivers/hid/hid-haptic.h | 20 +++++++++++ 2 files changed, 91 insertions(+), 1 deletion(-) diff --git a/drivers/hid/hid-haptic.c b/drivers/hid/hid-haptic.c index ad458bc7d4c5..85c4711f685e 100644 --- a/drivers/hid/hid-haptic.c +++ b/drivers/hid/hid-haptic.c @@ -51,8 +51,13 @@ bool hid_haptic_check_pressure_unit(struct hid_haptic_device *haptic, struct hid_input *hi, struct hid_field *field) { /* Accepted units are either grams or newtons. */ - if (field->unit == 0x0101 || field->unit == 0xe111) + if (field->unit == 0x0101 || field->unit == 0xe111) { + haptic->force_logical_minimum = field->logical_minimum; + haptic->force_physical_minimum = field->physical_minimum; + haptic->force_resolution = input_abs_get_res(hi->input, + ABS_MT_PRESSURE); return true; + } return false; } EXPORT_SYMBOL_GPL(hid_haptic_check_pressure_unit); @@ -352,6 +357,13 @@ static void hid_haptic_destroy(struct ff_device *ff) module_put(THIS_MODULE); } +static __u32 convert_force_to_logical(struct hid_haptic_device *haptic, + __u32 value) +{ + return (value - haptic->force_physical_minimum) * + haptic->force_resolution + haptic->force_logical_minimum; +} + int hid_haptic_init(struct hid_device *hdev, struct hid_haptic_device **haptic_ptr) { @@ -459,6 +471,13 @@ int hid_haptic_init(struct hid_device *hdev, fill_effect_buf(haptic, &stop_effect, &haptic->stop_effect, HID_HAPTIC_ORDINAL_WAVEFORMSTOP); + haptic->mode = HID_HAPTIC_MODE_DEVICE; + haptic->press_threshold = convert_force_to_logical(haptic, + HID_HAPTIC_PRESS_THRESH); + haptic->release_threshold = convert_force_to_logical(haptic, + HID_HAPTIC_RELEASE_THRESH); + + input_set_capability(dev, EV_FF, FF_HID); flush = dev->flush; @@ -550,3 +569,54 @@ int hid_haptic_init(struct hid_device *hdev, return ret; } EXPORT_SYMBOL_GPL(hid_haptic_init); + +void hid_haptic_handle_press_release(struct hid_haptic_device *haptic) +{ + int prev_pressed_state = haptic->pressed_state; + struct input_dev *input = haptic->input_dev; + unsigned long flags; + + if (haptic->pressure_sum > haptic->press_threshold) + haptic->pressed_state = 1; + else if (haptic->pressure_sum < haptic->release_threshold) + haptic->pressed_state = 0; + if (!prev_pressed_state && haptic->pressed_state && + haptic->mode == HID_HAPTIC_MODE_KERNEL) { + spin_lock_irqsave(&input->event_lock, flags); + input->ff->playback(input, PRESS_HID_EFFECT_ID, 1); + spin_unlock_irqrestore(&input->event_lock, flags); + } + if (prev_pressed_state && !haptic->pressed_state && + haptic->mode == HID_HAPTIC_MODE_KERNEL) { + spin_lock_irqsave(&input->event_lock, flags); + input->ff->playback(input, RELEASE_HID_EFFECT_ID, 1); + spin_unlock_irqrestore(&input->event_lock, flags); + } +} +EXPORT_SYMBOL_GPL(hid_haptic_handle_press_release); + +bool hid_haptic_handle_input(struct hid_haptic_device *haptic) +{ + if (haptic->mode == HID_HAPTIC_MODE_KERNEL) { + input_event(haptic->input_dev, EV_KEY, BTN_LEFT, + haptic->pressed_state); + input_event(haptic->input_dev, EV_ABS, ABS_PRESSURE, + haptic->pressure_sum); + return true; + } + return false; +} +EXPORT_SYMBOL_GPL(hid_haptic_handle_input); + +void hid_haptic_pressure_reset(struct hid_haptic_device *haptic) +{ + haptic->pressure_sum = 0; +} +EXPORT_SYMBOL_GPL(hid_haptic_pressure_reset); + +void hid_haptic_pressure_increase(struct hid_haptic_device *haptic, + __s32 pressure) +{ + haptic->pressure_sum += pressure; +} +EXPORT_SYMBOL_GPL(hid_haptic_pressure_increase); diff --git a/drivers/hid/hid-haptic.h b/drivers/hid/hid-haptic.h index 2581833125dd..27ae1ed576c4 100644 --- a/drivers/hid/hid-haptic.h +++ b/drivers/hid/hid-haptic.h @@ -83,6 +83,11 @@ int hid_haptic_input_configured(struct hid_device *hdev, struct hid_haptic_device *haptic, struct hid_input *hi); int hid_haptic_init(struct hid_device *hdev, struct hid_haptic_device **haptic_ptr); +void hid_haptic_handle_press_release(struct hid_haptic_device *haptic); +bool hid_haptic_handle_input(struct hid_haptic_device *haptic); +void hid_haptic_pressure_reset(struct hid_haptic_device *haptic); +void hid_haptic_pressure_increase(struct hid_haptic_device *haptic, + __s32 pressure); #else static inline void hid_haptic_feature_mapping(struct hid_device *hdev, @@ -117,4 +122,19 @@ int hid_haptic_init(struct hid_device *hdev, struct hid_haptic_device **haptic_p { return 0; } +static inline +void hid_haptic_handle_press_release(struct hid_haptic_device *haptic) +{} +static inline +bool hid_haptic_handle_input(struct hid_haptic_device *haptic) +{ + return false; +} +static inline +void hid_haptic_pressure_reset(struct hid_haptic_device *haptic) +{} +static inline +void hid_haptic_pressure_increase(struct hid_haptic_device *haptic, + __s32 pressure) +{} #endif From patchwork Tue Dec 21 19:17:38 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Angela Czubak X-Patchwork-Id: 12690463 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 vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id CBCBDC433F5 for ; Tue, 21 Dec 2021 19:17:56 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S241755AbhLUTR4 (ORCPT ); Tue, 21 Dec 2021 14:17:56 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:57878 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S241754AbhLUTRz (ORCPT ); Tue, 21 Dec 2021 14:17:55 -0500 Received: from mail-wm1-x32f.google.com (mail-wm1-x32f.google.com [IPv6:2a00:1450:4864:20::32f]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 760D9C06173F for ; Tue, 21 Dec 2021 11:17:55 -0800 (PST) Received: by mail-wm1-x32f.google.com with SMTP id j140-20020a1c2392000000b003399ae48f58so2401939wmj.5 for ; Tue, 21 Dec 2021 11:17:55 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=semihalf-com.20210112.gappssmtp.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=9DSFngfggMTRU52qjDLCHxShA19z3IYvtKyKtu3j4z8=; b=WO3nfI/GdUOiP6AfWmOzgudE4OABCS8qWUW1n4G4uFIXYuMvTQV32sBBTV6cwXufpI r6Csdcq6ksgzhLak7Ansn5A7IhHfI11E1bmJV+F5izXCH+EmMzszfK3aaKRxLkIb6g+l sNSiydjKg8x2p6G/VwfG2LWYBF7rjnyCGtVsf5pKCN9R7YkahOo93MAA91oNKU/COsv+ EP1VuW1sHlSUn9c6dCz7NpfNVBrKM+FRLNM+tQc7EUjpKUydOgsmm6UME/XvaFMHosf5 eo4eLiIPAn0JD98yxLYGYmMB4O4AaB4qOVOBt5nbAkfcVzpyVOAwMFbAI/+b/fA7LLYr Yw9w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=9DSFngfggMTRU52qjDLCHxShA19z3IYvtKyKtu3j4z8=; b=l7wsp739M74Ot34hAziJIl64AeV7JVArmZGW87fSmjl5JbYbV69VwugHf06tz8yCoV T639o7i+1E42hX3kbCyex9NmQav+POdSSWAb3H4RDWKyX7cBmEOuADuEZ+SDVHHU/1tW hvLFSshGBXVwVL/Jm61GNLPxCw4Y71//PSdQc2YnTyaxnN+CYqvd89NHIWgFqB7fITlb xwaCrYAHXDj+dJHQbOmA7YEFr+r6uXBv+UVjO7VxtsI/TBBg4Yehija+0fh2QxAotNHm XmjOJQAwBhxmHEFUOB7d4xM9E6Ukj5q4B23xgW3/eFNkLdbmZOS/o4zEMUp44aAFrtK6 5Kcg== X-Gm-Message-State: AOAM533/FhOi7z+UTz23xSPKto/AeKbo9XCSKNajCPB8/VZx/YS5Xd1E VHxPBLpf3q7Y5IAHlNoi17v29GWs+t1VCI7ST7s= X-Google-Smtp-Source: ABdhPJxvHX8WLsvCcIqUAanqMioG/bNqidxVgeq3VSTy0oUSoQLiYglyOklAm/UmwDbmO+MwMa20Dg== X-Received: by 2002:a7b:c202:: with SMTP id x2mr4006943wmi.57.1640114274051; Tue, 21 Dec 2021 11:17:54 -0800 (PST) Received: from aczubak.c.googlers.com.com (109.36.187.35.bc.googleusercontent.com. [35.187.36.109]) by smtp.gmail.com with ESMTPSA id t8sm3994846wmq.32.2021.12.21.11.17.53 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 21 Dec 2021 11:17:53 -0800 (PST) From: Angela Czubak To: linux-input@vger.kernel.org Cc: upstream@semihalf.com, dmitry.torokhov@gmail.com, Angela Czubak Subject: [PATCH 13/18] Input: MT - toggle ABS_PRESSURE pointer emulation Date: Tue, 21 Dec 2021 19:17:38 +0000 Message-Id: <20211221191743.1893185-14-acz@semihalf.com> X-Mailer: git-send-email 2.34.1.307.g9b7440fafd-goog In-Reply-To: <20211221191743.1893185-1-acz@semihalf.com> References: <20211221191743.1893185-1-acz@semihalf.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-input@vger.kernel.org Add a function to switch off ABS_PRESSURE generation if necessary. This may be helpful in case drivers want to generate ABS_PRESSURE events themselves from ABS_MT_PRESSURE. Signed-off-by: Angela Czubak --- drivers/input/input-mt.c | 18 ++++++++++++++++-- include/linux/input/mt.h | 4 ++++ 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/drivers/input/input-mt.c b/drivers/input/input-mt.c index 44fe6f2f063c..e0bf5917a8b5 100644 --- a/drivers/input/input-mt.c +++ b/drivers/input/input-mt.c @@ -52,6 +52,7 @@ int input_mt_init_slots(struct input_dev *dev, unsigned int num_slots, mt->num_slots = num_slots; mt->flags = flags; + mt->abs_pressure_gen = true; input_set_abs_params(dev, ABS_MT_SLOT, 0, num_slots - 1, 0, 0); input_set_abs_params(dev, ABS_MT_TRACKING_ID, 0, TRKID_MAX, 0, 0); @@ -244,12 +245,14 @@ void input_mt_report_pointer_emulation(struct input_dev *dev, bool use_count) input_event(dev, EV_ABS, ABS_X, x); input_event(dev, EV_ABS, ABS_Y, y); - if (test_bit(ABS_MT_PRESSURE, dev->absbit)) { + if (test_bit(ABS_MT_PRESSURE, dev->absbit) && + mt->abs_pressure_gen) { int p = input_mt_get_value(oldest, ABS_MT_PRESSURE); input_event(dev, EV_ABS, ABS_PRESSURE, p); } } else { - if (test_bit(ABS_MT_PRESSURE, dev->absbit)) + if (test_bit(ABS_MT_PRESSURE, dev->absbit) && + mt->abs_pressure_gen) input_event(dev, EV_ABS, ABS_PRESSURE, 0); } } @@ -312,6 +315,17 @@ void input_mt_sync_frame(struct input_dev *dev) } EXPORT_SYMBOL(input_mt_sync_frame); +void input_mt_pressure_toggle(struct input_dev *dev, bool toggle) +{ + struct input_mt *mt = dev->mt; + + if (!mt) + return; + + mt->abs_pressure_gen = toggle; +} +EXPORT_SYMBOL(input_mt_pressure_toggle); + static int adjust_dual(int *begin, int step, int *end, int eq, int mu) { int f, *p, s, c; diff --git a/include/linux/input/mt.h b/include/linux/input/mt.h index 3b8580bd33c1..c870a513bde1 100644 --- a/include/linux/input/mt.h +++ b/include/linux/input/mt.h @@ -38,6 +38,7 @@ struct input_mt_slot { * @flags: input_mt operation flags * @frame: increases every time input_mt_sync_frame() is called * @red: reduced cost matrix for in-kernel tracking + * @abs_pressure_gen: emulate pointer pressure * @slots: array of slots holding current values of tracked contacts */ struct input_mt { @@ -47,6 +48,7 @@ struct input_mt { unsigned int flags; unsigned int frame; int *red; + bool abs_pressure_gen; struct input_mt_slot slots[]; }; @@ -111,6 +113,8 @@ void input_mt_drop_unused(struct input_dev *dev); void input_mt_sync_frame(struct input_dev *dev); +void input_mt_pressure_toggle(struct input_dev *dev, bool toggle); + /** * struct input_mt_pos - contact position * @x: horizontal coordinate From patchwork Tue Dec 21 19:17:39 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Angela Czubak X-Patchwork-Id: 12690465 X-Patchwork-Delegate: jikos@jikos.cz 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 vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 1BA5CC433EF for ; Tue, 21 Dec 2021 19:17:57 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S241754AbhLUTR4 (ORCPT ); Tue, 21 Dec 2021 14:17:56 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:57882 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S241746AbhLUTR4 (ORCPT ); Tue, 21 Dec 2021 14:17:56 -0500 Received: from mail-wr1-x430.google.com (mail-wr1-x430.google.com [IPv6:2a00:1450:4864:20::430]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id DD1A8C061574 for ; Tue, 21 Dec 2021 11:17:55 -0800 (PST) Received: by mail-wr1-x430.google.com with SMTP id t26so69766wrb.4 for ; Tue, 21 Dec 2021 11:17:55 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=semihalf-com.20210112.gappssmtp.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=ck2vpnIS2DAqG7HXn27YA+85j6sVgbhINNF0cX2lN3Q=; b=pgpC68Vhb42OE/Fa8r1IAvrzmFPn2EAzRQnrqP3Dz/JPjaTSxvzMkFzQ7Bh3KabatW jDlelzRCpNf0huwKwneWZsqNHpJ/f7hGR7+zJ2dq8Pn2bBKTqg/Tp03P/rnW+hCyyyzO 7UDG9AMiUvlisPRvJhcJ9A+cnDDh4agfIqoVdMxEy39sAa9mpv4JSOBi3bjVIs5e/bkd UondidNflKbaICOzj/WLP0qMMKw2c5dz7omscXg6K1BDuJi9zvfPp2FA+PBvu+JKBicv 7nKiYjeH3jcv0KzpEYobMmYNBY1OmluzgtWNUFjami+EOcN6J7am540TUkHm2MvsFk7o BlZA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=ck2vpnIS2DAqG7HXn27YA+85j6sVgbhINNF0cX2lN3Q=; b=7gpBNiwASov+D1JaDMYxzHzUTVVBNRj3CdgJXUhrq/xR65T+6BIaJ7a7qjM0oOMoKg x4DMcvgY3Vcw1A5XVRYA11u1nKygpGdbI0R8mpF4V+zVJCleZQpMHz1DPJ6XxrQPhR81 FbJEKh24G19ls5egg+WV3fEuHzsYZQShvBZRyk13PGSHA4q+NEky+FfTyXZmYaYk3gsD NEI7d0j/fTq8c2JnW9qlGIaT24gv4XDJrfFynUk3Y8ePG3G90okBSIu0zTAdRCgj3w4o YDiKsmnBBJxeAq9+1lU/8ak3rFo5NajZxUmxa3ofIeRBCIMGZo848k9EHm+cPWIeMv3U vpAA== X-Gm-Message-State: AOAM530SMvcerWdXWLUq50C3zDWTsmnnanBpTqLmokgoIAgAqVOYFJRu xCVfgcWyEfTFIQatdQ4Oxesw89ZSLYM7zVPp+Cc= X-Google-Smtp-Source: ABdhPJxNOorVrqDRUN5orHalX0O9IlUFCZ2ShvaKsU0+RGL6dL2UU8uILseUW4GF/ZuOzyvE+MvVig== X-Received: by 2002:adf:f587:: with SMTP id f7mr3795250wro.671.1640114274510; Tue, 21 Dec 2021 11:17:54 -0800 (PST) Received: from aczubak.c.googlers.com.com (109.36.187.35.bc.googleusercontent.com. [35.187.36.109]) by smtp.gmail.com with ESMTPSA id t8sm3994846wmq.32.2021.12.21.11.17.54 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 21 Dec 2021 11:17:54 -0800 (PST) From: Angela Czubak To: linux-input@vger.kernel.org Cc: upstream@semihalf.com, dmitry.torokhov@gmail.com, Angela Czubak Subject: [PATCH 14/18] HID: haptic: add hid_haptic_switch_mode Date: Tue, 21 Dec 2021 19:17:39 +0000 Message-Id: <20211221191743.1893185-15-acz@semihalf.com> X-Mailer: git-send-email 2.34.1.307.g9b7440fafd-goog In-Reply-To: <20211221191743.1893185-1-acz@semihalf.com> References: <20211221191743.1893185-1-acz@semihalf.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-input@vger.kernel.org Function hid_haptic_switch_mode() can be used to turn off and on the autonomoums mode for the device. If the device supports press and release waveforms, let the kernel handle generation of haptic feedback instead of the device itself. Implement hid_haptic_resume() and hid_haptic_suspend() so that the autonomous mode gets switched off at resume and switched on at suspend. Signed-off-by: Angela Czubak --- drivers/hid/hid-haptic.c | 89 +++++++++++++++++++++++++++++++++++++--- drivers/hid/hid-haptic.h | 10 +++++ 2 files changed, 93 insertions(+), 6 deletions(-) diff --git a/drivers/hid/hid-haptic.c b/drivers/hid/hid-haptic.c index 85c4711f685e..e7fd53d1a7c1 100644 --- a/drivers/hid/hid-haptic.c +++ b/drivers/hid/hid-haptic.c @@ -8,6 +8,7 @@ /* */ +#include #include #include "hid-haptic.h" @@ -200,9 +201,61 @@ static void fill_effect_buf(struct hid_haptic_device *haptic, mutex_unlock(&haptic->manual_trigger_mutex); } +static void switch_mode(struct hid_device *hdev, struct hid_haptic_device *haptic, + int mode) +{ + struct hid_report *rep = haptic->auto_trigger_report; + struct hid_field *field; + s32 value; + int i, j; + + if (mode == HID_HAPTIC_MODE_KERNEL) { + value = HID_HAPTIC_ORDINAL_WAVEFORMSTOP; + input_mt_pressure_toggle(haptic->input_dev, 0); + } else { + value = haptic->default_auto_trigger; + input_mt_pressure_toggle(haptic->input_dev, 1); + } + + mutex_lock(&haptic->auto_trigger_mutex); + for (i = 0; i < rep->maxfield; i++) { + field = rep->field[i]; + /* Ignore if report count is out of bounds. */ + if (field->report_count < 1) + continue; + + for (j = 0; j < field->maxusage; j++) { + if (field->usage[j].hid == HID_HP_AUTOTRIGGER) + field->value[j] = value; + } + } + + /* send the report */ + hid_hw_request(hdev, rep, HID_REQ_SET_REPORT); + mutex_unlock(&haptic->auto_trigger_mutex); + haptic->mode = mode; +} + +#ifdef CONFIG_PM +void hid_haptic_resume(struct hid_device *hdev, struct hid_haptic_device *haptic) +{ + if (haptic->press_ordinal_cur && haptic->release_ordinal_cur) + switch_mode(hdev, haptic, HID_HAPTIC_MODE_KERNEL); +} +EXPORT_SYMBOL_GPL(hid_haptic_resume); + +void hid_haptic_suspend(struct hid_device *hdev, struct hid_haptic_device *haptic) +{ + if (haptic->press_ordinal_cur && haptic->release_ordinal_cur) + switch_mode(hdev, haptic, HID_HAPTIC_MODE_DEVICE); +} +EXPORT_SYMBOL_GPL(hid_haptic_suspend); +#endif + static int hid_haptic_upload_effect(struct input_dev *dev, struct ff_effect *effect, struct ff_effect *old) { + struct hid_device *hdev = input_get_drvdata(dev); struct ff_device *ff = dev->ff; struct hid_haptic_device *haptic = ff->private; int i, ordinal = 0; @@ -228,6 +281,20 @@ static int hid_haptic_upload_effect(struct input_dev *dev, struct ff_effect *eff fill_effect_buf(haptic, &effect->u.hid, &haptic->effect[effect->id], ordinal); + if (effect->id == HID_HAPTIC_RELEASE_EFFECT_ID) { + if (haptic->press_ordinal_cur && + haptic->mode == HID_HAPTIC_MODE_DEVICE) { + switch_mode(hdev, haptic, HID_HAPTIC_MODE_KERNEL); + } + haptic->release_ordinal_cur = ordinal; + } else if (effect->id == HID_HAPTIC_PRESS_EFFECT_ID) { + if (haptic->release_ordinal_cur && + haptic->mode == HID_HAPTIC_MODE_DEVICE) { + switch_mode(hdev, haptic, HID_HAPTIC_MODE_KERNEL); + } + haptic->press_ordinal_cur = ordinal; + } + return 0; } @@ -294,6 +361,7 @@ static void effect_set_default(struct ff_effect *effect) static int hid_haptic_erase(struct input_dev *dev, int effect_id) { struct hid_haptic_device *haptic = dev->ff->private; + struct hid_device *hdev = input_get_drvdata(dev); struct ff_effect effect; int ordinal; @@ -301,21 +369,29 @@ static int hid_haptic_erase(struct input_dev *dev, int effect_id) switch (effect_id) { case HID_HAPTIC_RELEASE_EFFECT_ID: ordinal = haptic->release_ordinal_orig; - if (!ordinal) + haptic->release_ordinal_cur = ordinal; + if (!ordinal) { ordinal = HID_HAPTIC_ORDINAL_WAVEFORMNONE; - else + if (haptic->mode == HID_HAPTIC_MODE_KERNEL) + switch_mode(hdev, haptic, HID_HAPTIC_MODE_DEVICE); + } else { effect.u.hid.hid_usage = HID_HP_WAVEFORMRELEASE & HID_USAGE; + } fill_effect_buf(haptic, &effect.u.hid, &haptic->effect[effect_id], ordinal); break; case HID_HAPTIC_PRESS_EFFECT_ID: ordinal = haptic->press_ordinal_orig; - if (!ordinal) + haptic->press_ordinal_cur = ordinal; + if (!ordinal) { ordinal = HID_HAPTIC_ORDINAL_WAVEFORMNONE; - else + if (haptic->mode == HID_HAPTIC_MODE_KERNEL) + switch_mode(hdev, haptic, HID_HAPTIC_MODE_DEVICE); + } else { effect.u.hid.hid_usage = HID_HP_WAVEFORMPRESS & HID_USAGE; + } fill_effect_buf(haptic, &effect.u.hid, &haptic->effect[effect_id], ordinal); break; @@ -408,6 +484,7 @@ int hid_haptic_init(struct hid_device *hdev, haptic->hid_usage_map[HID_HAPTIC_ORDINAL_WAVEFORMSTOP] = HID_HP_WAVEFORMSTOP & HID_USAGE; + mutex_init(&haptic->auto_trigger_mutex); for (r = 0; r < haptic->auto_trigger_report->maxfield; r++) parse_auto_trigger_field(haptic, haptic->auto_trigger_report->field[r]); @@ -583,13 +660,13 @@ void hid_haptic_handle_press_release(struct hid_haptic_device *haptic) if (!prev_pressed_state && haptic->pressed_state && haptic->mode == HID_HAPTIC_MODE_KERNEL) { spin_lock_irqsave(&input->event_lock, flags); - input->ff->playback(input, PRESS_HID_EFFECT_ID, 1); + input->ff->playback(input, HID_HAPTIC_PRESS_EFFECT_ID, 1); spin_unlock_irqrestore(&input->event_lock, flags); } if (prev_pressed_state && !haptic->pressed_state && haptic->mode == HID_HAPTIC_MODE_KERNEL) { spin_lock_irqsave(&input->event_lock, flags); - input->ff->playback(input, RELEASE_HID_EFFECT_ID, 1); + input->ff->playback(input, HID_HAPTIC_RELEASE_EFFECT_ID, 1); spin_unlock_irqrestore(&input->event_lock, flags); } } diff --git a/drivers/hid/hid-haptic.h b/drivers/hid/hid-haptic.h index 27ae1ed576c4..7a4571075a21 100644 --- a/drivers/hid/hid-haptic.h +++ b/drivers/hid/hid-haptic.h @@ -82,6 +82,10 @@ int hid_haptic_input_mapping(struct hid_device *hdev, int hid_haptic_input_configured(struct hid_device *hdev, struct hid_haptic_device *haptic, struct hid_input *hi); +#ifdef CONFIG_PM +void hid_haptic_resume(struct hid_device *hdev, struct hid_haptic_device *haptic); +void hid_haptic_suspend(struct hid_device *hdev, struct hid_haptic_device *haptic); +#endif int hid_haptic_init(struct hid_device *hdev, struct hid_haptic_device **haptic_ptr); void hid_haptic_handle_press_release(struct hid_haptic_device *haptic); bool hid_haptic_handle_input(struct hid_haptic_device *haptic); @@ -117,6 +121,12 @@ int hid_haptic_input_configured(struct hid_device *hdev, { return 0; } +#ifdef CONFIG_PM +static inline +void hid_haptic_resume(struct hid_device *hdev, struct hid_haptic_device *haptic) {} +static inline +void hid_haptic_suspend(struct hid_device *hdev, struct hid_haptic_device *haptic) {} +#endif static inline int hid_haptic_init(struct hid_device *hdev, struct hid_haptic_device **haptic_ptr) { From patchwork Tue Dec 21 19:17:40 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Angela Czubak X-Patchwork-Id: 12690467 X-Patchwork-Delegate: jikos@jikos.cz 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 vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id A9E48C4332F for ; Tue, 21 Dec 2021 19:17:57 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S241756AbhLUTR5 (ORCPT ); Tue, 21 Dec 2021 14:17:57 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:57884 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S241746AbhLUTR4 (ORCPT ); Tue, 21 Dec 2021 14:17:56 -0500 Received: from mail-wr1-x430.google.com (mail-wr1-x430.google.com [IPv6:2a00:1450:4864:20::430]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 65308C06173F for ; Tue, 21 Dec 2021 11:17:56 -0800 (PST) Received: by mail-wr1-x430.google.com with SMTP id v7so21606053wrv.12 for ; Tue, 21 Dec 2021 11:17:56 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=semihalf-com.20210112.gappssmtp.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=rmh8/R/qHcPfy44OFdiEPZyLcrT1H1MLJrXU2WV1zms=; b=UaU6tivnvFoKJpe3xBaTtB70fv7QBrhVqf+07hwnd2zWwcRBHNGBi3qzpUSomrj/0T ZTvuWuKYBCnc00l91ZTrr7QTlsBMon29eQJW7mf5fV6gihH9np1tdyG6ve2BRUhsFr5v RB2YCgm4NtRQQv2DCvMXs2Dlpymb/3oEBzq8Pc0yYJBPEc3eTrAuOqCtlgyyxtEY+3Sq IgGRwtImFy4MA0MrWB9l0NPYuSY0+1le5pBWL0UqOpRrZu1ZuI3v1TRFDNXYufTm4n6P HEz0RjXEB6ytWxreMwuoSjAobZ0peyRfF33BzJ1VQVf2eGLg+mgRq03G9znNiHsm1HNn +3Pw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=rmh8/R/qHcPfy44OFdiEPZyLcrT1H1MLJrXU2WV1zms=; b=OtTA9Y4cc9g6Utpm7mN40FpzeO7w8gF/MXLPrKaIeIuNkalCFR1m52UWDns96Bcidl sbmpCEoOQHPexJSVd7UUwjaRJ15RUu//NExkawmi3wCSqNhmDCK1M0PzRzhjunlV0H2O AZXURqt3Ov1UARn5ZvgGmlanHZ3WOUkHur2EGuYOp6bXHHYDqiYJcc1HMrBsPoXERKVX P/hIe90U9ko4nJtCbCjFsf5mtQ/AkFPbe3QLaI7re6sjVfqgHlgQjSW6+H9U/S6AO7Pl zCh8DLeby/gt2y7q3NsaiHHhAzfQq3p4VEGWFAMziNBDGu5q2gjbUcNtu5c6DAXcNKmo PdyA== X-Gm-Message-State: AOAM531X1Mz0W2oypWAQHReoHWrRygl7sgw5UsgRXpd8e0F9TBsGb5Y2 GSX0Fozp6zrBhaNny+QdDdV/uDvYhflF3wyUjtc= X-Google-Smtp-Source: ABdhPJyeFQ5dm0wdsfg6tBash2q2DBAUY7d+KvhjA00j/nVGwZY/NF/thQUfK8neSE/cX/MRO1IAmA== X-Received: by 2002:a05:6000:1845:: with SMTP id c5mr3687879wri.499.1640114274960; Tue, 21 Dec 2021 11:17:54 -0800 (PST) Received: from aczubak.c.googlers.com.com (109.36.187.35.bc.googleusercontent.com. [35.187.36.109]) by smtp.gmail.com with ESMTPSA id t8sm3994846wmq.32.2021.12.21.11.17.54 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 21 Dec 2021 11:17:54 -0800 (PST) From: Angela Czubak To: linux-input@vger.kernel.org Cc: upstream@semihalf.com, dmitry.torokhov@gmail.com, Angela Czubak Subject: [PATCH 15/18] HID: multitouch: add haptic multitouch support Date: Tue, 21 Dec 2021 19:17:40 +0000 Message-Id: <20211221191743.1893185-16-acz@semihalf.com> X-Mailer: git-send-email 2.34.1.307.g9b7440fafd-goog In-Reply-To: <20211221191743.1893185-1-acz@semihalf.com> References: <20211221191743.1893185-1-acz@semihalf.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-input@vger.kernel.org Add new option (MULTITOUCH_HAPTIC) to mark whether hid-multitouch should try and configure simple haptic device. Once this option is configured, and the device is recognized to have simple haptic capabilities, check input frames for pressure and handle it using hid_haptic_* API. Signed-off-by: Angela Czubak --- drivers/hid/Kconfig | 11 ++++++ drivers/hid/hid-multitouch.c | 71 +++++++++++++++++++++++++++++++++++- 2 files changed, 80 insertions(+), 2 deletions(-) diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig index 8d1eb4491a7f..d64e316eb2ca 100644 --- a/drivers/hid/Kconfig +++ b/drivers/hid/Kconfig @@ -742,6 +742,17 @@ config HID_MULTITOUCH To compile this driver as a module, choose M here: the module will be called hid-multitouch. +config MULTITOUCH_HAPTIC + bool "Simple haptic multitouch support" + depends on HID_MULTITOUCH + select HID_HAPTIC + default n + help + Support for simple multitouch haptic devices. + Adds extra parsing and FF device for the hid multitouch driver. + It can be used for Elan 2703 haptic touchpad. + To enable, say Y. + config HID_NINTENDO tristate "Nintendo Joy-Con and Pro Controller support" depends on HID diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c index 7beb3dfc3e67..260e5d9b891d 100644 --- a/drivers/hid/hid-multitouch.c +++ b/drivers/hid/hid-multitouch.c @@ -48,6 +48,8 @@ MODULE_LICENSE("GPL"); #include "hid-ids.h" +#include "hid-haptic.h" + /* quirks to control the device */ #define MT_QUIRK_NOT_SEEN_MEANS_UP BIT(0) #define MT_QUIRK_SLOT_IS_CONTACTID BIT(1) @@ -159,11 +161,13 @@ struct mt_report_data { struct mt_device { struct mt_class mtclass; /* our mt device class */ struct timer_list release_timer; /* to release sticky fingers */ + struct hid_haptic_device *haptic; /* haptic related configuration */ struct hid_device *hdev; /* hid_device we're attached to */ unsigned long mt_io_flags; /* mt flags (MT_IO_FLAGS_*) */ __u8 inputmode_value; /* InputMode HID feature value */ __u8 maxcontacts; bool is_buttonpad; /* is this device a button pad? */ + bool is_haptic_touchpad; /* is this device a haptic touchpad? */ bool serial_maybe; /* need to check for serial protocol */ struct list_head applications; @@ -469,6 +473,8 @@ static void mt_feature_mapping(struct hid_device *hdev, hid_get_feature(hdev, field->report); break; } + + hid_haptic_feature_mapping(hdev, td->haptic, field, usage); } static void set_abs(struct input_dev *input, unsigned int code, @@ -799,6 +805,9 @@ static int mt_touch_input_mapping(struct hid_device *hdev, struct hid_input *hi, case HID_DG_TIPPRESSURE: set_abs(hi->input, ABS_MT_PRESSURE, field, cls->sn_pressure); + td->is_haptic_touchpad = + hid_haptic_check_pressure_unit(td->haptic, + hi, field); MT_STORE_FIELD(p); return 1; case HID_DG_SCANTIME: @@ -912,8 +921,16 @@ static void mt_release_pending_palms(struct mt_device *td, static void mt_sync_frame(struct mt_device *td, struct mt_application *app, struct input_dev *input) { - if (app->quirks & MT_QUIRK_WIN8_PTP_BUTTONS) - input_event(input, EV_KEY, BTN_LEFT, app->left_button_state); + if (td->is_haptic_touchpad) + hid_haptic_handle_press_release(td->haptic); + + if (app->quirks & MT_QUIRK_WIN8_PTP_BUTTONS) { + if (!(td->is_haptic_touchpad && + hid_haptic_handle_input(td->haptic))) { + input_event(input, EV_KEY, BTN_LEFT, + app->left_button_state); + } + } input_mt_sync_frame(input); input_event(input, EV_MSC, MSC_TIMESTAMP, app->timestamp); @@ -923,6 +940,8 @@ static void mt_sync_frame(struct mt_device *td, struct mt_application *app, app->num_received = 0; app->left_button_state = 0; + if (td->is_haptic_touchpad) + hid_haptic_pressure_reset(td->haptic); if (test_bit(MT_IO_FLAGS_ACTIVE_SLOTS, &td->mt_io_flags)) set_bit(MT_IO_FLAGS_PENDING_SLOTS, &td->mt_io_flags); @@ -1072,6 +1091,9 @@ static int mt_process_slot(struct mt_device *td, struct input_dev *input, minor = minor >> 1; } + if (td->is_haptic_touchpad) + hid_haptic_pressure_increase(td->haptic, *slot->p); + input_event(input, EV_ABS, ABS_MT_POSITION_X, *slot->x); input_event(input, EV_ABS, ABS_MT_POSITION_Y, *slot->y); input_event(input, EV_ABS, ABS_MT_TOOL_X, *slot->cx); @@ -1281,6 +1303,7 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi, struct mt_device *td = hid_get_drvdata(hdev); struct mt_application *application; struct mt_report_data *rdata; + int ret; rdata = mt_find_report_data(td, field->report); if (!rdata) { @@ -1343,6 +1366,11 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi, if (field->physical == HID_DG_STYLUS) hi->application = HID_DG_STYLUS; + ret = hid_haptic_input_mapping(hdev, td->haptic, hi, field, usage, bit, + max); + if (ret != 0) + return ret; + /* let hid-core decide for the others */ return 0; } @@ -1593,6 +1621,14 @@ static int mt_input_configured(struct hid_device *hdev, struct hid_input *hi) } } + if (td->is_haptic_touchpad && (td->mtclass.name == MT_CLS_WIN_8 || + td->mtclass.name == MT_CLS_WIN_8_FORCE_MULTI_INPUT)) { + if (hid_haptic_input_configured(hdev, td->haptic, hi) == 0) + td->is_haptic_touchpad = false; + } else { + td->is_haptic_touchpad = false; + } + return 0; } @@ -1684,6 +1720,9 @@ static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id) dev_err(&hdev->dev, "cannot allocate multitouch data\n"); return -ENOMEM; } + td->haptic = kzalloc(sizeof(*(td->haptic)), GFP_KERNEL); + if (!td->haptic) + return -ENOMEM; td->hdev = hdev; td->mtclass = *mtclass; td->inputmode_value = MT_INPUTMODE_TOUCHSCREEN; @@ -1735,6 +1774,17 @@ static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id) mt_set_modes(hdev, HID_LATENCY_NORMAL, true, true); + if (td->is_haptic_touchpad) { + if (hid_haptic_init(hdev, &td->haptic)) { + dev_warn(&hdev->dev, "Cannot allocate haptic for %s\n", + hdev->name); + td->is_haptic_touchpad = false; + kfree(td->haptic); + } + } else { + kfree(td->haptic); + } + return 0; } @@ -1742,6 +1792,7 @@ static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id) static int mt_suspend(struct hid_device *hdev, pm_message_t state) { struct mt_device *td = hid_get_drvdata(hdev); + struct hid_haptic_device *haptic = td->haptic; /* High latency is desirable for power savings during S3/S0ix */ if ((td->mtclass.quirks & MT_QUIRK_DISABLE_WAKEUP) || @@ -1750,18 +1801,31 @@ static int mt_suspend(struct hid_device *hdev, pm_message_t state) else mt_set_modes(hdev, HID_LATENCY_HIGH, true, true); + if (td->is_haptic_touchpad) + hid_haptic_resume(hdev, haptic); + return 0; } static int mt_reset_resume(struct hid_device *hdev) { + struct mt_device *td = hid_get_drvdata(hdev); + struct hid_haptic_device *haptic = td->haptic; + mt_release_contacts(hdev); mt_set_modes(hdev, HID_LATENCY_NORMAL, true, true); + + if (td->is_haptic_touchpad) + hid_haptic_resume(hdev, haptic); + return 0; } static int mt_resume(struct hid_device *hdev) { + struct mt_device *td = hid_get_drvdata(hdev); + struct hid_haptic_device *haptic = td->haptic; + /* Some Elan legacy devices require SET_IDLE to be set on resume. * It should be safe to send it to other devices too. * Tested on 3M, Stantum, Cypress, Zytronic, eGalax, and Elan panels. */ @@ -1770,6 +1834,9 @@ static int mt_resume(struct hid_device *hdev) mt_set_modes(hdev, HID_LATENCY_NORMAL, true, true); + if (td->is_haptic_touchpad) + hid_haptic_suspend(hdev, haptic); + return 0; } #endif From patchwork Tue Dec 21 19:17:41 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Angela Czubak X-Patchwork-Id: 12690469 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 vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 88996C43217 for ; Tue, 21 Dec 2021 19:17:58 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S241760AbhLUTR6 (ORCPT ); Tue, 21 Dec 2021 14:17:58 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:57892 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S241757AbhLUTR5 (ORCPT ); Tue, 21 Dec 2021 14:17:57 -0500 Received: from mail-wm1-x332.google.com (mail-wm1-x332.google.com [IPv6:2a00:1450:4864:20::332]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 39200C06173F for ; Tue, 21 Dec 2021 11:17:57 -0800 (PST) Received: by mail-wm1-x332.google.com with SMTP id f134-20020a1c1f8c000000b00345c05bc12dso114726wmf.3 for ; Tue, 21 Dec 2021 11:17:57 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=semihalf-com.20210112.gappssmtp.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=tW/z0FhqWRFM5dtt1f2rkVB2ZdOrdJGy+6QhQufc+Cg=; b=JDgKOGuJvajszeAkp7BD1mpF5JnxPU8Xi0Emfxgqogfqr5lbFd7M90F630G+3wjbnO 7HCMjdkWLZng1Tpz4k+zTOFam5/REyvOaUsNzyY1wRIMBKirV3mQtsH5deB3G9NfFEiP pr8QTNcGrbOLO11DEeZnK0N8sWTHdng9k+3IutHXPGO+dpIsoRZ7dvcZKbC+dWEpXmwT KcKlxu4xoVBdlNj7m4PYO3cNVo+vTi1qEzwl0QNIgpEfBNEMPCJ4WOa+ZWSkWht3w2gt WPZisRljawH0dCbnSDM3EWG9Q504Jj20bVwgiYdsJCkOZHUssypQFEe/QtSO8yYVTyaA mV/g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=tW/z0FhqWRFM5dtt1f2rkVB2ZdOrdJGy+6QhQufc+Cg=; b=QrHDID9f3voyXq4puouKg3rViKvi+fbqwB+bOYUiek1cSaS4374ISgnDlKMZRAZeAt xHPn4N9Q+f+umi7jFcQyywZtTh0uz9Y0zqOqaEbiIHWQQiJWBXGJHorynuVBpMCfdi1l zlaYS8x+GJgj7019pknLtKbHqyZ5k+ItThTvS+fnrUgCeqareGA0rHBVwxOEQrJALJgT yc8aw8Cat4SNEJj+86IN3tC+bCEZSDXHkhoEl5p2xyqUKhrSnUzZRx+epmR7Lo3uyNJm MkxEcvdig6YyBySKiWxYIHJbTzqY7e9fz+FYHSpzRIA46BqxlqKZCszvClErRcLZn31Q joRQ== X-Gm-Message-State: AOAM530DUwfeAgMlYrMVrUSv7tdHKN+wrNCM+Z90KemS/4ae9ZG4jyRK ENCjbw0w27SoPr6IHkzOeADW1+GHeC6Dctdme0M= X-Google-Smtp-Source: ABdhPJyLVcZ3kwCys5F3Ep8NxTBWDGU0WYeJoEDAG2IYqboI6lKamczcwarZ7EFUIKIPIcre79Lifg== X-Received: by 2002:a05:600c:3b2a:: with SMTP id m42mr3837622wms.4.1640114275372; Tue, 21 Dec 2021 11:17:55 -0800 (PST) Received: from aczubak.c.googlers.com.com (109.36.187.35.bc.googleusercontent.com. [35.187.36.109]) by smtp.gmail.com with ESMTPSA id t8sm3994846wmq.32.2021.12.21.11.17.54 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 21 Dec 2021 11:17:55 -0800 (PST) From: Angela Czubak To: linux-input@vger.kernel.org Cc: upstream@semihalf.com, dmitry.torokhov@gmail.com, Angela Czubak Subject: [PATCH 16/18] Input: introduce EVIOCFF(TAKE|RELEASE)CONTROL Date: Tue, 21 Dec 2021 19:17:41 +0000 Message-Id: <20211221191743.1893185-17-acz@semihalf.com> X-Mailer: git-send-email 2.34.1.307.g9b7440fafd-goog In-Reply-To: <20211221191743.1893185-1-acz@semihalf.com> References: <20211221191743.1893185-1-acz@semihalf.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-input@vger.kernel.org Add new ioctls which can be used for simple haptic force feedback effects. Once the control is taken over the effect the kernel does not generate it on its own (EVIOCFFTAKECONTROL). To revert this action use EVIOCFFRELEASECONTROL. Signed-off-by: Angela Czubak --- drivers/input/evdev.c | 6 +++ drivers/input/ff-core.c | 89 +++++++++++++++++++++++++++++++++++++- include/linux/input.h | 5 +++ include/uapi/linux/input.h | 4 ++ 4 files changed, 103 insertions(+), 1 deletion(-) diff --git a/drivers/input/evdev.c b/drivers/input/evdev.c index 95f90699d2b1..6d25eb19e28e 100644 --- a/drivers/input/evdev.c +++ b/drivers/input/evdev.c @@ -1076,6 +1076,12 @@ static long evdev_do_ioctl(struct file *file, unsigned int cmd, case EVIOCRMFF: return input_ff_erase(dev, (int)(unsigned long) p, file); + case EVIOCFFTAKECONTROL: + return input_ff_take_control(dev, (int)(unsigned long) p, file); + + case EVIOCFFRELEASECONTROL: + return input_ff_release_control(dev, (int)(unsigned long) p, file); + case EVIOCGEFFECTS: i = test_bit(EV_FF, dev->evbit) ? dev->ff->max_effects : 0; diff --git a/drivers/input/ff-core.c b/drivers/input/ff-core.c index 960ae0e29348..7536274141e7 100644 --- a/drivers/input/ff-core.c +++ b/drivers/input/ff-core.c @@ -252,6 +252,91 @@ int input_ff_erase(struct input_dev *dev, int effect_id, struct file *file) } EXPORT_SYMBOL_GPL(input_ff_erase); +/* + * Take control over the effect if the requester is also the effect owner. + * The mutex should already be locked before calling this function. + */ +static int control_effect(struct input_dev *dev, int effect_id, + struct file *file, int take) +{ + struct ff_device *ff = dev->ff; + int error; + + error = check_effect_access(ff, effect_id, file); + if (error) { + error = check_effect_shared(ff, effect_id); + if (error) + return error; + } + + if (ff->change_control) { + error = ff->change_control(dev, effect_id, file, take); + if (error) + return error; + } + + return 0; +} +/** + * input_ff_take_control - take control over a force-feedback effect from kernel + * @dev: input device to take control over effect from + * @effect_id: id of the effect to take control over + * @file: purported owner of the request + * + * This function switches user-controlled mode on for the given force-feedback + * effect. The user-mode will persist unitl the last caller releases control. + * The effect will only be taken control of if it was uploaded through the same + * file handle that is requesting taking control or for simple haptic effects + * 0 and 1. + * Valid only for simple haptic effects (ff_hid_effect). + */ +int input_ff_take_control(struct input_dev *dev, int effect_id, + struct file *file) +{ + struct ff_device *ff = dev->ff; + int ret; + + if (!test_bit(EV_FF, dev->evbit)) + return -EINVAL; + + mutex_lock(&ff->mutex); + ret = control_effect(dev, effect_id, file, 1); + mutex_unlock(&ff->mutex); + + return ret; +} +EXPORT_SYMBOL_GPL(input_ff_take_control); + +/** + * input_ff_release_control - release control over a force-feedback effect + * @dev: input device to release control over effect to + * @effect_id: id of the effect to release control + * @file: purported owner of the request + * + * This function switches user-controlled mode off for the given force-feedback + * effect. The user-mode will persist unitl the last caller releases control. + * The control will be released of if it was uploaded through the same + * file handle that is requesting taking control or for simple haptic effects + * 0 and 1. + * Valid only for simple haptic effects (ff_hid_effect). + */ +int input_ff_release_control(struct input_dev *dev, int effect_id, + struct file *file) +{ + struct ff_device *ff = dev->ff; + int ret; + + if (!test_bit(EV_FF, dev->evbit)) + return -EINVAL; + + mutex_lock(&ff->mutex); + ret = control_effect(dev, effect_id, file, 0); + mutex_unlock(&ff->mutex); + + return ret; +} +EXPORT_SYMBOL_GPL(input_ff_release_control); + /* * input_ff_flush - erase all effects owned by a file handle * @dev: input device to erase effect from @@ -270,8 +355,10 @@ int input_ff_flush(struct input_dev *dev, struct file *file) mutex_lock(&ff->mutex); - for (i = 0; i < ff->max_effects; i++) + for (i = 0; i < ff->max_effects; i++) { + control_effect(dev, i, file, 0); erase_effect(dev, i, file); + } mutex_unlock(&ff->mutex); diff --git a/include/linux/input.h b/include/linux/input.h index 0354b298d874..cc432ff6a427 100644 --- a/include/linux/input.h +++ b/include/linux/input.h @@ -519,6 +519,7 @@ extern struct class input_class; * @upload: Called to upload an new effect into device * @erase: Called to erase an effect from device * @playback: Called to request device to start playing specified effect + * @change_control: Called to change control over specified effect * @set_gain: Called to set specified gain * @set_autocenter: Called to auto-center device * @destroy: called by input core when parent input device is being @@ -547,6 +548,8 @@ struct ff_device { int (*erase)(struct input_dev *dev, int effect_id); int (*playback)(struct input_dev *dev, int effect_id, int value); + int (*change_control)(struct input_dev *dev, int effect_id, + struct file *file, int take); void (*set_gain)(struct input_dev *dev, u16 gain); void (*set_autocenter)(struct input_dev *dev, u16 magnitude); @@ -570,6 +573,8 @@ int input_ff_event(struct input_dev *dev, unsigned int type, unsigned int code, int input_ff_upload(struct input_dev *dev, struct ff_effect *effect, struct file *file); int input_ff_erase(struct input_dev *dev, int effect_id, struct file *file); +int input_ff_take_control(struct input_dev *dev, int effect_id, struct file *file); +int input_ff_release_control(struct input_dev *dev, int effect_id, struct file *file); int input_ff_flush(struct input_dev *dev, struct file *file); int input_ff_create_memless(struct input_dev *dev, void *data, diff --git a/include/uapi/linux/input.h b/include/uapi/linux/input.h index 0d4d426cf75a..12acc3bb73d7 100644 --- a/include/uapi/linux/input.h +++ b/include/uapi/linux/input.h @@ -178,6 +178,10 @@ struct input_mask { #define EVIOCSFF _IOW('E', 0x80, struct ff_effect) /* send a force effect to a force feedback device */ #define EVIOCRMFF _IOW('E', 0x81, int) /* Erase a force effect */ +/* Take control over a force effect */ +#define EVIOCFFTAKECONTROL _IOW('E', 0x82, int) +/* Release control over a force effect */ +#define EVIOCFFRELEASECONTROL _IOW('E', 0x83, int) #define EVIOCGEFFECTS _IOR('E', 0x84, int) /* Report number of effects playable at the same time */ #define EVIOCGRAB _IOW('E', 0x90, int) /* Grab/Release device */ From patchwork Tue Dec 21 19:17:42 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Angela Czubak X-Patchwork-Id: 12690471 X-Patchwork-Delegate: jikos@jikos.cz 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 vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id C1668C433F5 for ; Tue, 21 Dec 2021 19:17:58 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S241757AbhLUTR6 (ORCPT ); Tue, 21 Dec 2021 14:17:58 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:57890 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S241746AbhLUTR5 (ORCPT ); Tue, 21 Dec 2021 14:17:57 -0500 Received: from mail-wr1-x431.google.com (mail-wr1-x431.google.com [IPv6:2a00:1450:4864:20::431]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 38C2CC061574 for ; Tue, 21 Dec 2021 11:17:57 -0800 (PST) Received: by mail-wr1-x431.google.com with SMTP id v7so21606115wrv.12 for ; Tue, 21 Dec 2021 11:17:57 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=semihalf-com.20210112.gappssmtp.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=XIB6WkBGCFXoVB/X4Gv7+7UWEjHlCE4f1AmUGXlmJB0=; b=z8JNlRJ9fo9Xfl7vPCjV+7L81fc6u0WudBXuaEu7qlK6B9QLf1FHpPej+OYqLiR8s2 I8nEK5tWGDe/du7S9lAfVm1feCZHdFjw+VdmAa9JsYFeJaEWAaDPUwcpFUndAy9SSWCF td1tT0HUaSSs3VqFNLy8zmrx8lYSC0+MaprH0IrtntRJf1vFIZsKnXKaTXa/zuVdSvfZ rMEq59eX9OLF6UEbBvswHkVySB93rJ9tSyBJmLMAcHbQtfgU43lMXEUPyVEjzYm52Lox KzD77/+i790otHHaXyvjE93B1laVM5ULb12UBVRm+s7/1Wqp0+sun0m4cPgHlavw1OiD 6Ggg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=XIB6WkBGCFXoVB/X4Gv7+7UWEjHlCE4f1AmUGXlmJB0=; b=gVbO/dZHLUQme23DK3Vi35naMJw1Z/Esbsh9o9hhMvGzV1JKTXtcMxOxlSPOeS1OtD nhDCy4cjGTeFwqLQVmec5eQW/XCRY8CFkWBJnI79jq5GYo7s8OXr3Ws1iLC7fY5Ew3Yv pLtxO0rCn803wSSAc7BoKCGyWwQhZn1QjcwhytYa5jd97ypM5VrE+t2iyOGWXQlZHSHB P6IIhUFs4yMDUnxAolrBHXTgo8kYG3EqdYA3V7plM5eBAXCdNESHmsEmEzEuCWie+F4i St/6xcSXJuOrR1OW6Bsaan4gDdpZ6v/FU3NuAu7ZgQ5lVuSu7Mv2E/YEYLgu4/n1ghx1 VHRg== X-Gm-Message-State: AOAM530JKzusqE+eqd6mxcDX+QbBPqVpoosVJy3HNpIBZ1990eEIvpPI LpHXeeuULWrtq7Aw4czsT4Ng4+RZJbPEsWt4iXI= X-Google-Smtp-Source: ABdhPJyvxS74R9I0Yc63MyVchppIJXeA7Zc6C7BjSppmPeAXuK95b+JJZsAMYJFdCMSadbroWFSEEw== X-Received: by 2002:a05:6000:18a2:: with SMTP id b2mr3837320wri.277.1640114275833; Tue, 21 Dec 2021 11:17:55 -0800 (PST) Received: from aczubak.c.googlers.com.com (109.36.187.35.bc.googleusercontent.com. [35.187.36.109]) by smtp.gmail.com with ESMTPSA id t8sm3994846wmq.32.2021.12.21.11.17.55 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 21 Dec 2021 11:17:55 -0800 (PST) From: Angela Czubak To: linux-input@vger.kernel.org Cc: upstream@semihalf.com, dmitry.torokhov@gmail.com, Angela Czubak Subject: [PATCH 17/18] HID: haptic: add hid_haptic_change_control Date: Tue, 21 Dec 2021 19:17:42 +0000 Message-Id: <20211221191743.1893185-18-acz@semihalf.com> X-Mailer: git-send-email 2.34.1.307.g9b7440fafd-goog In-Reply-To: <20211221191743.1893185-1-acz@semihalf.com> References: <20211221191743.1893185-1-acz@semihalf.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-input@vger.kernel.org Implement change_control callbacks for simple haptic device. If anybody has requested control over an effect, do not generate it in kernel. Signed-off-by: Angela Czubak --- drivers/hid/hid-haptic.c | 50 ++++++++++++++++++++++++++++++++++++++-- 1 file changed, 48 insertions(+), 2 deletions(-) diff --git a/drivers/hid/hid-haptic.c b/drivers/hid/hid-haptic.c index e7fd53d1a7c1..366b7f8a2c19 100644 --- a/drivers/hid/hid-haptic.c +++ b/drivers/hid/hid-haptic.c @@ -9,6 +9,7 @@ */ #include +#include #include #include "hid-haptic.h" @@ -348,6 +349,46 @@ static int hid_haptic_playback(struct input_dev *dev, int effect_id, int value) return 0; } +static int hid_haptic_change_control(struct input_dev *dev, int effect_id, + struct file *file, int take) +{ + struct hid_haptic_device *haptic = dev->ff->private; + struct hid_haptic_effect_node *effect_node; + struct hid_haptic_effect *effect; + bool found = false; + int ret = 0; + + effect = &haptic->effect[effect_id]; + mutex_lock(&effect->control_mutex); + list_for_each_entry(effect_node, &effect->control, node) { + if (effect_node->file == file) { + found = true; + break; + } + } + if (take) { + if (!found) { + effect_node = kvzalloc(sizeof(struct hid_haptic_effect), + GFP_KERNEL); + if (!effect_node) { + ret = -ENOMEM; + goto exit; + } + effect_node->file = file; + } + list_add(&effect_node->node, &effect->control); + } else { + if (found) { + list_del(&effect_node->node); + kvfree(effect_node); + } + } +exit: + mutex_unlock(&effect->control_mutex); + + return ret; +} + static void effect_set_default(struct ff_effect *effect) { effect->type = FF_HID; @@ -533,6 +574,8 @@ int hid_haptic_init(struct hid_device *hdev, } haptic->effect[r].input_dev = dev; INIT_WORK(&haptic->effect[r].work, haptic_work_handler); + INIT_LIST_HEAD(&haptic->effect[r].control); + mutex_init(&haptic->effect[r].control_mutex); } haptic->stop_effect.report_buf = hid_alloc_report_buf(haptic->manual_trigger_report, @@ -569,6 +612,7 @@ int hid_haptic_init(struct hid_device *hdev, ff->private = haptic; ff->upload = hid_haptic_upload_effect; ff->playback = hid_haptic_playback; + ff->change_control = hid_haptic_change_control; ff->erase = hid_haptic_erase; ff->destroy = hid_haptic_destroy; if (!try_module_get(THIS_MODULE)) { @@ -658,13 +702,15 @@ void hid_haptic_handle_press_release(struct hid_haptic_device *haptic) else if (haptic->pressure_sum < haptic->release_threshold) haptic->pressed_state = 0; if (!prev_pressed_state && haptic->pressed_state && - haptic->mode == HID_HAPTIC_MODE_KERNEL) { + haptic->mode == HID_HAPTIC_MODE_KERNEL && + list_empty(&haptic->effect[HID_HAPTIC_PRESS_EFFECT_ID].control)) { spin_lock_irqsave(&input->event_lock, flags); input->ff->playback(input, HID_HAPTIC_PRESS_EFFECT_ID, 1); spin_unlock_irqrestore(&input->event_lock, flags); } if (prev_pressed_state && !haptic->pressed_state && - haptic->mode == HID_HAPTIC_MODE_KERNEL) { + haptic->mode == HID_HAPTIC_MODE_KERNEL && + list_empty(&haptic->effect[HID_HAPTIC_RELEASE_EFFECT_ID].control)) { spin_lock_irqsave(&input->event_lock, flags); input->ff->playback(input, HID_HAPTIC_RELEASE_EFFECT_ID, 1); spin_unlock_irqrestore(&input->event_lock, flags); From patchwork Tue Dec 21 19:17:43 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Angela Czubak X-Patchwork-Id: 12690473 X-Patchwork-Delegate: jikos@jikos.cz 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 vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 010B4C433EF for ; Tue, 21 Dec 2021 19:17:58 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S241746AbhLUTR6 (ORCPT ); Tue, 21 Dec 2021 14:17:58 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:57894 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S241759AbhLUTR6 (ORCPT ); Tue, 21 Dec 2021 14:17:58 -0500 Received: from mail-wr1-x42a.google.com (mail-wr1-x42a.google.com [IPv6:2a00:1450:4864:20::42a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id A10ABC061401 for ; Tue, 21 Dec 2021 11:17:57 -0800 (PST) Received: by mail-wr1-x42a.google.com with SMTP id j18so86368wrd.2 for ; Tue, 21 Dec 2021 11:17:57 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=semihalf-com.20210112.gappssmtp.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=RRmjQmiLAYg0+TIS09+L7wuhdmQE94HxtricNmWM20Y=; b=qUXEflL0pGsis0SgzOIkdiGfquAN4cjAWlrMbqNFM/jxFqRX5hR0vPh3ZAtbemaa/H +sxFE0OO0uqky+MJwNMxCVeAYDu1mD+9zHZ3DqCRQ2Kkmc+Ztmggyv/IE7DNdteEydjw KUjcovr1idpGLqk1r71nh63rF7NkNPYK7UjdpZd5zWoB9LTjBBx3UvgdWHv+LGJE5zi+ BPZbT2SfwB6NOTpyguYJUNX0HI+2MMee6EDcQMm6vJSk5G7v+qvCJ1nCBxCpiBWP+bTB tBQFI2tQHNohi4emqna88DkAeFrt9v21r9XEoO2h7UypnmJd/j3YYEuQiLf0uJC78UJr zMqA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=RRmjQmiLAYg0+TIS09+L7wuhdmQE94HxtricNmWM20Y=; b=Ko3qDwO2+LMrBjdaHNRgBIu/z7I8eNLx13X0m4ws2jhqpjz6Jd5EQ7g0i2lhzN1RvH fSkGD7SlVsOCzpDmPa5ALy7uqe/19+Xrk3mcWVdSdfhzGSOfD5mMzpOsFANgTQQg62nw 1TAUIbZ6P/AKbep2rboD0niBeMPDxqA2dtR4HOE5B5uMIfco+XjwtzoZV5MDMEun80+Y o3LwSuklYcKOZOH88YcoVdk0gfYbmFuv3b0mc2FzpOvlBH1l4pb14ouQL7UZHeSmq/bK h3HvsRj2O8lwDYReXbWGQpL3MbfNeg9taHID3UywizBxR01fyBa0eYjavg6A4k8K3KHt VN5Q== X-Gm-Message-State: AOAM530IQ7I7YT3A22sznLZiCRyrCkufa+JaSv15mtNRxFfg/HwvdXEy sjwARre04smS+ivWd4jJudKMbCdkRgJ1Oz/uaHw= X-Google-Smtp-Source: ABdhPJzy37qnyMbz2zI3O6yonFi+vxGqXiABw4jir47okWfKb0oAtuIoM+bmqISlYl0qTA6JyqZCVw== X-Received: by 2002:a5d:64c8:: with SMTP id f8mr4052468wri.158.1640114276242; Tue, 21 Dec 2021 11:17:56 -0800 (PST) Received: from aczubak.c.googlers.com.com (109.36.187.35.bc.googleusercontent.com. [35.187.36.109]) by smtp.gmail.com with ESMTPSA id t8sm3994846wmq.32.2021.12.21.11.17.55 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 21 Dec 2021 11:17:55 -0800 (PST) From: Angela Czubak To: linux-input@vger.kernel.org Cc: upstream@semihalf.com, dmitry.torokhov@gmail.com, Angela Czubak Subject: [PATCH 18/18] HID: i2c-hid: fix i2c_hid_set_or_send_report Date: Tue, 21 Dec 2021 19:17:43 +0000 Message-Id: <20211221191743.1893185-19-acz@semihalf.com> X-Mailer: git-send-email 2.34.1.307.g9b7440fafd-goog In-Reply-To: <20211221191743.1893185-1-acz@semihalf.com> References: <20211221191743.1893185-1-acz@semihalf.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-input@vger.kernel.org If command & data registers are to be used and report ID >= 0xF use the sentinel value for report ID in the command. Do not alter the report ID itself as it needs to be inserted into the args buffer. If output register is to be used there is no need to insert report IDs >= 0xF. Signed-off-by: Angela Czubak Signed-off-by: Angela Czubak Signed-off-by: Dmitry Torokhov --- drivers/hid/i2c-hid/i2c-hid-core.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/hid/i2c-hid/i2c-hid-core.c b/drivers/hid/i2c-hid/i2c-hid-core.c index 517141138b00..8cb925c86bbf 100644 --- a/drivers/hid/i2c-hid/i2c-hid-core.c +++ b/drivers/hid/i2c-hid/i2c-hid-core.c @@ -341,6 +341,7 @@ static int i2c_hid_set_or_send_report(struct i2c_client *client, u8 reportType, u16 size; int args_len; int index = 0; + u8 cmdReportID = reportID; i2c_hid_dbg(ihid, "%s\n", __func__); @@ -357,16 +358,15 @@ static int i2c_hid_set_or_send_report(struct i2c_client *client, u8 reportType, if (!use_data && maxOutputLength == 0) return -ENOSYS; - if (reportID >= 0x0F) { - args[index++] = reportID; - reportID = 0x0F; - } - /* * use the data register for feature reports or if the device does not * support the output register */ if (use_data) { + if (reportID >= 0x0F) { + args[index++] = reportID; + cmdReportID = 0x0F; + } args[index++] = dataRegister & 0xFF; args[index++] = dataRegister >> 8; hidcmd = &hid_set_report_cmd; @@ -384,7 +384,7 @@ static int i2c_hid_set_or_send_report(struct i2c_client *client, u8 reportType, memcpy(&args[index], buf, data_len); - ret = __i2c_hid_command(client, hidcmd, reportID, + ret = __i2c_hid_command(client, hidcmd, cmdReportID, reportType, args, args_len, NULL, 0); if (ret) { dev_err(&client->dev, "failed to set a report to device.\n");