Skip to content

Commit dad74e1

Browse files
DanielOgorchockJiri Kosina
authored andcommitted
HID: nintendo: prevent needless queueing of the rumble worker
This patch adds a check for if the rumble queue ringbuffer is empty prior to queuing the rumble workqueue. If the current rumble setting is using a non-zero amplitude though, it will queue the worker anyway. This is because the controller will automatically disable the rumble effect if it isn't "refreshed". This change improves bluetooth communication reliability with the controller, since it reduces the amount of traffic. Note that we still send a few periodic zero packets to avoid scenarios where the controller fails to process the zero amplitude packet. Without sending a few to be sure, the rumble could get stuck on until the controller times out. Signed-off-by: Daniel J. Ogorchock <[email protected]> Signed-off-by: Jiri Kosina <[email protected]>
1 parent e93363f commit dad74e1

File tree

1 file changed

+17
-1
lines changed

1 file changed

+17
-1
lines changed

drivers/hid/hid-nintendo.c

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -400,6 +400,7 @@ struct joycon_input_report {
400400
static const u16 JC_RUMBLE_DFLT_LOW_FREQ = 160;
401401
static const u16 JC_RUMBLE_DFLT_HIGH_FREQ = 320;
402402
static const u16 JC_RUMBLE_PERIOD_MS = 50;
403+
static const unsigned short JC_RUMBLE_ZERO_AMP_PKT_CNT = 5;
403404

404405
static const char * const joycon_player_led_names[] = {
405406
LED_FUNCTION_PLAYER1,
@@ -464,6 +465,7 @@ struct joycon_ctlr {
464465
u16 rumble_lh_freq;
465466
u16 rumble_rl_freq;
466467
u16 rumble_rh_freq;
468+
unsigned short rumble_zero_countdown;
467469

468470
/* imu */
469471
struct input_dev *imu_input;
@@ -1218,8 +1220,19 @@ static void joycon_parse_report(struct joycon_ctlr *ctlr,
12181220

12191221
spin_lock_irqsave(&ctlr->lock, flags);
12201222
if (IS_ENABLED(CONFIG_NINTENDO_FF) && rep->vibrator_report &&
1221-
(msecs - ctlr->rumble_msecs) >= JC_RUMBLE_PERIOD_MS)
1223+
(msecs - ctlr->rumble_msecs) >= JC_RUMBLE_PERIOD_MS &&
1224+
(ctlr->rumble_queue_head != ctlr->rumble_queue_tail ||
1225+
ctlr->rumble_zero_countdown > 0)) {
1226+
/*
1227+
* When this value reaches 0, we know we've sent multiple
1228+
* packets to the controller instructing it to disable rumble.
1229+
* We can safely stop sending periodic rumble packets until the
1230+
* next ff effect.
1231+
*/
1232+
if (ctlr->rumble_zero_countdown > 0)
1233+
ctlr->rumble_zero_countdown--;
12221234
queue_work(ctlr->rumble_queue, &ctlr->rumble_worker);
1235+
}
12231236

12241237
/* Parse the battery status */
12251238
tmp = rep->bat_con;
@@ -1513,6 +1526,9 @@ static int joycon_set_rumble(struct joycon_ctlr *ctlr, u16 amp_r, u16 amp_l,
15131526
freq_r_high = ctlr->rumble_rh_freq;
15141527
freq_l_low = ctlr->rumble_ll_freq;
15151528
freq_l_high = ctlr->rumble_lh_freq;
1529+
/* limit number of silent rumble packets to reduce traffic */
1530+
if (amp_l != 0 || amp_r != 0)
1531+
ctlr->rumble_zero_countdown = JC_RUMBLE_ZERO_AMP_PKT_CNT;
15161532
spin_unlock_irqrestore(&ctlr->lock, flags);
15171533

15181534
/* right joy-con */

0 commit comments

Comments
 (0)