From nobody Thu Nov 14 05:43:16 2024 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id AF7E7EB64D7 for ; Tue, 20 Jun 2023 08:25:42 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231896AbjFTIZl (ORCPT ); Tue, 20 Jun 2023 04:25:41 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:41542 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229683AbjFTIZh (ORCPT ); Tue, 20 Jun 2023 04:25:37 -0400 Received: from mailgw02.mediatek.com (unknown [210.61.82.184]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 191FCDD; Tue, 20 Jun 2023 01:25:30 -0700 (PDT) X-UUID: 0256666c0f4411eeb20a276fd37b9834-20230620 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=mediatek.com; s=dk; h=Content-Type:MIME-Version:Message-ID:Date:Subject:CC:To:From; bh=4e7bpNhZE6fvxscNRuN8+Bxy+9be7E8GWrio0Cw5CoY=; b=u+fZrmF7iYDrPhFAIvKpxeBlgsfsRrat/6lvWRfj8CXcegfboJ+jGoFFxiXi1y0ejJBNoAwZMS2PhuCKYIBUcHgsOl+gfnx2giNXSQAqFwNpjxtEHjnH80PYkFZwX9DoAn5eOKN3sTFMTgrSHRClW1IweptLuUjpWMrJi+YFUi4=; X-CID-P-RULE: Release_Ham X-CID-O-INFO: VERSION:1.1.27,REQID:be8f75d7-2195-42f4-806f-6f0eca7053d8,IP:0,U RL:0,TC:0,Content:-25,EDM:0,RT:0,SF:0,FILE:0,BULK:0,RULE:Release_Ham,ACTIO N:release,TS:-25 X-CID-META: VersionHash:01c9525,CLOUDID:31ff313f-7aa7-41f3-a6bd-0433bee822f3,B ulkID:nil,BulkQuantity:0,Recheck:0,SF:102,TC:nil,Content:0,EDM:-3,IP:nil,U RL:0,File:nil,Bulk:nil,QS:nil,BEC:nil,COL:0,OSI:0,OSA:0,AV:0,LES:1,SPR:NO X-CID-BVR: 0 X-CID-BAS: 0,_,0,_ X-CID-FACTOR: TF_CID_SPAM_SNR X-UUID: 0256666c0f4411eeb20a276fd37b9834-20230620 Received: from mtkmbs11n2.mediatek.inc [(172.21.101.187)] by mailgw02.mediatek.com (envelope-from ) (Generic MTA with TLSv1.2 ECDHE-RSA-AES256-GCM-SHA384 256/256) with ESMTP id 439973206; Tue, 20 Jun 2023 16:25:26 +0800 Received: from mtkmbs11n1.mediatek.inc (172.21.101.186) by mtkmbs10n2.mediatek.inc (172.21.101.183) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1118.26; Tue, 20 Jun 2023 16:25:25 +0800 Received: from mtksdccf07.mediatek.inc (172.21.84.99) by mtkmbs11n1.mediatek.inc (172.21.101.73) with Microsoft SMTP Server id 15.2.1118.26 via Frontend Transport; Tue, 20 Jun 2023 16:25:25 +0800 From: Peter Tsao To: Josh Boyer , David Woodhouse , Ben Hutchings , Marcel Holtmann , Johan Hedberg CC: Chris Lu , Sean Wang , Deren Wu , Aaron Hou , "Steve Lee" , linux-bluetooth , linux-firmware , linux-kernel , linux-mediatek , Peter Tsao Subject: [PATCH] [PATCH v3] Bluetooth: btusb: Add support Mediatek MT7925 Date: Tue, 20 Jun 2023 16:25:23 +0800 Message-ID: <20230620082523.8879-1-peter.tsao@mediatek.com> X-Mailer: git-send-email 2.18.0 MIME-Version: 1.0 X-MTK: N Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" This patch is added support Mediatek MT7925. 1. The firmware location of MT7925 will set to /lib/firmware/mediatek/mt7925 2. Add Mediatek private data in hdev to record the device for handle MT7925 flow. 3. Use the recoreded dev_id to condition chip reset flow. The information in /sys/kernel/debug/usb/devices about the MT7925U Bluetooth device is listed as the below T: Bus=3D01 Lev=3D01 Prnt=3D01 Port=3D00 Cnt=3D01 Dev#=3D 27 Spd=3D480 Mx= Ch=3D 0 D: Ver=3D 2.10 Cls=3Def(misc ) Sub=3D02 Prot=3D01 MxPS=3D64 #Cfgs=3D 1 P: Vendor=3D0e8d ProdID=3D7925 Rev=3D 1.00 S: Manufacturer=3DMediaTek Inc. S: Product=3DWireless_Device S: SerialNumber=3D000000000 C:* #Ifs=3D 4 Cfg#=3D 1 Atr=3De0 MxPwr=3D100mA A: FirstIf#=3D 0 IfCount=3D 3 Cls=3De0(wlcon) Sub=3D01 Prot=3D01 I:* If#=3D 0 Alt=3D 0 #EPs=3D 5 Cls=3De0(wlcon) Sub=3D01 Prot=3D01 Driver= =3Dbtusb E: Ad=3D81(I) Atr=3D03(Int.) MxPS=3D 16 Ivl=3D125us E: Ad=3D01(O) Atr=3D02(Bulk) MxPS=3D 512 Ivl=3D0ms E: Ad=3D82(I) Atr=3D02(Bulk) MxPS=3D 512 Ivl=3D0ms E: Ad=3D02(O) Atr=3D02(Bulk) MxPS=3D 512 Ivl=3D0ms E: Ad=3D8f(I) Atr=3D03(Int.) MxPS=3D 2 Ivl=3D125us I:* If#=3D 1 Alt=3D 0 #EPs=3D 2 Cls=3De0(wlcon) Sub=3D01 Prot=3D01 Driver= =3Dbtusb E: Ad=3D83(I) Atr=3D01(Isoc) MxPS=3D 0 Ivl=3D1ms E: Ad=3D03(O) Atr=3D01(Isoc) MxPS=3D 0 Ivl=3D1ms I: If#=3D 1 Alt=3D 1 #EPs=3D 2 Cls=3De0(wlcon) Sub=3D01 Prot=3D01 Driver= =3Dbtusb E: Ad=3D83(I) Atr=3D01(Isoc) MxPS=3D 9 Ivl=3D1ms E: Ad=3D03(O) Atr=3D01(Isoc) MxPS=3D 9 Ivl=3D1ms I: If#=3D 1 Alt=3D 2 #EPs=3D 2 Cls=3De0(wlcon) Sub=3D01 Prot=3D01 Driver= =3Dbtusb E: Ad=3D83(I) Atr=3D01(Isoc) MxPS=3D 17 Ivl=3D1ms E: Ad=3D03(O) Atr=3D01(Isoc) MxPS=3D 17 Ivl=3D1ms I: If#=3D 1 Alt=3D 3 #EPs=3D 2 Cls=3De0(wlcon) Sub=3D01 Prot=3D01 Driver= =3Dbtusb E: Ad=3D83(I) Atr=3D01(Isoc) MxPS=3D 25 Ivl=3D1ms E: Ad=3D03(O) Atr=3D01(Isoc) MxPS=3D 25 Ivl=3D1ms I: If#=3D 1 Alt=3D 4 #EPs=3D 2 Cls=3De0(wlcon) Sub=3D01 Prot=3D01 Driver= =3Dbtusb E: Ad=3D83(I) Atr=3D01(Isoc) MxPS=3D 33 Ivl=3D1ms E: Ad=3D03(O) Atr=3D01(Isoc) MxPS=3D 33 Ivl=3D1ms I: If#=3D 1 Alt=3D 5 #EPs=3D 2 Cls=3De0(wlcon) Sub=3D01 Prot=3D01 Driver= =3Dbtusb E: Ad=3D83(I) Atr=3D01(Isoc) MxPS=3D 49 Ivl=3D1ms E: Ad=3D03(O) Atr=3D01(Isoc) MxPS=3D 49 Ivl=3D1ms I: If#=3D 1 Alt=3D 6 #EPs=3D 2 Cls=3De0(wlcon) Sub=3D01 Prot=3D01 Driver= =3Dbtusb E: Ad=3D83(I) Atr=3D01(Isoc) MxPS=3D 63 Ivl=3D1ms E: Ad=3D03(O) Atr=3D01(Isoc) MxPS=3D 63 Ivl=3D1ms I:* If#=3D 2 Alt=3D 0 #EPs=3D 2 Cls=3De0(wlcon) Sub=3D01 Prot=3D01 Driver= =3D(none) E: Ad=3D8a(I) Atr=3D03(Int.) MxPS=3D 64 Ivl=3D125us E: Ad=3D0a(O) Atr=3D03(Int.) MxPS=3D 64 Ivl=3D125us I: If#=3D 2 Alt=3D 1 #EPs=3D 2 Cls=3De0(wlcon) Sub=3D01 Prot=3D01 Driver= =3D(none) E: Ad=3D8a(I) Atr=3D03(Int.) MxPS=3D 512 Ivl=3D125us E: Ad=3D0a(O) Atr=3D03(Int.) MxPS=3D 512 Ivl=3D125us I:* If#=3D 3 Alt=3D 0 #EPs=3D 9 Cls=3Dff(vend.) Sub=3Dff Prot=3Dff Driver= =3D(none) E: Ad=3D84(I) Atr=3D02(Bulk) MxPS=3D 512 Ivl=3D0ms E: Ad=3D85(I) Atr=3D02(Bulk) MxPS=3D 512 Ivl=3D0ms E: Ad=3D08(O) Atr=3D02(Bulk) MxPS=3D 512 Ivl=3D0ms E: Ad=3D04(O) Atr=3D02(Bulk) MxPS=3D 512 Ivl=3D0ms E: Ad=3D05(O) Atr=3D02(Bulk) MxPS=3D 512 Ivl=3D0ms E: Ad=3D06(O) Atr=3D02(Bulk) MxPS=3D 512 Ivl=3D0ms E: Ad=3D07(O) Atr=3D02(Bulk) MxPS=3D 512 Ivl=3D0ms E: Ad=3D09(O) Atr=3D02(Bulk) MxPS=3D 512 Ivl=3D0ms E: Ad=3D86(I) Atr=3D03(Int.) MxPS=3D 2 Ivl=3D125us Signed-off-by: Peter Tsao --- drivers/bluetooth/btmtk.c | 1 + drivers/bluetooth/btmtk.h | 5 +++ drivers/bluetooth/btusb.c | 78 +++++++++++++++++++++++++++++---------- 3 files changed, 64 insertions(+), 20 deletions(-) diff --git a/drivers/bluetooth/btmtk.c b/drivers/bluetooth/btmtk.c index 809762d64fc6..9482401d97fa 100644 --- a/drivers/bluetooth/btmtk.c +++ b/drivers/bluetooth/btmtk.c @@ -289,3 +289,4 @@ MODULE_FIRMWARE(FIRMWARE_MT7622); MODULE_FIRMWARE(FIRMWARE_MT7663); MODULE_FIRMWARE(FIRMWARE_MT7668); MODULE_FIRMWARE(FIRMWARE_MT7961); +MODULE_FIRMWARE(FIRMWARE_MT7925); diff --git a/drivers/bluetooth/btmtk.h b/drivers/bluetooth/btmtk.h index 2a88ea8e475e..fadc1a520652 100644 --- a/drivers/bluetooth/btmtk.h +++ b/drivers/bluetooth/btmtk.h @@ -5,6 +5,7 @@ #define FIRMWARE_MT7663 "mediatek/mt7663pr2h.bin" #define FIRMWARE_MT7668 "mediatek/mt7668pr2h.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" =20 #define HCI_EV_WMT 0xe4 #define HCI_WMT_MAX_EVENT_SIZE 64 @@ -119,6 +120,10 @@ struct btmtk_hci_wmt_params { u32 *status; }; =20 +struct btmediatek_data { + u32 dev_id; +}; + typedef int (*wmt_cmd_sync_func_t)(struct hci_dev *, struct btmtk_hci_wmt_params *); =20 diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c index 8776e0f93c73..1328709c0f4f 100644 --- a/drivers/bluetooth/btusb.c +++ b/drivers/bluetooth/btusb.c @@ -2640,6 +2640,9 @@ static int btusb_recv_event_realtek(struct hci_dev *h= dev, struct sk_buff *skb) #define MTK_BT_RST_DONE 0x00000100 #define MTK_BT_RESET_WAIT_MS 100 #define MTK_BT_RESET_NUM_TRIES 10 +#define MTK_BT_RESET_REG_CONNV3 0x70028610 +#define MTK_BT_READ_DEV_ID 0x70010200 + =20 static void btusb_mtk_wmt_recv(struct urb *urb) { @@ -3020,10 +3023,11 @@ static int btusb_mtk_setup(struct hci_dev *hdev) struct sk_buff *skb; const char *fwname; int err, status; - u32 dev_id; + u32 dev_id =3D 0; char fw_bin_name[64]; u32 fw_version =3D 0; u8 param; + struct btmediatek_data *mediatek; =20 calltime =3D ktime_get(); =20 @@ -3033,7 +3037,7 @@ static int btusb_mtk_setup(struct hci_dev *hdev) return err; } =20 - if (!dev_id) { + if (!dev_id || dev_id !=3D 0x7663) { err =3D btusb_mtk_id_get(data, 0x70010200, &dev_id); if (err < 0) { bt_dev_err(hdev, "Failed to get device id (%d)", err); @@ -3046,6 +3050,9 @@ static int btusb_mtk_setup(struct hci_dev *hdev) } } =20 + mediatek =3D hci_get_priv(hdev); + mediatek->dev_id =3D dev_id; + switch (dev_id) { case 0x7663: fwname =3D FIRMWARE_MT7663; @@ -3055,9 +3062,16 @@ static int btusb_mtk_setup(struct hci_dev *hdev) break; case 0x7922: case 0x7961: - snprintf(fw_bin_name, sizeof(fw_bin_name), - "mediatek/BT_RAM_CODE_MT%04x_1_%x_hdr.bin", - dev_id & 0xffff, (fw_version & 0xff) + 1); + case 0x7925: + if (dev_id =3D=3D 0x7925) + snprintf(fw_bin_name, sizeof(fw_bin_name), + "mediatek/mt%04x/BT_RAM_CODE_MT%04x_1_%x_hdr.bin", + dev_id & 0xffff, dev_id & 0xffff, (fw_version & 0xff) + 1); + else + snprintf(fw_bin_name, sizeof(fw_bin_name), + "mediatek/BT_RAM_CODE_MT%04x_1_%x_hdr.bin", + dev_id & 0xffff, (fw_version & 0xff) + 1); + err =3D btmtk_setup_firmware_79xx(hdev, fw_bin_name, btusb_mtk_hci_wmt_sync); if (err < 0) { @@ -3200,6 +3214,7 @@ static void btusb_mtk_cmd_timeout(struct hci_dev *hde= v) struct btusb_data *data =3D hci_get_drvdata(hdev); u32 val; int err, retry =3D 0; + struct btmediatek_data *mediatek; =20 /* It's MediaTek specific bluetooth reset mechanism via USB */ if (test_and_set_bit(BTUSB_HW_RESET_ACTIVE, &data->flags)) { @@ -3213,22 +3228,42 @@ static void btusb_mtk_cmd_timeout(struct hci_dev *h= dev) =20 btusb_stop_traffic(data); usb_kill_anchored_urbs(&data->tx_anchor); + mediatek =3D hci_get_priv(hdev); + + if (mediatek->dev_id =3D=3D 0x7925) { + btusb_mtk_uhw_reg_read(data, MTK_BT_RESET_REG_CONNV3, &val); + val |=3D (1 << 5); + btusb_mtk_uhw_reg_write(data, MTK_BT_RESET_REG_CONNV3, val); + btusb_mtk_uhw_reg_read(data, MTK_BT_RESET_REG_CONNV3, &val); + val &=3D 0xFFFF00FF; + val |=3D (1 << 13); + btusb_mtk_uhw_reg_write(data, MTK_BT_RESET_REG_CONNV3, val); + btusb_mtk_uhw_reg_write(data, MTK_EP_RST_OPT, 0x00010001); + btusb_mtk_uhw_reg_read(data, MTK_BT_RESET_REG_CONNV3, &val); + val |=3D (1 << 0); + btusb_mtk_uhw_reg_write(data, MTK_BT_RESET_REG_CONNV3, val); + btusb_mtk_uhw_reg_write(data, MTK_UDMA_INT_STA_BT, 0x000000FF); + btusb_mtk_uhw_reg_read(data, MTK_UDMA_INT_STA_BT, &val); + btusb_mtk_uhw_reg_write(data, MTK_UDMA_INT_STA_BT1, 0x000000FF); + btusb_mtk_uhw_reg_read(data, MTK_UDMA_INT_STA_BT1, &val); + msleep(100); + } else { + /* It's Device EndPoint Reset Option Register */ + bt_dev_dbg(hdev, "Initiating reset mechanism via uhw"); + btusb_mtk_uhw_reg_write(data, MTK_EP_RST_OPT, MTK_EP_RST_IN_OUT_OPT); + btusb_mtk_uhw_reg_read(data, MTK_BT_WDT_STATUS, &val); =20 - /* It's Device EndPoint Reset Option Register */ - bt_dev_dbg(hdev, "Initiating reset mechanism via uhw"); - btusb_mtk_uhw_reg_write(data, MTK_EP_RST_OPT, MTK_EP_RST_IN_OUT_OPT); - btusb_mtk_uhw_reg_read(data, MTK_BT_WDT_STATUS, &val); - - /* Reset the bluetooth chip via USB interface. */ - btusb_mtk_uhw_reg_write(data, MTK_BT_SUBSYS_RST, 1); - btusb_mtk_uhw_reg_write(data, MTK_UDMA_INT_STA_BT, 0x000000FF); - btusb_mtk_uhw_reg_read(data, MTK_UDMA_INT_STA_BT, &val); - btusb_mtk_uhw_reg_write(data, MTK_UDMA_INT_STA_BT1, 0x000000FF); - btusb_mtk_uhw_reg_read(data, MTK_UDMA_INT_STA_BT1, &val); - /* MT7921 need to delay 20ms between toggle reset bit */ - msleep(20); - btusb_mtk_uhw_reg_write(data, MTK_BT_SUBSYS_RST, 0); - btusb_mtk_uhw_reg_read(data, MTK_BT_SUBSYS_RST, &val); + /* Reset the bluetooth chip via USB interface. */ + btusb_mtk_uhw_reg_write(data, MTK_BT_SUBSYS_RST, 1); + btusb_mtk_uhw_reg_write(data, MTK_UDMA_INT_STA_BT, 0x000000FF); + btusb_mtk_uhw_reg_read(data, MTK_UDMA_INT_STA_BT, &val); + btusb_mtk_uhw_reg_write(data, MTK_UDMA_INT_STA_BT1, 0x000000FF); + btusb_mtk_uhw_reg_read(data, MTK_UDMA_INT_STA_BT1, &val); + /* MT7921 need to delay 20ms between toggle reset bit */ + msleep(20); + btusb_mtk_uhw_reg_write(data, MTK_BT_SUBSYS_RST, 0); + btusb_mtk_uhw_reg_read(data, MTK_BT_SUBSYS_RST, &val); + } =20 /* Poll the register until reset is completed */ do { @@ -4269,6 +4304,9 @@ static int btusb_probe(struct usb_interface *intf, priv_size +=3D sizeof(struct btrealtek_data); =20 data->recv_event =3D btusb_recv_event_realtek; + } else if (id->driver_info & BTUSB_MEDIATEK) { + /* Allocate extra space for Mediatek device */ + priv_size +=3D sizeof(struct btmediatek_data); } =20 data->recv_acl =3D hci_recv_frame; --=20 2.18.0