Skip to content
Open
25 changes: 25 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
name: CI

on: [pull_request]

jobs:
ci:
runs-on: ubuntu-latest
name: CI for Pull Request
steps:
- name: Checkout the source code
uses: actions/checkout@v3
with:
path: src/src

- name: CI
uses: tedd-an/bzcafe@main
with:
task: ci
base_folder: src
space: kernel
github_token: ${{ secrets.GITHUB_TOKEN }}
email_token: ${{ secrets.EMAIL_TOKEN }}
patchwork_token: ${{ secrets.PATCHWORK_TOKEN }}
patchwork_user: ${{ secrets.PATCHWORK_USER }}

43 changes: 43 additions & 0 deletions .github/workflows/sync.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
name: Sync

on:
schedule:
- cron: "*/30 * * * *"

jobs:
sync_repo:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
with:
ref: master

- name: Sync Repo
uses: tedd-an/bzcafe@main
with:
task: sync
upstream_repo: 'https://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth-next.git'
github_token: ${{ secrets.GITHUB_TOKEN }}

- name: Cleanup PR
uses: tedd-an/bzcafe@main
with:
task: cleanup
github_token: ${{ secrets.ACTION_TOKEN }}

sync_patchwork:
needs: sync_repo
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3

- name: Sync Patchwork
uses: tedd-an/bzcafe@main
with:
task: patchwork
space: kernel
github_token: ${{ secrets.ACTION_TOKEN }}
email_token: ${{ secrets.EMAIL_TOKEN }}
patchwork_token: ${{ secrets.PATCHWORK_TOKEN }}
patchwork_user: ${{ secrets.PATCHWORK_USER }}

63 changes: 57 additions & 6 deletions drivers/bluetooth/btmtk.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,22 @@
/* It is for mt79xx iso data transmission setting */
#define MTK_ISO_THRESHOLD 264

/* Known MT6639 (MT7927) Bluetooth USB devices.
* Used to scope the zero-CHIPID workaround to real MT6639 hardware,
* since some boards return 0x0000 from the MMIO chip ID register.
*/
static const struct {
u16 vendor;
u16 product;
} btmtk_mt6639_devs[] = {
{ 0x0489, 0xe13a }, /* ASUS ROG Crosshair X870E Hero */
{ 0x0489, 0xe0fa }, /* Lenovo Legion Pro 7 16ARX9 */
{ 0x0489, 0xe10f }, /* Gigabyte Z790 AORUS MASTER X */
{ 0x0489, 0xe110 }, /* MSI X870E Ace Max */
{ 0x0489, 0xe116 }, /* TP-Link Archer TBE550E */
{ 0x13d3, 0x3588 }, /* ASUS ROG STRIX X870E-E */
};

