Skip to content

Instantly share code, notes, and snippets.

@shenghaoyang
Last active February 19, 2024 00:14
Show Gist options
  • 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 :)

@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