Skip to content

Commit c603bf1

Browse files
moore-brosholtmann
authored andcommitted
Bluetooth: btmtksdio: add MT7921s Bluetooth support
add MT7921s Bluetooth support Co-developed-by: Mark-yw Chen <[email protected]> Signed-off-by: Mark-yw Chen <[email protected]> Signed-off-by: Sean Wang <[email protected]> Signed-off-by: Marcel Holtmann <[email protected]>
1 parent 1705643 commit c603bf1

File tree

2 files changed

+144
-8
lines changed

2 files changed

+144
-8
lines changed

drivers/bluetooth/btmtk.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,16 @@
77

88
#define HCI_WMT_MAX_EVENT_SIZE 64
99

10+
#define BTMTK_WMT_REG_READ 0x2
11+
1012
enum {
1113
BTMTK_WMT_PATCH_DWNLD = 0x1,
1214
BTMTK_WMT_TEST = 0x2,
1315
BTMTK_WMT_WAKEUP = 0x3,
1416
BTMTK_WMT_HIF = 0x4,
1517
BTMTK_WMT_FUNC_CTRL = 0x6,
1618
BTMTK_WMT_RST = 0x7,
19+
BTMTK_WMT_REGISTER = 0x8,
1720
BTMTK_WMT_SEMAPHORE = 0x17,
1821
};
1922

@@ -49,6 +52,14 @@ struct btmtk_hci_wmt_evt_funcc {
4952
__be16 status;
5053
} __packed;
5154

