xref: /openbmc/linux/drivers/bluetooth/btmtksdio.c (revision 9aebfd4a)
19aebfd4aSSean Wang // SPDX-License-Identifier: GPL-2.0
29aebfd4aSSean Wang // Copyright (c) 2019 MediaTek Inc.
39aebfd4aSSean Wang 
49aebfd4aSSean Wang /*
59aebfd4aSSean Wang  * Bluetooth support for MediaTek SDIO devices
69aebfd4aSSean Wang  *
79aebfd4aSSean Wang  * This file is written based on btsdio.c and btmtkuart.c.
89aebfd4aSSean Wang  *
99aebfd4aSSean Wang  * Author: Sean Wang <sean.wang@mediatek.com>
109aebfd4aSSean Wang  *
119aebfd4aSSean Wang  */
129aebfd4aSSean Wang 
139aebfd4aSSean Wang #include <asm/unaligned.h>
149aebfd4aSSean Wang #include <linux/atomic.h>
159aebfd4aSSean Wang #include <linux/firmware.h>
169aebfd4aSSean Wang #include <linux/init.h>
179aebfd4aSSean Wang #include <linux/iopoll.h>
189aebfd4aSSean Wang #include <linux/kernel.h>
199aebfd4aSSean Wang #include <linux/module.h>
209aebfd4aSSean Wang #include <linux/skbuff.h>
219aebfd4aSSean Wang 
229aebfd4aSSean Wang #include <linux/mmc/host.h>
239aebfd4aSSean Wang #include <linux/mmc/sdio_ids.h>
249aebfd4aSSean Wang #include <linux/mmc/sdio_func.h>
259aebfd4aSSean Wang 
269aebfd4aSSean Wang #include <net/bluetooth/bluetooth.h>
279aebfd4aSSean Wang #include <net/bluetooth/hci_core.h>
289aebfd4aSSean Wang 
299aebfd4aSSean Wang #include "h4_recv.h"
309aebfd4aSSean Wang 
319aebfd4aSSean Wang #define VERSION "0.1"
329aebfd4aSSean Wang 
339aebfd4aSSean Wang #define FIRMWARE_MT7663		"mediatek/mt7663pr2h.bin"
349aebfd4aSSean Wang #define FIRMWARE_MT7668		"mediatek/mt7668pr2h.bin"
359aebfd4aSSean Wang 
369aebfd4aSSean Wang struct btmtksdio_data {
379aebfd4aSSean Wang 	const char *fwname;
389aebfd4aSSean Wang };
399aebfd4aSSean Wang 
409aebfd4aSSean Wang static const struct btmtksdio_data mt7663_data = {
419aebfd4aSSean Wang 	.fwname = FIRMWARE_MT7663,
429aebfd4aSSean Wang };
439aebfd4aSSean Wang 
449aebfd4aSSean Wang static const struct btmtksdio_data mt7668_data = {
459aebfd4aSSean Wang 	.fwname = FIRMWARE_MT7668,
469aebfd4aSSean Wang };
479aebfd4aSSean Wang 
489aebfd4aSSean Wang static const struct sdio_device_id btmtksdio_table[] = {
499aebfd4aSSean Wang 	{SDIO_DEVICE(SDIO_VENDOR_ID_MEDIATEK, 0x7663),
509aebfd4aSSean Wang 	 .driver_data = (kernel_ulong_t)&mt7663_data },
519aebfd4aSSean Wang 	{SDIO_DEVICE(SDIO_VENDOR_ID_MEDIATEK, 0x7668),
529aebfd4aSSean Wang 	 .driver_data = (kernel_ulong_t)&mt7668_data },
539aebfd4aSSean Wang 	{ }	/* Terminating entry */
549aebfd4aSSean Wang };
559aebfd4aSSean Wang 
569aebfd4aSSean Wang #define MTK_REG_CHLPCR		0x4	/* W1S */
579aebfd4aSSean Wang #define C_INT_EN_SET		BIT(0)
589aebfd4aSSean Wang #define C_INT_EN_CLR		BIT(1)
599aebfd4aSSean Wang #define C_FW_OWN_REQ_SET	BIT(8)
609aebfd4aSSean Wang #define C_FW_OWN_REQ_CLR	BIT(9)
619aebfd4aSSean Wang 
629aebfd4aSSean Wang #define MTK_REG_CSDIOCSR	0x8
639aebfd4aSSean Wang #define SDIO_RE_INIT_EN		BIT(0)
649aebfd4aSSean Wang #define SDIO_INT_CTL		BIT(2)
659aebfd4aSSean Wang 
669aebfd4aSSean Wang #define MTK_REG_CHCR		0xc
679aebfd4aSSean Wang #define C_INT_CLR_CTRL		BIT(1)
689aebfd4aSSean Wang 
699aebfd4aSSean Wang /* CHISR have the same bits field definition with CHIER */
709aebfd4aSSean Wang #define MTK_REG_CHISR		0x10
719aebfd4aSSean Wang #define MTK_REG_CHIER		0x14
729aebfd4aSSean Wang #define FW_OWN_BACK_INT		BIT(0)
739aebfd4aSSean Wang #define RX_DONE_INT		BIT(1)
749aebfd4aSSean Wang #define TX_EMPTY		BIT(2)
759aebfd4aSSean Wang #define TX_FIFO_OVERFLOW	BIT(8)
769aebfd4aSSean Wang #define RX_PKT_LEN		GENMASK(31, 16)
779aebfd4aSSean Wang 
789aebfd4aSSean Wang #define MTK_REG_CTDR		0x18
799aebfd4aSSean Wang 
809aebfd4aSSean Wang #define MTK_REG_CRDR		0x1c
819aebfd4aSSean Wang 
829aebfd4aSSean Wang #define MTK_SDIO_BLOCK_SIZE	256
839aebfd4aSSean Wang 
849aebfd4aSSean Wang #define BTMTKSDIO_TX_WAIT_VND_EVT	1
859aebfd4aSSean Wang 
869aebfd4aSSean Wang enum {
879aebfd4aSSean Wang 	MTK_WMT_PATCH_DWNLD = 0x1,
889aebfd4aSSean Wang 	MTK_WMT_TEST = 0x2,
899aebfd4aSSean Wang 	MTK_WMT_WAKEUP = 0x3,
909aebfd4aSSean Wang 	MTK_WMT_HIF = 0x4,
919aebfd4aSSean Wang 	MTK_WMT_FUNC_CTRL = 0x6,
929aebfd4aSSean Wang 	MTK_WMT_RST = 0x7,
939aebfd4aSSean Wang 	MTK_WMT_SEMAPHORE = 0x17,
949aebfd4aSSean Wang };
959aebfd4aSSean Wang 
969aebfd4aSSean Wang enum {
979aebfd4aSSean Wang 	BTMTK_WMT_INVALID,
989aebfd4aSSean Wang 	BTMTK_WMT_PATCH_UNDONE,
999aebfd4aSSean Wang 	BTMTK_WMT_PATCH_DONE,
1009aebfd4aSSean Wang 	BTMTK_WMT_ON_UNDONE,
1019aebfd4aSSean Wang 	BTMTK_WMT_ON_DONE,
1029aebfd4aSSean Wang 	BTMTK_WMT_ON_PROGRESS,
1039aebfd4aSSean Wang };
1049aebfd4aSSean Wang 
1059aebfd4aSSean Wang struct mtkbtsdio_hdr {
1069aebfd4aSSean Wang 	__le16	len;
1079aebfd4aSSean Wang 	__le16	reserved;
1089aebfd4aSSean Wang 	u8	bt_type;
1099aebfd4aSSean Wang } __packed;
1109aebfd4aSSean Wang 
1119aebfd4aSSean Wang struct mtk_wmt_hdr {
1129aebfd4aSSean Wang 	u8	dir;
1139aebfd4aSSean Wang 	u8	op;
1149aebfd4aSSean Wang 	__le16	dlen;
1159aebfd4aSSean Wang 	u8	flag;
1169aebfd4aSSean Wang } __packed;
1179aebfd4aSSean Wang 
1189aebfd4aSSean Wang struct mtk_hci_wmt_cmd {
1199aebfd4aSSean Wang 	struct mtk_wmt_hdr hdr;
1209aebfd4aSSean Wang 	u8 data[256];
1219aebfd4aSSean Wang } __packed;
1229aebfd4aSSean Wang 
1239aebfd4aSSean Wang struct btmtk_hci_wmt_evt {
1249aebfd4aSSean Wang 	struct hci_event_hdr hhdr;
1259aebfd4aSSean Wang 	struct mtk_wmt_hdr whdr;
1269aebfd4aSSean Wang } __packed;
1279aebfd4aSSean Wang 
1289aebfd4aSSean Wang struct btmtk_hci_wmt_evt_funcc {
1299aebfd4aSSean Wang 	struct btmtk_hci_wmt_evt hwhdr;
1309aebfd4aSSean Wang 	__be16 status;
1319aebfd4aSSean Wang } __packed;
1329aebfd4aSSean Wang 
1339aebfd4aSSean Wang struct btmtk_tci_sleep {
1349aebfd4aSSean Wang 	u8 mode;
1359aebfd4aSSean Wang 	__le16 duration;
1369aebfd4aSSean Wang 	__le16 host_duration;
1379aebfd4aSSean Wang 	u8 host_wakeup_pin;
1389aebfd4aSSean Wang 	u8 time_compensation;
1399aebfd4aSSean Wang } __packed;
1409aebfd4aSSean Wang 
1419aebfd4aSSean Wang struct btmtk_hci_wmt_params {
1429aebfd4aSSean Wang 	u8 op;
1439aebfd4aSSean Wang 	u8 flag;
1449aebfd4aSSean Wang 	u16 dlen;
1459aebfd4aSSean Wang 	const void *data;
1469aebfd4aSSean Wang 	u32 *status;
1479aebfd4aSSean Wang };
1489aebfd4aSSean Wang 
1499aebfd4aSSean Wang struct btmtksdio_dev {
1509aebfd4aSSean Wang 	struct hci_dev *hdev;
1519aebfd4aSSean Wang 	struct sdio_func *func;
1529aebfd4aSSean Wang 
1539aebfd4aSSean Wang 	struct work_struct tx_work;
1549aebfd4aSSean Wang 	unsigned long tx_state;
1559aebfd4aSSean Wang 	struct sk_buff_head txq;
1569aebfd4aSSean Wang 
1579aebfd4aSSean Wang 	struct sk_buff *evt_skb;
1589aebfd4aSSean Wang 
1599aebfd4aSSean Wang 	const struct btmtksdio_data *data;
1609aebfd4aSSean Wang };
1619aebfd4aSSean Wang 
1629aebfd4aSSean Wang static int mtk_hci_wmt_sync(struct hci_dev *hdev,
1639aebfd4aSSean Wang 			    struct btmtk_hci_wmt_params *wmt_params)
1649aebfd4aSSean Wang {
1659aebfd4aSSean Wang 	struct btmtksdio_dev *bdev = hci_get_drvdata(hdev);
1669aebfd4aSSean Wang 	struct btmtk_hci_wmt_evt_funcc *wmt_evt_funcc;
1679aebfd4aSSean Wang 	u32 hlen, status = BTMTK_WMT_INVALID;
1689aebfd4aSSean Wang 	struct btmtk_hci_wmt_evt *wmt_evt;
1699aebfd4aSSean Wang 	struct mtk_hci_wmt_cmd wc;
1709aebfd4aSSean Wang 	struct mtk_wmt_hdr *hdr;
1719aebfd4aSSean Wang 	int err;
1729aebfd4aSSean Wang 
1739aebfd4aSSean Wang 	hlen = sizeof(*hdr) + wmt_params->dlen;
1749aebfd4aSSean Wang 	if (hlen > 255)
1759aebfd4aSSean Wang 		return -EINVAL;
1769aebfd4aSSean Wang 
1779aebfd4aSSean Wang 	hdr = (struct mtk_wmt_hdr *)&wc;
1789aebfd4aSSean Wang 	hdr->dir = 1;
1799aebfd4aSSean Wang 	hdr->op = wmt_params->op;
1809aebfd4aSSean Wang 	hdr->dlen = cpu_to_le16(wmt_params->dlen + 1);
1819aebfd4aSSean Wang 	hdr->flag = wmt_params->flag;
1829aebfd4aSSean Wang 	memcpy(wc.data, wmt_params->data, wmt_params->dlen);
1839aebfd4aSSean Wang 
1849aebfd4aSSean Wang 	set_bit(BTMTKSDIO_TX_WAIT_VND_EVT, &bdev->tx_state);
1859aebfd4aSSean Wang 
1869aebfd4aSSean Wang 	err = __hci_cmd_send(hdev, 0xfc6f, hlen, &wc);
1879aebfd4aSSean Wang 	if (err < 0) {
1889aebfd4aSSean Wang 		clear_bit(BTMTKSDIO_TX_WAIT_VND_EVT, &bdev->tx_state);
1899aebfd4aSSean Wang 		return err;
1909aebfd4aSSean Wang 	}
1919aebfd4aSSean Wang 
1929aebfd4aSSean Wang 	/* The vendor specific WMT commands are all answered by a vendor
1939aebfd4aSSean Wang 	 * specific event and will not have the Command Status or Command
1949aebfd4aSSean Wang 	 * Complete as with usual HCI command flow control.
1959aebfd4aSSean Wang 	 *
1969aebfd4aSSean Wang 	 * After sending the command, wait for BTMTKSDIO_TX_WAIT_VND_EVT
1979aebfd4aSSean Wang 	 * state to be cleared. The driver specific event receive routine
1989aebfd4aSSean Wang 	 * will clear that state and with that indicate completion of the
1999aebfd4aSSean Wang 	 * WMT command.
2009aebfd4aSSean Wang 	 */
2019aebfd4aSSean Wang 	err = wait_on_bit_timeout(&bdev->tx_state, BTMTKSDIO_TX_WAIT_VND_EVT,
2029aebfd4aSSean Wang 				  TASK_INTERRUPTIBLE, HCI_INIT_TIMEOUT);
2039aebfd4aSSean Wang 	if (err == -EINTR) {
2049aebfd4aSSean Wang 		bt_dev_err(hdev, "Execution of wmt command interrupted");
2059aebfd4aSSean Wang 		clear_bit(BTMTKSDIO_TX_WAIT_VND_EVT, &bdev->tx_state);
2069aebfd4aSSean Wang 		return err;
2079aebfd4aSSean Wang 	}
2089aebfd4aSSean Wang 
2099aebfd4aSSean Wang 	if (err) {
2109aebfd4aSSean Wang 		bt_dev_err(hdev, "Execution of wmt command timed out");
2119aebfd4aSSean Wang 		clear_bit(BTMTKSDIO_TX_WAIT_VND_EVT, &bdev->tx_state);
2129aebfd4aSSean Wang 		return -ETIMEDOUT;
2139aebfd4aSSean Wang 	}
2149aebfd4aSSean Wang 
2159aebfd4aSSean Wang 	/* Parse and handle the return WMT event */
2169aebfd4aSSean Wang 	wmt_evt = (struct btmtk_hci_wmt_evt *)bdev->evt_skb->data;
2179aebfd4aSSean Wang 	if (wmt_evt->whdr.op != hdr->op) {
2189aebfd4aSSean Wang 		bt_dev_err(hdev, "Wrong op received %d expected %d",
2199aebfd4aSSean Wang 			   wmt_evt->whdr.op, hdr->op);
2209aebfd4aSSean Wang 		err = -EIO;
2219aebfd4aSSean Wang 		goto err_free_skb;
2229aebfd4aSSean Wang 	}
2239aebfd4aSSean Wang 
2249aebfd4aSSean Wang 	switch (wmt_evt->whdr.op) {
2259aebfd4aSSean Wang 	case MTK_WMT_SEMAPHORE:
2269aebfd4aSSean Wang 		if (wmt_evt->whdr.flag == 2)
2279aebfd4aSSean Wang 			status = BTMTK_WMT_PATCH_UNDONE;
2289aebfd4aSSean Wang 		else
2299aebfd4aSSean Wang 			status = BTMTK_WMT_PATCH_DONE;
2309aebfd4aSSean Wang 		break;
2319aebfd4aSSean Wang 	case MTK_WMT_FUNC_CTRL:
2329aebfd4aSSean Wang 		wmt_evt_funcc = (struct btmtk_hci_wmt_evt_funcc *)wmt_evt;
2339aebfd4aSSean Wang 		if (be16_to_cpu(wmt_evt_funcc->status) == 0x404)
2349aebfd4aSSean Wang 			status = BTMTK_WMT_ON_DONE;
2359aebfd4aSSean Wang 		else if (be16_to_cpu(wmt_evt_funcc->status) == 0x420)
2369aebfd4aSSean Wang 			status = BTMTK_WMT_ON_PROGRESS;
2379aebfd4aSSean Wang 		else
2389aebfd4aSSean Wang 			status = BTMTK_WMT_ON_UNDONE;
2399aebfd4aSSean Wang 		break;
2409aebfd4aSSean Wang 	}
2419aebfd4aSSean Wang 
2429aebfd4aSSean Wang 	if (wmt_params->status)
2439aebfd4aSSean Wang 		*wmt_params->status = status;
2449aebfd4aSSean Wang 
2459aebfd4aSSean Wang err_free_skb:
2469aebfd4aSSean Wang 	kfree_skb(bdev->evt_skb);
2479aebfd4aSSean Wang 	bdev->evt_skb = NULL;
2489aebfd4aSSean Wang 
2499aebfd4aSSean Wang 	return err;
2509aebfd4aSSean Wang }
2519aebfd4aSSean Wang 
2529aebfd4aSSean Wang static int btmtksdio_tx_packet(struct btmtksdio_dev *bdev,
2539aebfd4aSSean Wang 			       struct sk_buff *skb)
2549aebfd4aSSean Wang {
2559aebfd4aSSean Wang 	struct mtkbtsdio_hdr *sdio_hdr;
2569aebfd4aSSean Wang 	int err;
2579aebfd4aSSean Wang 
2589aebfd4aSSean Wang 	/* Make sure that there are enough rooms for SDIO header */
2599aebfd4aSSean Wang 	if (unlikely(skb_headroom(skb) < sizeof(*sdio_hdr))) {
2609aebfd4aSSean Wang 		err = pskb_expand_head(skb, sizeof(*sdio_hdr), 0,
2619aebfd4aSSean Wang 				       GFP_ATOMIC);
2629aebfd4aSSean Wang 		if (err < 0)
2639aebfd4aSSean Wang 			return err;
2649aebfd4aSSean Wang 	}
2659aebfd4aSSean Wang 
2669aebfd4aSSean Wang 	/* Prepend MediaTek SDIO Specific Header */
2679aebfd4aSSean Wang 	skb_push(skb, sizeof(*sdio_hdr));
2689aebfd4aSSean Wang 
2699aebfd4aSSean Wang 	sdio_hdr = (void *)skb->data;
2709aebfd4aSSean Wang 	sdio_hdr->len = cpu_to_le16(skb->len);
2719aebfd4aSSean Wang 	sdio_hdr->reserved = cpu_to_le16(0);
2729aebfd4aSSean Wang 	sdio_hdr->bt_type = hci_skb_pkt_type(skb);
2739aebfd4aSSean Wang 
2749aebfd4aSSean Wang 	err = sdio_writesb(bdev->func, MTK_REG_CTDR, skb->data,
2759aebfd4aSSean Wang 			   round_up(skb->len, MTK_SDIO_BLOCK_SIZE));
2769aebfd4aSSean Wang 	if (err < 0)
2779aebfd4aSSean Wang 		goto err_skb_pull;
2789aebfd4aSSean Wang 
2799aebfd4aSSean Wang 	bdev->hdev->stat.byte_tx += skb->len;
2809aebfd4aSSean Wang 
2819aebfd4aSSean Wang 	kfree_skb(skb);
2829aebfd4aSSean Wang 
2839aebfd4aSSean Wang 	return 0;
2849aebfd4aSSean Wang 
2859aebfd4aSSean Wang err_skb_pull:
2869aebfd4aSSean Wang 	skb_pull(skb, sizeof(*sdio_hdr));
2879aebfd4aSSean Wang 
2889aebfd4aSSean Wang 	return err;
2899aebfd4aSSean Wang }
2909aebfd4aSSean Wang 
2919aebfd4aSSean Wang static u32 btmtksdio_drv_own_query(struct btmtksdio_dev *bdev)
2929aebfd4aSSean Wang {
2939aebfd4aSSean Wang 	return sdio_readl(bdev->func, MTK_REG_CHLPCR, NULL);
2949aebfd4aSSean Wang }
2959aebfd4aSSean Wang 
2969aebfd4aSSean Wang static void btmtksdio_tx_work(struct work_struct *work)
2979aebfd4aSSean Wang {
2989aebfd4aSSean Wang 	struct btmtksdio_dev *bdev = container_of(work, struct btmtksdio_dev,
2999aebfd4aSSean Wang 						  tx_work);
3009aebfd4aSSean Wang 	struct sk_buff *skb;
3019aebfd4aSSean Wang 	int err;
3029aebfd4aSSean Wang 
3039aebfd4aSSean Wang 	sdio_claim_host(bdev->func);
3049aebfd4aSSean Wang 
3059aebfd4aSSean Wang 	while ((skb = skb_dequeue(&bdev->txq))) {
3069aebfd4aSSean Wang 		err = btmtksdio_tx_packet(bdev, skb);
3079aebfd4aSSean Wang 		if (err < 0) {
3089aebfd4aSSean Wang 			bdev->hdev->stat.err_tx++;
3099aebfd4aSSean Wang 			skb_queue_head(&bdev->txq, skb);
3109aebfd4aSSean Wang 			break;
3119aebfd4aSSean Wang 		}
3129aebfd4aSSean Wang 	}
3139aebfd4aSSean Wang 
3149aebfd4aSSean Wang 	sdio_release_host(bdev->func);
3159aebfd4aSSean Wang }
3169aebfd4aSSean Wang 
3179aebfd4aSSean Wang static int btmtksdio_recv_event(struct hci_dev *hdev, struct sk_buff *skb)
3189aebfd4aSSean Wang {
3199aebfd4aSSean Wang 	struct btmtksdio_dev *bdev = hci_get_drvdata(hdev);
3209aebfd4aSSean Wang 	struct hci_event_hdr *hdr = (void *)skb->data;
3219aebfd4aSSean Wang 	int err;
3229aebfd4aSSean Wang 
3239aebfd4aSSean Wang 	/* Fix up the vendor event id with 0xff for vendor specific instead
3249aebfd4aSSean Wang 	 * of 0xe4 so that event send via monitoring socket can be parsed
3259aebfd4aSSean Wang 	 * properly.
3269aebfd4aSSean Wang 	 */
3279aebfd4aSSean Wang 	if (hdr->evt == 0xe4)
3289aebfd4aSSean Wang 		hdr->evt = HCI_EV_VENDOR;
3299aebfd4aSSean Wang 
3309aebfd4aSSean Wang 	/* When someone waits for the WMT event, the skb is being cloned
3319aebfd4aSSean Wang 	 * and being processed the events from there then.
3329aebfd4aSSean Wang 	 */
3339aebfd4aSSean Wang 	if (test_bit(BTMTKSDIO_TX_WAIT_VND_EVT, &bdev->tx_state)) {
3349aebfd4aSSean Wang 		bdev->evt_skb = skb_clone(skb, GFP_KERNEL);
3359aebfd4aSSean Wang 		if (!bdev->evt_skb) {
3369aebfd4aSSean Wang 			err = -ENOMEM;
3379aebfd4aSSean Wang 			goto err_out;
3389aebfd4aSSean Wang 		}
3399aebfd4aSSean Wang 	}
3409aebfd4aSSean Wang 
3419aebfd4aSSean Wang 	err = hci_recv_frame(hdev, skb);
3429aebfd4aSSean Wang 	if (err < 0)
3439aebfd4aSSean Wang 		goto err_free_skb;
3449aebfd4aSSean Wang 
3459aebfd4aSSean Wang 	if (hdr->evt == HCI_EV_VENDOR) {
3469aebfd4aSSean Wang 		if (test_and_clear_bit(BTMTKSDIO_TX_WAIT_VND_EVT,
3479aebfd4aSSean Wang 				       &bdev->tx_state)) {
3489aebfd4aSSean Wang 			/* Barrier to sync with other CPUs */
3499aebfd4aSSean Wang 			smp_mb__after_atomic();
3509aebfd4aSSean Wang 			wake_up_bit(&bdev->tx_state, BTMTKSDIO_TX_WAIT_VND_EVT);
3519aebfd4aSSean Wang 		}
3529aebfd4aSSean Wang 	}
3539aebfd4aSSean Wang 
3549aebfd4aSSean Wang 	return 0;
3559aebfd4aSSean Wang 
3569aebfd4aSSean Wang err_free_skb:
3579aebfd4aSSean Wang 	kfree_skb(bdev->evt_skb);
3589aebfd4aSSean Wang 	bdev->evt_skb = NULL;
3599aebfd4aSSean Wang 
3609aebfd4aSSean Wang err_out:
3619aebfd4aSSean Wang 	return err;
3629aebfd4aSSean Wang }
3639aebfd4aSSean Wang 
3649aebfd4aSSean Wang static const struct h4_recv_pkt mtk_recv_pkts[] = {
3659aebfd4aSSean Wang 	{ H4_RECV_ACL,      .recv = hci_recv_frame },
3669aebfd4aSSean Wang 	{ H4_RECV_SCO,      .recv = hci_recv_frame },
3679aebfd4aSSean Wang 	{ H4_RECV_EVENT,    .recv = btmtksdio_recv_event },
3689aebfd4aSSean Wang };
3699aebfd4aSSean Wang 
3709aebfd4aSSean Wang static int btmtksdio_rx_packet(struct btmtksdio_dev *bdev, u16 rx_size)
3719aebfd4aSSean Wang {
3729aebfd4aSSean Wang 	const struct h4_recv_pkt *pkts = mtk_recv_pkts;
3739aebfd4aSSean Wang 	int pkts_count = ARRAY_SIZE(mtk_recv_pkts);
3749aebfd4aSSean Wang 	struct mtkbtsdio_hdr *sdio_hdr;
3759aebfd4aSSean Wang 	unsigned char *old_data;
3769aebfd4aSSean Wang 	unsigned int old_len;
3779aebfd4aSSean Wang 	int err, i, pad_size;
3789aebfd4aSSean Wang 	struct sk_buff *skb;
3799aebfd4aSSean Wang 	u16 dlen;
3809aebfd4aSSean Wang 
3819aebfd4aSSean Wang 	if (rx_size < sizeof(*sdio_hdr))
3829aebfd4aSSean Wang 		return -EILSEQ;
3839aebfd4aSSean Wang 
3849aebfd4aSSean Wang 	/* A SDIO packet is exactly containing a Bluetooth packet */
3859aebfd4aSSean Wang 	skb = bt_skb_alloc(rx_size, GFP_KERNEL);
3869aebfd4aSSean Wang 	if (!skb)
3879aebfd4aSSean Wang 		return -ENOMEM;
3889aebfd4aSSean Wang 
3899aebfd4aSSean Wang 	skb_put(skb, rx_size);
3909aebfd4aSSean Wang 
3919aebfd4aSSean Wang 	err = sdio_readsb(bdev->func, skb->data, MTK_REG_CRDR, rx_size);
3929aebfd4aSSean Wang 	if (err < 0)
3939aebfd4aSSean Wang 		goto err_kfree_skb;
3949aebfd4aSSean Wang 
3959aebfd4aSSean Wang 	/* Keep old data for dump the content in case of some error is
3969aebfd4aSSean Wang 	 * caught in the following packet parsing.
3979aebfd4aSSean Wang 	 */
3989aebfd4aSSean Wang 	old_data = skb->data;
3999aebfd4aSSean Wang 	old_len = skb->len;
4009aebfd4aSSean Wang 
4019aebfd4aSSean Wang 	bdev->hdev->stat.byte_rx += rx_size;
4029aebfd4aSSean Wang 
4039aebfd4aSSean Wang 	sdio_hdr = (void *)skb->data;
4049aebfd4aSSean Wang 
4059aebfd4aSSean Wang 	/* We assume the default error as -EILSEQ simply to make the error path
4069aebfd4aSSean Wang 	 * be cleaner.
4079aebfd4aSSean Wang 	 */
4089aebfd4aSSean Wang 	err = -EILSEQ;
4099aebfd4aSSean Wang 
4109aebfd4aSSean Wang 	if (rx_size != le16_to_cpu(sdio_hdr->len)) {
4119aebfd4aSSean Wang 		bt_dev_err(bdev->hdev, "Rx size in sdio header is mismatched ");
4129aebfd4aSSean Wang 		goto err_kfree_skb;
4139aebfd4aSSean Wang 	}
4149aebfd4aSSean Wang 
4159aebfd4aSSean Wang 	hci_skb_pkt_type(skb) = sdio_hdr->bt_type;
4169aebfd4aSSean Wang 
4179aebfd4aSSean Wang 	/* Remove MediaTek SDIO header */
4189aebfd4aSSean Wang 	skb_pull(skb, sizeof(*sdio_hdr));
4199aebfd4aSSean Wang 
4209aebfd4aSSean Wang 	/* We have to dig into the packet to get payload size and then know how
4219aebfd4aSSean Wang 	 * many padding bytes at the tail, these padding bytes should be removed
4229aebfd4aSSean Wang 	 * before the packet is indicated to the core layer.
4239aebfd4aSSean Wang 	 */
4249aebfd4aSSean Wang 	for (i = 0; i < pkts_count; i++) {
4259aebfd4aSSean Wang 		if (sdio_hdr->bt_type == (&pkts[i])->type)
4269aebfd4aSSean Wang 			break;
4279aebfd4aSSean Wang 	}
4289aebfd4aSSean Wang 
4299aebfd4aSSean Wang 	if (i >= pkts_count) {
4309aebfd4aSSean Wang 		bt_dev_err(bdev->hdev, "Invalid bt type 0x%02x",
4319aebfd4aSSean Wang 			   sdio_hdr->bt_type);
4329aebfd4aSSean Wang 		goto err_kfree_skb;
4339aebfd4aSSean Wang 	}
4349aebfd4aSSean Wang 
4359aebfd4aSSean Wang 	/* Remaining bytes cannot hold a header*/
4369aebfd4aSSean Wang 	if (skb->len < (&pkts[i])->hlen) {
4379aebfd4aSSean Wang 		bt_dev_err(bdev->hdev, "The size of bt header is mismatched");
4389aebfd4aSSean Wang 		goto err_kfree_skb;
4399aebfd4aSSean Wang 	}
4409aebfd4aSSean Wang 
4419aebfd4aSSean Wang 	switch ((&pkts[i])->lsize) {
4429aebfd4aSSean Wang 		case 1:
4439aebfd4aSSean Wang 			dlen = skb->data[(&pkts[i])->loff];
4449aebfd4aSSean Wang 			break;
4459aebfd4aSSean Wang 		case 2:
4469aebfd4aSSean Wang 			dlen = get_unaligned_le16(skb->data +
4479aebfd4aSSean Wang 						  (&pkts[i])->loff);
4489aebfd4aSSean Wang 			break;
4499aebfd4aSSean Wang 		default:
4509aebfd4aSSean Wang 			goto err_kfree_skb;
4519aebfd4aSSean Wang 	}
4529aebfd4aSSean Wang 
4539aebfd4aSSean Wang 	pad_size = skb->len - (&pkts[i])->hlen -  dlen;
4549aebfd4aSSean Wang 
4559aebfd4aSSean Wang 	/* Remaining bytes cannot hold a payload */
4569aebfd4aSSean Wang 	if (pad_size < 0) {
4579aebfd4aSSean Wang 		bt_dev_err(bdev->hdev, "The size of bt payload is mismatched");
4589aebfd4aSSean Wang 		goto err_kfree_skb;
4599aebfd4aSSean Wang 	}
4609aebfd4aSSean Wang 
4619aebfd4aSSean Wang 	/* Remove padding bytes */
4629aebfd4aSSean Wang 	skb_trim(skb, skb->len - pad_size);
4639aebfd4aSSean Wang 
4649aebfd4aSSean Wang 	/* Complete frame */
4659aebfd4aSSean Wang 	(&pkts[i])->recv(bdev->hdev, skb);
4669aebfd4aSSean Wang 
4679aebfd4aSSean Wang 	return 0;
4689aebfd4aSSean Wang 
4699aebfd4aSSean Wang err_kfree_skb:
4709aebfd4aSSean Wang 	print_hex_dump(KERN_ERR, "err sdio rx: ", DUMP_PREFIX_NONE, 4, 1,
4719aebfd4aSSean Wang 		       old_data, old_len, true);
4729aebfd4aSSean Wang 	kfree_skb(skb);
4739aebfd4aSSean Wang 
4749aebfd4aSSean Wang 	return err;
4759aebfd4aSSean Wang }
4769aebfd4aSSean Wang 
4779aebfd4aSSean Wang static void btmtksdio_interrupt(struct sdio_func *func)
4789aebfd4aSSean Wang {
4799aebfd4aSSean Wang 	struct btmtksdio_dev *bdev = sdio_get_drvdata(func);
4809aebfd4aSSean Wang 	u32 int_status;
4819aebfd4aSSean Wang 	u16 rx_size;
4829aebfd4aSSean Wang 
4839aebfd4aSSean Wang 	/* Disable interrupt */
4849aebfd4aSSean Wang 	sdio_writel(func, C_INT_EN_CLR, MTK_REG_CHLPCR, 0);
4859aebfd4aSSean Wang 
4869aebfd4aSSean Wang 	int_status = sdio_readl(func, MTK_REG_CHISR, NULL);
4879aebfd4aSSean Wang 
4889aebfd4aSSean Wang 	/* Ack an interrupt as soon as possible before any operation on
4899aebfd4aSSean Wang 	 * hardware.
4909aebfd4aSSean Wang 	 *
4919aebfd4aSSean Wang 	 * Note that we don't ack any status during operations to avoid race
4929aebfd4aSSean Wang 	 * condition between the host and the device such as it's possible to
4939aebfd4aSSean Wang 	 * mistakenly ack RX_DONE for the next packet and then cause interrupts
4949aebfd4aSSean Wang 	 * not be raised again but there is still pending data in the hardware
4959aebfd4aSSean Wang 	 * FIFO.
4969aebfd4aSSean Wang 	 */
4979aebfd4aSSean Wang 	sdio_writel(func, int_status, MTK_REG_CHISR, NULL);
4989aebfd4aSSean Wang 
4999aebfd4aSSean Wang 	if (unlikely(!int_status))
5009aebfd4aSSean Wang 		bt_dev_err(bdev->hdev, "CHISR is 0\n");
5019aebfd4aSSean Wang 
5029aebfd4aSSean Wang 	if (int_status & FW_OWN_BACK_INT)
5039aebfd4aSSean Wang 		bt_dev_dbg(bdev->hdev, "Get fw own back\n");
5049aebfd4aSSean Wang 
5059aebfd4aSSean Wang 	if (int_status & TX_EMPTY)
5069aebfd4aSSean Wang 		schedule_work(&bdev->tx_work);
5079aebfd4aSSean Wang 	else if (unlikely(int_status & TX_FIFO_OVERFLOW))
5089aebfd4aSSean Wang 		bt_dev_warn(bdev->hdev, "Tx fifo overflow\n");
5099aebfd4aSSean Wang 
5109aebfd4aSSean Wang 	if (int_status & RX_DONE_INT) {
5119aebfd4aSSean Wang 		rx_size = (int_status & RX_PKT_LEN) >> 16;
5129aebfd4aSSean Wang 
5139aebfd4aSSean Wang 		if (btmtksdio_rx_packet(bdev, rx_size) < 0)
5149aebfd4aSSean Wang 			bdev->hdev->stat.err_rx++;
5159aebfd4aSSean Wang 	}
5169aebfd4aSSean Wang 
5179aebfd4aSSean Wang 	/* Enable interrupt */
5189aebfd4aSSean Wang 	sdio_writel(func, C_INT_EN_SET, MTK_REG_CHLPCR, 0);
5199aebfd4aSSean Wang }
5209aebfd4aSSean Wang 
5219aebfd4aSSean Wang static int btmtksdio_open(struct hci_dev *hdev)
5229aebfd4aSSean Wang {
5239aebfd4aSSean Wang 	struct btmtksdio_dev *bdev = hci_get_drvdata(hdev);
5249aebfd4aSSean Wang 	int err;
5259aebfd4aSSean Wang 	u32 status;
5269aebfd4aSSean Wang 
5279aebfd4aSSean Wang 	sdio_claim_host(bdev->func);
5289aebfd4aSSean Wang 
5299aebfd4aSSean Wang 	err = sdio_enable_func(bdev->func);
5309aebfd4aSSean Wang 	if (err < 0)
5319aebfd4aSSean Wang 		goto err_release_host;
5329aebfd4aSSean Wang 
5339aebfd4aSSean Wang 	/* Get ownership from the device */
5349aebfd4aSSean Wang 	sdio_writel(bdev->func, C_FW_OWN_REQ_CLR, MTK_REG_CHLPCR, &err);
5359aebfd4aSSean Wang 	if (err < 0)
5369aebfd4aSSean Wang 		goto err_disable_func;
5379aebfd4aSSean Wang 
5389aebfd4aSSean Wang 	err = readx_poll_timeout(btmtksdio_drv_own_query, bdev, status,
5399aebfd4aSSean Wang 				 status & C_FW_OWN_REQ_SET, 2000, 1000000);
5409aebfd4aSSean Wang 	if (err < 0) {
5419aebfd4aSSean Wang 		bt_dev_err(bdev->hdev, "Cannot get ownership from device");
5429aebfd4aSSean Wang 		goto err_disable_func;
5439aebfd4aSSean Wang 	}
5449aebfd4aSSean Wang 
5459aebfd4aSSean Wang 	/* Disable interrupt & mask out all interrupt sources */
5469aebfd4aSSean Wang 	sdio_writel(bdev->func, C_INT_EN_CLR, MTK_REG_CHLPCR, &err);
5479aebfd4aSSean Wang 	if (err < 0)
5489aebfd4aSSean Wang 		goto err_disable_func;
5499aebfd4aSSean Wang 
5509aebfd4aSSean Wang 	sdio_writel(bdev->func, 0, MTK_REG_CHIER, &err);
5519aebfd4aSSean Wang 	if (err < 0)
5529aebfd4aSSean Wang 		goto err_disable_func;
5539aebfd4aSSean Wang 
5549aebfd4aSSean Wang 	err = sdio_claim_irq(bdev->func, btmtksdio_interrupt);
5559aebfd4aSSean Wang 	if (err < 0)
5569aebfd4aSSean Wang 		goto err_disable_func;
5579aebfd4aSSean Wang 
5589aebfd4aSSean Wang 	err = sdio_set_block_size(bdev->func, MTK_SDIO_BLOCK_SIZE);
5599aebfd4aSSean Wang 	if (err < 0)
5609aebfd4aSSean Wang 		goto err_release_irq;
5619aebfd4aSSean Wang 
5629aebfd4aSSean Wang 	/* SDIO CMD 5 allows the SDIO device back to idle state an
5639aebfd4aSSean Wang 	 * synchronous interrupt is supported in SDIO 4-bit mode
5649aebfd4aSSean Wang 	 */
5659aebfd4aSSean Wang 	sdio_writel(bdev->func, SDIO_INT_CTL | SDIO_RE_INIT_EN,
5669aebfd4aSSean Wang 		    MTK_REG_CSDIOCSR, &err);
5679aebfd4aSSean Wang 	if (err < 0)
5689aebfd4aSSean Wang 		goto err_release_irq;
5699aebfd4aSSean Wang 
5709aebfd4aSSean Wang 	/* Setup write-1-clear for CHISR register */
5719aebfd4aSSean Wang 	sdio_writel(bdev->func, C_INT_CLR_CTRL, MTK_REG_CHCR, &err);
5729aebfd4aSSean Wang 	if (err < 0)
5739aebfd4aSSean Wang 		goto err_release_irq;
5749aebfd4aSSean Wang 
5759aebfd4aSSean Wang 	/* Setup interrupt sources */
5769aebfd4aSSean Wang 	sdio_writel(bdev->func, RX_DONE_INT | TX_EMPTY | TX_FIFO_OVERFLOW,
5779aebfd4aSSean Wang 		    MTK_REG_CHIER, &err);
5789aebfd4aSSean Wang 	if (err < 0)
5799aebfd4aSSean Wang 		goto err_release_irq;
5809aebfd4aSSean Wang 
5819aebfd4aSSean Wang 	/* Enable interrupt */
5829aebfd4aSSean Wang 	sdio_writel(bdev->func, C_INT_EN_SET, MTK_REG_CHLPCR, &err);
5839aebfd4aSSean Wang 	if (err < 0)
5849aebfd4aSSean Wang 		goto err_release_irq;
5859aebfd4aSSean Wang 
5869aebfd4aSSean Wang 	sdio_release_host(bdev->func);
5879aebfd4aSSean Wang 
5889aebfd4aSSean Wang 	return 0;
5899aebfd4aSSean Wang 
5909aebfd4aSSean Wang err_release_irq:
5919aebfd4aSSean Wang 	sdio_release_irq(bdev->func);
5929aebfd4aSSean Wang 
5939aebfd4aSSean Wang err_disable_func:
5949aebfd4aSSean Wang 	sdio_disable_func(bdev->func);
5959aebfd4aSSean Wang 
5969aebfd4aSSean Wang err_release_host:
5979aebfd4aSSean Wang 	sdio_release_host(bdev->func);
5989aebfd4aSSean Wang 
5999aebfd4aSSean Wang 	return err;
6009aebfd4aSSean Wang }
6019aebfd4aSSean Wang 
6029aebfd4aSSean Wang static int btmtksdio_close(struct hci_dev *hdev)
6039aebfd4aSSean Wang {
6049aebfd4aSSean Wang 	struct btmtksdio_dev *bdev = hci_get_drvdata(hdev);
6059aebfd4aSSean Wang 	u32 status;
6069aebfd4aSSean Wang 	int err;
6079aebfd4aSSean Wang 
6089aebfd4aSSean Wang 	sdio_claim_host(bdev->func);
6099aebfd4aSSean Wang 
6109aebfd4aSSean Wang 	/* Disable interrupt */
6119aebfd4aSSean Wang 	sdio_writel(bdev->func, C_INT_EN_CLR, MTK_REG_CHLPCR, NULL);
6129aebfd4aSSean Wang 
6139aebfd4aSSean Wang 	sdio_release_irq(bdev->func);
6149aebfd4aSSean Wang 
6159aebfd4aSSean Wang 	/* Return ownership to the device */
6169aebfd4aSSean Wang 	sdio_writel(bdev->func, C_FW_OWN_REQ_SET, MTK_REG_CHLPCR, NULL);
6179aebfd4aSSean Wang 
6189aebfd4aSSean Wang 	err = readx_poll_timeout(btmtksdio_drv_own_query, bdev, status,
6199aebfd4aSSean Wang 				 !(status & C_FW_OWN_REQ_SET), 2000, 1000000);
6209aebfd4aSSean Wang 	if (err < 0)
6219aebfd4aSSean Wang 		bt_dev_err(bdev->hdev, "Cannot return ownership to device");
6229aebfd4aSSean Wang 
6239aebfd4aSSean Wang 	sdio_disable_func(bdev->func);
6249aebfd4aSSean Wang 
6259aebfd4aSSean Wang 	sdio_release_host(bdev->func);
6269aebfd4aSSean Wang 
6279aebfd4aSSean Wang 	return 0;
6289aebfd4aSSean Wang }
6299aebfd4aSSean Wang 
6309aebfd4aSSean Wang static int btmtksdio_flush(struct hci_dev *hdev)
6319aebfd4aSSean Wang {
6329aebfd4aSSean Wang 	struct btmtksdio_dev *bdev = hci_get_drvdata(hdev);
6339aebfd4aSSean Wang 
6349aebfd4aSSean Wang 	skb_queue_purge(&bdev->txq);
6359aebfd4aSSean Wang 
6369aebfd4aSSean Wang 	cancel_work_sync(&bdev->tx_work);
6379aebfd4aSSean Wang 
6389aebfd4aSSean Wang 	return 0;
6399aebfd4aSSean Wang }
6409aebfd4aSSean Wang 
6419aebfd4aSSean Wang static int btmtksdio_func_query(struct hci_dev *hdev)
6429aebfd4aSSean Wang {
6439aebfd4aSSean Wang 	struct btmtk_hci_wmt_params wmt_params;
6449aebfd4aSSean Wang 	int status, err;
6459aebfd4aSSean Wang 	u8 param = 0;
6469aebfd4aSSean Wang 
6479aebfd4aSSean Wang 	/* Query whether the function is enabled */
6489aebfd4aSSean Wang 	wmt_params.op = MTK_WMT_FUNC_CTRL;
6499aebfd4aSSean Wang 	wmt_params.flag = 4;
6509aebfd4aSSean Wang 	wmt_params.dlen = sizeof(param);
6519aebfd4aSSean Wang 	wmt_params.data = &param;
6529aebfd4aSSean Wang 	wmt_params.status = &status;
6539aebfd4aSSean Wang 
6549aebfd4aSSean Wang 	err = mtk_hci_wmt_sync(hdev, &wmt_params);
6559aebfd4aSSean Wang 	if (err < 0) {
6569aebfd4aSSean Wang 		bt_dev_err(hdev, "Failed to query function status (%d)", err);
6579aebfd4aSSean Wang 		return err;
6589aebfd4aSSean Wang 	}
6599aebfd4aSSean Wang 
6609aebfd4aSSean Wang 	return status;
6619aebfd4aSSean Wang }
6629aebfd4aSSean Wang 
6639aebfd4aSSean Wang static int mtk_setup_firmware(struct hci_dev *hdev, const char *fwname)
6649aebfd4aSSean Wang {
6659aebfd4aSSean Wang 	struct btmtk_hci_wmt_params wmt_params;
6669aebfd4aSSean Wang 	const struct firmware *fw;
6679aebfd4aSSean Wang 	const u8 *fw_ptr;
6689aebfd4aSSean Wang 	size_t fw_size;
6699aebfd4aSSean Wang 	int err, dlen;
6709aebfd4aSSean Wang 	u8 flag;
6719aebfd4aSSean Wang 
6729aebfd4aSSean Wang 	err = request_firmware(&fw, fwname, &hdev->dev);
6739aebfd4aSSean Wang 	if (err < 0) {
6749aebfd4aSSean Wang 		bt_dev_err(hdev, "Failed to load firmware file (%d)", err);
6759aebfd4aSSean Wang 		return err;
6769aebfd4aSSean Wang 	}
6779aebfd4aSSean Wang 
6789aebfd4aSSean Wang 	fw_ptr = fw->data;
6799aebfd4aSSean Wang 	fw_size = fw->size;
6809aebfd4aSSean Wang 
6819aebfd4aSSean Wang 	/* The size of patch header is 30 bytes, should be skip */
6829aebfd4aSSean Wang 	if (fw_size < 30) {
6839aebfd4aSSean Wang 		err = -EINVAL;
6849aebfd4aSSean Wang 		goto free_fw;
6859aebfd4aSSean Wang 	}
6869aebfd4aSSean Wang 
6879aebfd4aSSean Wang 	fw_size -= 30;
6889aebfd4aSSean Wang 	fw_ptr += 30;
6899aebfd4aSSean Wang 	flag = 1;
6909aebfd4aSSean Wang 
6919aebfd4aSSean Wang 	wmt_params.op = MTK_WMT_PATCH_DWNLD;
6929aebfd4aSSean Wang 	wmt_params.status = NULL;
6939aebfd4aSSean Wang 
6949aebfd4aSSean Wang 	while (fw_size > 0) {
6959aebfd4aSSean Wang 		dlen = min_t(int, 250, fw_size);
6969aebfd4aSSean Wang 
6979aebfd4aSSean Wang 		/* Tell device the position in sequence */
6989aebfd4aSSean Wang 		if (fw_size - dlen <= 0)
6999aebfd4aSSean Wang 			flag = 3;
7009aebfd4aSSean Wang 		else if (fw_size < fw->size - 30)
7019aebfd4aSSean Wang 			flag = 2;
7029aebfd4aSSean Wang 
7039aebfd4aSSean Wang 		wmt_params.flag = flag;
7049aebfd4aSSean Wang 		wmt_params.dlen = dlen;
7059aebfd4aSSean Wang 		wmt_params.data = fw_ptr;
7069aebfd4aSSean Wang 
7079aebfd4aSSean Wang 		err = mtk_hci_wmt_sync(hdev, &wmt_params);
7089aebfd4aSSean Wang 		if (err < 0) {
7099aebfd4aSSean Wang 			bt_dev_err(hdev, "Failed to send wmt patch dwnld (%d)",
7109aebfd4aSSean Wang 				   err);
7119aebfd4aSSean Wang 			goto free_fw;
7129aebfd4aSSean Wang 		}
7139aebfd4aSSean Wang 
7149aebfd4aSSean Wang 		fw_size -= dlen;
7159aebfd4aSSean Wang 		fw_ptr += dlen;
7169aebfd4aSSean Wang 	}
7179aebfd4aSSean Wang 
7189aebfd4aSSean Wang 	wmt_params.op = MTK_WMT_RST;
7199aebfd4aSSean Wang 	wmt_params.flag = 4;
7209aebfd4aSSean Wang 	wmt_params.dlen = 0;
7219aebfd4aSSean Wang 	wmt_params.data = NULL;
7229aebfd4aSSean Wang 	wmt_params.status = NULL;
7239aebfd4aSSean Wang 
7249aebfd4aSSean Wang 	/* Activate funciton the firmware providing to */
7259aebfd4aSSean Wang 	err = mtk_hci_wmt_sync(hdev, &wmt_params);
7269aebfd4aSSean Wang 	if (err < 0) {
7279aebfd4aSSean Wang 		bt_dev_err(hdev, "Failed to send wmt rst (%d)", err);
7289aebfd4aSSean Wang 		goto free_fw;
7299aebfd4aSSean Wang 	}
7309aebfd4aSSean Wang 
7319aebfd4aSSean Wang 	/* Wait a few moments for firmware activation done */
7329aebfd4aSSean Wang 	usleep_range(10000, 12000);
7339aebfd4aSSean Wang 
7349aebfd4aSSean Wang free_fw:
7359aebfd4aSSean Wang 	release_firmware(fw);
7369aebfd4aSSean Wang 	return err;
7379aebfd4aSSean Wang }
7389aebfd4aSSean Wang 
7399aebfd4aSSean Wang static int btmtksdio_setup(struct hci_dev *hdev)
7409aebfd4aSSean Wang {
7419aebfd4aSSean Wang 	struct btmtksdio_dev *bdev = hci_get_drvdata(hdev);
7429aebfd4aSSean Wang 	struct btmtk_hci_wmt_params wmt_params;
7439aebfd4aSSean Wang 	ktime_t calltime, delta, rettime;
7449aebfd4aSSean Wang 	struct btmtk_tci_sleep tci_sleep;
7459aebfd4aSSean Wang 	unsigned long long duration;
7469aebfd4aSSean Wang 	struct sk_buff *skb;
7479aebfd4aSSean Wang 	int err, status;
7489aebfd4aSSean Wang 	u8 param = 0x1;
7499aebfd4aSSean Wang 
7509aebfd4aSSean Wang 	calltime = ktime_get();
7519aebfd4aSSean Wang 
7529aebfd4aSSean Wang 	/* Query whether the firmware is already download */
7539aebfd4aSSean Wang 	wmt_params.op = MTK_WMT_SEMAPHORE;
7549aebfd4aSSean Wang 	wmt_params.flag = 1;
7559aebfd4aSSean Wang 	wmt_params.dlen = 0;
7569aebfd4aSSean Wang 	wmt_params.data = NULL;
7579aebfd4aSSean Wang 	wmt_params.status = &status;
7589aebfd4aSSean Wang 
7599aebfd4aSSean Wang 	err = mtk_hci_wmt_sync(hdev, &wmt_params);
7609aebfd4aSSean Wang 	if (err < 0) {
7619aebfd4aSSean Wang 		bt_dev_err(hdev, "Failed to query firmware status (%d)", err);
7629aebfd4aSSean Wang 		return err;
7639aebfd4aSSean Wang 	}
7649aebfd4aSSean Wang 
7659aebfd4aSSean Wang 	if (status == BTMTK_WMT_PATCH_DONE) {
7669aebfd4aSSean Wang 		bt_dev_info(hdev, "Firmware already downloaded");
7679aebfd4aSSean Wang 		goto ignore_setup_fw;
7689aebfd4aSSean Wang 	}
7699aebfd4aSSean Wang 
7709aebfd4aSSean Wang 	/* Setup a firmware which the device definitely requires */
7719aebfd4aSSean Wang 	err = mtk_setup_firmware(hdev, bdev->data->fwname);
7729aebfd4aSSean Wang 	if (err < 0)
7739aebfd4aSSean Wang 		return err;
7749aebfd4aSSean Wang 
7759aebfd4aSSean Wang ignore_setup_fw:
7769aebfd4aSSean Wang 	/* Query whether the device is already enabled */
7779aebfd4aSSean Wang 	err = readx_poll_timeout(btmtksdio_func_query, hdev, status,
7789aebfd4aSSean Wang 				 status < 0 || status != BTMTK_WMT_ON_PROGRESS,
7799aebfd4aSSean Wang 				 2000, 5000000);
7809aebfd4aSSean Wang 	/* -ETIMEDOUT happens */
7819aebfd4aSSean Wang 	if (err < 0)
7829aebfd4aSSean Wang 		return err;
7839aebfd4aSSean Wang 
7849aebfd4aSSean Wang 	/* The other errors happen in btusb_mtk_func_query */
7859aebfd4aSSean Wang 	if (status < 0)
7869aebfd4aSSean Wang 		return status;
7879aebfd4aSSean Wang 
7889aebfd4aSSean Wang 	if (status == BTMTK_WMT_ON_DONE) {
7899aebfd4aSSean Wang 		bt_dev_info(hdev, "function already on");
7909aebfd4aSSean Wang 		goto ignore_func_on;
7919aebfd4aSSean Wang 	}
7929aebfd4aSSean Wang 
7939aebfd4aSSean Wang 	/* Enable Bluetooth protocol */
7949aebfd4aSSean Wang 	wmt_params.op = MTK_WMT_FUNC_CTRL;
7959aebfd4aSSean Wang 	wmt_params.flag = 0;
7969aebfd4aSSean Wang 	wmt_params.dlen = sizeof(param);
7979aebfd4aSSean Wang 	wmt_params.data = &param;
7989aebfd4aSSean Wang 	wmt_params.status = NULL;
7999aebfd4aSSean Wang 
8009aebfd4aSSean Wang 	err = mtk_hci_wmt_sync(hdev, &wmt_params);
8019aebfd4aSSean Wang 	if (err < 0) {
8029aebfd4aSSean Wang 		bt_dev_err(hdev, "Failed to send wmt func ctrl (%d)", err);
8039aebfd4aSSean Wang 		return err;
8049aebfd4aSSean Wang 	}
8059aebfd4aSSean Wang 
8069aebfd4aSSean Wang ignore_func_on:
8079aebfd4aSSean Wang 	/* Apply the low power environment setup */
8089aebfd4aSSean Wang 	tci_sleep.mode = 0x5;
8099aebfd4aSSean Wang 	tci_sleep.duration = cpu_to_le16(0x640);
8109aebfd4aSSean Wang 	tci_sleep.host_duration = cpu_to_le16(0x640);
8119aebfd4aSSean Wang 	tci_sleep.host_wakeup_pin = 0;
8129aebfd4aSSean Wang 	tci_sleep.time_compensation = 0;
8139aebfd4aSSean Wang 
8149aebfd4aSSean Wang 	skb = __hci_cmd_sync(hdev, 0xfc7a, sizeof(tci_sleep), &tci_sleep,
8159aebfd4aSSean Wang 			     HCI_INIT_TIMEOUT);
8169aebfd4aSSean Wang 	if (IS_ERR(skb)) {
8179aebfd4aSSean Wang 		err = PTR_ERR(skb);
8189aebfd4aSSean Wang 		bt_dev_err(hdev, "Failed to apply low power setting (%d)", err);
8199aebfd4aSSean Wang 		return err;
8209aebfd4aSSean Wang 	}
8219aebfd4aSSean Wang 	kfree_skb(skb);
8229aebfd4aSSean Wang 
8239aebfd4aSSean Wang 	rettime = ktime_get();
8249aebfd4aSSean Wang 	delta = ktime_sub(rettime, calltime);
8259aebfd4aSSean Wang 	duration = (unsigned long long)ktime_to_ns(delta) >> 10;
8269aebfd4aSSean Wang 
8279aebfd4aSSean Wang 	bt_dev_info(hdev, "Device setup in %llu usecs", duration);
8289aebfd4aSSean Wang 
8299aebfd4aSSean Wang 	return 0;
8309aebfd4aSSean Wang }
8319aebfd4aSSean Wang 
8329aebfd4aSSean Wang static int btmtksdio_shutdown(struct hci_dev *hdev)
8339aebfd4aSSean Wang {
8349aebfd4aSSean Wang 	struct btmtk_hci_wmt_params wmt_params;
8359aebfd4aSSean Wang 	u8 param = 0x0;
8369aebfd4aSSean Wang 	int err;
8379aebfd4aSSean Wang 
8389aebfd4aSSean Wang 	/* Disable the device */
8399aebfd4aSSean Wang 	wmt_params.op = MTK_WMT_FUNC_CTRL;
8409aebfd4aSSean Wang 	wmt_params.flag = 0;
8419aebfd4aSSean Wang 	wmt_params.dlen = sizeof(param);
8429aebfd4aSSean Wang 	wmt_params.data = &param;
8439aebfd4aSSean Wang 	wmt_params.status = NULL;
8449aebfd4aSSean Wang 
8459aebfd4aSSean Wang 	err = mtk_hci_wmt_sync(hdev, &wmt_params);
8469aebfd4aSSean Wang 	if (err < 0) {
8479aebfd4aSSean Wang 		bt_dev_err(hdev, "Failed to send wmt func ctrl (%d)", err);
8489aebfd4aSSean Wang 		return err;
8499aebfd4aSSean Wang 	}
8509aebfd4aSSean Wang 
8519aebfd4aSSean Wang 	return 0;
8529aebfd4aSSean Wang }
8539aebfd4aSSean Wang 
8549aebfd4aSSean Wang static int btmtksdio_send_frame(struct hci_dev *hdev, struct sk_buff *skb)
8559aebfd4aSSean Wang {
8569aebfd4aSSean Wang 	struct btmtksdio_dev *bdev = hci_get_drvdata(hdev);
8579aebfd4aSSean Wang 
8589aebfd4aSSean Wang 	switch (hci_skb_pkt_type(skb)) {
8599aebfd4aSSean Wang 	case HCI_COMMAND_PKT:
8609aebfd4aSSean Wang 		hdev->stat.cmd_tx++;
8619aebfd4aSSean Wang 		break;
8629aebfd4aSSean Wang 
8639aebfd4aSSean Wang 	case HCI_ACLDATA_PKT:
8649aebfd4aSSean Wang 		hdev->stat.acl_tx++;
8659aebfd4aSSean Wang 		break;
8669aebfd4aSSean Wang 
8679aebfd4aSSean Wang 	case HCI_SCODATA_PKT:
8689aebfd4aSSean Wang 		hdev->stat.sco_tx++;
8699aebfd4aSSean Wang 		break;
8709aebfd4aSSean Wang 
8719aebfd4aSSean Wang 	default:
8729aebfd4aSSean Wang 		return -EILSEQ;
8739aebfd4aSSean Wang 	}
8749aebfd4aSSean Wang 
8759aebfd4aSSean Wang 	skb_queue_tail(&bdev->txq, skb);
8769aebfd4aSSean Wang 
8779aebfd4aSSean Wang 	schedule_work(&bdev->tx_work);
8789aebfd4aSSean Wang 
8799aebfd4aSSean Wang 	return 0;
8809aebfd4aSSean Wang }
8819aebfd4aSSean Wang 
8829aebfd4aSSean Wang static int btmtksdio_probe(struct sdio_func *func,
8839aebfd4aSSean Wang 			   const struct sdio_device_id *id)
8849aebfd4aSSean Wang {
8859aebfd4aSSean Wang 	struct btmtksdio_dev *bdev;
8869aebfd4aSSean Wang 	struct hci_dev *hdev;
8879aebfd4aSSean Wang 	int err;
8889aebfd4aSSean Wang 
8899aebfd4aSSean Wang 	bdev = devm_kzalloc(&func->dev, sizeof(*bdev), GFP_KERNEL);
8909aebfd4aSSean Wang 	if (!bdev)
8919aebfd4aSSean Wang 		return -ENOMEM;
8929aebfd4aSSean Wang 
8939aebfd4aSSean Wang 	bdev->data = (void *)id->driver_data;
8949aebfd4aSSean Wang 	if (!bdev->data)
8959aebfd4aSSean Wang 		return -ENODEV;
8969aebfd4aSSean Wang 
8979aebfd4aSSean Wang 	bdev->func = func;
8989aebfd4aSSean Wang 
8999aebfd4aSSean Wang 	INIT_WORK(&bdev->tx_work, btmtksdio_tx_work);
9009aebfd4aSSean Wang 	skb_queue_head_init(&bdev->txq);
9019aebfd4aSSean Wang 
9029aebfd4aSSean Wang 	/* Initialize and register HCI device */
9039aebfd4aSSean Wang 	hdev = hci_alloc_dev();
9049aebfd4aSSean Wang 	if (!hdev) {
9059aebfd4aSSean Wang 		dev_err(&func->dev, "Can't allocate HCI device\n");
9069aebfd4aSSean Wang 		return -ENOMEM;
9079aebfd4aSSean Wang 	}
9089aebfd4aSSean Wang 
9099aebfd4aSSean Wang 	bdev->hdev = hdev;
9109aebfd4aSSean Wang 
9119aebfd4aSSean Wang 	hdev->bus = HCI_SDIO;
9129aebfd4aSSean Wang 	hci_set_drvdata(hdev, bdev);
9139aebfd4aSSean Wang 
9149aebfd4aSSean Wang 	hdev->open     = btmtksdio_open;
9159aebfd4aSSean Wang 	hdev->close    = btmtksdio_close;
9169aebfd4aSSean Wang 	hdev->flush    = btmtksdio_flush;
9179aebfd4aSSean Wang 	hdev->setup    = btmtksdio_setup;
9189aebfd4aSSean Wang 	hdev->shutdown = btmtksdio_shutdown;
9199aebfd4aSSean Wang 	hdev->send     = btmtksdio_send_frame;
9209aebfd4aSSean Wang 	SET_HCIDEV_DEV(hdev, &func->dev);
9219aebfd4aSSean Wang 
9229aebfd4aSSean Wang 	hdev->manufacturer = 70;
9239aebfd4aSSean Wang 	set_bit(HCI_QUIRK_NON_PERSISTENT_SETUP, &hdev->quirks);
9249aebfd4aSSean Wang 
9259aebfd4aSSean Wang 	err = hci_register_dev(hdev);
9269aebfd4aSSean Wang 	if (err < 0) {
9279aebfd4aSSean Wang 		dev_err(&func->dev, "Can't register HCI device\n");
9289aebfd4aSSean Wang 		hci_free_dev(hdev);
9299aebfd4aSSean Wang 		return err;
9309aebfd4aSSean Wang 	}
9319aebfd4aSSean Wang 
9329aebfd4aSSean Wang 	sdio_set_drvdata(func, bdev);
9339aebfd4aSSean Wang 
9349aebfd4aSSean Wang 	return 0;
9359aebfd4aSSean Wang }
9369aebfd4aSSean Wang 
9379aebfd4aSSean Wang static void btmtksdio_remove(struct sdio_func *func)
9389aebfd4aSSean Wang {
9399aebfd4aSSean Wang 	struct btmtksdio_dev *bdev = sdio_get_drvdata(func);
9409aebfd4aSSean Wang 	struct hci_dev *hdev;
9419aebfd4aSSean Wang 
9429aebfd4aSSean Wang 	if (!bdev)
9439aebfd4aSSean Wang 		return;
9449aebfd4aSSean Wang 
9459aebfd4aSSean Wang 	hdev = bdev->hdev;
9469aebfd4aSSean Wang 
9479aebfd4aSSean Wang 	sdio_set_drvdata(func, NULL);
9489aebfd4aSSean Wang 	hci_unregister_dev(hdev);
9499aebfd4aSSean Wang 	hci_free_dev(hdev);
9509aebfd4aSSean Wang }
9519aebfd4aSSean Wang 
9529aebfd4aSSean Wang static struct sdio_driver btmtksdio_driver = {
9539aebfd4aSSean Wang 	.name		= "btmtksdio",
9549aebfd4aSSean Wang 	.probe		= btmtksdio_probe,
9559aebfd4aSSean Wang 	.remove		= btmtksdio_remove,
9569aebfd4aSSean Wang 	.id_table	= btmtksdio_table,
9579aebfd4aSSean Wang };
9589aebfd4aSSean Wang 
9599aebfd4aSSean Wang static int __init btmtksdio_init(void)
9609aebfd4aSSean Wang {
9619aebfd4aSSean Wang 	BT_INFO("MediaTek Bluetooth SDIO driver ver %s", VERSION);
9629aebfd4aSSean Wang 
9639aebfd4aSSean Wang 	return sdio_register_driver(&btmtksdio_driver);
9649aebfd4aSSean Wang }
9659aebfd4aSSean Wang 
9669aebfd4aSSean Wang static void __exit btmtksdio_exit(void)
9679aebfd4aSSean Wang {
9689aebfd4aSSean Wang 	sdio_unregister_driver(&btmtksdio_driver);
9699aebfd4aSSean Wang }
9709aebfd4aSSean Wang 
9719aebfd4aSSean Wang module_init(btmtksdio_init);
9729aebfd4aSSean Wang module_exit(btmtksdio_exit);
9739aebfd4aSSean Wang 
9749aebfd4aSSean Wang MODULE_AUTHOR("Sean Wang <sean.wang@mediatek.com>");
9759aebfd4aSSean Wang MODULE_DESCRIPTION("MediaTek Bluetooth SDIO driver ver " VERSION);
9769aebfd4aSSean Wang MODULE_VERSION(VERSION);
9779aebfd4aSSean Wang MODULE_LICENSE("GPL");
9789aebfd4aSSean Wang MODULE_FIRMWARE(FIRMWARE_MT7663);
9799aebfd4aSSean Wang MODULE_FIRMWARE(FIRMWARE_MT7668);
980