struct btmtk_patch_header {
u8 datetime[16];
u8 platform[4];
Expand Down Expand Up @@ -112,7 +128,11 @@ static void btmtk_coredump_notify(struct hci_dev *hdev, int state)
void btmtk_fw_get_filename(char *buf, size_t size, u32 dev_id, u32 fw_ver,
u32 fw_flavor)
{
if (dev_id == 0x7925)
if (dev_id == 0x6639)
snprintf(buf, size,
"mediatek/mt7927/BT_RAM_CODE_MT%04x_2_%x_hdr.bin",
dev_id & 0xffff, (fw_ver & 0xff) + 1);
else if (dev_id == 0x7925)
snprintf(buf, size,
"mediatek/mt%04x/BT_RAM_CODE_MT%04x_1_%x_hdr.bin",
dev_id & 0xffff, dev_id & 0xffff, (fw_ver & 0xff) + 1);
Expand All @@ -128,7 +148,8 @@ void btmtk_fw_get_filename(char *buf, size_t size, u32 dev_id, u32 fw_ver,
EXPORT_SYMBOL_GPL(btmtk_fw_get_filename);

int btmtk_setup_firmware_79xx(struct hci_dev *hdev, const char *fwname,
wmt_cmd_sync_func_t wmt_cmd_sync)
wmt_cmd_sync_func_t wmt_cmd_sync,
u32 dev_id)
{
struct btmtk_hci_wmt_params wmt_params;
struct btmtk_patch_header *hdr;
Expand Down Expand Up @@ -166,6 +187,14 @@ int btmtk_setup_firmware_79xx(struct hci_dev *hdev, const char *fwname,
section_offset = le32_to_cpu(sectionmap->secoffset);
dl_size = le32_to_cpu(sectionmap->bin_info_spec.dlsize);

/* MT6639: only download sections where dlmode byte0 == 0x01,
* matching the Windows driver behavior which skips WiFi/other
* sections that would cause the chip to hang.
*/
if (dev_id == 0x6639 && dl_size > 0 &&
(le32_to_cpu(sectionmap->bin_info_spec.dlmodecrctype) & 0xff) != 0x01)
continue;

if (dl_size > 0) {
retry = 20;
while (retry > 0) {
Expand Down Expand Up @@ -852,7 +881,7 @@ int btmtk_usb_subsys_reset(struct hci_dev *hdev, u32 dev_id)
if (err < 0)
return err;
msleep(100);
} else if (dev_id == 0x7925) {
} else if (dev_id == 0x7925 || dev_id == 0x6639) {
err = btmtk_usb_uhw_reg_read(hdev, MTK_BT_RESET_REG_CONNV3, &val);
if (err < 0)
return err;
Expand Down Expand Up @@ -938,7 +967,7 @@ int btmtk_usb_subsys_reset(struct hci_dev *hdev, u32 dev_id)
}

err = btmtk_usb_id_get(hdev, 0x70010200, &val);
if (err < 0 || !val)
if (err < 0 || (!val && dev_id != 0x6639))
bt_dev_err(hdev, "Can't get device id, subsys reset fail.");

return err;
Expand Down Expand Up @@ -1000,7 +1029,8 @@ static int __set_mtk_intr_interface(struct hci_dev *hdev)
if (!btmtk_data->isopkt_intf)
return -ENODEV;

err = usb_set_interface(btmtk_data->udev, MTK_ISO_IFNUM, 1);
err = usb_set_interface(btmtk_data->udev, MTK_ISO_IFNUM,
(intf->num_altsetting > 1) ? 1 : 0);
if (err < 0) {
bt_dev_err(hdev, "setting interface failed (%d)", -err);
return err;
Expand Down Expand Up @@ -1303,6 +1333,24 @@ int btmtk_usb_setup(struct hci_dev *hdev)
fw_flavor = (fw_flavor & 0x00000080) >> 7;
}

if (!dev_id) {
u16 vid = le16_to_cpu(btmtk_data->udev->descriptor.idVendor);
u16 pid = le16_to_cpu(btmtk_data->udev->descriptor.idProduct);
int i;

for (i = 0; i < ARRAY_SIZE(btmtk_mt6639_devs); i++) {
if (vid == btmtk_mt6639_devs[i].vendor &&
pid == btmtk_mt6639_devs[i].product) {
dev_id = 0x6639;
break;
}
}

if (dev_id)
bt_dev_info(hdev, "MT6639: CHIPID=0x0000 with VID=%04x PID=%04x, using 0x6639",
vid, pid);
}

btmtk_data->dev_id = dev_id;

err = btmtk_register_coredump(hdev, btmtk_data->drv_name, fw_version);
Expand All @@ -1320,11 +1368,13 @@ int btmtk_usb_setup(struct hci_dev *hdev)
case 0x7925:
case 0x7961:
case 0x7902:
case 0x6639:
btmtk_fw_get_filename(fw_bin_name, sizeof(fw_bin_name), dev_id,
fw_version, fw_flavor);

err = btmtk_setup_firmware_79xx(hdev, fw_bin_name,
btmtk_usb_hci_wmt_sync);
btmtk_usb_hci_wmt_sync,
dev_id);
if (err < 0) {
/* retry once if setup firmware error */
if (!test_and_set_bit(BTMTK_FIRMWARE_DL_RETRY, &btmtk_data->flags))
Expand Down Expand Up @@ -1497,3 +1547,4 @@ MODULE_FIRMWARE(FIRMWARE_MT7668);
MODULE_FIRMWARE(FIRMWARE_MT7922);
MODULE_FIRMWARE(FIRMWARE_MT7961);
MODULE_FIRMWARE(FIRMWARE_MT7925);
MODULE_FIRMWARE(FIRMWARE_MT7927);
7 changes: 5 additions & 2 deletions drivers/bluetooth/btmtk.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#define FIRMWARE_MT7902 "mediatek/BT_RAM_CODE_MT7902_1_1_hdr.bin"
#define FIRMWARE_MT7961 "mediatek/BT_RAM_CODE_MT7961_1_2_hdr.bin"
#define FIRMWARE_MT7925 "mediatek/mt7925/BT_RAM_CODE_MT7925_1_1_hdr.bin"
#define FIRMWARE_MT7927 "mediatek/mt7927/BT_RAM_CODE_MT6639_2_1_hdr.bin"

#define HCI_EV_WMT 0xe4
#define HCI_WMT_MAX_EVENT_SIZE 64
Expand Down Expand Up @@ -189,7 +190,8 @@ typedef int (*wmt_cmd_sync_func_t)(struct hci_dev *,
int btmtk_set_bdaddr(struct hci_dev *hdev, const bdaddr_t *bdaddr);

int btmtk_setup_firmware_79xx(struct hci_dev *hdev, const char *fwname,
wmt_cmd_sync_func_t wmt_cmd_sync);
wmt_cmd_sync_func_t wmt_cmd_sync,
u32 dev_id);

int btmtk_setup_firmware(struct hci_dev *hdev, const char *fwname,
wmt_cmd_sync_func_t wmt_cmd_sync);
Expand Down Expand Up @@ -228,7 +230,8 @@ static inline int btmtk_set_bdaddr(struct hci_dev *hdev,

static inline int btmtk_setup_firmware_79xx(struct hci_dev *hdev,
const char *fwname,
wmt_cmd_sync_func_t wmt_cmd_sync)
wmt_cmd_sync_func_t wmt_cmd_sync,
u32 dev_id)
{
return -EOPNOTSUPP;
}
Expand Down
2 changes: 1 addition & 1 deletion drivers/bluetooth/btmtksdio.c
Original file line number Diff line number Diff line change
Expand Up @@ -883,7 +883,7 @@ static int mt79xx_setup(struct hci_dev *hdev, const char *fwname)
u8 param = 0x1;
int err;

err = btmtk_setup_firmware_79xx(hdev, fwname, mtk_hci_wmt_sync);
err = btmtk_setup_firmware_79xx(hdev, fwname, mtk_hci_wmt_sync, 0);
if (err < 0) {
bt_dev_err(hdev, "Failed to setup 79xx firmware (%d)", err);
return err;
Expand Down
12 changes: 12 additions & 0 deletions drivers/bluetooth/btusb.c
Original file line number Diff line number Diff line change
Expand Up @@ -751,6 +751,18 @@ static const struct usb_device_id quirks_table[] = {
BTUSB_WIDEBAND_SPEECH },
{ USB_DEVICE(0x0489, 0xe139), .driver_info = BTUSB_MEDIATEK |
BTUSB_WIDEBAND_SPEECH },
{ USB_DEVICE(0x0489, 0xe13a), .driver_info = BTUSB_MEDIATEK |
BTUSB_WIDEBAND_SPEECH },
{ USB_DEVICE(0x0489, 0xe0fa), .driver_info = BTUSB_MEDIATEK |
BTUSB_WIDEBAND_SPEECH },
{ USB_DEVICE(0x0489, 0xe10f), .driver_info = BTUSB_MEDIATEK |
BTUSB_WIDEBAND_SPEECH },
{ USB_DEVICE(0x0489, 0xe110), .driver_info = BTUSB_MEDIATEK |
BTUSB_WIDEBAND_SPEECH },
{ USB_DEVICE(0x0489, 0xe116), .driver_info = BTUSB_MEDIATEK |
BTUSB_WIDEBAND_SPEECH },
{ USB_DEVICE(0x13d3, 0x3588), .driver_info = BTUSB_MEDIATEK |
BTUSB_WIDEBAND_SPEECH },
{ USB_DEVICE(0x0489, 0xe14e), .driver_info = BTUSB_MEDIATEK |
BTUSB_WIDEBAND_SPEECH },
{ USB_DEVICE(0x0489, 0xe14f), .driver_info = BTUSB_MEDIATEK |
Expand Down
Loading