55+
struct btmtk_hci_wmt_evt_reg {
56+
struct btmtk_hci_wmt_evt hwhdr;
57+
u8 rsv[2];
58+
u8 num;
59+
__le32 addr;
60+
__le32 val;
61+
} __packed;
62+
5263
struct btmtk_tci_sleep {
5364
u8 mode;
5465
__le16 duration;

drivers/bluetooth/btmtksdio.c

Lines changed: 133 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -37,21 +37,31 @@ static bool enable_autosuspend;
3737

3838
struct btmtksdio_data {
3939
const char *fwname;
40+
u16 chipid;
4041
};
4142

4243
static const struct btmtksdio_data mt7663_data = {
4344
.fwname = FIRMWARE_MT7663,
45+
.chipid = 0x7663,
4446
};
4547

4648
static const struct btmtksdio_data mt7668_data = {
4749
.fwname = FIRMWARE_MT7668,
50+
.chipid = 0x7668,
51+
};
52+
53+
static const struct btmtksdio_data mt7921_data = {
54+
.fwname = FIRMWARE_MT7961,
55+
.chipid = 0x7921,
4856
};
4957

5058
static const struct sdio_device_id btmtksdio_table[] = {
5159
{SDIO_DEVICE(SDIO_VENDOR_ID_MEDIATEK, SDIO_DEVICE_ID_MEDIATEK_MT7663),
5260
.driver_data = (kernel_ulong_t)&mt7663_data },
5361
{SDIO_DEVICE(SDIO_VENDOR_ID_MEDIATEK, SDIO_DEVICE_ID_MEDIATEK_MT7668),
5462
.driver_data = (kernel_ulong_t)&mt7668_data },
63+
{SDIO_DEVICE(SDIO_VENDOR_ID_MEDIATEK, SDIO_DEVICE_ID_MEDIATEK_MT7961),
64+
.driver_data = (kernel_ulong_t)&mt7921_data },
5565
{ } /* Terminating entry */
5666
};
5767
MODULE_DEVICE_TABLE(sdio, btmtksdio_table);
@@ -115,6 +125,7 @@ static int mtk_hci_wmt_sync(struct hci_dev *hdev,
115125
{
116126
struct btmtksdio_dev *bdev = hci_get_drvdata(hdev);
117127
struct btmtk_hci_wmt_evt_funcc *wmt_evt_funcc;
128+
struct btmtk_hci_wmt_evt_reg *wmt_evt_reg;
118129
u32 hlen, status = BTMTK_WMT_INVALID;
119130
struct btmtk_hci_wmt_evt *wmt_evt;
120131
struct btmtk_hci_wmt_cmd *wc;
@@ -194,6 +205,19 @@ static int mtk_hci_wmt_sync(struct hci_dev *hdev,
194205
else
195206
status = BTMTK_WMT_ON_UNDONE;
196207
break;
208+
case BTMTK_WMT_PATCH_DWNLD:
209+
if (wmt_evt->whdr.flag == 2)
210+
status = BTMTK_WMT_PATCH_DONE;
211+
else if (wmt_evt->whdr.flag == 1)
212+
status = BTMTK_WMT_PATCH_PROGRESS;
213+
else
214+
status = BTMTK_WMT_PATCH_UNDONE;
215+
break;
216+
case BTMTK_WMT_REGISTER:
217+
wmt_evt_reg = (struct btmtk_hci_wmt_evt_reg *)wmt_evt;
218+
if (le16_to_cpu(wmt_evt->whdr.dlen) == 12)
219+
status = le32_to_cpu(wmt_evt_reg->val);
220+
break;
197221
}
198222

199223
if (wmt_params->status)
@@ -634,20 +658,14 @@ static int btmtksdio_func_query(struct hci_dev *hdev)
634658
return status;
635659
}
636660

637-
static int btmtksdio_setup(struct hci_dev *hdev)
661+
static int mt76xx_setup(struct hci_dev *hdev, const char *fwname)
638662
{
639-
struct btmtksdio_dev *bdev = hci_get_drvdata(hdev);
640663
struct btmtk_hci_wmt_params wmt_params;
641-
ktime_t calltime, delta, rettime;
642664
struct btmtk_tci_sleep tci_sleep;
643-
unsigned long long duration;
644665
struct sk_buff *skb;
645666
int err, status;
646667
u8 param = 0x1;
647668

648-
calltime = ktime_get();
649-
bdev->hw_tx_ready = true;
650-
651669
/* Query whether the firmware is already download */
652670
wmt_params.op = BTMTK_WMT_SEMAPHORE;
653671
wmt_params.flag = 1;
@@ -667,7 +685,7 @@ static int btmtksdio_setup(struct hci_dev *hdev)
667685
}
668686

669687
/* Setup a firmware which the device definitely requires */
670-
err = btmtk_setup_firmware(hdev, bdev->data->fwname, mtk_hci_wmt_sync);
688+
err = btmtk_setup_firmware(hdev, fwname, mtk_hci_wmt_sync);
671689
if (err < 0)
672690
return err;
673691

@@ -719,6 +737,113 @@ static int btmtksdio_setup(struct hci_dev *hdev)
719737
}
720738
kfree_skb(skb);
721739

740+
return 0;
741+
}
742+
743+
static int mt79xx_setup(struct hci_dev *hdev, const char *fwname)
744+
{
745+
struct btmtk_hci_wmt_params wmt_params;
746+
u8 param = 0x1;
747+
int err;
748+
749+
err = btmtk_setup_firmware_79xx(hdev, fwname, mtk_hci_wmt_sync);
750+
if (err < 0) {
751+
bt_dev_err(hdev, "Failed to setup 79xx firmware (%d)", err);
752+
return err;
753+
}
754+
755+
/* Enable Bluetooth protocol */
756+
wmt_params.op = BTMTK_WMT_FUNC_CTRL;
757+
wmt_params.flag = 0;
758+
wmt_params.dlen = sizeof(param);
759+
wmt_params.data = &param;
760+
wmt_params.status = NULL;
761+
762+
err = mtk_hci_wmt_sync(hdev, &wmt_params);
763+
if (err < 0) {
764+
bt_dev_err(hdev, "Failed to send wmt func ctrl (%d)", err);
765+
return err;
766+
}
767+
768+
return err;
769+
}
770+
771+
static int btsdio_mtk_reg_read(struct hci_dev *hdev, u32 reg, u32 *val)
772+
{
773+
struct btmtk_hci_wmt_params wmt_params;
774+
struct reg_read_cmd {
775+
u8 type;
776+
u8 rsv;
777+
u8 num;
778+
__le32 addr;
779+
} __packed reg_read = {
780+
.type = 1,
781+
.num = 1,
782+
};
783+
u32 status;
784+
int err;
785+
786+
reg_read.addr = cpu_to_le32(reg);
787+
wmt_params.op = BTMTK_WMT_REGISTER;
788+
wmt_params.flag = BTMTK_WMT_REG_READ;
789+
wmt_params.dlen = sizeof(reg_read);
790+
wmt_params.data = &reg_read;
791+
wmt_params.status = &status;
792+
793+
err = mtk_hci_wmt_sync(hdev, &wmt_params);
794+
if (err < 0) {
795+
bt_dev_err(hdev, "Failed to read reg(%d)", err);
796+
return err;
797+
}
798+
799+
*val = status;
800+
801+
return err;
802+
}
803+
804+
static int btmtksdio_setup(struct hci_dev *hdev)
805+
{
806+
struct btmtksdio_dev *bdev = hci_get_drvdata(hdev);
807+
ktime_t calltime, delta, rettime;
808+
unsigned long long duration;
809+
char fwname[64];
810+
int err, dev_id;
811+
u32 fw_version = 0;
812+
813+
calltime = ktime_get();
814+
bdev->hw_tx_ready = true;
815+
816+
switch (bdev->data->chipid) {
817+
case 0x7921:
818+
err = btsdio_mtk_reg_read(hdev, 0x70010200, &dev_id);
819+
if (err < 0) {
820+
bt_dev_err(hdev, "Failed to get device id (%d)", err);
821+
return err;
822+
}
823+
824+
err = btsdio_mtk_reg_read(hdev, 0x80021004, &fw_version);
825+
if (err < 0) {
826+
bt_dev_err(hdev, "Failed to get fw version (%d)", err);
827+
return err;
828+
}
829+
830+
snprintf(fwname, sizeof(fwname),
831+
"mediatek/BT_RAM_CODE_MT%04x_1_%x_hdr.bin",
832+
dev_id & 0xffff, (fw_version & 0xff) + 1);
833+
err = mt79xx_setup(hdev, fwname);
834+
if (err < 0)
835+
return err;
836+
break;
837+
case 0x7663:
838+
case 0x7668:
839+
err = mt76xx_setup(hdev, bdev->data->fwname);
840+
if (err < 0)
841+
return err;
842+
break;
843+
default:
844+
return -ENODEV;
845+
}
846+
722847
rettime = ktime_get();
723848
delta = ktime_sub(rettime, calltime);
724849
duration = (unsigned long long)ktime_to_ns(delta) >> 10;

0 commit comments

Comments
 (0)