Park the DualSense-microphone-over-Bluetooth feature. Investigation log + diagnostic infrastructure ship as-is for a future contributor who wants to take another crack at it. BLUETOOTH_AUDIO_NOTES.md (new): full hand-off doc covering what we tried, what we found, where Sony / the kernel / the public RE community currently stand on DS5 BT mic. Highlights: - Real DS5 mic works fine over USB; our dongle's UAC1 descriptor matches the DS5's exactly. The data path is correct. - DS5 firmware on the test controller (build date Jul 4 2025) does not stream microphone audio over the standard BT-HID L2CAP channels. Confirmed by: every BT input report is a standard 79- byte 0x31 report with no audio appended; no alternative report IDs ever arrive; no bit of byte 2 correlates with mic-tagged frames; bidirectional-audio hypothesis (aplay + arecord) did not trigger streaming. - Upstream awalol/DS5Dongle 'mic' branch's RE — 71-byte Opus at data + 4 of frames where (data[2] >> 1) & 1 — appears to be firmware-revision-specific; bit 1 of byte 2 is never set on the current firmware. - Linux kernel hid-playstation.c line ~1509 explicitly says "Bluetooth audio is currently not supported" — the kernel maintainers reached the same conclusion. - Our state config (AllowAudioControl=1, MicSelect=Internal, VolumeMic=0x40, MicMute=0, AudioPowerSave=0) matches exactly what the kernel driver sends to enable the mic over USB. The bytes are right; the BT-side trigger we're missing is not in the standard DS5 protocol. Diagnostic infrastructure stays in firmware (mic_diag.sh, vendor feature reports 0xFD/0xFE, OLED Diagnostics rate counters, Opus-decoder + mic_fifo wired but gated behind `if (false)` in on_bt_data). Zero cost when mic-add is disabled; ready to flip back on the moment someone identifies the right trigger. README.md: short "known issue" entry pointing users at USB-direct when they need the mic, and at BLUETOOTH_AUDIO_NOTES.md for the research log. Possible next steps for the curious: - SDP browse the DS5 to discover non-HID L2CAP services - BT sniffer (~$50-200) between a real PS5 and a DS5 during voice chat — would settle the protocol question definitively - Test with an older DS5 firmware revision (pre-2024) to see if the BT mic path used to work and got removed Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
7.5 KiB
Bluetooth microphone investigation — current status
TL;DR: The DualSense's built-in microphone does not work when the controller is paired to this dongle over Bluetooth. It works fine when the controller is connected directly to a host over USB. This is a Sony / DS5-firmware-side limitation we currently can't work around without reverse engineering or BT-sniffer access to PS5 ↔ DS5 traffic. The same limitation is documented in the upstream Linux kernel driver (drivers/hid/hid-playstation.c line ~1509: "Bluetooth audio is currently not supported").
This file is a hand-off / research log for the next person who tries.
What does work
- Direct USB-C from DS5 → host: mic enumerates as a UAC1 IN endpoint at 48 kHz / 16-bit / 2 channels on
EP 0x82, max packet 196 bytes. ALSA recognizes it ascard N: Controller [DualSense Wireless Controller].arecordcaptures real audio after raising theHeadset Capture Volumemixer control (it defaults to 0 dB). - Our dongle's USB descriptor correctly mirrors the DS5's UAC1 layout — same interfaces, same alt settings, same endpoint addresses, same packet sizes. Verified with
lsusb -vagainst a real DS5. - All the firmware-side decode infrastructure for BT mic is in place (Opus decoder,
mic_fifoqueue,tud_audio_writeto the IN endpoint, mono → stereo duplication) — seesrc/audio.cpp. It's currently gated behindif (false)insrc/main.cpp'son_bt_data()because we have nothing to feed it.
What doesn't, and why
The DS5 firmware on the test controller (build date Jul 4 2025, queried via feature report 0x20) does not stream microphone audio over the standard BT-HID L2CAP channels (PSM 0x11 control + 0x13 interrupt).
What we tried:
- Upstream
awalol/DS5Donglemicbranch as reference. That branch claims to extract a 71-byte Opus packet atdata + 4of any BT input report where(data[2] >> 1) & 1is set. On our DS5 firmware, bit 1 of byte 2 is never set (verified across thousands of frames via theg_31_b2_orOR mask). The upstream RE was likely done on a different (older) DS5 firmware revision. - Bit 0 of byte 2 matches roughly all standard input reports — confirmed by reading the supposed "mic prefix" via
0xFDfeature report and seeing live stick X/Y values (not Opus data). Not a mic flag. - Frame length sweep. Longest BT 0x31 frame we ever see is 79 bytes — a fully-decoded standard DS5 input report (sticks + IMU + touchpad + battery + sensor timestamp + trailing zeros). No audio bytes appended anywhere.
- Other report IDs. Counted ALL incoming BT input reports by report ID. Only
0x01(rare) and0x31(common). No 0x33 / 0x35 / 0x36 / 0x39 / etc. The DS5 isn't sending anything mic-shaped on a different ID. - State configuration matching the kernel. Set
AllowAudioControl=1,AllowMicVolume=1,AllowAudioMute=1,MicSelect=Internal,VolumeMic=0x40,MicMute=0,AudioPowerSave=0— exactly whathid-playstation.csets when calling its "Enable microphone" path. DS5 still doesn't stream. - Bidirectional audio session hypothesis. Maybe the DS5 only streams mic when there's also active speaker audio (
0x36packets) flowing. Tested: ranaplay /dev/zerosimultaneously witharecord. No change in BT-side counters, no new report IDs, no longer frames. Disproved. - State refresh on host UAC1 alt-setting change. Considered hooking
tud_audio_set_itf_cb(itf=2, alt=1)to send the DS5 a fresh "enable mic" state update. Not implemented — given the kernel comment and our state matching the kernel's own "enable" sequence, this wouldn't have helped.
What we did not try (real next steps if anyone picks this up):
- SDP browse the DS5 over BT after pairing. Discover what L2CAP PSMs / services it advertises beyond HID. If there's a Sony proprietary audio PSM we haven't subscribed to, that's where mic traffic might live.
- Open additional L2CAP channels (proprietary audio PSM if found, or standard ones like A2DP=0x19 / RFCOMM=0x03) and watch for unsolicited inbound data.
- Compare DS5 firmware revisions. Test with an older DS5 (pre-2024 manufacture) and see if it streams mic over BT — that would tell us whether Sony removed the feature or just nobody documented the protocol. (We only have one DS5; can't test.)
- BT sniffer between a PS5 console and a DS5 during voice chat. Tells us exactly what L2CAP channels and bytes Sony uses for mic. Equipment-intensive (~$50–200 for an Ubertooth or commercial sniffer).
- DS5 firmware disassembly. Legally fraught, almost certainly EULA-violating.
What we built that's useful regardless
These all stay shipped — they're general-purpose audio-debug infrastructure now:
scripts/mic_diag.shwith subcommandsstatus,capture [secs],watch,bt-trace. Drives the entire diagnostic loop from the host without needing OLED-relay-through-the-user; reads vendor feature reports via/dev/hidraw.- Vendor HID feature report
0xFD(32 bytes): BT input-report counter, non-0x31 counter, last seen non-0x31 report ID, OR mask of byte 2 across 0x31 frames, length range, hex prefix of last frame. - Vendor HID feature report
0xFE(82 bytes): full content of the longest 0x31 frame seen, for byte-level inspection. - OLED Diagnostics screen carries BT31/Mic rate + recent frame prefix + opus dec/wrote bytes — useful for any future audio-path debugging at the bench.
src/audio.cppmic-decode infrastructure (Opus decoder on core0, FIFO, mono → stereo duplication,tud_audio_writeto IN endpoint). Disabled at themic_add_queuecall site, ready to re-enable the moment a real mic trigger is identified.src/state_mgr.cppinitial state corrected —VolumeMicwas0xff(out of valid range per spec; max is0x40),MuteControlhad all*PowerSavebits set which would have power-gated the audio DSP. These corrections don't enable BT mic but they're the right defaults regardless.
References
- Linux kernel
drivers/hid/hid-playstation.c. Quoted lines: ~1407–1420 (mic enable/disable), ~1509 ("Bluetooth audio is currently not supported"). Raw source on GitHub mirror. - PSDevWiki DualSense HID Commands — has factory/manufacturer commands (report IDs 128, 129, 160, 164, 165) for BT patches and audio codec selection, but explicitly notes most "do not work with retail controllers". Not a path forward.
- Upstream
awalol/DS5Donglebranchmic(commits9c197fc feat: mic work,3829163 mic mono channel). RE'd a working mic path for an older DS5 firmware revision; we ported the data plumbing but the BT-side trigger differs on current firmware. - dualsensectl:
command_microphone on/offsetsvalid_flag0 |= DS_OUTPUT_VALID_FLAG0_AUDIO_CONTROL_ENABLEand clearsDS_OUTPUT_POWER_SAVE_CONTROL_MIC_MUTE. Same as what we already do on connect.
For users asking about the mic
When users report "the mic doesn't work":
- Plug the DS5 into the host via USB. Mic works out of the box. You may need to raise the
Headset Capture Volumemixer control if it defaults to 0 dB. - Over the dongle's Bluetooth pairing, the mic is currently a known limitation — not something a firmware update on our side can fix without further reverse engineering of the DS5's proprietary BT audio path.
- The diagnostic tools in
scripts/mic_diag.share available if you want to help reverse engineer this; PRs welcome.