From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 5F39E222574; Mon, 31 Mar 2025 14:52:55 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1743432776; cv=none; b=GgUX1mWOsFtfsr6tOIv7EHvb708z36MUUt7mMndoA4DJc+KkiSbV6Zz/0ezo0VxhkkwzQdaYmGPkwPxMjDijFmnyh0M9nThNyHtpEyQzEXRAZ8yGQAaD/nNFE8vL8KnSq90wbOx5gDmg1WNjZLjF57AsXyXuHgeoWrnymAVkiGQ= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1743432776; c=relaxed/simple; bh=8Tct2/58lapSimulN1jrVvHZeZxDXiAt41ip2hMtjPk=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version:Content-Type; b=VgSLG6q50a7wntbKZVjQj9PvV5fMkytnFlFpRflQ2uK02dYMpUaS9NPOnvzyhBpKpS17ZxJ+Cm8YgKsjdnrLgycRnG3KGDArswiR3gqehhfM0CcjNHTbvMBF1N8nG3rq4gQ0pva5DSdO2jCdGHUmpjydvZynoEg8Y/+vZ6R+dZE= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=BkXoXRJk; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="BkXoXRJk" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 4EBE7C4CEE4; Mon, 31 Mar 2025 14:52:54 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1743432775; bh=8Tct2/58lapSimulN1jrVvHZeZxDXiAt41ip2hMtjPk=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=BkXoXRJk08ohX7DOYQP62swXxcQcL7VeZHJP/64ieF4q3pw2gKshs6xQVkyLcLz4s A4jTSyFB7heU7FCgk0kDLTry0T2UqCb68pwyNxUxZngUqyHsJ5vEWp99/hMMD3xvPU v5gmQlMeaG+gzqEcESJGgQR7jP4hZXGCwdLt6XBTM0RLnpb/aCj2LwMOvgaLmRFmLQ kXrJobMqTXRLLg924do9xm+F/Qm6qjgwVf4cuEROXlyjwfMRRuanJiFwhe1CARow4f dcK8SHACrFUqPZ3ottl5JQEYctEuix57Tzi/t/bK12Md3bRSWDO89zrH2VPh2jkbG6 iP3qePraAkgMA== From: Sasha Levin To: linux-kernel@vger.kernel.org, stable@vger.kernel.org Cc: =?UTF-8?q?Tomasz=20Paku=C5=82a?= , Makarenko Oleg , =?UTF-8?q?Micha=C5=82=20Kope=C4=87?= , Paul Dino Jones , =?UTF-8?q?Crist=C3=B3ferson=20Bueno?= , Pablo Cisneros , Jiri Kosina , Sasha Levin , jikos@kernel.org, bentiss@kernel.org, linux-usb@vger.kernel.org, linux-input@vger.kernel.org Subject: [PATCH AUTOSEL 6.14 05/27] HID: pidff: Add MISSING_DELAY quirk and its detection Date: Mon, 31 Mar 2025 10:52:23 -0400 Message-Id: <20250331145245.1704714-5-sashal@kernel.org> X-Mailer: git-send-email 2.39.5 In-Reply-To: <20250331145245.1704714-1-sashal@kernel.org> References: <20250331145245.1704714-1-sashal@kernel.org> Precedence: bulk X-Mailing-List: linux-input@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 X-stable: review X-Patchwork-Hint: Ignore X-stable-base: Linux 6.14 Content-Transfer-Encoding: 8bit From: Tomasz Pakuła [ Upstream commit 2d5c7ce5bf4cc27db41632f357f682d0ee4518e7 ] A lot of devices do not include this field, and it's seldom used in force feedback implementations. I tested about three dozen applications and none of them make use of the delay. This fixes initialization of a lot of PID wheels like Cammus, VRS, FFBeast This change has no effect on fully compliant devices Co-developed-by: Makarenko Oleg Signed-off-by: Makarenko Oleg Signed-off-by: Tomasz Pakuła Reviewed-by: Michał Kopeć Reviewed-by: Paul Dino Jones Tested-by: Paul Dino Jones Tested-by: Cristóferson Bueno Tested-by: Pablo Cisneros Signed-off-by: Jiri Kosina Signed-off-by: Sasha Levin --- drivers/hid/usbhid/hid-pidff.c | 33 ++++++++++++++++++++++++++++----- include/linux/hid.h | 3 +++ 2 files changed, 31 insertions(+), 5 deletions(-) diff --git a/drivers/hid/usbhid/hid-pidff.c b/drivers/hid/usbhid/hid-pidff.c index a01c1b2ab2f4c..929f5967e7cb1 100644 --- a/drivers/hid/usbhid/hid-pidff.c +++ b/drivers/hid/usbhid/hid-pidff.c @@ -185,6 +185,8 @@ struct pidff_device { int operation_id[sizeof(pidff_effect_operation_status)]; int pid_id[PID_EFFECTS_MAX]; + + u32 quirks; }; /* @@ -329,7 +331,10 @@ static void pidff_set_effect_report(struct pidff_device *pidff, pidff->effect_direction->value[0] = pidff_rescale(effect->direction, 0xffff, pidff->effect_direction); - pidff->set_effect[PID_START_DELAY].value[0] = effect->replay.delay; + + /* Omit setting delay field if it's missing */ + if (!(pidff->quirks & HID_PIDFF_QUIRK_MISSING_DELAY)) + pidff->set_effect[PID_START_DELAY].value[0] = effect->replay.delay; hid_hw_request(pidff->hid, pidff->reports[PID_SET_EFFECT], HID_REQ_SET_REPORT); @@ -748,7 +753,10 @@ static void pidff_autocenter(struct pidff_device *pidff, u16 magnitude) pidff->set_effect[PID_TRIGGER_REPEAT_INT].value[0] = 0; pidff_set(&pidff->set_effect[PID_GAIN], magnitude); pidff->set_effect[PID_DIRECTION_ENABLE].value[0] = 1; - pidff->set_effect[PID_START_DELAY].value[0] = 0; + + /* Omit setting delay field if it's missing */ + if (!(pidff->quirks & HID_PIDFF_QUIRK_MISSING_DELAY)) + pidff->set_effect[PID_START_DELAY].value[0] = 0; hid_hw_request(pidff->hid, pidff->reports[PID_SET_EFFECT], HID_REQ_SET_REPORT); @@ -771,6 +779,7 @@ static int pidff_find_fields(struct pidff_usage *usage, const u8 *table, struct hid_report *report, int count, int strict) { int i, j, k, found; + int return_value = 0; for (k = 0; k < count; k++) { found = 0; @@ -795,12 +804,17 @@ static int pidff_find_fields(struct pidff_usage *usage, const u8 *table, if (found) break; } - if (!found && strict) { + if (!found && table[k] == pidff_set_effect[PID_START_DELAY]) { + pr_debug("Delay field not found, but that's OK\n"); + pr_debug("Setting MISSING_DELAY quirk\n"); + return_value |= HID_PIDFF_QUIRK_MISSING_DELAY; + } + else if (!found && strict) { pr_debug("failed to locate %d\n", k); return -1; } } - return 0; + return return_value; } /* @@ -1075,11 +1089,19 @@ static int pidff_find_effects(struct pidff_device *pidff, static int pidff_init_fields(struct pidff_device *pidff, struct input_dev *dev) { int envelope_ok = 0; + int status = 0; - if (PIDFF_FIND_FIELDS(set_effect, PID_SET_EFFECT, 1)) { + /* Save info about the device not having the DELAY ffb field. */ + status = PIDFF_FIND_FIELDS(set_effect, PID_SET_EFFECT, 1); + if (status == -1) { hid_err(pidff->hid, "unknown set_effect report layout\n"); return -ENODEV; } + pidff->quirks |= status; + + if (status & HID_PIDFF_QUIRK_MISSING_DELAY) + hid_dbg(pidff->hid, "Adding MISSING_DELAY quirk\n"); + PIDFF_FIND_FIELDS(block_load, PID_BLOCK_LOAD, 0); if (!pidff->block_load[PID_EFFECT_BLOCK_INDEX].value) { @@ -1323,6 +1345,7 @@ int hid_pidff_init(struct hid_device *hid) ff->playback = pidff_playback; hid_info(dev, "Force feedback for USB HID PID devices by Anssi Hannula \n"); + hid_dbg(dev, "Active quirks mask: 0x%x\n", pidff->quirks); hid_device_io_stop(hid); diff --git a/include/linux/hid.h b/include/linux/hid.h index cdc0dc13c87fe..9c3a728786c3e 100644 --- a/include/linux/hid.h +++ b/include/linux/hid.h @@ -1228,6 +1228,9 @@ int hid_pidff_init(struct hid_device *hid); #define hid_pidff_init NULL #endif +/* HID PIDFF quirks */ +#define HID_PIDFF_QUIRK_MISSING_DELAY BIT(0) + #define dbg_hid(fmt, ...) pr_debug("%s: " fmt, __FILE__, ##__VA_ARGS__) #define hid_err(hid, fmt, ...) \ -- 2.39.5