diff mbox series

[v4] Bluetooth: btusb: Add support Mediatek MT7925

Message ID 20230620082750.9218-1-peter.tsao@mediatek.com (mailing list archive)
State Accepted
Commit 631016e6154d9bb1f992e1bd31615194cc5a872b
Headers show
Series [v4] Bluetooth: btusb: Add support Mediatek MT7925 | expand

Checks

Context Check Description
tedd_an/pre-ci_am success Success
tedd_an/CheckPatch success CheckPatch PASS
tedd_an/GitLint success Gitlint PASS
tedd_an/SubjectPrefix success Gitlint PASS
tedd_an/BuildKernel success BuildKernel PASS
tedd_an/CheckAllWarning success CheckAllWarning PASS
tedd_an/CheckSparse success CheckSparse PASS
tedd_an/CheckSmatch success CheckSparse PASS
tedd_an/BuildKernel32 success BuildKernel32 PASS
tedd_an/TestRunnerSetup success TestRunnerSetup PASS
tedd_an/TestRunner_l2cap-tester success TestRunner PASS
tedd_an/TestRunner_iso-tester success TestRunner PASS
tedd_an/TestRunner_bnep-tester success TestRunner PASS
tedd_an/TestRunner_mgmt-tester success TestRunner PASS
tedd_an/TestRunner_rfcomm-tester success TestRunner PASS
tedd_an/TestRunner_sco-tester success TestRunner PASS
tedd_an/TestRunner_ioctl-tester success TestRunner PASS
tedd_an/TestRunner_mesh-tester success TestRunner PASS
tedd_an/TestRunner_smp-tester success TestRunner PASS
tedd_an/TestRunner_userchan-tester success TestRunner PASS
tedd_an/IncrementalBuild success Incremental Build PASS

Commit Message

