Skip to content

Commit 3a72204

Browse files
moore-brosholtmann
authored andcommitted
Bluetooth: btmtksido: rely on BT_MTK module
Rely on btmtk module to reduce duplicated code Signed-off-by: Sean Wang <[email protected]> Signed-off-by: Marcel Holtmann <[email protected]>
1 parent 8c0d17b commit 3a72204

File tree

3 files changed

+28
-168
lines changed

3 files changed

+28
-168
lines changed

drivers/bluetooth/Kconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -388,6 +388,7 @@ config BT_ATH3K
388388
config BT_MTKSDIO
389389
tristate "MediaTek HCI SDIO driver"
390390
depends on MMC
391+
select BT_MTK
391392
help
392393
MediaTek Bluetooth HCI SDIO driver.
393394
This driver is required if you want to use MediaTek Bluetooth

drivers/bluetooth/btmtk.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@
99

1010
enum {
1111
BTMTK_WMT_PATCH_DWNLD = 0x1,
12+
BTMTK_WMT_TEST = 0x2,
13+
BTMTK_WMT_WAKEUP = 0x3,
14+
BTMTK_WMT_HIF = 0x4,
1215
BTMTK_WMT_FUNC_CTRL = 0x6,
1316
BTMTK_WMT_RST = 0x7,
1417
BTMTK_WMT_SEMAPHORE = 0x17,

drivers/bluetooth/btmtksdio.c

Lines changed: 24 additions & 168 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@
1212

1313
#include <asm/unaligned.h>
1414
#include <linux/atomic.h>
15-
#include <linux/firmware.h>
1615
#include <linux/init.h>
1716
#include <linux/iopoll.h>
1817
#include <linux/kernel.h>
@@ -28,12 +27,10 @@
2827
#include <net/bluetooth/hci_core.h>
2928

3029
#include "h4_recv.h"
30+
#include "btmtk.h"
3131

3232
#define VERSION "0.1"
3333

34-
#define FIRMWARE_MT7663 "mediatek/mt7663pr2h.bin"
35-
#define FIRMWARE_MT7668 "mediatek/mt7668pr2h.bin"
36-
3734
#define MTKBTSDIO_AUTOSUSPEND_DELAY 8000
3835

3936
static bool enable_autosuspend;
@@ -90,69 +87,12 @@ MODULE_DEVICE_TABLE(sdio, btmtksdio_table);
9087

9188
#define BTMTKSDIO_TX_WAIT_VND_EVT 1
9289

93-
enum {
94-
MTK_WMT_PATCH_DWNLD = 0x1,
95-
MTK_WMT_TEST = 0x2,
96-
MTK_WMT_WAKEUP = 0x3,
97-
MTK_WMT_HIF = 0x4,
98-
MTK_WMT_FUNC_CTRL = 0x6,
99-
MTK_WMT_RST = 0x7,
100-
MTK_WMT_SEMAPHORE = 0x17,
101-
};
102-
103-
enum {
104-
BTMTK_WMT_INVALID,
105-
BTMTK_WMT_PATCH_UNDONE,
106-
BTMTK_WMT_PATCH_DONE,
107-
BTMTK_WMT_ON_UNDONE,
108-
BTMTK_WMT_ON_DONE,
109-
BTMTK_WMT_ON_PROGRESS,
110-
};
111-
11290
struct mtkbtsdio_hdr {
11391
__le16 len;
11492
__le16 reserved;
11593
u8 bt_type;
11694
} __packed;
11795

118-
struct mtk_wmt_hdr {
119-
u8 dir;
120-
u8 op;
121-
__le16 dlen;
122-
u8 flag;
123-
} __packed;
124-
125-
struct mtk_hci_wmt_cmd {
126-
struct mtk_wmt_hdr hdr;
127-
u8 data[256];
128-
} __packed;
129-
130-
struct btmtk_hci_wmt_evt {
131-
struct hci_event_hdr hhdr;
132-
struct mtk_wmt_hdr whdr;
133-
} __packed;
134-
135-
struct btmtk_hci_wmt_evt_funcc {
136-
struct btmtk_hci_wmt_evt hwhdr;
137-
__be16 status;
138-
} __packed;
139-
140-
struct btmtk_tci_sleep {
141-
u8 mode;
142-
__le16 duration;
143-
__le16 host_duration;
144-
u8 host_wakeup_pin;
145-
u8 time_compensation;
146-
} __packed;
147-
148-
struct btmtk_hci_wmt_params {
149-
u8 op;
150-
u8 flag;
151-
u16 dlen;
152-
const void *data;
153-
u32 *status;
154-
};
155-
15696
struct btmtksdio_dev {
15797
struct hci_dev *hdev;
15898
struct sdio_func *func;
@@ -174,27 +114,32 @@ static int mtk_hci_wmt_sync(struct hci_dev *hdev,
174114
struct btmtk_hci_wmt_evt_funcc *wmt_evt_funcc;
175115
u32 hlen, status = BTMTK_WMT_INVALID;
176116
struct btmtk_hci_wmt_evt *wmt_evt;
177-
struct mtk_hci_wmt_cmd wc;
178-
struct mtk_wmt_hdr *hdr;
117+
struct btmtk_hci_wmt_cmd *wc;
118+
struct btmtk_wmt_hdr *hdr;
179119
int err;
180120

121+
/* Send the WMT command and wait until the WMT event returns */
181122
hlen = sizeof(*hdr) + wmt_params->dlen;
182123
if (hlen > 255)
183124
return -EINVAL;
184125

185-
hdr = (struct mtk_wmt_hdr *)&wc;
126+
wc = kzalloc(hlen, GFP_KERNEL);
127+
if (!wc)
128+
return -ENOMEM;
129+
130+
hdr = &wc->hdr;
186131
hdr->dir = 1;
187132
hdr->op = wmt_params->op;
188133
hdr->dlen = cpu_to_le16(wmt_params->dlen + 1);
189134
hdr->flag = wmt_params->flag;
190-
memcpy(wc.data, wmt_params->data, wmt_params->dlen);
135+
memcpy(wc->data, wmt_params->data, wmt_params->dlen);
191136

192137
set_bit(BTMTKSDIO_TX_WAIT_VND_EVT, &bdev->tx_state);
193138

194-
err = __hci_cmd_send(hdev, 0xfc6f, hlen, &wc);
139+
err = __hci_cmd_send(hdev, 0xfc6f, hlen, wc);
195140
if (err < 0) {
196141
clear_bit(BTMTKSDIO_TX_WAIT_VND_EVT, &bdev->tx_state);
197-
return err;
142+
goto err_free_wc;
198143
}
199144

200145
/* The vendor specific WMT commands are all answered by a vendor
@@ -211,13 +156,14 @@ static int mtk_hci_wmt_sync(struct hci_dev *hdev,
211156
if (err == -EINTR) {
212157
bt_dev_err(hdev, "Execution of wmt command interrupted");
213158
clear_bit(BTMTKSDIO_TX_WAIT_VND_EVT, &bdev->tx_state);
214-
return err;
159+
goto err_free_wc;
215160
}
216161

217162
if (err) {
218163
bt_dev_err(hdev, "Execution of wmt command timed out");
219164
clear_bit(BTMTKSDIO_TX_WAIT_VND_EVT, &bdev->tx_state);
220-
return -ETIMEDOUT;
165+
err = -ETIMEDOUT;
166+
goto err_free_wc;
221167
}
222168

223169
/* Parse and handle the return WMT event */
@@ -230,13 +176,13 @@ static int mtk_hci_wmt_sync(struct hci_dev *hdev,
230176
}
231177

232178
switch (wmt_evt->whdr.op) {
233-
case MTK_WMT_SEMAPHORE:
179+
case BTMTK_WMT_SEMAPHORE:
234180
if (wmt_evt->whdr.flag == 2)
235181
status = BTMTK_WMT_PATCH_UNDONE;
236182
else
237183
status = BTMTK_WMT_PATCH_DONE;
238184
break;
239-
case MTK_WMT_FUNC_CTRL:
185+
case BTMTK_WMT_FUNC_CTRL:
240186
wmt_evt_funcc = (struct btmtk_hci_wmt_evt_funcc *)wmt_evt;
241187
if (be16_to_cpu(wmt_evt_funcc->status) == 0x404)
242188
status = BTMTK_WMT_ON_DONE;
@@ -253,6 +199,8 @@ static int mtk_hci_wmt_sync(struct hci_dev *hdev,
253199
err_free_skb:
254200
kfree_skb(bdev->evt_skb);
255201
bdev->evt_skb = NULL;
202+
err_free_wc:
203+
kfree(wc);
256204

257205
return err;
258206
}
@@ -663,7 +611,7 @@ static int btmtksdio_func_query(struct hci_dev *hdev)
663611
u8 param = 0;
664612

665613
/* Query whether the function is enabled */
666-
wmt_params.op = MTK_WMT_FUNC_CTRL;
614+
wmt_params.op = BTMTK_WMT_FUNC_CTRL;
667615
wmt_params.flag = 4;
668616
wmt_params.dlen = sizeof(param);
669617
wmt_params.data = &param;
@@ -678,96 +626,6 @@ static int btmtksdio_func_query(struct hci_dev *hdev)
678626
return status;
679627
}
680628

681-
static int mtk_setup_firmware(struct hci_dev *hdev, const char *fwname)
682-
{
683-
struct btmtk_hci_wmt_params wmt_params;
684-
const struct firmware *fw;
685-
const u8 *fw_ptr;
686-
size_t fw_size;
687-
int err, dlen;
688-
u8 flag, param;
689-
690-
err = request_firmware(&fw, fwname, &hdev->dev);
691-
if (err < 0) {
692-
bt_dev_err(hdev, "Failed to load firmware file (%d)", err);
693-
return err;
694-
}
695-
696-
/* Power on data RAM the firmware relies on. */
697-
param = 1;
698-
wmt_params.op = MTK_WMT_FUNC_CTRL;
699-
wmt_params.flag = 3;
700-
wmt_params.dlen = sizeof(param);
701-
wmt_params.data = &param;
702-
wmt_params.status = NULL;
703-
704-
err = mtk_hci_wmt_sync(hdev, &wmt_params);
705-
if (err < 0) {
706-
bt_dev_err(hdev, "Failed to power on data RAM (%d)", err);
707-
goto free_fw;
708-
}
709-
710-
fw_ptr = fw->data;
711-
fw_size = fw->size;
712-
713-
/* The size of patch header is 30 bytes, should be skip */
714-
if (fw_size < 30) {
715-
err = -EINVAL;
716-
goto free_fw;
717-
}
718-
719-
fw_size -= 30;
720-
fw_ptr += 30;
721-
flag = 1;
722-
723-
wmt_params.op = MTK_WMT_PATCH_DWNLD;
724-
wmt_params.status = NULL;
725-
726-
while (fw_size > 0) {
727-
dlen = min_t(int, 250, fw_size);
728-
729-
/* Tell device the position in sequence */
730-
if (fw_size - dlen <= 0)
731-
flag = 3;
732-
else if (fw_size < fw->size - 30)
733-
flag = 2;
734-
735-
wmt_params.flag = flag;
736-
wmt_params.dlen = dlen;
737-
wmt_params.data = fw_ptr;
738-
739-
err = mtk_hci_wmt_sync(hdev, &wmt_params);
740-
if (err < 0) {
741-
bt_dev_err(hdev, "Failed to send wmt patch dwnld (%d)",
742-
err);
743-
goto free_fw;
744-
}
745-
746-
fw_size -= dlen;
747-
fw_ptr += dlen;
748-
}
749-
750-
wmt_params.op = MTK_WMT_RST;
751-
wmt_params.flag = 4;
752-
wmt_params.dlen = 0;
753-
wmt_params.data = NULL;
754-
wmt_params.status = NULL;
755-
756-
/* Activate funciton the firmware providing to */
757-
err = mtk_hci_wmt_sync(hdev, &wmt_params);
758-
if (err < 0) {
759-
bt_dev_err(hdev, "Failed to send wmt rst (%d)", err);
760-
goto free_fw;
761-
}
762-
763-
/* Wait a few moments for firmware activation done */
764-
usleep_range(10000, 12000);
765-
766-
free_fw:
767-
release_firmware(fw);
768-
return err;
769-
}
770-
771629
static int btmtksdio_setup(struct hci_dev *hdev)
772630
{
773631
struct btmtksdio_dev *bdev = hci_get_drvdata(hdev);
@@ -782,7 +640,7 @@ static int btmtksdio_setup(struct hci_dev *hdev)
782640
calltime = ktime_get();
783641

784642
/* Query whether the firmware is already download */
785-
wmt_params.op = MTK_WMT_SEMAPHORE;
643+
wmt_params.op = BTMTK_WMT_SEMAPHORE;
786644
wmt_params.flag = 1;
787645
wmt_params.dlen = 0;
788646
wmt_params.data = NULL;
@@ -800,7 +658,7 @@ static int btmtksdio_setup(struct hci_dev *hdev)
800658
}
801659

802660
/* Setup a firmware which the device definitely requires */
803-
err = mtk_setup_firmware(hdev, bdev->data->fwname);
661+
err = btmtk_setup_firmware(hdev, bdev->data->fwname, mtk_hci_wmt_sync);
804662
if (err < 0)
805663
return err;
806664

@@ -823,7 +681,7 @@ static int btmtksdio_setup(struct hci_dev *hdev)
823681
}
824682

825683
/* Enable Bluetooth protocol */
826-
wmt_params.op = MTK_WMT_FUNC_CTRL;
684+
wmt_params.op = BTMTK_WMT_FUNC_CTRL;
827685
wmt_params.flag = 0;
828686
wmt_params.dlen = sizeof(param);
829687
wmt_params.data = &param;
@@ -891,7 +749,7 @@ static int btmtksdio_shutdown(struct hci_dev *hdev)
891749
pm_runtime_get_sync(bdev->dev);
892750

893751
/* Disable the device */
894-
wmt_params.op = MTK_WMT_FUNC_CTRL;
752+
wmt_params.op = BTMTK_WMT_FUNC_CTRL;
895753
wmt_params.flag = 0;
896754
wmt_params.dlen = sizeof(param);
897755
wmt_params.data = &param;
@@ -1112,5 +970,3 @@ MODULE_AUTHOR("Sean Wang <[email protected]>");
1112970
MODULE_DESCRIPTION("MediaTek Bluetooth SDIO driver ver " VERSION);
1113971
MODULE_VERSION(VERSION);
1114972
MODULE_LICENSE("GPL");
1115-
MODULE_FIRMWARE(FIRMWARE_MT7663);
1116-
MODULE_FIRMWARE(FIRMWARE_MT7668);

0 commit comments

Comments
 (0)