@@ -433,7 +433,9 @@ struct joycon_ctlr {
433
433
u8 usb_ack_match ;
434
434
u8 subcmd_ack_match ;
435
435
bool received_input_report ;
436
+ unsigned int last_input_report_msecs ;
436
437
unsigned int last_subcmd_sent_msecs ;
438
+ unsigned int consecutive_valid_report_deltas ;
437
439
438
440
/* factory calibration data */
439
441
struct joycon_stick_cal left_stick_cal_x ;
@@ -543,19 +545,54 @@ static void joycon_wait_for_input_report(struct joycon_ctlr *ctlr)
543
545
* Sending subcommands and/or rumble data at too high a rate can cause bluetooth
544
546
* controller disconnections.
545
547
*/
548
+ #define JC_INPUT_REPORT_MIN_DELTA 8
549
+ #define JC_INPUT_REPORT_MAX_DELTA 17
550
+ #define JC_SUBCMD_TX_OFFSET_MS 4
551
+ #define JC_SUBCMD_VALID_DELTA_REQ 3
552
+ #define JC_SUBCMD_RATE_MAX_ATTEMPTS 500
553
+ #define JC_SUBCMD_RATE_LIMITER_USB_MS 20
554
+ #define JC_SUBCMD_RATE_LIMITER_BT_MS 60
555
+ #define JC_SUBCMD_RATE_LIMITER_MS (ctlr ) ((ctlr)->hdev->bus == BUS_USB ? JC_SUBCMD_RATE_LIMITER_USB_MS : JC_SUBCMD_RATE_LIMITER_BT_MS)
546
556
static void joycon_enforce_subcmd_rate (struct joycon_ctlr * ctlr )
547
557
{
548
- static const unsigned int max_subcmd_rate_ms = 25 ;
549
- unsigned int current_ms = jiffies_to_msecs (jiffies );
550
- unsigned int delta_ms = current_ms - ctlr -> last_subcmd_sent_msecs ;
558
+ unsigned int current_ms ;
559
+ unsigned long subcmd_delta ;
560
+ int consecutive_valid_deltas = 0 ;
561
+ int attempts = 0 ;
562
+ unsigned long flags ;
563
+
564
+ if (unlikely (ctlr -> ctlr_state != JOYCON_CTLR_STATE_READ ))
565
+ return ;
551
566
552
- while (delta_ms < max_subcmd_rate_ms &&
553
- ctlr -> ctlr_state == JOYCON_CTLR_STATE_READ ) {
567
+ do {
554
568
joycon_wait_for_input_report (ctlr );
555
569
current_ms = jiffies_to_msecs (jiffies );
556
- delta_ms = current_ms - ctlr -> last_subcmd_sent_msecs ;
570
+ subcmd_delta = current_ms - ctlr -> last_subcmd_sent_msecs ;
571
+
572
+ spin_lock_irqsave (& ctlr -> lock , flags );
573
+ consecutive_valid_deltas = ctlr -> consecutive_valid_report_deltas ;
574
+ spin_unlock_irqrestore (& ctlr -> lock , flags );
575
+
576
+ attempts ++ ;
577
+ } while ((consecutive_valid_deltas < JC_SUBCMD_VALID_DELTA_REQ ||
578
+ subcmd_delta < JC_SUBCMD_RATE_LIMITER_MS (ctlr )) &&
579
+ ctlr -> ctlr_state == JOYCON_CTLR_STATE_READ &&
580
+ attempts < JC_SUBCMD_RATE_MAX_ATTEMPTS );
581
+
582
+ if (attempts >= JC_SUBCMD_RATE_MAX_ATTEMPTS ) {
583
+ hid_warn (ctlr -> hdev , "%s: exceeded max attempts" , __func__ );
584
+ return ;
557
585
}
586
+
558
587
ctlr -> last_subcmd_sent_msecs = current_ms ;
588
+
589
+ /*
590
+ * Wait a short time after receiving an input report before
591
+ * transmitting. This should reduce odds of a TX coinciding with an RX.
592
+ * Minimizing concurrent BT traffic with the controller seems to lower
593
+ * the rate of disconnections.
594
+ */
595
+ msleep (JC_SUBCMD_TX_OFFSET_MS );
559
596
}
560
597
561
598
static int joycon_hid_send_sync (struct joycon_ctlr * ctlr , u8 * data , size_t len ,
@@ -1223,6 +1260,7 @@ static void joycon_parse_report(struct joycon_ctlr *ctlr,
1223
1260
u8 tmp ;
1224
1261
u32 btns ;
1225
1262
unsigned long msecs = jiffies_to_msecs (jiffies );
1263
+ unsigned long report_delta_ms = msecs - ctlr -> last_input_report_msecs ;
1226
1264
1227
1265
spin_lock_irqsave (& ctlr -> lock , flags );
1228
1266
if (IS_ENABLED (CONFIG_NINTENDO_FF ) && rep -> vibrator_report &&
@@ -1364,6 +1402,31 @@ static void joycon_parse_report(struct joycon_ctlr *ctlr,
1364
1402
1365
1403
input_sync (dev );
1366
1404
1405
+ spin_lock_irqsave (& ctlr -> lock , flags );
1406
+ ctlr -> last_input_report_msecs = msecs ;
1407
+ /*
1408
+ * Was this input report a reasonable time delta compared to the prior
1409
+ * report? We use this information to decide when a safe time is to send
1410
+ * rumble packets or subcommand packets.
1411
+ */
1412
+ if (report_delta_ms >= JC_INPUT_REPORT_MIN_DELTA &&
1413
+ report_delta_ms <= JC_INPUT_REPORT_MAX_DELTA ) {
1414
+ if (ctlr -> consecutive_valid_report_deltas < JC_SUBCMD_VALID_DELTA_REQ )
1415
+ ctlr -> consecutive_valid_report_deltas ++ ;
1416
+ } else {
1417
+ ctlr -> consecutive_valid_report_deltas = 0 ;
1418
+ }
1419
+ /*
1420
+ * Our consecutive valid report tracking is only relevant for
1421
+ * bluetooth-connected controllers. For USB devices, we're beholden to
1422
+ * USB's underlying polling rate anyway. Always set to the consecutive
1423
+ * delta requirement.
1424
+ */
1425
+ if (ctlr -> hdev -> bus == BUS_USB )
1426
+ ctlr -> consecutive_valid_report_deltas = JC_SUBCMD_VALID_DELTA_REQ ;
1427
+
1428
+ spin_unlock_irqrestore (& ctlr -> lock , flags );
1429
+
1367
1430
/*
1368
1431
* Immediately after receiving a report is the most reliable time to
1369
1432
* send a subcommand to the controller. Wake any subcommand senders
@@ -1527,6 +1590,7 @@ static int joycon_set_rumble(struct joycon_ctlr *ctlr, u16 amp_r, u16 amp_l,
1527
1590
u16 freq_l_low ;
1528
1591
u16 freq_l_high ;
1529
1592
unsigned long flags ;
1593
+ int next_rq_head ;
1530
1594
1531
1595
spin_lock_irqsave (& ctlr -> lock , flags );
1532
1596
freq_r_low = ctlr -> rumble_rl_freq ;
@@ -1547,8 +1611,21 @@ static int joycon_set_rumble(struct joycon_ctlr *ctlr, u16 amp_r, u16 amp_l,
1547
1611
joycon_encode_rumble (data , freq_l_low , freq_l_high , amp );
1548
1612
1549
1613
spin_lock_irqsave (& ctlr -> lock , flags );
1550
- if (++ ctlr -> rumble_queue_head >= JC_RUMBLE_QUEUE_SIZE )
1551
- ctlr -> rumble_queue_head = 0 ;
1614
+
1615
+ next_rq_head = ctlr -> rumble_queue_head + 1 ;
1616
+ if (next_rq_head >= JC_RUMBLE_QUEUE_SIZE )
1617
+ next_rq_head = 0 ;
1618
+
1619
+ /* Did we overrun the circular buffer?
1620
+ * If so, be sure we keep the latest intended rumble state.
1621
+ */
1622
+ if (next_rq_head == ctlr -> rumble_queue_tail ) {
1623
+ hid_dbg (ctlr -> hdev , "rumble queue is full" );
1624
+ /* overwrite the prior value at the end of the circular buf */
1625
+ next_rq_head = ctlr -> rumble_queue_head ;
1626
+ }
1627
+
1628
+ ctlr -> rumble_queue_head = next_rq_head ;
1552
1629
memcpy (ctlr -> rumble_data [ctlr -> rumble_queue_head ], data ,
1553
1630
JC_RUMBLE_DATA_SIZE );
1554
1631
@@ -2128,7 +2205,7 @@ static int nintendo_hid_probe(struct hid_device *hdev,
2128
2205
2129
2206
ctlr -> hdev = hdev ;
2130
2207
ctlr -> ctlr_state = JOYCON_CTLR_STATE_INIT ;
2131
- ctlr -> rumble_queue_head = JC_RUMBLE_QUEUE_SIZE - 1 ;
2208
+ ctlr -> rumble_queue_head = 0 ;
2132
2209
ctlr -> rumble_queue_tail = 0 ;
2133
2210
hid_set_drvdata (hdev , ctlr );
2134
2211
mutex_init (& ctlr -> output_mutex );
0 commit comments