Skip to content

Commit 58feecb

Browse files
Roderick ColenbranderJiri Kosina
authored andcommitted
HID: playstation: set default DualShock4 BT poll interval to 4ms.
The poll interval for DualShock4 in Bluetooth mode is adjustable through the main output report. Configure it to 4ms, which is similar to USB. Signed-off-by: Roderick Colenbrander <[email protected]> Signed-off-by: Jiri Kosina <[email protected]>
1 parent 2d77474 commit 58feecb

File tree

1 file changed

+29
-0
lines changed

1 file changed

+29
-0
lines changed

drivers/hid/hid-playstation.c

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -316,6 +316,17 @@ struct dualsense_output_report {
316316
/* Battery status within batery_status field. */
317317
#define DS4_BATTERY_STATUS_FULL 11
318318

319+
/* The lower 6 bits of hw_control of the Bluetooth main output report
320+
* control the interval at which Dualshock 4 reports data:
321+
* 0x00 - 1ms
322+
* 0x01 - 1ms
323+
* 0x02 - 2ms
324+
* 0x3E - 62ms
325+
* 0x3F - disabled
326+
*/
327+
#define DS4_OUTPUT_HWCTL_BT_POLL_MASK 0x3F
328+
/* Default to 4ms poll interval, which is same as USB (not adjustable). */
329+
#define DS4_BT_DEFAULT_POLL_INTERVAL_MS 4
319330
#define DS4_OUTPUT_HWCTL_CRC32 0x40
320331
#define DS4_OUTPUT_HWCTL_HID 0x80
321332

@@ -348,6 +359,10 @@ struct dualshock4 {
348359
uint32_t prev_sensor_timestamp;
349360
uint32_t sensor_timestamp_us;
350361

362+
/* Bluetooth poll interval */
363+
bool update_bt_poll_interval;
364+
uint8_t bt_poll_interval;
365+
351366
bool update_rumble;
352367
uint8_t motor_left;
353368
uint8_t motor_right;
@@ -2010,6 +2025,11 @@ static void dualshock4_output_worker(struct work_struct *work)
20102025
*/
20112026
report.bt->hw_control = DS4_OUTPUT_HWCTL_HID | DS4_OUTPUT_HWCTL_CRC32;
20122027

2028+
if (ds4->update_bt_poll_interval) {
2029+
report.bt->hw_control |= ds4->bt_poll_interval;
2030+
ds4->update_bt_poll_interval = false;
2031+
}
2032+
20132033
crc = crc32_le(0xFFFFFFFF, &seed, 1);
20142034
crc = ~crc32_le(crc, report.data, report.len - 4);
20152035

@@ -2241,6 +2261,13 @@ static inline void dualshock4_schedule_work(struct dualshock4 *ds4)
22412261
spin_unlock_irqrestore(&ds4->base.lock, flags);
22422262
}
22432263

2264+
static void dualshock4_set_bt_poll_interval(struct dualshock4 *ds4, uint8_t interval)
2265+
{
2266+
ds4->bt_poll_interval = interval;
2267+
ds4->update_bt_poll_interval = true;
2268+
dualshock4_schedule_work(ds4);
2269+
}
2270+
22442271
/* Set default lightbar color based on player. */
22452272
static void dualshock4_set_default_lightbar_colors(struct dualshock4 *ds4)
22462273
{
@@ -2372,6 +2399,8 @@ static struct ps_device *dualshock4_create(struct hid_device *hdev)
23722399
goto err;
23732400
}
23742401

2402+
dualshock4_set_bt_poll_interval(ds4, DS4_BT_DEFAULT_POLL_INTERVAL_MS);
2403+
23752404
ret = ps_device_set_player_id(ps_dev);
23762405
if (ret) {
23772406
hid_err(hdev, "Failed to assign player id for DualShock4: %d\n", ret);

0 commit comments

Comments
 (0)