Peter Tsao June 20, 2023, 8:27 a.m. UTC
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=01 Lev=01 Prnt=01 Port=00 Cnt=01 Dev#= 27 Spd=480  MxCh= 0
D:  Ver= 2.10 Cls=ef(misc ) Sub=02 Prot=01 MxPS=64 #Cfgs=  1
P:  Vendor=0e8d ProdID=7925 Rev= 1.00
S:  Manufacturer=MediaTek Inc.
S:  Product=Wireless_Device
S:  SerialNumber=000000000
C:* #Ifs= 4 Cfg#= 1 Atr=e0 MxPwr=100mA
A:  FirstIf#= 0 IfCount= 3 Cls=e0(wlcon) Sub=01 Prot=01
I:* If#= 0 Alt= 0 #EPs= 5 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
E:  Ad=81(I) Atr=03(Int.) MxPS=  16 Ivl=125us
E:  Ad=01(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E:  Ad=82(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E:  Ad=02(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E:  Ad=8f(I) Atr=03(Int.) MxPS=   2 Ivl=125us
I:* If#= 1 Alt= 0 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
E:  Ad=83(I) Atr=01(Isoc) MxPS=   0 Ivl=1ms
E:  Ad=03(O) Atr=01(Isoc) MxPS=   0 Ivl=1ms
I:  If#= 1 Alt= 1 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
E:  Ad=83(I) Atr=01(Isoc) MxPS=   9 Ivl=1ms
E:  Ad=03(O) Atr=01(Isoc) MxPS=   9 Ivl=1ms
I:  If#= 1 Alt= 2 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
E:  Ad=83(I) Atr=01(Isoc) MxPS=  17 Ivl=1ms
E:  Ad=03(O) Atr=01(Isoc) MxPS=  17 Ivl=1ms
I:  If#= 1 Alt= 3 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
E:  Ad=83(I) Atr=01(Isoc) MxPS=  25 Ivl=1ms
E:  Ad=03(O) Atr=01(Isoc) MxPS=  25 Ivl=1ms
I:  If#= 1 Alt= 4 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
E:  Ad=83(I) Atr=01(Isoc) MxPS=  33 Ivl=1ms
E:  Ad=03(O) Atr=01(Isoc) MxPS=  33 Ivl=1ms
I:  If#= 1 Alt= 5 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
E:  Ad=83(I) Atr=01(Isoc) MxPS=  49 Ivl=1ms
E:  Ad=03(O) Atr=01(Isoc) MxPS=  49 Ivl=1ms
I:  If#= 1 Alt= 6 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
E:  Ad=83(I) Atr=01(Isoc) MxPS=  63 Ivl=1ms
E:  Ad=03(O) Atr=01(Isoc) MxPS=  63 Ivl=1ms
I:* If#= 2 Alt= 0 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=(none)
E:  Ad=8a(I) Atr=03(Int.) MxPS=  64 Ivl=125us
E:  Ad=0a(O) Atr=03(Int.) MxPS=  64 Ivl=125us
I:  If#= 2 Alt= 1 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=(none)
E:  Ad=8a(I) Atr=03(Int.) MxPS= 512 Ivl=125us
E:  Ad=0a(O) Atr=03(Int.) MxPS= 512 Ivl=125us
I:* If#= 3 Alt= 0 #EPs= 9 Cls=ff(vend.) Sub=ff Prot=ff Driver=(none)
E:  Ad=84(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E:  Ad=85(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E:  Ad=08(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E:  Ad=04(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E:  Ad=05(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E:  Ad=06(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E:  Ad=07(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E:  Ad=09(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E:  Ad=86(I) Atr=03(Int.) MxPS=   2 Ivl=125us

Signed-off-by: Peter Tsao <peter.tsao@mediatek.com>
---
 drivers/bluetooth/btmtk.c |  1 +
 drivers/bluetooth/btmtk.h |  5 +++
 drivers/bluetooth/btusb.c | 78 +++++++++++++++++++++++++++++----------
 3 files changed, 64 insertions(+), 20 deletions(-)

Comments

bluez.test.bot@gmail.com June 20, 2023, 9 a.m. UTC | #1
This is automated email and please do not reply to this email!

Dear submitter,

Thank you for submitting the patches to the linux bluetooth mailing list.
This is a CI test results with your patch series:
PW Link:https://patchwork.kernel.org/project/bluetooth/list/?series=758585

---Test result---

Test Summary:
CheckPatch                    PASS      1.20 seconds
GitLint                       PASS      0.33 seconds
SubjectPrefix                 PASS      0.10 seconds
BuildKernel                   PASS      38.83 seconds
CheckAllWarning               PASS      42.52 seconds
CheckSparse                   PASS      48.10 seconds
CheckSmatch                   PASS      129.99 seconds
BuildKernel32                 PASS      37.44 seconds
TestRunnerSetup               PASS      533.47 seconds
TestRunner_l2cap-tester       PASS      19.45 seconds
TestRunner_iso-tester         PASS      28.21 seconds
TestRunner_bnep-tester        PASS      6.93 seconds
TestRunner_mgmt-tester        PASS      130.99 seconds
TestRunner_rfcomm-tester      PASS      10.67 seconds
TestRunner_sco-tester         PASS      9.96 seconds
TestRunner_ioctl-tester       PASS      11.62 seconds
TestRunner_mesh-tester        PASS      8.61 seconds
TestRunner_smp-tester         PASS      9.71 seconds
TestRunner_userchan-tester    PASS      7.19 seconds
IncrementalBuild              PASS      35.47 seconds



---
Regards,
Linux Bluetooth
Paul Menzel June 20, 2023, 9:13 a.m. UTC | #2
Dear Peter,


Thank you for your patch.

Am 20.06.23 um 10:27 schrieb Peter Tsao:
> This patch is added support Mediatek MT7925.

Maybe:

This patch adds support for the Mediatek MT7925.

Or in imperative mood:

Add support for the Mediatek MT7925.

Could you please add some more information to the chip. What chip is it 
similar to, what is different.

> 1. The firmware location of MT7925 will set to
> /lib/firmware/mediatek/mt7925

The firmware location of MT7925 is …

> 2. Add Mediatek private data in hdev
> to record the device for handle MT7925 flow.

Sorry, I do not understand. Could you please rephrase.

> 3. Use the recoreded dev_id to condition chip reset flow.

recorded

Could you please document the name and version of the datasheet you used?

> The information in /sys/kernel/debug/usb/devices about the MT7925U
> Bluetooth device is listed as the below
> 
> T:  Bus=01 Lev=01 Prnt=01 Port=00 Cnt=01 Dev#= 27 Spd=480  MxCh= 0
> D:  Ver= 2.10 Cls=ef(misc ) Sub=02 Prot=01 MxPS=64 #Cfgs=  1
> P:  Vendor=0e8d ProdID=7925 Rev= 1.00
> S:  Manufacturer=MediaTek Inc.
> S:  Product=Wireless_Device
> S:  SerialNumber=000000000
> C:* #Ifs= 4 Cfg#= 1 Atr=e0 MxPwr=100mA
> A:  FirstIf#= 0 IfCount= 3 Cls=e0(wlcon) Sub=01 Prot=01
> I:* If#= 0 Alt= 0 #EPs= 5 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
> E:  Ad=81(I) Atr=03(Int.) MxPS=  16 Ivl=125us
> E:  Ad=01(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
> E:  Ad=82(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
> E:  Ad=02(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
> E:  Ad=8f(I) Atr=03(Int.) MxPS=   2 Ivl=125us
> I:* If#= 1 Alt= 0 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
> E:  Ad=83(I) Atr=01(Isoc) MxPS=   0 Ivl=1ms
> E:  Ad=03(O) Atr=01(Isoc) MxPS=   0 Ivl=1ms
> I:  If#= 1 Alt= 1 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
> E:  Ad=83(I) Atr=01(Isoc) MxPS=   9 Ivl=1ms
> E:  Ad=03(O) Atr=01(Isoc) MxPS=   9 Ivl=1ms
> I:  If#= 1 Alt= 2 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
> E:  Ad=83(I) Atr=01(Isoc) MxPS=  17 Ivl=1ms
> E:  Ad=03(O) Atr=01(Isoc) MxPS=  17 Ivl=1ms
> I:  If#= 1 Alt= 3 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
> E:  Ad=83(I) Atr=01(Isoc) MxPS=  25 Ivl=1ms
> E:  Ad=03(O) Atr=01(Isoc) MxPS=  25 Ivl=1ms
> I:  If#= 1 Alt= 4 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
> E:  Ad=83(I) Atr=01(Isoc) MxPS=  33 Ivl=1ms
> E:  Ad=03(O) Atr=01(Isoc) MxPS=  33 Ivl=1ms
> I:  If#= 1 Alt= 5 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
> E:  Ad=83(I) Atr=01(Isoc) MxPS=  49 Ivl=1ms
> E:  Ad=03(O) Atr=01(Isoc) MxPS=  49 Ivl=1ms
> I:  If#= 1 Alt= 6 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
> E:  Ad=83(I) Atr=01(Isoc) MxPS=  63 Ivl=1ms
> E:  Ad=03(O) Atr=01(Isoc) MxPS=  63 Ivl=1ms
> I:* If#= 2 Alt= 0 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=(none)
> E:  Ad=8a(I) Atr=03(Int.) MxPS=  64 Ivl=125us
> E:  Ad=0a(O) Atr=03(Int.) MxPS=  64 Ivl=125us
> I:  If#= 2 Alt= 1 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=(none)
> E:  Ad=8a(I) Atr=03(Int.) MxPS= 512 Ivl=125us
> E:  Ad=0a(O) Atr=03(Int.) MxPS= 512 Ivl=125us
> I:* If#= 3 Alt= 0 #EPs= 9 Cls=ff(vend.) Sub=ff Prot=ff Driver=(none)
> E:  Ad=84(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
> E:  Ad=85(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
> E:  Ad=08(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
> E:  Ad=04(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
> E:  Ad=05(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
> E:  Ad=06(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
> E:  Ad=07(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
> E:  Ad=09(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
> E:  Ad=86(I) Atr=03(Int.) MxPS=   2 Ivl=125us
> 
> Signed-off-by: Peter Tsao <peter.tsao@mediatek.com>
> ---
>   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);

Sort it lexicographically?

> 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"

Ditto.

>   #define HCI_EV_WMT 0xe4
>   #define HCI_WMT_MAX_EVENT_SIZE		64
> @@ -119,6 +120,10 @@ struct btmtk_hci_wmt_params {
>   	u32 *status;
>   };
>   
> +struct btmediatek_data {
> +	u32 dev_id;
> +};
> +
>   typedef int (*wmt_cmd_sync_func_t)(struct hci_dev *,
>   				   struct btmtk_hci_wmt_params *);
>   
> 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 *hdev, 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
> +
>   
>   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 = 0;

Why?

>   	char fw_bin_name[64];
>   	u32 fw_version = 0;
>   	u8 param;
> +	struct btmediatek_data *mediatek;
>   
>   	calltime = ktime_get();
>   
> @@ -3033,7 +3037,7 @@ static int btusb_mtk_setup(struct hci_dev *hdev)
>   		return err;
>   	}
>   
> -	if (!dev_id) {
> +	if (!dev_id || dev_id != 0x7663) {

Define a macro for the id?

>   		err = 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)
>   		}
>   	}
>   
> +	mediatek = hci_get_priv(hdev);
> +	mediatek->dev_id = dev_id;
> +
>   	switch (dev_id) {
>   	case 0x7663:
>   		fwname = 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:

Sort it?

> +		if (dev_id == 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);

So this has a new subdirectory (mt%04x)? Why is that needed?

> +		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 = 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 *hdev)
>   	struct btusb_data *data = hci_get_drvdata(hdev);
>   	u32 val;
>   	int err, retry = 0;
> +	struct btmediatek_data *mediatek;
>   
>   	/* 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 *hdev)
>   
>   	btusb_stop_traffic(data);
>   	usb_kill_anchored_urbs(&data->tx_anchor);
> +	mediatek = hci_get_priv(hdev);
> +
> +	if (mediatek->dev_id == 0x7925) {
> +		btusb_mtk_uhw_reg_read(data, MTK_BT_RESET_REG_CONNV3, &val);
> +		val |= (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 &= 0xFFFF00FF;
> +		val |= (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 |= (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);

A delay of 100 ms is quite excessive. Please add comment to the 
datasheet section requiring this.

> +	} 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);
>   
> -	/* 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);
> +	}

I’d factor both branches into two new functions.

>   
>   	/* Poll the register until reset is completed */
>   	do {
> @@ -4269,6 +4304,9 @@ static int btusb_probe(struct usb_interface *intf,
>   		priv_size += sizeof(struct btrealtek_data);
>   
>   		data->recv_event = btusb_recv_event_realtek;
> +	} else if (id->driver_info & BTUSB_MEDIATEK) {
> +		/* Allocate extra space for Mediatek device */
> +		priv_size += sizeof(struct btmediatek_data);

This affects all Mediatek devices, right? Please make it a separate 
commit with a dedicated commit message.

>   	}
>   
>   	data->recv_acl = hci_recv_frame;


Kind regards,

Paul
diff mbox series

Patch

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"
 
 #define HCI_EV_WMT 0xe4
 #define HCI_WMT_MAX_EVENT_SIZE		64
@@ -119,6 +120,10 @@  struct btmtk_hci_wmt_params {
 	u32 *status;
 };
 
+struct btmediatek_data {
+	u32 dev_id;
+};
+
 typedef int (*wmt_cmd_sync_func_t)(struct hci_dev *,
 				   struct btmtk_hci_wmt_params *);
 
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 *hdev, 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
+
 
 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 = 0;
 	char fw_bin_name[64];
 	u32 fw_version = 0;
 	u8 param;
+	struct btmediatek_data *mediatek;
 
 	calltime = ktime_get();
 
@@ -3033,7 +3037,7 @@  static int btusb_mtk_setup(struct hci_dev *hdev)
 		return err;
 	}
 
-	if (!dev_id) {
+	if (!dev_id || dev_id != 0x7663) {
 		err = 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)
 		}
 	}
 
+	mediatek = hci_get_priv(hdev);
+	mediatek->dev_id = dev_id;
+
 	switch (dev_id) {
 	case 0x7663:
 		fwname = 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 == 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 = 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 *hdev)
 	struct btusb_data *data = hci_get_drvdata(hdev);
 	u32 val;
 	int err, retry = 0;
+	struct btmediatek_data *mediatek;
 
 	/* 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 *hdev)
 
 	btusb_stop_traffic(data);
 	usb_kill_anchored_urbs(&data->tx_anchor);
+	mediatek = hci_get_priv(hdev);
+
+	if (mediatek->dev_id == 0x7925) {
+		btusb_mtk_uhw_reg_read(data, MTK_BT_RESET_REG_CONNV3, &val);
+		val |= (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 &= 0xFFFF00FF;
+		val |= (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 |= (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);
 
-	/* 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);
+	}
 
 	/* Poll the register until reset is completed */
 	do {
@@ -4269,6 +4304,9 @@  static int btusb_probe(struct usb_interface *intf,
 		priv_size += sizeof(struct btrealtek_data);
 
 		data->recv_event = btusb_recv_event_realtek;
+	} else if (id->driver_info & BTUSB_MEDIATEK) {
+		/* Allocate extra space for Mediatek device */
+		priv_size += sizeof(struct btmediatek_data);
 	}
 
 	data->recv_acl = hci_recv_frame;