Skip to content

Instantly share code, notes, and snippets.

@shenghaoyang
Last active February 19, 2024 00:14
Show Gist options
  • Star 11 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save shenghaoyang/92e6dd65b9f0cc736a419f3e640663c2 to your computer and use it in GitHub Desktop.
Save shenghaoyang/92e6dd65b9f0cc736a419f3e640663c2 to your computer and use it in GitHub Desktop.
Bluetooth support on Raspberry Pis running Arch Linux ARM with non-mainline kernel.

#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

Enabling bluetooth

[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 <stefan.wahren@i2se.com>
 *
 * Tested on a Raspberry Pi Zero W.
 *
 * Copyright (C) 2018 Shenghao Yang <me@shenghaoyang.info>
 *
 */

/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 :)

@meskarune
Copy link

I just used this on a raspberry pi 4 b on arch linux arm and it worked perfectly!

@emmanuelux
Copy link

On raspberry pi 4 the audio sound seems to be limited to 115200 bauds and is choppy at this speed.
with hciattach I have 30000 bauds.
on blueman 11,20 KB/s is the rate of youtube stream and the sound is choppy, even if "max-speed = <2000000>;" is setted.
with hciattach it is 30 KB/s or more but unstable, the stream is stopping after somme minutes on youtube with many errors like : "hci0: Frame reassembly failed (-84)" on dmesg.

@shenghaoyang
Copy link
Author

shenghaoyang commented Jun 28, 2020 via email

@strobo5
Copy link

strobo5 commented Mar 10, 2021

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's bcmbt-overlay.dts, but apparently it's enabled by the krnbt=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 further btattach 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.

@shenghaoyang
Copy link
Author

shenghaoyang commented Mar 12, 2021 via email

@ioaniatr
Copy link

ioaniatr commented Oct 2, 2021

I have just tested this on Raspberry Pi 4B, under Kali-Linux 2021-3 kernel 5.4.83 aarch64. Since Kali has an upstream kernel work like a charm!!!
Thanks!!

@idun-project
Copy link

idun-project commented Feb 19, 2024

You correctly pointed out in your original post:

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

My use case is that the plo11 UART is used by another device connected to the GPIO header, so Bluetooth has to be utilized via the miniuart. I'm sure you know about the miniuart-bt overlay. But if there's no way to combine that overlay with the new krnbt=on parameter, then anyone wanting to use the GPIO serial AND Bluetooth is out of luck, I think.

I'm trying to find a workaround. It seems like an updated miniuart-bt overlay should be required, but isn't forthcoming.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment