Skip to content

Instantly share code, notes, and snippets.

@max-prtsr
Created February 14, 2026 15:25
Show Gist options
  • Select an option

  • Save max-prtsr/2e19d74e421b60fbad30b6932772e76e to your computer and use it in GitHub Desktop.

Select an option

Save max-prtsr/2e19d74e421b60fbad30b6932772e76e to your computer and use it in GitHub Desktop.
MediaTek MT7927 (MT6639) Bluetooth on Linux — Kernel 6.18+

MediaTek MT7927 (MT6639) Bluetooth on Linux — Kernel 6.18+

Getting Bluetooth working for the MediaTek MT7927 (Filogic 380) combo chip on Linux. Tested on Arch Linux with kernel 6.18.7 and ASUS ROG STRIX X870-I GAMING WIFI.

Based on jfmarliere/linux-driver-mediatek-mt7927-bluetooth, adapted for kernel 6.18+.

The Problem

The MT7927 chip (USB ID 0489:e13a) is recognized by the kernel but btusb doesn't know how to initialize it:

  • The USB ID is missing from the device table
  • The hardware variant 0x6639 is not handled in btmtk.c
  • The firmware contains WiFi sections that hang the chip if sent over Bluetooth

Prerequisites

  • linux-headers for your running kernel
  • base-devel (or equivalent build tools)
  • zstd
  • Python 3 (for firmware extraction)

Step 1: Extract Firmware

Download the official MediaTek Bluetooth driver from your motherboard's ASUS support page (Windows 11 → Bluetooth). Extract the zip, then:

python3 -c "
import struct
data = open('path/to/mtkbt.dat', 'rb').read()
offset = 0x10
name = data[offset:offset+48].split(b'\x00')[0].decode()
data_offset = struct.unpack_from('<I', data, offset + 64)[0]
data_size = struct.unpack_from('<I', data, offset + 68)[0]
fw = data[data_offset:data_offset + data_size]
open('BT_RAM_CODE_MT6639_2_1_hdr.bin', 'wb').write(fw)
print(f'Extracted {name}: {len(fw)} bytes')
"

sudo mkdir -p /lib/firmware/mediatek/mt6639
sudo cp BT_RAM_CODE_MT6639_2_1_hdr.bin /lib/firmware/mediatek/mt6639/

mtkbt.dat is inside the extracted driver zip under the BT/ directory.

Step 2: Get Kernel Sources

The original repo ships sources from kernel 6.12 which won't compile on 6.18+. Grab the sources matching your kernel:

KVER=$(uname -r | sed 's/-.*//')  # e.g. 6.18.7
mkdir mt7927-bt && cd mt7927-bt

for f in btusb.c btmtk.c btmtk.h btrtl.c btrtl.h btintel.c btintel.h btbcm.c btbcm.h btqca.c btqca.h; do
  curl -sLO "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/plain/drivers/bluetooth/${f}?h=v${KVER}"
done

Step 3: Apply Patches

Three changes are needed:

3a. btusb.c — Add USB device ID

Find the MediaTek MT7925 device block and add before it:

/* MediaTek MT7927 Bluetooth devices */
{ USB_DEVICE(0x0489, 0xe13a), .driver_info = BTUSB_MEDIATEK |
                                             BTUSB_WIDEBAND_SPEECH },

3b. btmtk.h — Add firmware define

After the FIRMWARE_MT7925 line:

#define FIRMWARE_MT7927   "mediatek/mt7927/BT_RAM_CODE_MT7927_1_1_hdr.bin"

3c. btmtk.c — Three changes

1) Firmware filename format — in btmtk_fw_get_filename(), add before the 0x7925 check:

if (dev_id == 0x6639)
    snprintf(buf, size,
             "mediatek/mt%04x/BT_RAM_CODE_MT%04x_2_%x_hdr.bin",
             dev_id & 0xffff, dev_id & 0xffff, (fw_ver & 0xff) + 1);
else if (dev_id == 0x7925)

2) Section filtering — in btmtk_setup_firmware_79xx(), after dl_size = ..., add:

/* MT6639: skip non-BT sections that hang the chip */
if (dl_size > 0 &&
    (le32_to_cpu(sectionmap->bin_info_spec.dlmodecrctype) & 0xff) != 0x01) {
    bt_dev_info(hdev, "MT7927: skipping section %d (non-BT)", i);
    continue;
}

3) Add 0x6639 to existing switch/case blocks:

  • Reset handler: } else if (dev_id == 0x7925 || dev_id == 0x6639) {
  • Setup handler: add case 0x6639: next to case 0x7922:

Step 4: Build & Install

cat > Makefile << 'EOF'
obj-m += btusb.o btmtk.o btrtl.o btintel.o btbcm.o btqca.o
KDIR := /lib/modules/$(shell uname -r)/build
all:
	make -C $(KDIR) M=$(PWD) modules
clean:
	make -C $(KDIR) M=$(PWD) clean
EOF

make

# Test (temporary, until reboot)
sudo modprobe -r btusb
sudo modprobe -r btmtk btrtl btintel btbcm btqca
sudo modprobe bluetooth
for mod in btrtl btintel btbcm btqca btmtk btusb; do
  sudo insmod ${mod}.ko
done
sudo rfkill unblock bluetooth

# Verify
bluetoothctl list

Step 5: Make Permanent

MODDIR=/lib/modules/$(uname -r)/kernel/drivers/bluetooth

# Backup originals
mkdir -p ~/.btmtk_backup/$(uname -r)
for mod in btusb btmtk btrtl btintel btbcm btqca; do
  sudo cp "$MODDIR/${mod}.ko.zst" ~/.btmtk_backup/$(uname -r)/
done

# Install patched
for mod in btusb btmtk btrtl btintel btbcm btqca; do
  zstd -c ${mod}.ko | sudo tee "$MODDIR/${mod}.ko.zst" > /dev/null
done
sudo depmod -a

Notes

  • This only fixes Bluetooth. WiFi from the same MT7927 chip requires a separate driver (mt76).
  • If the chip hangs during failed init, do a full power cycle (unplug PSU, wait 10s).
  • You'll need to rebuild after kernel updates.
  • The setting interface failed (22) and ISO intf not support warnings are harmless.

Tested On

  • Board: ASUS ROG STRIX X870-I GAMING WIFI
  • Chip: MediaTek MT7927 (USB 0489:e13a)
  • Kernel: 6.18.7-arch1-1
  • OS: Arch Linux
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment