mirror of
https://github.com/libretro/Lakka-LibreELEC.git
synced 2025-03-01 06:51:22 +00:00
74 lines
2.5 KiB
Diff
74 lines
2.5 KiB
Diff
From 6496b24a48a06224741ac7746065c1eff40169af Mon Sep 17 00:00:00 2001
|
|
From: "Daniel J. Ogorchock" <djogorchock@gmail.com>
|
|
Date: Tue, 8 Oct 2019 21:29:09 -0500
|
|
Subject: [PATCH] HID: nintendo: send subcommands after receiving input report
|
|
|
|
Waiting to send subcommands until right after receiving an input report
|
|
drastically improves subcommand reliability. If the driver has finished
|
|
initial controller configuration, it now waits until receiving an input
|
|
report for all subcommands.
|
|
|
|
Signed-off-by: Daniel J. Ogorchock <djogorchock@gmail.com>
|
|
---
|
|
drivers/hid/hid-nintendo.c | 33 +++++++++++++++++++++++++++++++++
|
|
1 file changed, 33 insertions(+)
|
|
|
|
diff --git a/drivers/hid/hid-nintendo.c b/drivers/hid/hid-nintendo.c
|
|
index 2638c6aff9d2..2ec099dc3869 100644
|
|
--- a/drivers/hid/hid-nintendo.c
|
|
+++ b/drivers/hid/hid-nintendo.c
|
|
@@ -328,6 +328,7 @@ struct joycon_ctlr {
|
|
bool received_resp;
|
|
u8 usb_ack_match;
|
|
u8 subcmd_ack_match;
|
|
+ bool received_input_report;
|
|
|
|
/* factory calibration data */
|
|
struct joycon_stick_cal left_stick_cal_x;
|
|
@@ -381,6 +382,26 @@ static int joycon_hid_send_sync(struct joycon_ctlr *ctlr, u8 *data, size_t len,
|
|
* doing one retry after a timeout appears to always work.
|
|
*/
|
|
while (tries--) {
|
|
+ /*
|
|
+ * If we are in the proper reporting mode, wait for an input
|
|
+ * report prior to sending the subcommand. This improves
|
|
+ * reliability considerably.
|
|
+ */
|
|
+ if (ctlr->ctlr_state == JOYCON_CTLR_STATE_READ) {
|
|
+ unsigned long flags;
|
|
+
|
|
+ spin_lock_irqsave(&ctlr->lock, flags);
|
|
+ ctlr->received_input_report = false;
|
|
+ spin_unlock_irqrestore(&ctlr->lock, flags);
|
|
+ ret = wait_event_timeout(ctlr->wait,
|
|
+ ctlr->received_input_report,
|
|
+ HZ / 4);
|
|
+ /* We will still proceed, even with a timeout here */
|
|
+ if (!ret)
|
|
+ hid_warn(ctlr->hdev,
|
|
+ "timeout waiting for input report\n");
|
|
+ }
|
|
+
|
|
ret = __joycon_hid_send(ctlr->hdev, data, len);
|
|
if (ret < 0) {
|
|
memset(ctlr->input_buf, 0, JC_MAX_RESP_SIZE);
|
|
@@ -753,6 +774,18 @@ static void joycon_parse_report(struct joycon_ctlr *ctlr,
|
|
}
|
|
|
|
input_sync(dev);
|
|
+
|
|
+ /*
|
|
+ * Immediately after receiving a report is the most reliable time to
|
|
+ * send a subcommand to the controller. Wake any subcommand senders
|
|
+ * waiting for a report.
|
|
+ */
|
|
+ if (unlikely(mutex_is_locked(&ctlr->output_mutex))) {
|
|
+ spin_lock_irqsave(&ctlr->lock, flags);
|
|
+ ctlr->received_input_report = true;
|
|
+ spin_unlock_irqrestore(&ctlr->lock, flags);
|
|
+ wake_up(&ctlr->wait);
|
|
+ }
|
|
}
|
|
|
|
static void joycon_rumble_worker(struct work_struct *work)
|