#1 Update: Recent Rapsberry Pi (downstream) kernel dt-overlays now exposes a config option "krnbt" that negates the need for all this.
Relevant PRs: raspberrypi/linux#3682
[Pi 3B (Non-Plus) / Pi Zero W ONLY]
As of kernel package, linux-raspberrypi-4.14.59-1
, support for notifying the kernel of the
Broadcom bluetooth device through the device tree has been enabled.
There is no longer a need for btattach
, which makes the lives of everyone
easier. There is also no need to fall back to hciattach
for better performance, as the
kernel correctly restores a higher baud rate after writing out required firmware
to the bluetooth controller at a lower baud rate.
This requires a device tree node to be added, and that can be accomplished with a
simple overlay (bcmbt-overlay.dts
):
/*
* The code contained herein is licensed under the GNU General Public
* License. You may obtain a copy of the GNU General Public License
* Version 2 or later at the following location:
*
* http://www.gnu.org/copyleft/gpl.html
*
* Device tree overlay for Raspberry Pi devices with bluetooth to
* inform the kernel that a bluetooth controller can be accessed
* over serial using the main UART (pl011 UART, not mini-UART)
* via HCI. Assumes the main UART node is termed uart0.
*
* Modified from mainline device tree source for Pi Zero W,
* bcm2835-rpi-zero-w.dts,
* Copyright (C) 2017 Stefan Wahren <[email protected]>
*
* Tested on a Raspberry Pi Zero W.
*
* Copyright (C) 2018 Shenghao Yang <[email protected]>
*
*/
/dts-v1/;
/plugin/;
/ {
compatible = "brcm,bcm2708";
fragment@0 {
target-path = "uart0";
__overlay__ {
bluetooth {
compatible = "brcm,bcm43438-bt";
max-speed = <2000000>; /* You can experiment with this */
/* Other elements omitted, pins may be different on different PI models */
};
};
};
};
(NOTE: This overlay assumes a clean configuration, with the pl011 UART routed to the bluetooth controller. This is untested on a configuration with the mini-UART routed to the bluetooth controller. YMMV)
To compile this overlay, you'll require the dtc
package. After which, you can execute,
in the directory where you've placed the file,
dtc -I dts -O dtb bcmbt-overlay.dts -o bcmbt.dtbo
Afterwards, copy the generated bcmbt.dtbo
file to /boot/overlays/
, and enable the
overlay in config.txt
, by adding this line at the end of the file:
...
dtoverlay=bcmbt
If all goes well, reboot and you should see the following kernel messages:
[ 12.440976] Bluetooth: hci0: BCM: chip id 94
[ 12.441473] Bluetooth: hci0: BCM: features 0x2e
[ 12.443187] Bluetooth: hci0: BCM43430A1
[ 12.443216] Bluetooth: hci0: BCM43430A1 (001.002.009) build 0000
[ 13.143103] Bluetooth: hci0: BCM (001.002.009) build 0360
Afterwards, you can proceed with installing all the userspace software required
for Bluetooth to operate! (a-la bluez
, bluez-utils
, ...)
Footnotes:
I'm not sure why upstream raspberrypi/linux
is not using this strategy...
perhaps users will freak out over the loss of ttyAMA0
?
Testing:
I've tested streaming music from a phone to the Pi and relaying that over to another
computer through the UAC2
gadget functionality, which has also been recently enabled.
It ran for around 20 minutes before I stopped it, which seems decently stable for me.
All of this was done on a Pi Zero W using the dts as above. This should work on a
Pi 3, but I've not tested that, yet. The Pi 3 has to be running the non-mainline
kernel, of course...., because the mainline dts already has this node built-in :)
I found it far from obvious how to enable Bluetooth on a RaspberryPi 4. I'm dumping some info here in case someone else stumbles upon this.
Bluetooth functionality is not part of the SoC, it's on the same chip as WiFi (BCM43455 or so), but communicates with the BCM2711 SoC on a separate channel (UART). This makes total sense but nobody tells you, or I looked at the wrong places, impatiently as I have to admit.
raspberrypi/firmware/boot/bcm2711-rpi-4-b.dtb
has an entry similar to the device tree node in this post'sbcmbt-overlay.dts
, but apparently it's enabled by thekrnbt=on
parameter as you are told by your/boot/overlays/README
. Easy to miss I guess.So put
dtparam=krnbt=on
in your/boot/config.txt
and hci0 should come up after boot, and of course no furtherbtattach
or so is needed.I tried playing back music from my Android phone, so using the RPi4 as Bluetooth speakers, and there were infrequent short gaps but better than nothing. Also Arch Linux ARM btw, I love it.