#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 just used this on a raspberry pi 4 b on arch linux arm and it worked perfectly!