mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2025-01-18 11:54:37 +08:00
Bluetooth: btusb: Add support Mediatek MT7925
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> Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
This commit is contained in:
parent
8f0a3786f5
commit
4c92ae75ea
@ -289,3 +289,4 @@ MODULE_FIRMWARE(FIRMWARE_MT7622);
|
||||
MODULE_FIRMWARE(FIRMWARE_MT7663);
|
||||
MODULE_FIRMWARE(FIRMWARE_MT7668);
|
||||
MODULE_FIRMWARE(FIRMWARE_MT7961);
|
||||
MODULE_FIRMWARE(FIRMWARE_MT7925);
|
||||
|
@ -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 *);
|
||||
|
||||
|
@ -2659,6 +2659,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)
|
||||
{
|
||||
@ -3039,10 +3042,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();
|
||||
|
||||
@ -3052,7 +3056,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);
|
||||
@ -3065,6 +3069,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;
|
||||
@ -3074,9 +3081,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) {
|
||||
@ -3219,6 +3233,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)) {
|
||||
@ -3232,22 +3247,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);
|
||||
|
||||
/* 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);
|
||||
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);
|
||||
|
||||
/* 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 {
|
||||
@ -4289,6 +4324,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;
|
||||
|
Loading…
Reference in New Issue
Block a user