From patchwork Fri Jan 14 18:31:37 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Angela Czubak X-Patchwork-Id: 12713909 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 1C872C433EF for ; Fri, 14 Jan 2022 18:32:25 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S243007AbiANScY (ORCPT ); Fri, 14 Jan 2022 13:32:24 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:50646 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S242991AbiANScY (ORCPT ); Fri, 14 Jan 2022 13:32:24 -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 A5EEFC061574 for ; Fri, 14 Jan 2022 10:32:23 -0800 (PST) Received: by mail-wm1-x32f.google.com with SMTP id p1-20020a1c7401000000b00345c2d068bdso8840560wmc.3 for ; Fri, 14 Jan 2022 10:32:23 -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=Sz6tgUi+1lixPu1s8iY/vOhgmToeWlY9JUjdC2Z9s5w=; b=lkhgaiqkgO/6KMIZ+NRyolQdiRweXZqmCGKnd8XykoSt7gVlGjTrD6m2qTJsbGiAAG PhzJV9LyUEjM0eqfXl5H8jL4SPeKVwvZFfRVpkkpASSgruXS/eiA+edkfvhTeY/59XOF gHsWIE5np8nAT8cVT7JtKgFgY0/M0KKo+YG8ujlJVTywfUw4MH8XTW1ckZ2SdEkHoWdv bWLhKul4BA9uH/sQ103dBcao6Lp4XK1Kujo5zKKTTkC30AnsadvG3/SVVF8QHPF/h2+N KrGKGoYWx7B+HeskZ2m//+sgHRz3O47NPJU4NWnahNI6yZ9+innxIkYKDMUwwJt178GH kIZQ== 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=Sz6tgUi+1lixPu1s8iY/vOhgmToeWlY9JUjdC2Z9s5w=; b=nWK5oNd/jmOd+DG/Ncd6FX7+2qQX2rRCiZGwCCW/1ZytLdnqynSdlxTRcrNI2CbvuL AP9z/zp1KGlTaVQmM3az1DeFk17oAQAg7d6722tRMX46ibNWg4bTdKNe+u4l3hhn1Luk VjcDdlYkr/uMbG+Bq2in3/T+7CxF9otJj0sXYGPKF8Kw6fWnNJ/UjFthvykhr+jbxW0T 03YZhr5rnzSzY6GoqUYEeOU3MJdJtVAdAaZ7gi/afJ/zXH6r7o6HPXWArF9VRt0o/jzC Od85kSG4YwaXXzfGCcoistGEZ/BJ4jtXFbkk/PdjaCt63Pcs5s0cDvTe5Lwxtfx+47ZN exWQ== X-Gm-Message-State: AOAM530FchQU0ogl8W5U7DYBIYi1I+Ee+wvyQMWHYxTAXVMw9rIzgkuJ PDlVkFQXFlgor+dCvoGv+9zQJq2y9z6fsTMq4Ws= X-Google-Smtp-Source: ABdhPJwjZ2BsPpbnRl5pRs0+jBVUZvEVqhbgzTloQOp9BOwRrlbCtlYMK/QksbvnpMa2M9pl9NZQAA== X-Received: by 2002:a05:600c:1c9f:: with SMTP id k31mr5674211wms.40.1642185142255; Fri, 14 Jan 2022 10:32:22 -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 az4sm6410984wrb.14.2022.01.14.10.32.21 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 14 Jan 2022 10:32:22 -0800 (PST) From: Angela Czubak To: linux-input@vger.kernel.org Cc: upstream@semihalf.com, dmitry.torokhov@gmail.com, benjamin.tissoires@redhat.com, jikos@kernel.org, Angela Czubak Subject: [PATCH v2 01/16] HID: add haptics page defines Date: Fri, 14 Jan 2022 18:31:37 +0000 Message-Id: <20220114183152.1691659-2-acz@semihalf.com> X-Mailer: git-send-email 2.34.1.703.g22d0c6ccf7-goog In-Reply-To: <20220114183152.1691659-1-acz@semihalf.com> References: <20220114183152.1691659-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. Add HID units for newton and gram. Signed-off-by: Angela Czubak --- include/linux/hid.h | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/include/linux/hid.h b/include/linux/hid.h index 7487b0586fe6..4584ce744d02 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 @@ -311,6 +312,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 @@ -398,6 +421,12 @@ struct hid_item { #define HID_REPORT_PROTOCOL 1 #define HID_BOOT_PROTOCOL 0 +/* + * HID units + */ +#define HID_UNIT_GRAM 0x0101 +#define HID_UNIT_NEWTON 0xe111 + /* * This is the global environment of the parser. This information is * persistent for main-items. The global environment can be saved and From patchwork Fri Jan 14 18:31:38 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Angela Czubak X-Patchwork-Id: 12713910 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 B1599C433FE for ; Fri, 14 Jan 2022 18:32:26 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S243011AbiANSc0 (ORCPT ); Fri, 14 Jan 2022 13:32:26 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:50654 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S242991AbiANScZ (ORCPT ); Fri, 14 Jan 2022 13:32:25 -0500 Received: from mail-wm1-x336.google.com (mail-wm1-x336.google.com [IPv6:2a00:1450:4864:20::336]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 16EAFC061574 for ; Fri, 14 Jan 2022 10:32:25 -0800 (PST) Received: by mail-wm1-x336.google.com with SMTP id l4so7656237wmq.3 for ; Fri, 14 Jan 2022 10:32:25 -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=L5oUo6fWhfami6YFCkAzy2ZN790EtzaP0uYG2BdwtUg=; b=s3LbRq8oqG3eFQroAxO+tshwzBVVVN+qeUQ5WjNjvYGstuXibA5bQYjS+OL99qspyd foJkryhuQMC0riYvrSl7Fenmk9uhTp19Z3LMizAQZIt/SQnPfPXtlkKcIFyj1/duhfhD k1mOBKVoGHpCRgEhfeMa1ZaXsv/Uckan/t8DPOqaF0mtZZ05nB/y6QrcNBjbSz5WC54X wCIYfPftL4zTplf5KDINWNHm9bTkfUYp9nDrw6lUKz9liA+pTVIpPLPZUn5n7zBv3OwA HLSbvuAvM3mv07R2c9PELGZoMY5d5YODRAEqFhy0FBCrGgJRdgG5gCi+fRTEDNYBt7bN v3Vw== 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=L5oUo6fWhfami6YFCkAzy2ZN790EtzaP0uYG2BdwtUg=; b=W+Ur1iP1umWyqudwyNTT0YQ4kobwrx3mK1OBg+9msurWSkmJ5V2Z2REtbqjQhsW8t5 bPVcgp/pp8ZRZg0MEl3LobR9qGu1M8hQd+XjRh00f1DIjPOhpzzYvzxeQEwGhdjGUi5m nbCwvloH6scvV4rEqDxzsW9WOcqKwL4Zv4h6VDzGLXqQPWORgD2zNuzRBJlhqlBBLyFs kj9KQDuslvqZ9sj2+yx7vMUVkvC52O8+OI5XF7HMM+ZiGqVQYtraxen205c2wYHfNgXH 6a+xRQMz7T/FHOABYL6ufJOEHbW7g6S+b28309R83t8kvhwz/r7fmCwS+3mNIkDVPWua WksA== X-Gm-Message-State: AOAM530e/7tWlZvTkD7B0vZdy/xSeXnNx5zKHKYKkV6IDI6mxSvGfdx7 TiUKK/S2+iXOAWabOXP45uHsZCFMofeD4oXeKzM= X-Google-Smtp-Source: ABdhPJyabKcmWVX3JYnEj5fwzeu3LHcv/D6MxafUk8IyhEkvgHXMQZQBRgooKeoL/XJFJ49K7XuhyQ== X-Received: by 2002:a5d:4c81:: with SMTP id z1mr9595190wrs.204.1642185143711; Fri, 14 Jan 2022 10:32:23 -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 az4sm6410984wrb.14.2022.01.14.10.32.23 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 14 Jan 2022 10:32:23 -0800 (PST) From: Angela Czubak To: linux-input@vger.kernel.org Cc: upstream@semihalf.com, dmitry.torokhov@gmail.com, benjamin.tissoires@redhat.com, jikos@kernel.org, Angela Czubak Subject: [PATCH v2 02/16] Input: add FF_HID effect type Date: Fri, 14 Jan 2022 18:31:38 +0000 Message-Id: <20220114183152.1691659-3-acz@semihalf.com> X-Mailer: git-send-email 2.34.1.703.g22d0c6ccf7-goog In-Reply-To: <20220114183152.1691659-1-acz@semihalf.com> References: <20220114183152.1691659-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..ccf43a21d43d 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_waveform_page: 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 Fri Jan 14 18:31:39 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Angela Czubak X-Patchwork-Id: 12713911 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 E88BAC433EF for ; Fri, 14 Jan 2022 18:32:27 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S243022AbiANSc0 (ORCPT ); Fri, 14 Jan 2022 13:32:26 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:50656 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S242991AbiANSc0 (ORCPT ); Fri, 14 Jan 2022 13:32:26 -0500 Received: from mail-wm1-x329.google.com (mail-wm1-x329.google.com [IPv6:2a00:1450:4864:20::329]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 1D9FCC061574 for ; Fri, 14 Jan 2022 10:32:26 -0800 (PST) Received: by mail-wm1-x329.google.com with SMTP id n19-20020a7bc5d3000000b003466ef16375so8865621wmk.1 for ; Fri, 14 Jan 2022 10:32:26 -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=Abe1KfF+lJ/PybXuWerxm4ZC1PLP/89AOoSNsN3Hla0=; b=4Jfa4HP8Uu+mME3E7E5ygZltxj0CTwO5kEfCCcOb1o64YCBWqQBuiD8ikSsMlJY5Co LE7qDMIe2lmdB9to+ToUbCYUELvR0PnA69kh0MXP2ntE8y2qpEWUFIpr0sG09Jc8VZyR Kd4gYEqR9RN+uCrXJiK2O4pfrHs3ASDx+7NXGnIfhahNXlJIOCXVgbpOaYF8HTmAO2LF tih8cnexU74DTs/1a4suN3tqxir93gvkICfnZjpAvJR0R6j67t1Oxtcdwqi5y3+FpSvb 0xInqhHMqLRzpbhs+H/1SFvHNXIpMGr4X1PEFNMPx11vGn6yXz6x1T4dOWomLUocDFnh us2w== 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=Abe1KfF+lJ/PybXuWerxm4ZC1PLP/89AOoSNsN3Hla0=; b=WlCBm3kim32fMSy4iW3tLnza2DM9mbROEsNDJotqURfcL+ORNPb5mnaP1UeuWsFqf+ bBPco9WWAN6XyMDPSCx4GotCgqWRL4hhLGiG2ikNsASx+OFheWacAmsoAt6SfEhcI3Cn 5wuH5GM5QHHrbf4Mfgon7sVcTBC1wT/oTYaEV0H/NX7Egd6XalW6MV9q88WC3v/jHmHl 7zaZD5plHXgdOXFbtIOg6qw+DgunTxEnimEv3Bd9lXWugtWvLwIJBTyVqAW3TN8NQ59C HCfeFBqTsCSY+Xu02FtHeJYJlNRBvr6y8ZNxr1vaOIfhdp4U+SiB+VWf+rWX5aPzK4hm MebQ== X-Gm-Message-State: AOAM530T3OSYcRADszpsB+cKlJQaY1Bo9oKyRjuaBO5wye2PE1awIL/S WQhObUdkVEr/BPf3MftByXLqB6PiRnUDhnEGxBI= X-Google-Smtp-Source: ABdhPJzFK66wNPvM9JVuDTuZIlGmuFKcBCZxuVRGV+8ZwehFJnfFxx9msA512GelRP1IATLLBeSyIw== X-Received: by 2002:a05:600c:3ac8:: with SMTP id d8mr9619818wms.72.1642185144683; Fri, 14 Jan 2022 10:32:24 -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 az4sm6410984wrb.14.2022.01.14.10.32.24 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 14 Jan 2022 10:32:24 -0800 (PST) From: Angela Czubak To: linux-input@vger.kernel.org Cc: upstream@semihalf.com, dmitry.torokhov@gmail.com, benjamin.tissoires@redhat.com, jikos@kernel.org, Angela Czubak Subject: [PATCH v2 03/16] Input: add INPUT_PROP_HAPTIC_TOUCHPAD Date: Fri, 14 Jan 2022 18:31:39 +0000 Message-Id: <20220114183152.1691659-4-acz@semihalf.com> X-Mailer: git-send-email 2.34.1.703.g22d0c6ccf7-goog In-Reply-To: <20220114183152.1691659-1-acz@semihalf.com> References: <20220114183152.1691659-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 --- Documentation/input/event-codes.rst | 14 ++++++++++++++ include/uapi/linux/input-event-codes.h | 1 + 2 files changed, 15 insertions(+) diff --git a/Documentation/input/event-codes.rst b/Documentation/input/event-codes.rst index b24ae7d292cc..bbf2510c2b1a 100644 --- a/Documentation/input/event-codes.rst +++ b/Documentation/input/event-codes.rst @@ -390,6 +390,20 @@ can report through the rotational axes (absolute and/or relative rx, ry, rz). All other axes retain their meaning. A device must not mix regular directional axes and accelerometer axes on the same event node. +INPUT_PROP_HAPTIC_TOUCHPAD +-------------------------- + +The INPUT_PROP_HAPTIC_TOUCHPAD property indicates that device: +- supports simple haptic auto and manual triggering +- can differentiate between at least 5 fingers +- uses correct resolution for the X/Y (units and value) +- report correct force per touch, and correct units for them (newtons or grams) +- follows the MT protocol type B + +Summing up, such devices follow the MS spec for input devices in +Win8 and Win8.1, and in addition support the Simple haptic controller HID table, +and report correct units for the pressure. + Guidelines ========== 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 Fri Jan 14 18:31:40 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Angela Czubak X-Patchwork-Id: 12713912 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 ED064C433EF for ; Fri, 14 Jan 2022 18:32:31 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S242991AbiANSca (ORCPT ); Fri, 14 Jan 2022 13:32:30 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:50666 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S243074AbiANSc1 (ORCPT ); Fri, 14 Jan 2022 13:32:27 -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 1875BC061574 for ; Fri, 14 Jan 2022 10:32:27 -0800 (PST) Received: by mail-wm1-x32f.google.com with SMTP id w26so7689247wmi.0 for ; Fri, 14 Jan 2022 10:32:27 -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=F6dgo/VtRvg7jFI73Uw9wSSOHiw5h8cMUYKD+BdbIj8=; b=1Ohe0pYqWBc07mwAHVXbfVpm5JskC7wHBzuubCqH457zH9xLANP11CywqYhmMhkhAs LJpLwtrds55wsfpnzlOkENJGhjiGFYep9Rlk1SfCUMbr7BDg+JgJjHTwDwnsgEjuGtaE kBeWv7lbRpciQZ8K0+JGEE0GyuWotlrCxsnfo2QE6VqeUZ+J0rjcXRFGZhqMhZ4m0ARC tlZ9DXh7xLH8NEslQOI5LW/AmDWnnKsdy4/Ve/b4czR+CoUTrqxD2a699cx7bxlWE4Gu f2rSMM/MhRI7ajwO+/WRNGXV6/z704M4V+d3/pQUUYs8VFjE4bvAOU9b7YvRMY2kA18H xpZQ== 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=F6dgo/VtRvg7jFI73Uw9wSSOHiw5h8cMUYKD+BdbIj8=; b=j8zFhFR1Hk6lJTuJF1s4152UwhipT5/b/qE9kqDyNdnr4ygPoTuf6tfb9fIhGlc4iF f68zf5zdO6Oua88+k7Bx/LDjaR5bKxJrHZ97OFonfWwucmzaDJfXrQtSaBK2OgBZ6CZH BBIJ1pPm6gjlW1YqTH1c+wIKPdfLEEl1bDQL/dQK+69YD1flE51E/tmdlje/iJkEp3oI HO6rViHdXpZYw/b1s81YcEaELSA+YD5engvaFecEoDIESh6wGu9yRQER9DeJBYX0fPLT atpD4mJY/Z6FemKjLba0Eq1R9WiDYxSW6X15uVRwIk0Ek2Xqmxuyh96vJYn43GLkoByb hW2Q== X-Gm-Message-State: AOAM531+WgCerE9jPBDBm1vNQwu3AUIvZ8lL2MgxZc+HDxLSeXlDGqXT v+Y22/akEoYampw4PQuCnGFKDCXL2iDWegbz3Y8= X-Google-Smtp-Source: ABdhPJz74v44uGNGF+iR02lOdi4d0Vn2CdZOAchfA1HlpoVsPr2tr6ghUAZiyKs5l49abwky+E+h/w== X-Received: by 2002:a05:600c:1907:: with SMTP id j7mr16676036wmq.175.1642185145690; Fri, 14 Jan 2022 10:32:25 -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 az4sm6410984wrb.14.2022.01.14.10.32.25 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 14 Jan 2022 10:32:25 -0800 (PST) From: Angela Czubak To: linux-input@vger.kernel.org Cc: upstream@semihalf.com, dmitry.torokhov@gmail.com, benjamin.tissoires@redhat.com, jikos@kernel.org, Angela Czubak Subject: [PATCH v2 04/16] HID: haptic: introduce hid_haptic_device Date: Fri, 14 Jan 2022 18:31:40 +0000 Message-Id: <20220114183152.1691659-5-acz@semihalf.com> X-Mailer: git-send-email 2.34.1.703.g22d0c6ccf7-goog In-Reply-To: <20220114183152.1691659-1-acz@semihalf.com> References: <20220114183152.1691659-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. 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/Kconfig | 3 ++ drivers/hid/Makefile | 1 + drivers/hid/hid-haptic.c | 72 +++++++++++++++++++++++++ drivers/hid/hid-haptic.h | 114 +++++++++++++++++++++++++++++++++++++++ 4 files changed, 190 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 f5544157576c..3e7555b868e7 100644 --- a/drivers/hid/Kconfig +++ b/drivers/hid/Kconfig @@ -89,6 +89,9 @@ config HID_GENERIC If unsure, say Y. +config HID_HAPTIC + bool + menu "Special HID drivers" depends on HID diff --git a/drivers/hid/Makefile b/drivers/hid/Makefile index 6d3e630e81af..f21338e142ef 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..d659a430c1a6 --- /dev/null +++ b/drivers/hid/hid-haptic.c @@ -0,0 +1,72 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * HID Haptic support for Linux + * + * Copyright (c) 2021 Angela Czubak + */ + +#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_device_io_start(hdev); + hid_hw_request(hdev, field->report, HID_REQ_GET_REPORT); + hid_hw_wait(hdev); + hid_device_io_stop(hdev); + 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) +{ + if (field->unit == HID_UNIT_GRAM || field->unit == HID_UNIT_NEWTON) + 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 new file mode 100644 index 000000000000..601630e7049f --- /dev/null +++ b/drivers/hid/hid-haptic.h @@ -0,0 +1,114 @@ +/* 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; +}; + +#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 Fri Jan 14 18:31:41 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Angela Czubak X-Patchwork-Id: 12713913 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 CF8F3C433FE for ; Fri, 14 Jan 2022 18:32:32 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S243074AbiANSca (ORCPT ); Fri, 14 Jan 2022 13:32:30 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:50668 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S243079AbiANSc2 (ORCPT ); Fri, 14 Jan 2022 13:32:28 -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 061A2C06161C for ; Fri, 14 Jan 2022 10:32:28 -0800 (PST) Received: by mail-wm1-x332.google.com with SMTP id d187-20020a1c1dc4000000b003474b4b7ebcso7228898wmd.5 for ; Fri, 14 Jan 2022 10:32:27 -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=CC3fg4tLPbBqyg9QQ9rodaBfRAw+nKJ9yBWklaxbIJ8=; b=yL56HZREeP5piwVRAutc0USqp6uguNrvllYOvMvFkfw7Yx6IOdDhq3EOfUP1nDGanK sFh6b5+6n+09yA/xcqiZDVf6X19LeQgtK+nYG0BIlEX8uZhEex6wfIe5BhEAmDroviVW 2uhC5kuN6EC/h/+7mLqqJkD+je7d4opNAQXTDolzWbDdnsd08BdZlo0kItYZyhW2k8Wg xzgYqLxqjM+Lm5kqIFdNe5/c+d9+Q1Ow4D8KAX/9IbMK8qGqoixBnWPBlOuCTmwjbmvG wH7STa7+5z2U46rNfJKVXyle4HInMgfM6crM2EWF/JVCMyhYjvn5YRQy6okx2bk2swSH GIdw== 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=CC3fg4tLPbBqyg9QQ9rodaBfRAw+nKJ9yBWklaxbIJ8=; b=8BUVCH7MKwP76uDgb66erzmaOKZvNmB5QtWnJPHthnd7gNPLY4u3xHH2MoCXIU/E+S EVeETfuvywVH4Zr3N2eHh9CGzd+LW4yyOjg88UcVSYHl4z+69grTKkuOHTXoguEgGb4k 8431ySyWu83S/OlTLtwpnBnDYIDsEBEkrzkupUnEumxio93x3O1DDchjySNg/+lg0jC8 bk2okPqpU3PCTh8X951JvA5snlz8wAmmmNy/mnXN2C7MwsAsYt6bV6V7LYh0YXPw1nt7 o6EkdI9fCXcvOgWUtqfK8YQL4NE8qlQteYzllpAPrVF7rHQUMFr9oyfykHEnsXPlLX9w 8rbQ== X-Gm-Message-State: AOAM532VXSFhIY95EzBusKMKJYpO+KBGqPrWED149tENT9cXuDW9jalg AtqLXwGu95QqXhMEXOWQDuza8KqGyabTQmOa60s= X-Google-Smtp-Source: ABdhPJxORal5+LDne3fPR6Hsj8VAWGtv8FRkPOJ3SS6b9gOMj+b+hBcp1h2U5eY2VWLmB3YepAcvjA== X-Received: by 2002:a05:600c:4f13:: with SMTP id l19mr16546258wmq.152.1642185146657; Fri, 14 Jan 2022 10:32:26 -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 az4sm6410984wrb.14.2022.01.14.10.32.26 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 14 Jan 2022 10:32:26 -0800 (PST) From: Angela Czubak To: linux-input@vger.kernel.org Cc: upstream@semihalf.com, dmitry.torokhov@gmail.com, benjamin.tissoires@redhat.com, jikos@kernel.org, Angela Czubak Subject: [PATCH v2 05/16] HID: input: allow mapping of haptic output Date: Fri, 14 Jan 2022 18:31:41 +0000 Message-Id: <20220114183152.1691659-6-acz@semihalf.com> X-Mailer: git-send-email 2.34.1.703.g22d0c6ccf7-goog In-Reply-To: <20220114183152.1691659-1-acz@semihalf.com> References: <20220114183152.1691659-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 --- 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 1ce75e8b49d5..9dd4a146576a 100644 --- a/drivers/hid/hid-input.c +++ b/drivers/hid/hid-input.c @@ -600,9 +600,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 Fri Jan 14 18:31:42 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Angela Czubak X-Patchwork-Id: 12713914 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 86983C433EF for ; Fri, 14 Jan 2022 18:32:34 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S243079AbiANScc (ORCPT ); Fri, 14 Jan 2022 13:32:32 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:50676 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S243099AbiANSc3 (ORCPT ); Fri, 14 Jan 2022 13:32:29 -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 2E949C061574 for ; Fri, 14 Jan 2022 10:32:29 -0800 (PST) Received: by mail-wm1-x330.google.com with SMTP id 25-20020a05600c231900b003497473a9c4so8842889wmo.5 for ; Fri, 14 Jan 2022 10:32:29 -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=0oUQIWqxTrN5LE6vB8OzGFRvhaWOAYRm+59RLbh28c8=; b=MuL7BNU66gUULtIO9U/j+UzV1B03bbPFbrmbvr92aT8SVWdZDx+mE2z1ySvqGhbsBs XR0kZ9u5X0Qf5kQdlvkBotQvMvRl/RW5BUmc8ZuBIqU8eJfuNaKAXUO+DrYV11oHmz6l keyujEkhDHr24w7RnqVbl2CNbFYk7ixBiPQ2TzN4bDSqkOBcMRx3qBx/DwAQPXwc8OMK KC2/p/CVJrI4wdX93BvldQkNhMlKaXmwHYJ9+ST6YYXT86iAfrcjamtHIhn4Ab4oCMXe Fb61ekV1Cwn1fOf8anTNDHFg1sGF67dj6Xf9qY6yZBMFcsLpyr25YOW8yPp2jcpxk7Kb ASFw== 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=0oUQIWqxTrN5LE6vB8OzGFRvhaWOAYRm+59RLbh28c8=; b=UoS00jhaOLwxYvVWOkS5EkM89bSy7daon31PzYvuhRrs5mvawwOGCadreOuGtrTE2m OHCd0C4KMXLv8hY0GNB+PlkAQqwbKHiqPxzcbaYJ2TmxyJ5s6h+Yx+G72l78nz28keX9 igD9KaDOkznoN+cXvjE0CoTgkbr3gJC6WKdjPfm+J9zX+uh++O8t9zoH6A6ktHqjN9vJ v7J5DvYzI5J2pMdu1K3L8yMJDJTz4VGI00XWw+5vrIuyIJECiU05VVFHP4gU6vQXDPJc 8OS/hDGp38kXl3l0V6VvDs6ltUQKdh2pTEA8kvlM4W9Qk/8Vf84851MBy4M6201PyO1D uMVw== X-Gm-Message-State: AOAM533NjO0k55GBaCPvUewPdKtZKJpUklBjteKwuOvR9/jkhMv5g6+i zCkTi2p2H8Rsy8DmHa0Lj4yOQIdPOMeJoruOp6A= X-Google-Smtp-Source: ABdhPJwf3ON4fU9Y4peo18+SGo2e8isU1YNzgWfD6QH5sCtdr9KHXRbMilBprLtTq067qFzyiKB4hA== X-Received: by 2002:a5d:4e51:: with SMTP id r17mr9325861wrt.444.1642185147735; Fri, 14 Jan 2022 10:32:27 -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 az4sm6410984wrb.14.2022.01.14.10.32.27 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 14 Jan 2022 10:32:27 -0800 (PST) From: Angela Czubak To: linux-input@vger.kernel.org Cc: upstream@semihalf.com, dmitry.torokhov@gmail.com, benjamin.tissoires@redhat.com, jikos@kernel.org, Angela Czubak Subject: [PATCH v2 06/16] HID: haptic: initialize haptic device Date: Fri, 14 Jan 2022 18:31:42 +0000 Message-Id: <20220114183152.1691659-7-acz@semihalf.com> X-Mailer: git-send-email 2.34.1.703.g22d0c6ccf7-goog In-Reply-To: <20220114183152.1691659-1-acz@semihalf.com> References: <20220114183152.1691659-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 | 444 +++++++++++++++++++++++++++++++++++++++ drivers/hid/hid-haptic.h | 6 + 2 files changed, 450 insertions(+) diff --git a/drivers/hid/hid-haptic.c b/drivers/hid/hid-haptic.c index d659a430c1a6..7dffd0fa68c6 100644 --- a/drivers/hid/hid-haptic.c +++ b/drivers/hid/hid-haptic.c @@ -5,12 +5,16 @@ * Copyright (c) 2021 Angela Czubak */ +#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); @@ -70,3 +88,429 @@ 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 601630e7049f..e686f7ec42b9 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 Fri Jan 14 18:31:43 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Angela Czubak X-Patchwork-Id: 12713915 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 242B0C433F5 for ; Fri, 14 Jan 2022 18:32:36 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S243108AbiANSce (ORCPT ); Fri, 14 Jan 2022 13:32:34 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:50678 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S243105AbiANSca (ORCPT ); Fri, 14 Jan 2022 13:32:30 -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 25110C06173E for ; Fri, 14 Jan 2022 10:32:30 -0800 (PST) Received: by mail-wm1-x330.google.com with SMTP id l12-20020a7bc34c000000b003467c58cbdfso8854656wmj.2 for ; Fri, 14 Jan 2022 10:32:30 -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=AHLt3sUb2fMQkhkkdlUxnnWbR3Lx+wdC9flrm9iGQO4=; b=7Dkb/qKDO1L36vg4sgekDMMyZEbKiIjHLqOhnAX4i5bJokoxq51rirgz77tYhEspC5 2WxVFGlfhrCvqC6pIIySX7D3LfAsiE47oF6rPyG+cwqQ2FVt7vG0y3QHdL+dEfsmwDpq 6t0aw1j5iVuSwnQVaxHO3CdIdoRUwoOmx0/TvxwCjtJT16d9hQ2WBiWqh+f5EZGekoMb aYv2B0g+Q8SHO79LhbJmKVWLni643HXPZIqdjGkoF2B+ybiAYLJFeEixMwkFa3Qp1E2w 18LNwIT/35FAmBXL4w7GjwNWkZVdH2TUquNeYXPhn8rMXh7uE1rf2m+vy0PbLaktskGU 128A== 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=AHLt3sUb2fMQkhkkdlUxnnWbR3Lx+wdC9flrm9iGQO4=; b=56vZrwMCFOR5j7dZPquDbJmlKNXZBAvjSQdZb1ev0+wilpidX/h9XIoQ9n5H28twnU vqcCiNj95lmNYhx5EpIP/esqm7PQKMYGAS2k3rRkHSW4u5PU9hjqnPpOU29G/r8AmLez lwMEKTF/kxmC6GCa0r9W+cYA33t+0VqO8jB4X3QcyYO1a2+mq6/gvdBbbnY58kfBvapP FMW78s9GyKftV0xENizXMFCB4RSDeInmws2rwa+pW50kJV/h0mjxPDgBa0eST2bb3/PF FFjwmUxgKKCsWcpUpjvutbK9oALth26Gx3LlTGjXmV+9dZtAHkANTcl/H939NgJTpPnw oO2w== X-Gm-Message-State: AOAM533kkLmyaEm4c7qYKBwJ4Jy64TEvZ/jXDy7Y3/8QyqXd1BaH1QBW ugQhNLd7UrL9KNApCpbfntloORdRomz2jXVEBLU= X-Google-Smtp-Source: ABdhPJzHpNIBoYVgPg0UAQdrRibUhkAc2A9nn2eUjVaOTp7QZB7vi2udrcM8Mx8MFzWV6i47Qo1RFQ== X-Received: by 2002:a05:600c:1991:: with SMTP id t17mr16558965wmq.21.1642185148766; Fri, 14 Jan 2022 10:32:28 -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 az4sm6410984wrb.14.2022.01.14.10.32.28 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 14 Jan 2022 10:32:28 -0800 (PST) From: Angela Czubak To: linux-input@vger.kernel.org Cc: upstream@semihalf.com, dmitry.torokhov@gmail.com, benjamin.tissoires@redhat.com, jikos@kernel.org, Angela Czubak Subject: [PATCH v2 07/16] Input: add shared effects Date: Fri, 14 Jan 2022 18:31:43 +0000 Message-Id: <20220114183152.1691659-8-acz@semihalf.com> X-Mailer: git-send-email 2.34.1.703.g22d0c6ccf7-goog In-Reply-To: <20220114183152.1691659-1-acz@semihalf.com> References: <20220114183152.1691659-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 Fri Jan 14 18:31:44 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Angela Czubak X-Patchwork-Id: 12713916 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 B6613C4332F for ; Fri, 14 Jan 2022 18:32:36 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S243105AbiANScf (ORCPT ); Fri, 14 Jan 2022 13:32:35 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:50686 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S243120AbiANScb (ORCPT ); Fri, 14 Jan 2022 13:32:31 -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 21D87C06161C for ; Fri, 14 Jan 2022 10:32:31 -0800 (PST) Received: by mail-wm1-x32f.google.com with SMTP id c126-20020a1c9a84000000b00346f9ebee43so7227853wme.4 for ; Fri, 14 Jan 2022 10:32:31 -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=QkRLDEpyd2dj86Jt9gdru7NEOV/insLnjmGna/TlM78=; b=LbC0JqBkagUJMu0kJxwU29nFuFWivn5jt7WKo2C1EM57k/1X6C9uXhWL/PrUhPe0L2 u2Bt3DtXITvq/iWIGKVDglBRLj7cX+1L5lYQyXTV4MEArcBG3VEeUocPG/oOCE2tc/x1 4ZGGR5CR7MIjRq0PiFYSnSX0Z0Gaa2fNWGL6Q0dD9zCACTfAt54dshNyLnkzvpFfwMnM 9QZxaLADxcLOK5neLROHvJ4N0FQ1OK3QzjiTe9NWwbBg1IHfjAOD//3Ro7KKegsDEyUW 1+5MDhgY+dXVcm9gWINQ5UZzxs4VAvl4g6SXUilkdO858Ay0NuH/H6HVHNvhBw68uEDg okcg== 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=QkRLDEpyd2dj86Jt9gdru7NEOV/insLnjmGna/TlM78=; b=pgytBRxRd6JEbs2K7DQLQIzZKHQjYikbPEJDk9gQBg77+FGbtu+mKcS10mlWnGDN0m Drp42fUe4fbifjeQctc1l7kCUIlkZ5S3L/CYeGchnfHQ+O4foG6gL1JU1KqY6Wxyp28w V/AQzfEBrlZXQSqTl8WUEjln18sSgHL67Bmh3k8KW7DdnF5OavCXi2ybfOga3DjdZvmi kr+Jm0Cet6cLUAb/fUxIit7sFDvkXrwo/kQuhJoIyHJb6bqiPCOEQn+nQRjMXQinr3Fn 8wQ+7zZUGV4zpZvHPbrz/AeE7rRKcluGUn4sxINqlXI4FiYLiVJZu5OmULUQn8Ix6ugD lnZw== X-Gm-Message-State: AOAM531JhSCsu0lqag+g6AmXS9ZaTe6YtNolsw9PMUd69VnbF2OQXcSs +Vhtb5bMu9aaSc3nR5TLsAARNwpFYXrJx8TGTR0= X-Google-Smtp-Source: ABdhPJwhTt9wu0VIlh4ZsSrWsdgkIOlidSCwbPJvHU7ymIgJakngv37o93qyWVu0JyOFUndZDnprfw== X-Received: by 2002:a5d:52c4:: with SMTP id r4mr9624116wrv.521.1642185149736; Fri, 14 Jan 2022 10:32:29 -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 az4sm6410984wrb.14.2022.01.14.10.32.29 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 14 Jan 2022 10:32:29 -0800 (PST) From: Angela Czubak To: linux-input@vger.kernel.org Cc: upstream@semihalf.com, dmitry.torokhov@gmail.com, benjamin.tissoires@redhat.com, jikos@kernel.org, Angela Czubak Subject: [PATCH v2 08/16] HID: haptic: implement release and press effects Date: Fri, 14 Jan 2022 18:31:44 +0000 Message-Id: <20220114183152.1691659-9-acz@semihalf.com> X-Mailer: git-send-email 2.34.1.703.g22d0c6ccf7-goog In-Reply-To: <20220114183152.1691659-1-acz@semihalf.com> References: <20220114183152.1691659-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 7dffd0fa68c6..64e354cb3f2e 100644 --- a/drivers/hid/hid-haptic.c +++ b/drivers/hid/hid-haptic.c @@ -365,6 +365,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); @@ -481,8 +482,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 Fri Jan 14 18:31:45 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Angela Czubak X-Patchwork-Id: 12713917 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 8D291C433EF for ; Fri, 14 Jan 2022 18:32:38 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S243146AbiANScg (ORCPT ); Fri, 14 Jan 2022 13:32:36 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:50676 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S243050AbiANScc (ORCPT ); Fri, 14 Jan 2022 13:32:32 -0500 Received: from mail-wm1-x331.google.com (mail-wm1-x331.google.com [IPv6:2a00:1450:4864:20::331]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 3788BC061574 for ; Fri, 14 Jan 2022 10:32:32 -0800 (PST) Received: by mail-wm1-x331.google.com with SMTP id l4so7656907wmq.3 for ; Fri, 14 Jan 2022 10:32:32 -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=6cBfTFoWrKbOrWZZ9T9FRTNRu/mK8t2sxofNFZHrCmc=; b=CqMso+/WKJkZW/QUimeNOXpAZ2lCmr0Uxfg1GsSab0TTW56uiqnwtHXIe1vO7UvMoE vdNUigvnJqDjt1mkc3Xds7BpPT0JhucXnpNro3wzhoGLH7/YYmthpGiHZshaFaIchtDH POx+5xMRBAEAyaYiJuYidoWB13TqBiQsUp601dPiDBRJVqJ5ih9hrIrcz3OduZ7yvBKk G9FbkK4MRGS+twY1u4T8fEKAvi4GwrTlOiyr7NCC2m+jDeHsCrvThV1g612Gq5XIVsqu fae2IFBCm2aV0ncJ7pJvOa/WDmHZ2QshMul0DdeQOJnFiGW1hQQ2hLK8aooERS4NzXbx glNQ== 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=6cBfTFoWrKbOrWZZ9T9FRTNRu/mK8t2sxofNFZHrCmc=; b=KCkmofyBUHib0IHWhNi3p3oNdZtkMHDDmNJIAt48V8OPMRR6t10H/eVp/tZgm67G0B 7xG74xqcaYJwNMOZevbfs6P6/vy7AJ4eOvCSQ4K9/mzrM4bEYzXGUpuMuQlQss+6cMC0 5haLp7Do/eVk7nsOfQL9kkzXL652IukanYAq77RrFS0ERWnmstZUvHI7yXUtcPl1eZhF mBlEZ6ZoJJ+zPUI+TYlTXFbwhC9DODvmvr7hMJcixO3VzC3QU/EnWy5IzFde83CQU1qn 9hsTAiaGTtZoTW7qy+LSh2g8xW58It7CuqfN3C7kqHQwnl9xWT/ty6l8aeP0GjIVZaS3 bEQA== X-Gm-Message-State: AOAM532Myez63O0yg4mIXpGRj6A27ks0xf8GBxL/xEOzmgi+kATxWYg9 eo9I5zD7Fobw6ARCRQFo+4EgoPh2fAmX9shmvw0= X-Google-Smtp-Source: ABdhPJy7Ygo+l6lws6cw8Uo5nHSbpaobPdg6Lh0XO5bGEGqVl6rxuR8TjS0s/8EhflFH6puDVqLECw== X-Received: by 2002:a05:600c:4caa:: with SMTP id g42mr12704671wmp.60.1642185150812; Fri, 14 Jan 2022 10:32:30 -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 az4sm6410984wrb.14.2022.01.14.10.32.30 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 14 Jan 2022 10:32:30 -0800 (PST) From: Angela Czubak To: linux-input@vger.kernel.org Cc: upstream@semihalf.com, dmitry.torokhov@gmail.com, benjamin.tissoires@redhat.com, jikos@kernel.org, Angela Czubak Subject: [PATCH v2 09/16] HID: input: calculate resolution for pressure Date: Fri, 14 Jan 2022 18:31:45 +0000 Message-Id: <20220114183152.1691659-10-acz@semihalf.com> X-Mailer: git-send-email 2.34.1.703.g22d0c6ccf7-goog In-Reply-To: <20220114183152.1691659-1-acz@semihalf.com> References: <20220114183152.1691659-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 9dd4a146576a..4917cdf5df27 100644 --- a/drivers/hid/hid-input.c +++ b/drivers/hid/hid-input.c @@ -258,6 +258,19 @@ __s32 hidinput_calc_abs_res(const struct hid_field *field, __u16 code) } break; + case ABS_PRESSURE: + case ABS_MT_PRESSURE: + if (field->unit == HID_UNIT_NEWTON) { + /* Convert to grams, 1 newton is 101.97 grams */ + prev = physical_extents; + physical_extents *= 10197; + if (physical_extents < prev) + return 0; + unit_exponent -= 2; + } else if (field->unit != HID_UNIT_GRAM) { + return 0; + } + break; default: return 0; } From patchwork Fri Jan 14 18:31:46 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Angela Czubak X-Patchwork-Id: 12713918 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 2D421C433FE for ; Fri, 14 Jan 2022 18:32:39 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S243164AbiANSch (ORCPT ); Fri, 14 Jan 2022 13:32:37 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:50678 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S243088AbiANScd (ORCPT ); Fri, 14 Jan 2022 13:32:33 -0500 Received: from mail-wm1-x32b.google.com (mail-wm1-x32b.google.com [IPv6:2a00:1450:4864:20::32b]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 35C00C06173F for ; Fri, 14 Jan 2022 10:32:33 -0800 (PST) Received: by mail-wm1-x32b.google.com with SMTP id q141-20020a1ca793000000b00347b48dfb53so7265029wme.0 for ; Fri, 14 Jan 2022 10:32:33 -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=JL2oUXxSmPHvaHeRcPzyrtG4kTUnGJI+q7n4E7t0vwc=; b=NcsT6YxY1wcPVgNtDPXf6ubOts3rLji7vUUxZrIDpKJD7GV7oWvqo1UYRsD2kL7cat gg9Z+n3spO0F8Gfd/iMqByUOL//bN1NIsZL3s79rNzPC3g4aVGzRGG7FzAXlDq9Rb/x2 hIRgPVNbq8S6HfcqC5tWU0RVtjW9mnXxiJ4WhlFRUbtjqgweq3tHBCue/I40/Q/JbFXj YeTlvGRt5hA9Ps8lGHnxADDFGfB4tUCn3cOa6cqXkGhqcS5HvscM26bbCs08jr3O2/TL X507aAwLQfBLT8PXK8wz1/xV77UX0JfH3JCAJG3ATOOAUqbI7fnqElpvcCgV2nPRbcSV bKbw== 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=JL2oUXxSmPHvaHeRcPzyrtG4kTUnGJI+q7n4E7t0vwc=; b=QkZcZzeVQgGB0WEytDAibDplLK/cINS/5Gx5sBzDPHSX/MjGcYm2zaeTkwLW7u2eZf HhYFCMxENMn6oYCNQDwpVjTWf4jzJ+8jVP0Ty7TqfIOHPi8Vy/9rZBb6tINbFOvUsc4b IdgVq2WnQ75qc8C+tpivEts9hauYmt3QL99VRlxMJxV91wnvP98xR3TRkImgB4J6VMCN 6Hu7hR4PryOl25k0jUGvKAFCVU9Bx6Ez1HJJeh4t7qiST1r9lU8sLWsN6vjgAiZaMkGS AIU+BKz1UaF1s8GGjJxPX0VeEzK1k2rlg5csHrogcaLK7efBs31H9O8SdQh03+rr/Fyi dKEg== X-Gm-Message-State: AOAM533l1+JtCyZ9foc0mvWdXDGvVOhD5WXXyqvtl3rOKHlJQ8AxuGmp RK4A/zbcWgZ9Ocint34yQUj/p+Sm95VXS9KoumI= X-Google-Smtp-Source: ABdhPJwcCA5N6gGsLgK+9tlAcda/TBhg+yyBgaisKOeFUGLg1OtAalXeqXql0gd2cGJkyKghCy7ifA== X-Received: by 2002:a05:6000:15c9:: with SMTP id y9mr7795879wry.5.1642185151844; Fri, 14 Jan 2022 10:32:31 -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 az4sm6410984wrb.14.2022.01.14.10.32.31 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 14 Jan 2022 10:32:31 -0800 (PST) From: Angela Czubak To: linux-input@vger.kernel.org Cc: upstream@semihalf.com, dmitry.torokhov@gmail.com, benjamin.tissoires@redhat.com, jikos@kernel.org, Angela Czubak Subject: [PATCH v2 10/16] HID: haptic: add functions handling events Date: Fri, 14 Jan 2022 18:31:46 +0000 Message-Id: <20220114183152.1691659-11-acz@semihalf.com> X-Mailer: git-send-email 2.34.1.703.g22d0c6ccf7-goog In-Reply-To: <20220114183152.1691659-1-acz@semihalf.com> References: <20220114183152.1691659-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 | 71 +++++++++++++++++++++++++++++++++++++++- drivers/hid/hid-haptic.h | 18 ++++++++++ 2 files changed, 88 insertions(+), 1 deletion(-) diff --git a/drivers/hid/hid-haptic.c b/drivers/hid/hid-haptic.c index 64e354cb3f2e..4a5d5e7b92d1 100644 --- a/drivers/hid/hid-haptic.c +++ b/drivers/hid/hid-haptic.c @@ -50,8 +50,13 @@ 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) { - if (field->unit == HID_UNIT_GRAM || field->unit == HID_UNIT_NEWTON) + if (field->unit == HID_UNIT_GRAM || field->unit == HID_UNIT_NEWTON) { + 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); @@ -350,6 +355,12 @@ 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) { @@ -457,6 +468,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; @@ -548,3 +566,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 e686f7ec42b9..586f20be0061 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,17 @@ 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 Fri Jan 14 18:31:47 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Angela Czubak X-Patchwork-Id: 12713919 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 168B7C433F5 for ; Fri, 14 Jan 2022 18:32:44 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S243100AbiANScl (ORCPT ); Fri, 14 Jan 2022 13:32:41 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:50686 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S243134AbiANSce (ORCPT ); Fri, 14 Jan 2022 13:32:34 -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 425E8C061747 for ; Fri, 14 Jan 2022 10:32:34 -0800 (PST) Received: by mail-wm1-x330.google.com with SMTP id ay4-20020a05600c1e0400b0034a81a94607so6318001wmb.1 for ; Fri, 14 Jan 2022 10:32:34 -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=1MvDm6chj8/OR9+iaUSWg8PUJVBeuAtEH6jWvTqle30=; b=WfWX+StJf1W7YZDUDy2Y4/pzgqNnbJB5yhmqQXNI6m/pBs+Jk/U9SjeF2YR5Tj3++2 2aUAkfdzTv1uEP2ap4ejIVZDsi8Pc1wY2QplVY2fVLVVmnL4XITZfI+1KNMcvw471FO+ A4vFSH5Uuij0PLt+VdHIvbstf4vunqVEcgiplqBoxcNGQS3D0sBBTXeXuqwY54XiOYYs igIf8ilPHkLPky21Ni1/2ccXX2t4mp+BOOawGBP/m/rf7Q05PlnhjRhKpbE91tw2sI7X 6saPybCHbTrmE8xCcvervO921XmDQ9thEWnRsdoKkzKoPXp9DUySuhcHT3OFnDEQVjd4 LNPA== 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=1MvDm6chj8/OR9+iaUSWg8PUJVBeuAtEH6jWvTqle30=; b=qKFU1xu+eK24w2+GpMXKlxAAREHfTE2TsVgYtRzCvJumGbYwrhlGzglELsx/kdH5M2 WjxAezZxVuZomxygpU0KjUcMq8QUpHwihczgEuTORpQN9mWcoqXj3ygWKI6JeXP/JbyD gZuR/wW8IboSrKEAF+ViOFArSYW781YUGZbaybnYf9Vwgj7lBEDlog1OtESvUNI3uXlA 0X6r1jm+Pi8psQWv8tOYwIfT7TgOfWYYflWT64A2wq6iSQGG6PKUmg/NwGV2iqtrB1Mj BopQx+wp0OXjDN/06Jmb9WXBboBwH+cukJukMdzZDAFC1jGZsGE6SUx1E+THMaCcUptC tGrw== X-Gm-Message-State: AOAM532F5qqOQN+nOo4s9G6Q2ticE5ZUcWDf9XUufgOvic69F4WfS2Bk Qru71344uI3FY63PT9WxScLZnabH71thh53qjPE= X-Google-Smtp-Source: ABdhPJxXb0FldDTrIzr8XBsZPladkRnhhCwiEWF2dQnXpNTtgHf95ZmXFtyY7Dw50Un9Ph2GjP8DkQ== X-Received: by 2002:adf:ec8c:: with SMTP id z12mr9543167wrn.176.1642185152892; Fri, 14 Jan 2022 10:32:32 -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 az4sm6410984wrb.14.2022.01.14.10.32.32 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 14 Jan 2022 10:32:32 -0800 (PST) From: Angela Czubak To: linux-input@vger.kernel.org Cc: upstream@semihalf.com, dmitry.torokhov@gmail.com, benjamin.tissoires@redhat.com, jikos@kernel.org, Angela Czubak Subject: [PATCH v2 11/16] Input: MT - add INPUT_MT_TOTAL_FORCE flags Date: Fri, 14 Jan 2022 18:31:47 +0000 Message-Id: <20220114183152.1691659-12-acz@semihalf.com> X-Mailer: git-send-email 2.34.1.703.g22d0c6ccf7-goog In-Reply-To: <20220114183152.1691659-1-acz@semihalf.com> References: <20220114183152.1691659-1-acz@semihalf.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-input@vger.kernel.org Add a flag to generate ABS_PRESSURE as sum of ABS_MT_PRESSURE across all slots. This flag should be set if one knows a device reports true force and would like to report total force to the userspace. Signed-off-by: Angela Czubak --- drivers/input/input-mt.c | 14 ++++++++++---- include/linux/input/mt.h | 1 + 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/drivers/input/input-mt.c b/drivers/input/input-mt.c index 44fe6f2f063c..d84768329083 100644 --- a/drivers/input/input-mt.c +++ b/drivers/input/input-mt.c @@ -197,6 +197,7 @@ void input_mt_report_pointer_emulation(struct input_dev *dev, bool use_count) struct input_mt *mt = dev->mt; struct input_mt_slot *oldest; int oldid, count, i; + int p, reported_p = 0; if (!mt) return; @@ -215,6 +216,13 @@ void input_mt_report_pointer_emulation(struct input_dev *dev, bool use_count) oldest = ps; oldid = id; } + if (test_bit(ABS_MT_PRESSURE, dev->absbit)) { + p = input_mt_get_value(ps, ABS_MT_PRESSURE); + if (mt->flags & INPUT_MT_TOTAL_FORCE) + reported_p += p; + else if (oldid == id) + reported_p = p; + } count++; } @@ -244,10 +252,8 @@ 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)) { - int p = input_mt_get_value(oldest, ABS_MT_PRESSURE); - input_event(dev, EV_ABS, ABS_PRESSURE, p); - } + if (test_bit(ABS_MT_PRESSURE, dev->absbit)) + input_event(dev, EV_ABS, ABS_PRESSURE, reported_p); } else { if (test_bit(ABS_MT_PRESSURE, dev->absbit)) input_event(dev, EV_ABS, ABS_PRESSURE, 0); diff --git a/include/linux/input/mt.h b/include/linux/input/mt.h index 3b8580bd33c1..58d5402d382a 100644 --- a/include/linux/input/mt.h +++ b/include/linux/input/mt.h @@ -17,6 +17,7 @@ #define INPUT_MT_DROP_UNUSED 0x0004 /* drop contacts not seen in frame */ #define INPUT_MT_TRACK 0x0008 /* use in-kernel tracking */ #define INPUT_MT_SEMI_MT 0x0010 /* semi-mt device, finger count handled manually */ +#define INPUT_MT_TOTAL_FORCE 0x0020 /* calculate total force from slots pressure */ /** * struct input_mt_slot - represents the state of an input MT slot From patchwork Fri Jan 14 18:31:48 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Angela Czubak X-Patchwork-Id: 12713920 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 4EAC3C4332F for ; Fri, 14 Jan 2022 18:32:45 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S243134AbiANScn (ORCPT ); Fri, 14 Jan 2022 13:32:43 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:50710 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S243143AbiANScf (ORCPT ); Fri, 14 Jan 2022 13:32:35 -0500 Received: from mail-wm1-x335.google.com (mail-wm1-x335.google.com [IPv6:2a00:1450:4864:20::335]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 417F7C06161C for ; Fri, 14 Jan 2022 10:32:35 -0800 (PST) Received: by mail-wm1-x335.google.com with SMTP id l4so7657234wmq.3 for ; Fri, 14 Jan 2022 10:32:35 -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=g3sB5uCnTT9ZtnzwIjCaF04FDLQYv1DqM96R/bmNdOo=; b=mst0nTvIMYtNxl/2nems0zhFYKhZyM9+RBMtHEQDMdMs4gyOwP4CO1v7abin4ov98k xVXQSMw5TY6IAowM96ceMm9mKMPR3TON8/T49AWKB+7BT5vHjpGJCUGjxlmC0PeK67BA blN2BxhzONQoKfFGr7e+q+S0eqaPB2jqAGhGUfzNZ+HJLYpwIoMOiKOut7O39e1bSOWK jdvcyigvWWaWZlZS6bCsrj/pFFSGYg5zCRWkuv5SLGuMo0Cew0e6ni4U62Xhv6b7Y/an S9Ege/i+RiHUDe0VCeFM1J06O2Ly5uli/uQXTQGwiJA8C4NSlJ1XiY0Rm4+PoQQwrIJm ED0g== 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=g3sB5uCnTT9ZtnzwIjCaF04FDLQYv1DqM96R/bmNdOo=; b=V1V8M0EQL212ck6gz/kxM8bVIuqPb3PwH0F3ofqm+/M3A8Rgy3iJu2rKekw2fZ5Tan VOKWRYeX2r2zTh0s+kmeQYwPTiZ9RX/kUVqm+YZx6Zfx2Mxo54dAYgXg6ef4lda24Ke0 pRbcjcHMboVnI8Zm4ch90cx2JYKtI3/6giaF1DK1Pgvg25UxgW1eioUQ+RmqPBLe3OoO 0ZQGeCllXMp4qxlk245GUHtn/r0jZkuiAopmzP1vnDcRVYJlnCnjKj+I4uSCgONkb/pr 21j1C97hYz1D2Amy0HDb2J8DkGcGKk9TVSOaqpsa6ikHLqTl8UkJa9/gc58nnVhLXcfC J4Gw== X-Gm-Message-State: AOAM533POP/w6Kvy5n//Y5sb11czhwwNH4Aal6ecmHTMgBtIEM0jh6DW xYOeSSzqG/J+2Z3qHeiEIbRqdqjA2AH7LJamiXY= X-Google-Smtp-Source: ABdhPJx58RzTWrweVwG33CLHhBMxCS/6XcUMb1+Waevh/1u1ah0SIhjG1D4AHlx8gfe9VKxhluA8Mw== X-Received: by 2002:a5d:6612:: with SMTP id n18mr9218152wru.366.1642185153867; Fri, 14 Jan 2022 10:32:33 -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 az4sm6410984wrb.14.2022.01.14.10.32.33 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 14 Jan 2022 10:32:33 -0800 (PST) From: Angela Czubak To: linux-input@vger.kernel.org Cc: upstream@semihalf.com, dmitry.torokhov@gmail.com, benjamin.tissoires@redhat.com, jikos@kernel.org, Angela Czubak Subject: [PATCH v2 12/16] HID: haptic: add hid_haptic_switch_mode Date: Fri, 14 Jan 2022 18:31:48 +0000 Message-Id: <20220114183152.1691659-13-acz@semihalf.com> X-Mailer: git-send-email 2.34.1.703.g22d0c6ccf7-goog In-Reply-To: <20220114183152.1691659-1-acz@semihalf.com> References: <20220114183152.1691659-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 | 88 ++++++++++++++++++++++++++++++++++++---- drivers/hid/hid-haptic.h | 10 +++++ 2 files changed, 90 insertions(+), 8 deletions(-) diff --git a/drivers/hid/hid-haptic.c b/drivers/hid/hid-haptic.c index 4a5d5e7b92d1..2035b8a6037f 100644 --- a/drivers/hid/hid-haptic.c +++ b/drivers/hid/hid-haptic.c @@ -5,6 +5,7 @@ * Copyright (c) 2021 Angela Czubak */ +#include #include #include "hid-haptic.h" @@ -199,9 +200,58 @@ 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; + else + value = haptic->default_auto_trigger; + + 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; @@ -227,6 +277,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; } @@ -292,6 +356,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; @@ -299,21 +364,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; @@ -405,6 +478,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]); @@ -580,13 +654,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); } } @@ -597,8 +671,6 @@ 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; diff --git a/drivers/hid/hid-haptic.h b/drivers/hid/hid-haptic.h index 586f20be0061..280534be7e81 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 Fri Jan 14 18:31:49 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Angela Czubak X-Patchwork-Id: 12713921 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 AB35AC433FE for ; Fri, 14 Jan 2022 18:32:45 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S243143AbiANSco (ORCPT ); Fri, 14 Jan 2022 13:32:44 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:50676 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S243123AbiANScg (ORCPT ); Fri, 14 Jan 2022 13:32:36 -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 6C634C061574 for ; Fri, 14 Jan 2022 10:32:36 -0800 (PST) Received: by mail-wm1-x330.google.com with SMTP id ay4-20020a05600c1e0400b0034a81a94607so6318232wmb.1 for ; Fri, 14 Jan 2022 10:32:36 -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=PayoLFvRwC+37a4oakMmMBF6Q5SFDBpj4RWVePynPxo=; b=c4LkiYwffb39zsEmgIz+bGA02zqLWHItPK9DSorW9/8J6tosUJ2whjV8iTipO3HbJA nF7pjV4JXt78kGhVgKMDcsCHJbSYVXoqtPODxSDhHE60AuSUrfTyPZ6UncZsiGH710QP I9Z33+lk6B+Dv+6dQ0ucBRHF05Y3akW/Ar2xlXBVsFQzrwtNfrgNB443ONlJ5ze1uH7E /MCz5AXqSYl5l1kBTON02i+erj66kA9vPDSYi7ZQ+CLgZhxpi1N3PnDb9WF6GcN5kGRx j/yMmDUVuRV9gSOXZAZ2CEcgTihIKgIQBBR63eycD/fR107yQXUqycokvpAxqt6h4QPM UtJg== 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=PayoLFvRwC+37a4oakMmMBF6Q5SFDBpj4RWVePynPxo=; b=djq8/sXfzbS+Y4366VS1jPRTDWr28zNZDm78BEOBHIlDcpPMxYUWxTXlNpkOX6w9yw LURgp1PrinbdtKRW9v0CW2tL6m1BZLejGruoFWCQVPR5Px/XqMo8qro3n5tQu8Ns0YKc qIVz7+qQkFYnkWgCsaYYv5ZOE0dmDRkIzfIHumAdvsfC0zbREfPCdwKUO928ovlwKxlv Vk2zJ3JfXkHTN2b/WXdGFwtX+Td0sEBQ8u7/rq7xjSgLNsrlfsbakX4g8owxWZyTkYHH 3pzFd9Ov5oX2JxynQ6IJ/hIBtn8YhsIrBYDTLecHrc4gmtQOYBgYqb3mW5yLvye5eMyo doZA== X-Gm-Message-State: AOAM533LpooI/xepeU3eKi8pGKbsDuBq+qJTxcw5Hgrd0eEYUfmVXVAI gVR2XwtreTxYxBwwuWE8t3GmIC4fUp3ECFZSRiU= X-Google-Smtp-Source: ABdhPJxUumeoJo+uP6/WboGqTv5cQk3DqKo/V6LKfiBxxu2TlsQ8jae67wEBy+kL5Gs00wCwX/ME8w== X-Received: by 2002:adf:fa02:: with SMTP id m2mr8943201wrr.571.1642185154831; Fri, 14 Jan 2022 10:32:34 -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 az4sm6410984wrb.14.2022.01.14.10.32.34 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 14 Jan 2022 10:32:34 -0800 (PST) From: Angela Czubak To: linux-input@vger.kernel.org Cc: upstream@semihalf.com, dmitry.torokhov@gmail.com, benjamin.tissoires@redhat.com, jikos@kernel.org, Angela Czubak Subject: [PATCH v2 13/16] HID: multitouch: add haptic multitouch support Date: Fri, 14 Jan 2022 18:31:49 +0000 Message-Id: <20220114183152.1691659-14-acz@semihalf.com> X-Mailer: git-send-email 2.34.1.703.g22d0c6ccf7-goog In-Reply-To: <20220114183152.1691659-1-acz@semihalf.com> References: <20220114183152.1691659-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 | 74 +++++++++++++++++++++++++++++++++++- 2 files changed, 83 insertions(+), 2 deletions(-) diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig index 3e7555b868e7..a202f01de912 100644 --- a/drivers/hid/Kconfig +++ b/drivers/hid/Kconfig @@ -755,6 +755,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 99eabfb4145b..ec51e189bb1d 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; @@ -501,6 +505,8 @@ static void mt_feature_mapping(struct hid_device *hdev, mt_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, @@ -831,6 +837,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: @@ -944,8 +953,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); @@ -955,6 +972,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); @@ -1104,6 +1123,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); @@ -1278,6 +1300,9 @@ static int mt_touch_input_configured(struct hid_device *hdev, if (cls->is_indirect) app->mt_flags |= INPUT_MT_POINTER; + if (td->is_haptic_touchpad) + app->mt_flags |= INPUT_MT_TOTAL_FORCE; + if (app->quirks & MT_QUIRK_NOT_SEEN_MEANS_UP) app->mt_flags |= INPUT_MT_DROP_UNUSED; @@ -1313,6 +1338,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) { @@ -1375,6 +1401,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; } @@ -1568,6 +1599,14 @@ static int mt_input_configured(struct hid_device *hdev, struct hid_input *hi) struct hid_report *report; int ret; + 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; + } + list_for_each_entry(report, &hi->reports, hidinput_list) { rdata = mt_find_report_data(td, report); if (!rdata) { @@ -1713,6 +1752,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; @@ -1764,6 +1806,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; } @@ -1771,6 +1824,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) || @@ -1779,18 +1833,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. */ @@ -1799,6 +1866,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 Fri Jan 14 18:31:50 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Angela Czubak X-Patchwork-Id: 12713922 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 DD281C43217 for ; Fri, 14 Jan 2022 18:32:46 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S243123AbiANScp (ORCPT ); Fri, 14 Jan 2022 13:32:45 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:50678 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S243050AbiANSch (ORCPT ); Fri, 14 Jan 2022 13:32:37 -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 52619C06173F for ; Fri, 14 Jan 2022 10:32:37 -0800 (PST) Received: by mail-wm1-x32f.google.com with SMTP id l4so7657402wmq.3 for ; Fri, 14 Jan 2022 10:32:37 -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=76JfNjVFSUsVS8oWMOx2DCBRy/YQ+e0AT9T0ErYf4Kc=; b=dsccLJPiAHFgpSQ7rbkaDWEVbAhP0uBfDlvIKVPpAWVfPAHYRS6N43mCh8L0nj0MmE iBrw5MKTIdSyx6FCVd1gghLfeBnCK2Z4i0DmVLchRHEjLUgfshGOZOx4oqmKmNvE+CoE y6BLe29JRE5bKMcpANRXa3AXJR677KSCSb8QCjMSz7gt3ryVihVDuYP7Lu23hsUbHgMc BxJ/Z1KVEb8DIv0MBRD87HCIDxqm5Zol3uwPW5Tn15LVc4b/SF/XpNXwkiUpK+AciAES upZ3LHodC6paSCWrzZhcBXBJVU0mA9VbO68TwrQi4zU0/SQZ+CdTcJDPuLDZY4K0hjdI KyeQ== 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=76JfNjVFSUsVS8oWMOx2DCBRy/YQ+e0AT9T0ErYf4Kc=; b=XE869Boxc+tbHDr+OE9kAyuldsfJymgYwcZEN5/5sJaW/Il1ITBRuoMdt4b/vnfkRp 8ez9ZM4QCHS93z9UqerWIOiZt753siwl/d2g+kPQF3MW6ecOurRqutXwOdSUEXGTk9GO rIGictJn+AgLIgrEvPJJuLZHfHFG1MzZxd+fYwsLfL0atljeXROgjWEIgwvkMU9o4jhj M00KeBsdH/BuHq86zbnBZxpJ1tllXr4aiwLlCh3pJfJANe0O1NoNiWqOdEV7Vhd7H15g JE+1Unfj/fM65op/m5MOOPCCRxQ9T7kF2/3PicxuREIsL7Zcaf8HxFwfYS8OlKXdcfVC lPkQ== X-Gm-Message-State: AOAM531jFhh9PUXykIG+tVvhR1YZpnRbSpX2ynL+55C6aAc+A/HHtuYT D6TTnruvuFa0WuQpB+qwVX3X/xwA66CTvnW8CU8= X-Google-Smtp-Source: ABdhPJzMDovZr3wd1DuxsR6OlMLA/T6IiYrrcIJ4h9wjNNYMbDaGFyBKVHAaDyBFszSk3DAN2bozoA== X-Received: by 2002:a5d:584f:: with SMTP id i15mr9298235wrf.361.1642185155879; Fri, 14 Jan 2022 10:32:35 -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 az4sm6410984wrb.14.2022.01.14.10.32.35 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 14 Jan 2022 10:32:35 -0800 (PST) From: Angela Czubak To: linux-input@vger.kernel.org Cc: upstream@semihalf.com, dmitry.torokhov@gmail.com, benjamin.tissoires@redhat.com, jikos@kernel.org, Angela Czubak Subject: [PATCH v2 14/16] Input: introduce EVIOCFF(TAKE|RELEASE)CONTROL Date: Fri, 14 Jan 2022 18:31:50 +0000 Message-Id: <20220114183152.1691659-15-acz@semihalf.com> X-Mailer: git-send-email 2.34.1.703.g22d0c6ccf7-goog In-Reply-To: <20220114183152.1691659-1-acz@semihalf.com> References: <20220114183152.1691659-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 ccf43a21d43d..cce37336ab38 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 Fri Jan 14 18:31:51 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Angela Czubak X-Patchwork-Id: 12713923 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 8CCCCC433F5 for ; Fri, 14 Jan 2022 18:32:47 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S243050AbiANScq (ORCPT ); Fri, 14 Jan 2022 13:32:46 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:50696 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S243088AbiANSci (ORCPT ); Fri, 14 Jan 2022 13:32:38 -0500 Received: from mail-wm1-x32a.google.com (mail-wm1-x32a.google.com [IPv6:2a00:1450:4864:20::32a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 5279CC06173E for ; Fri, 14 Jan 2022 10:32:38 -0800 (PST) Received: by mail-wm1-x32a.google.com with SMTP id v123so7670121wme.2 for ; Fri, 14 Jan 2022 10:32:38 -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=9VwfXgg7eLphDCQdohq0yPt7WdrkP6UeE6DuepexdMI=; b=EpsmghBASmSA+4g472Dn0yVR4I4XgNi26rX/vNP8n2bY/Y9e0jSZnRtWnRu7u9l3Uk EeQQ+43ibRel2q10vbw8KdRkAPc4uxBM/APYNC/tOdTvG1gPvCqudjMAqtizLLVI8kCW M8uu6JAC//6jcemIDX7w9Pz50g9a0CR6/53f/97Me0QAOOGdD4OBjthZy78p6snZs1uq LCckxnDDIRgk5jbb4+Xt0fg9rkhbHRE+CP74irY0E2U15dmga70HJoL8FCLZI02L+Eq8 hsJ4vCOV76Xw6GD6a4yTmd6g/NQNG9GV61pVBgIPlTkRK8h3lpL1cr6QNB7Rhd33JLpQ g0SA== 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=9VwfXgg7eLphDCQdohq0yPt7WdrkP6UeE6DuepexdMI=; b=lFuaPHAULZubKYYV1+OaP8tBNwx1b8uzzbSW3XEEfeUuLEqsiEzYBB7a+d97NM0X1C VHdOWjIgl8M+/d7px2CzDUViZNjsdJPVf2rmUVZaULclUYNDoO66zDCY/M1zZwLeh/aC 38nwGzAllU0pNKutqa2pgiB5+e6uHEco0mgH7QP5xaXq7dtvvPGPbUC5QYqRTKj1cH8b EepzG6PhmomzAvFIUe6PDsQYdGl4WUZjUop43bpWgbkZfp062AOCIpgVLLPIFUeAFId+ WsPqdUO7f1c7ZtT5TdIobz8tNPN72MBDYen4AiJKsB6SJ/4RvyHvX3P4J0zsVTBxCxS3 LFpQ== X-Gm-Message-State: AOAM532J4XTyUZT8SAic8zyB6MY/Q0ARCXOvYVrMfLYJO5EHAmOEatX+ 18LaOg2EzdSm6pXNb0V4UEoVZUSJZoFDtqP1yFQ= X-Google-Smtp-Source: ABdhPJyoYuElB9cp9svuaSkC6agItX7Vh885eixvtHTL6hr2+hvG44A0Ayt7bpptO6mV2p5k+X5pZw== X-Received: by 2002:a5d:4c81:: with SMTP id z1mr9595982wrs.204.1642185156929; Fri, 14 Jan 2022 10:32:36 -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 az4sm6410984wrb.14.2022.01.14.10.32.36 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 14 Jan 2022 10:32:36 -0800 (PST) From: Angela Czubak To: linux-input@vger.kernel.org Cc: upstream@semihalf.com, dmitry.torokhov@gmail.com, benjamin.tissoires@redhat.com, jikos@kernel.org, Angela Czubak Subject: [PATCH v2 15/16] HID: haptic: add hid_haptic_change_control Date: Fri, 14 Jan 2022 18:31:51 +0000 Message-Id: <20220114183152.1691659-16-acz@semihalf.com> X-Mailer: git-send-email 2.34.1.703.g22d0c6ccf7-goog In-Reply-To: <20220114183152.1691659-1-acz@semihalf.com> References: <20220114183152.1691659-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 2035b8a6037f..adc11bd1d84b 100644 --- a/drivers/hid/hid-haptic.c +++ b/drivers/hid/hid-haptic.c @@ -6,6 +6,7 @@ */ #include +#include #include #include "hid-haptic.h" @@ -343,6 +344,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; @@ -527,6 +568,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, @@ -563,6 +606,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)) { @@ -652,13 +696,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 Fri Jan 14 18:31:52 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Angela Czubak X-Patchwork-Id: 12713924 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 4823BC4321E for ; Fri, 14 Jan 2022 18:32:48 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S243088AbiANScr (ORCPT ); Fri, 14 Jan 2022 13:32:47 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:50700 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S243089AbiANScj (ORCPT ); Fri, 14 Jan 2022 13:32:39 -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 39099C061746 for ; Fri, 14 Jan 2022 10:32:39 -0800 (PST) Received: by mail-wm1-x334.google.com with SMTP id s6-20020a7bc386000000b0034a89445406so5076683wmj.2 for ; Fri, 14 Jan 2022 10:32:39 -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=PPhgwQ8WkgPyMrOjDMnndrFsC54fCBYnmYW2kzBu0ks=; b=6jt6q+eiZcRb6bVZKY3YXveqMzOJsrBjufmuIYrDC3kAfSw0ZxD9DXEqrI6MeqYjF4 Q7ujBuJW2uV/Wy7Wm6HQLqV1L/N38VZUiDLiYeNU0snkSpcLg8u3XG6Rb0WSpjnBl5Hl JmNcT1l1sxtIQRZv65/NAkfMY10FSIgjY9l7kogUqcRpHGjut6rniPtNuoC3qvUN2sE+ HURkYixhtttwEq/d/730S+YjBz78dfAjsd+n68NORAZsVGXbk+kG3XvkrGAhlvKN8vYf ZCi8U14q4uZa5Ypt01OWZ0Kox8UO3vIqzUT5L7bWRkWJD5lIFRVr2ccHKPuqfJp1AjWM amAA== 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=PPhgwQ8WkgPyMrOjDMnndrFsC54fCBYnmYW2kzBu0ks=; b=KtIuCeAgpHSabcYFBAsGQx+xrfdHT7e9ptMxl2sh71s18AgUIzZ7HYkQiXwT8cZ6FQ L3hZOMBqCbR6op8I5I9x+wxZr9z7LuuVnrd5nTRagERHiWzK0SHYDWLUu640UKCao0Gh /clXYXj5BK7bWnVEqw5TKfH7SY+S+GVH1kIcWzRihOaD0BM+QQmluDsbubHCj0KthOgg sL+7tfRz0VBsr1RpYs3Y2q4q6dhn1jAxIYkyLLNTlpcEnHqlwycTGT/maskANqRiWBAY 5Ghnft8BLzc0hYsdhZ7mAETitjQXCVQf+zNqTLVlZI7p9VnNSxRXjSL+i7MAtozBE8+l k9KQ== X-Gm-Message-State: AOAM532Ol0hs+tog3rWf410ZRLYar6ErPMbxBX2Lvdy9hMBw5nQ0Hymq g8JIXMrTrvX8yzBGUDwW7mJr0UBYwWE6Y5VI0WQ= X-Google-Smtp-Source: ABdhPJy6zTyMjXBX9Im3H2yOaVVK5nUvF17gSJSLXvlvlIqiTCo3uGMpztee8ccrSP2VVTfzBZDofw== X-Received: by 2002:a05:600c:21cf:: with SMTP id x15mr9280402wmj.8.1642185157885; Fri, 14 Jan 2022 10:32:37 -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 az4sm6410984wrb.14.2022.01.14.10.32.37 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 14 Jan 2022 10:32:37 -0800 (PST) From: Angela Czubak To: linux-input@vger.kernel.org Cc: upstream@semihalf.com, dmitry.torokhov@gmail.com, benjamin.tissoires@redhat.com, jikos@kernel.org, Angela Czubak Subject: [PATCH v2 16/16] HID: i2c-hid: fix handling numbered reports with IDs of 15 and above Date: Fri, 14 Jan 2022 18:31:52 +0000 Message-Id: <20220114183152.1691659-17-acz@semihalf.com> X-Mailer: git-send-email 2.34.1.703.g22d0c6ccf7-goog In-Reply-To: <20220114183152.1691659-1-acz@semihalf.com> References: <20220114183152.1691659-1-acz@semihalf.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-input@vger.kernel.org Special handling of numbered reports with IDs of 15 and above is only needed when executing what HID-I2C spec is calling "Class Specific Requests", and not when simply sending output reports. Additionally, our mangling of report ID in i2c_hid_set_or_send_report() resulted in incorrect report ID being written into SET_REPORT command payload. To solve it let's move all the report ID manipulation into __i2c_hid_command() where we form the command data structure. Signed-off-by: Angela Czubak Signed-off-by: Dmitry Torokhov --- drivers/hid/i2c-hid/i2c-hid-core.c | 22 +++++++++------------- 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/drivers/hid/i2c-hid/i2c-hid-core.c b/drivers/hid/i2c-hid/i2c-hid-core.c index 6726567d7297..3195a1ffae23 100644 --- a/drivers/hid/i2c-hid/i2c-hid-core.c +++ b/drivers/hid/i2c-hid/i2c-hid-core.c @@ -97,6 +97,7 @@ union command { __le16 reg; __u8 reportTypeID; __u8 opcode; + __u8 reportID; } __packed c; }; @@ -232,7 +233,13 @@ static int __i2c_hid_command(struct i2c_client *client, if (length > 2) { cmd->c.opcode = command->opcode; - cmd->c.reportTypeID = reportID | reportType << 4; + if (reportID < 0x0F) { + cmd->c.reportTypeID = reportType << 4 | reportID; + } else { + cmd->c.reportTypeID = reportType << 4 | 0x0F; + cmd->c.reportID = reportID; + length++; + } } memcpy(cmd->data + length, args, args_len); @@ -300,11 +307,6 @@ static int i2c_hid_get_report(struct i2c_client *client, u8 reportType, i2c_hid_dbg(ihid, "%s\n", __func__); - if (reportID >= 0x0F) { - args[args_len++] = reportID; - reportID = 0x0F; - } - args[args_len++] = readRegister & 0xFF; args[args_len++] = readRegister >> 8; @@ -350,18 +352,12 @@ static int i2c_hid_set_or_send_report(struct i2c_client *client, u8 reportType, size = 2 /* size */ + (reportID ? 1 : 0) /* reportID */ + data_len /* buf */; - args_len = (reportID >= 0x0F ? 1 : 0) /* optional third byte */ + - 2 /* dataRegister */ + + args_len = 2 /* dataRegister */ + size /* args */; 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