xref: /openbmc/linux/drivers/bluetooth/btmtksdio.c (revision 095519de)
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/init.h>
169aebfd4aSSean Wang #include <linux/iopoll.h>
179aebfd4aSSean Wang #include <linux/kernel.h>
189aebfd4aSSean Wang #include <linux/module.h>
197f3c563cSSean Wang #include <linux/pm_runtime.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"
303a722044SSean Wang #include "btmtk.h"
319aebfd4aSSean Wang 
329aebfd4aSSean Wang #define VERSION "0.1"
339aebfd4aSSean Wang 
347f3c563cSSean Wang #define MTKBTSDIO_AUTOSUSPEND_DELAY	8000
357f3c563cSSean Wang 
367f3c563cSSean Wang static bool enable_autosuspend;
377f3c563cSSean Wang 
389aebfd4aSSean Wang struct btmtksdio_data {
399aebfd4aSSean Wang 	const char *fwname;
40c603bf1fSSean Wang 	u16 chipid;
4101ecc177SMark Chen 	bool lp_mbox_supported;
429aebfd4aSSean Wang };
439aebfd4aSSean Wang 
449aebfd4aSSean Wang static const struct btmtksdio_data mt7663_data = {
459aebfd4aSSean Wang 	.fwname = FIRMWARE_MT7663,
46c603bf1fSSean Wang 	.chipid = 0x7663,
4701ecc177SMark Chen 	.lp_mbox_supported = false,
489aebfd4aSSean Wang };
499aebfd4aSSean Wang 
509aebfd4aSSean Wang static const struct btmtksdio_data mt7668_data = {
519aebfd4aSSean Wang 	.fwname = FIRMWARE_MT7668,
52c603bf1fSSean Wang 	.chipid = 0x7668,
5301ecc177SMark Chen 	.lp_mbox_supported = false,
54c603bf1fSSean Wang };
55c603bf1fSSean Wang 
56c603bf1fSSean Wang static const struct btmtksdio_data mt7921_data = {
57c603bf1fSSean Wang 	.fwname = FIRMWARE_MT7961,
58c603bf1fSSean Wang 	.chipid = 0x7921,
5901ecc177SMark Chen 	.lp_mbox_supported = true,
609aebfd4aSSean Wang };
619aebfd4aSSean Wang 
629aebfd4aSSean Wang static const struct sdio_device_id btmtksdio_table[] = {
63baaa110dSPali Rohár 	{SDIO_DEVICE(SDIO_VENDOR_ID_MEDIATEK, SDIO_DEVICE_ID_MEDIATEK_MT7663),
649aebfd4aSSean Wang 	 .driver_data = (kernel_ulong_t)&mt7663_data },
65baaa110dSPali Rohár 	{SDIO_DEVICE(SDIO_VENDOR_ID_MEDIATEK, SDIO_DEVICE_ID_MEDIATEK_MT7668),
669aebfd4aSSean Wang 	 .driver_data = (kernel_ulong_t)&mt7668_data },
67c603bf1fSSean Wang 	{SDIO_DEVICE(SDIO_VENDOR_ID_MEDIATEK, SDIO_DEVICE_ID_MEDIATEK_MT7961),
68c603bf1fSSean Wang 	 .driver_data = (kernel_ulong_t)&mt7921_data },
699aebfd4aSSean Wang 	{ }	/* Terminating entry */
709aebfd4aSSean Wang };
7153121a7cSBartosz Golaszewski MODULE_DEVICE_TABLE(sdio, btmtksdio_table);
729aebfd4aSSean Wang 
739aebfd4aSSean Wang #define MTK_REG_CHLPCR		0x4	/* W1S */
749aebfd4aSSean Wang #define C_INT_EN_SET		BIT(0)
759aebfd4aSSean Wang #define C_INT_EN_CLR		BIT(1)
762e47cc2bSSean Wang #define C_FW_OWN_REQ_SET	BIT(8)  /* For write */
772e47cc2bSSean Wang #define C_COM_DRV_OWN		BIT(8)  /* For read */
789aebfd4aSSean Wang #define C_FW_OWN_REQ_CLR	BIT(9)
799aebfd4aSSean Wang 
809aebfd4aSSean Wang #define MTK_REG_CSDIOCSR	0x8
819aebfd4aSSean Wang #define SDIO_RE_INIT_EN		BIT(0)
829aebfd4aSSean Wang #define SDIO_INT_CTL		BIT(2)
839aebfd4aSSean Wang 
849aebfd4aSSean Wang #define MTK_REG_CHCR		0xc
859aebfd4aSSean Wang #define C_INT_CLR_CTRL		BIT(1)
869aebfd4aSSean Wang 
879aebfd4aSSean Wang /* CHISR have the same bits field definition with CHIER */
889aebfd4aSSean Wang #define MTK_REG_CHISR		0x10
899aebfd4aSSean Wang #define MTK_REG_CHIER		0x14
909aebfd4aSSean Wang #define FW_OWN_BACK_INT		BIT(0)
919aebfd4aSSean Wang #define RX_DONE_INT		BIT(1)
929aebfd4aSSean Wang #define TX_EMPTY		BIT(2)
939aebfd4aSSean Wang #define TX_FIFO_OVERFLOW	BIT(8)
942fc967ccSMark Chen #define FW_MAILBOX_INT		BIT(15)
959aebfd4aSSean Wang #define RX_PKT_LEN		GENMASK(31, 16)
969aebfd4aSSean Wang 
9701ecc177SMark Chen #define MTK_REG_CSICR		0xc0
9801ecc177SMark Chen #define CSICR_CLR_MBOX_ACK BIT(0)
992fc967ccSMark Chen #define MTK_REG_PH2DSM0R	0xc4
1002fc967ccSMark Chen #define PH2DSM0R_DRIVER_OWN	BIT(0)
10101ecc177SMark Chen #define MTK_REG_PD2HRM0R	0xdc
10201ecc177SMark Chen #define PD2HRM0R_DRV_OWN	BIT(0)
1032fc967ccSMark Chen 
1049aebfd4aSSean Wang #define MTK_REG_CTDR		0x18
1059aebfd4aSSean Wang 
1069aebfd4aSSean Wang #define MTK_REG_CRDR		0x1c
1079aebfd4aSSean Wang 
108184ea403SSean Wang #define MTK_REG_CRPLR		0x24
109184ea403SSean Wang 
1109aebfd4aSSean Wang #define MTK_SDIO_BLOCK_SIZE	256
1119aebfd4aSSean Wang 
1129aebfd4aSSean Wang #define BTMTKSDIO_TX_WAIT_VND_EVT	1
113d555b1f2SSean Wang #define BTMTKSDIO_HW_TX_READY		2
1144b4b2228SSean Wang #define BTMTKSDIO_FUNC_ENABLED		3
11501ecc177SMark Chen #define BTMTKSDIO_PATCH_ENABLED		4
1169aebfd4aSSean Wang 
1179aebfd4aSSean Wang struct mtkbtsdio_hdr {
1189aebfd4aSSean Wang 	__le16	len;
1199aebfd4aSSean Wang 	__le16	reserved;
1209aebfd4aSSean Wang 	u8	bt_type;
1219aebfd4aSSean Wang } __packed;
1229aebfd4aSSean Wang 
1239aebfd4aSSean Wang struct btmtksdio_dev {
1249aebfd4aSSean Wang 	struct hci_dev *hdev;
1259aebfd4aSSean Wang 	struct sdio_func *func;
1267f3c563cSSean Wang 	struct device *dev;
1279aebfd4aSSean Wang 
12826270bc1SSean Wang 	struct work_struct txrx_work;
1299aebfd4aSSean Wang 	unsigned long tx_state;
1309aebfd4aSSean Wang 	struct sk_buff_head txq;
1319aebfd4aSSean Wang 
1329aebfd4aSSean Wang 	struct sk_buff *evt_skb;
1339aebfd4aSSean Wang 
1349aebfd4aSSean Wang 	const struct btmtksdio_data *data;
1359aebfd4aSSean Wang };
1369aebfd4aSSean Wang 
1379aebfd4aSSean Wang static int mtk_hci_wmt_sync(struct hci_dev *hdev,
1389aebfd4aSSean Wang 			    struct btmtk_hci_wmt_params *wmt_params)
1399aebfd4aSSean Wang {
1409aebfd4aSSean Wang 	struct btmtksdio_dev *bdev = hci_get_drvdata(hdev);
1419aebfd4aSSean Wang 	struct btmtk_hci_wmt_evt_funcc *wmt_evt_funcc;
142c603bf1fSSean Wang 	struct btmtk_hci_wmt_evt_reg *wmt_evt_reg;
1439aebfd4aSSean Wang 	u32 hlen, status = BTMTK_WMT_INVALID;
1449aebfd4aSSean Wang 	struct btmtk_hci_wmt_evt *wmt_evt;
1453a722044SSean Wang 	struct btmtk_hci_wmt_cmd *wc;
1463a722044SSean Wang 	struct btmtk_wmt_hdr *hdr;
1479aebfd4aSSean Wang 	int err;
1489aebfd4aSSean Wang 
1493a722044SSean Wang 	/* Send the WMT command and wait until the WMT event returns */
1509aebfd4aSSean Wang 	hlen = sizeof(*hdr) + wmt_params->dlen;
1519aebfd4aSSean Wang 	if (hlen > 255)
1529aebfd4aSSean Wang 		return -EINVAL;
1539aebfd4aSSean Wang 
1543a722044SSean Wang 	wc = kzalloc(hlen, GFP_KERNEL);
1553a722044SSean Wang 	if (!wc)
1563a722044SSean Wang 		return -ENOMEM;
1573a722044SSean Wang 
1583a722044SSean Wang 	hdr = &wc->hdr;
1599aebfd4aSSean Wang 	hdr->dir = 1;
1609aebfd4aSSean Wang 	hdr->op = wmt_params->op;
1619aebfd4aSSean Wang 	hdr->dlen = cpu_to_le16(wmt_params->dlen + 1);
1629aebfd4aSSean Wang 	hdr->flag = wmt_params->flag;
1633a722044SSean Wang 	memcpy(wc->data, wmt_params->data, wmt_params->dlen);
1649aebfd4aSSean Wang 
1659aebfd4aSSean Wang 	set_bit(BTMTKSDIO_TX_WAIT_VND_EVT, &bdev->tx_state);
1669aebfd4aSSean Wang 
1673a722044SSean Wang 	err = __hci_cmd_send(hdev, 0xfc6f, hlen, wc);
1689aebfd4aSSean Wang 	if (err < 0) {
1699aebfd4aSSean Wang 		clear_bit(BTMTKSDIO_TX_WAIT_VND_EVT, &bdev->tx_state);
1703a722044SSean Wang 		goto err_free_wc;
1719aebfd4aSSean Wang 	}
1729aebfd4aSSean Wang 
1739aebfd4aSSean Wang 	/* The vendor specific WMT commands are all answered by a vendor
1749aebfd4aSSean Wang 	 * specific event and will not have the Command Status or Command
1759aebfd4aSSean Wang 	 * Complete as with usual HCI command flow control.
1769aebfd4aSSean Wang 	 *
1779aebfd4aSSean Wang 	 * After sending the command, wait for BTMTKSDIO_TX_WAIT_VND_EVT
1789aebfd4aSSean Wang 	 * state to be cleared. The driver specific event receive routine
1799aebfd4aSSean Wang 	 * will clear that state and with that indicate completion of the
1809aebfd4aSSean Wang 	 * WMT command.
1819aebfd4aSSean Wang 	 */
1829aebfd4aSSean Wang 	err = wait_on_bit_timeout(&bdev->tx_state, BTMTKSDIO_TX_WAIT_VND_EVT,
1839aebfd4aSSean Wang 				  TASK_INTERRUPTIBLE, HCI_INIT_TIMEOUT);
1849aebfd4aSSean Wang 	if (err == -EINTR) {
1859aebfd4aSSean Wang 		bt_dev_err(hdev, "Execution of wmt command interrupted");
1869aebfd4aSSean Wang 		clear_bit(BTMTKSDIO_TX_WAIT_VND_EVT, &bdev->tx_state);
1873a722044SSean Wang 		goto err_free_wc;
1889aebfd4aSSean Wang 	}
1899aebfd4aSSean Wang 
1909aebfd4aSSean Wang 	if (err) {
1919aebfd4aSSean Wang 		bt_dev_err(hdev, "Execution of wmt command timed out");
1929aebfd4aSSean Wang 		clear_bit(BTMTKSDIO_TX_WAIT_VND_EVT, &bdev->tx_state);
1933a722044SSean Wang 		err = -ETIMEDOUT;
1943a722044SSean Wang 		goto err_free_wc;
1959aebfd4aSSean Wang 	}
1969aebfd4aSSean Wang 
1979aebfd4aSSean Wang 	/* Parse and handle the return WMT event */
1989aebfd4aSSean Wang 	wmt_evt = (struct btmtk_hci_wmt_evt *)bdev->evt_skb->data;
1999aebfd4aSSean Wang 	if (wmt_evt->whdr.op != hdr->op) {
2009aebfd4aSSean Wang 		bt_dev_err(hdev, "Wrong op received %d expected %d",
2019aebfd4aSSean Wang 			   wmt_evt->whdr.op, hdr->op);
2029aebfd4aSSean Wang 		err = -EIO;
2039aebfd4aSSean Wang 		goto err_free_skb;
2049aebfd4aSSean Wang 	}
2059aebfd4aSSean Wang 
2069aebfd4aSSean Wang 	switch (wmt_evt->whdr.op) {
2073a722044SSean Wang 	case BTMTK_WMT_SEMAPHORE:
2089aebfd4aSSean Wang 		if (wmt_evt->whdr.flag == 2)
2099aebfd4aSSean Wang 			status = BTMTK_WMT_PATCH_UNDONE;
2109aebfd4aSSean Wang 		else
2119aebfd4aSSean Wang 			status = BTMTK_WMT_PATCH_DONE;
2129aebfd4aSSean Wang 		break;
2133a722044SSean Wang 	case BTMTK_WMT_FUNC_CTRL:
2149aebfd4aSSean Wang 		wmt_evt_funcc = (struct btmtk_hci_wmt_evt_funcc *)wmt_evt;
2159aebfd4aSSean Wang 		if (be16_to_cpu(wmt_evt_funcc->status) == 0x404)
2169aebfd4aSSean Wang 			status = BTMTK_WMT_ON_DONE;
2179aebfd4aSSean Wang 		else if (be16_to_cpu(wmt_evt_funcc->status) == 0x420)
2189aebfd4aSSean Wang 			status = BTMTK_WMT_ON_PROGRESS;
2199aebfd4aSSean Wang 		else
2209aebfd4aSSean Wang 			status = BTMTK_WMT_ON_UNDONE;
2219aebfd4aSSean Wang 		break;
222c603bf1fSSean Wang 	case BTMTK_WMT_PATCH_DWNLD:
223c603bf1fSSean Wang 		if (wmt_evt->whdr.flag == 2)
224c603bf1fSSean Wang 			status = BTMTK_WMT_PATCH_DONE;
225c603bf1fSSean Wang 		else if (wmt_evt->whdr.flag == 1)
226c603bf1fSSean Wang 			status = BTMTK_WMT_PATCH_PROGRESS;
227c603bf1fSSean Wang 		else
228c603bf1fSSean Wang 			status = BTMTK_WMT_PATCH_UNDONE;
229c603bf1fSSean Wang 		break;
230c603bf1fSSean Wang 	case BTMTK_WMT_REGISTER:
231c603bf1fSSean Wang 		wmt_evt_reg = (struct btmtk_hci_wmt_evt_reg *)wmt_evt;
232c603bf1fSSean Wang 		if (le16_to_cpu(wmt_evt->whdr.dlen) == 12)
233c603bf1fSSean Wang 			status = le32_to_cpu(wmt_evt_reg->val);
234c603bf1fSSean Wang 		break;
2359aebfd4aSSean Wang 	}
2369aebfd4aSSean Wang 
2379aebfd4aSSean Wang 	if (wmt_params->status)
2389aebfd4aSSean Wang 		*wmt_params->status = status;
2399aebfd4aSSean Wang 
2409aebfd4aSSean Wang err_free_skb:
2419aebfd4aSSean Wang 	kfree_skb(bdev->evt_skb);
2429aebfd4aSSean Wang 	bdev->evt_skb = NULL;
2433a722044SSean Wang err_free_wc:
2443a722044SSean Wang 	kfree(wc);
2459aebfd4aSSean Wang 
2469aebfd4aSSean Wang 	return err;
2479aebfd4aSSean Wang }
2489aebfd4aSSean Wang 
2499aebfd4aSSean Wang static int btmtksdio_tx_packet(struct btmtksdio_dev *bdev,
2509aebfd4aSSean Wang 			       struct sk_buff *skb)
2519aebfd4aSSean Wang {
2529aebfd4aSSean Wang 	struct mtkbtsdio_hdr *sdio_hdr;
2539aebfd4aSSean Wang 	int err;
2549aebfd4aSSean Wang 
2559aebfd4aSSean Wang 	/* Make sure that there are enough rooms for SDIO header */
2569aebfd4aSSean Wang 	if (unlikely(skb_headroom(skb) < sizeof(*sdio_hdr))) {
2579aebfd4aSSean Wang 		err = pskb_expand_head(skb, sizeof(*sdio_hdr), 0,
2589aebfd4aSSean Wang 				       GFP_ATOMIC);
2599aebfd4aSSean Wang 		if (err < 0)
2609aebfd4aSSean Wang 			return err;
2619aebfd4aSSean Wang 	}
2629aebfd4aSSean Wang 
2639aebfd4aSSean Wang 	/* Prepend MediaTek SDIO Specific Header */
2649aebfd4aSSean Wang 	skb_push(skb, sizeof(*sdio_hdr));
2659aebfd4aSSean Wang 
2669aebfd4aSSean Wang 	sdio_hdr = (void *)skb->data;
2679aebfd4aSSean Wang 	sdio_hdr->len = cpu_to_le16(skb->len);
2689aebfd4aSSean Wang 	sdio_hdr->reserved = cpu_to_le16(0);
2699aebfd4aSSean Wang 	sdio_hdr->bt_type = hci_skb_pkt_type(skb);
2709aebfd4aSSean Wang 
271d555b1f2SSean Wang 	clear_bit(BTMTKSDIO_HW_TX_READY, &bdev->tx_state);
2729aebfd4aSSean Wang 	err = sdio_writesb(bdev->func, MTK_REG_CTDR, skb->data,
2739aebfd4aSSean Wang 			   round_up(skb->len, MTK_SDIO_BLOCK_SIZE));
2749aebfd4aSSean Wang 	if (err < 0)
2759aebfd4aSSean Wang 		goto err_skb_pull;
2769aebfd4aSSean Wang 
2779aebfd4aSSean Wang 	bdev->hdev->stat.byte_tx += skb->len;
2789aebfd4aSSean Wang 
2799aebfd4aSSean Wang 	kfree_skb(skb);
2809aebfd4aSSean Wang 
2819aebfd4aSSean Wang 	return 0;
2829aebfd4aSSean Wang 
2839aebfd4aSSean Wang err_skb_pull:
2849aebfd4aSSean Wang 	skb_pull(skb, sizeof(*sdio_hdr));
2859aebfd4aSSean Wang 
2869aebfd4aSSean Wang 	return err;
2879aebfd4aSSean Wang }
2889aebfd4aSSean Wang 
2899aebfd4aSSean Wang static u32 btmtksdio_drv_own_query(struct btmtksdio_dev *bdev)
2909aebfd4aSSean Wang {
2919aebfd4aSSean Wang 	return sdio_readl(bdev->func, MTK_REG_CHLPCR, NULL);
2929aebfd4aSSean Wang }
2939aebfd4aSSean Wang 
29401ecc177SMark Chen static u32 btmtksdio_drv_own_query_79xx(struct btmtksdio_dev *bdev)
29501ecc177SMark Chen {
29601ecc177SMark Chen 	return sdio_readl(bdev->func, MTK_REG_PD2HRM0R, NULL);
29701ecc177SMark Chen }
29801ecc177SMark Chen 
299c7e301d7SMark Chen static int btmtksdio_fw_pmctrl(struct btmtksdio_dev *bdev)
300c7e301d7SMark Chen {
301c7e301d7SMark Chen 	u32 status;
302c7e301d7SMark Chen 	int err;
303c7e301d7SMark Chen 
304c7e301d7SMark Chen 	sdio_claim_host(bdev->func);
305c7e301d7SMark Chen 
30601ecc177SMark Chen 	if (bdev->data->lp_mbox_supported &&
30701ecc177SMark Chen 	    test_bit(BTMTKSDIO_PATCH_ENABLED, &bdev->tx_state)) {
30801ecc177SMark Chen 		sdio_writel(bdev->func, CSICR_CLR_MBOX_ACK, MTK_REG_CSICR,
30901ecc177SMark Chen 			    &err);
31001ecc177SMark Chen 		err = readx_poll_timeout(btmtksdio_drv_own_query_79xx, bdev,
31101ecc177SMark Chen 					 status, !(status & PD2HRM0R_DRV_OWN),
31201ecc177SMark Chen 					 2000, 1000000);
31301ecc177SMark Chen 		if (err < 0) {
31401ecc177SMark Chen 			bt_dev_err(bdev->hdev, "mailbox ACK not cleared");
31501ecc177SMark Chen 			goto out;
31601ecc177SMark Chen 		}
31701ecc177SMark Chen 	}
31801ecc177SMark Chen 
319c7e301d7SMark Chen 	/* Return ownership to the device */
320c7e301d7SMark Chen 	sdio_writel(bdev->func, C_FW_OWN_REQ_SET, MTK_REG_CHLPCR, &err);
321c7e301d7SMark Chen 	if (err < 0)
322c7e301d7SMark Chen 		goto out;
323c7e301d7SMark Chen 
324c7e301d7SMark Chen 	err = readx_poll_timeout(btmtksdio_drv_own_query, bdev, status,
325c7e301d7SMark Chen 				 !(status & C_COM_DRV_OWN), 2000, 1000000);
326c7e301d7SMark Chen 
327c7e301d7SMark Chen out:
328c7e301d7SMark Chen 	sdio_release_host(bdev->func);
329c7e301d7SMark Chen 
330c7e301d7SMark Chen 	if (err < 0)
331c7e301d7SMark Chen 		bt_dev_err(bdev->hdev, "Cannot return ownership to device");
332c7e301d7SMark Chen 
333c7e301d7SMark Chen 	return err;
334c7e301d7SMark Chen }
335c7e301d7SMark Chen 
336c7e301d7SMark Chen static int btmtksdio_drv_pmctrl(struct btmtksdio_dev *bdev)
337c7e301d7SMark Chen {
338c7e301d7SMark Chen 	u32 status;
339c7e301d7SMark Chen 	int err;
340c7e301d7SMark Chen 
341c7e301d7SMark Chen 	sdio_claim_host(bdev->func);
342c7e301d7SMark Chen 
343c7e301d7SMark Chen 	/* Get ownership from the device */
344c7e301d7SMark Chen 	sdio_writel(bdev->func, C_FW_OWN_REQ_CLR, MTK_REG_CHLPCR, &err);
345c7e301d7SMark Chen 	if (err < 0)
346c7e301d7SMark Chen 		goto out;
347c7e301d7SMark Chen 
348c7e301d7SMark Chen 	err = readx_poll_timeout(btmtksdio_drv_own_query, bdev, status,
349c7e301d7SMark Chen 				 status & C_COM_DRV_OWN, 2000, 1000000);
350c7e301d7SMark Chen 
35101ecc177SMark Chen 	if (!err && bdev->data->lp_mbox_supported &&
35201ecc177SMark Chen 	    test_bit(BTMTKSDIO_PATCH_ENABLED, &bdev->tx_state))
35301ecc177SMark Chen 		err = readx_poll_timeout(btmtksdio_drv_own_query_79xx, bdev,
35401ecc177SMark Chen 					 status, status & PD2HRM0R_DRV_OWN,
35501ecc177SMark Chen 					 2000, 1000000);
35601ecc177SMark Chen 
357c7e301d7SMark Chen out:
358c7e301d7SMark Chen 	sdio_release_host(bdev->func);
359c7e301d7SMark Chen 
360c7e301d7SMark Chen 	if (err < 0)
361c7e301d7SMark Chen 		bt_dev_err(bdev->hdev, "Cannot get ownership from device");
362c7e301d7SMark Chen 
363c7e301d7SMark Chen 	return err;
364c7e301d7SMark Chen }
365c7e301d7SMark Chen 
3669aebfd4aSSean Wang static int btmtksdio_recv_event(struct hci_dev *hdev, struct sk_buff *skb)
3679aebfd4aSSean Wang {
3689aebfd4aSSean Wang 	struct btmtksdio_dev *bdev = hci_get_drvdata(hdev);
3699aebfd4aSSean Wang 	struct hci_event_hdr *hdr = (void *)skb->data;
3709aebfd4aSSean Wang 	int err;
3719aebfd4aSSean Wang 
3729aebfd4aSSean Wang 	/* Fix up the vendor event id with 0xff for vendor specific instead
3739aebfd4aSSean Wang 	 * of 0xe4 so that event send via monitoring socket can be parsed
3749aebfd4aSSean Wang 	 * properly.
3759aebfd4aSSean Wang 	 */
3769aebfd4aSSean Wang 	if (hdr->evt == 0xe4)
3779aebfd4aSSean Wang 		hdr->evt = HCI_EV_VENDOR;
3789aebfd4aSSean Wang 
3799aebfd4aSSean Wang 	/* When someone waits for the WMT event, the skb is being cloned
3809aebfd4aSSean Wang 	 * and being processed the events from there then.
3819aebfd4aSSean Wang 	 */
3829aebfd4aSSean Wang 	if (test_bit(BTMTKSDIO_TX_WAIT_VND_EVT, &bdev->tx_state)) {
3839aebfd4aSSean Wang 		bdev->evt_skb = skb_clone(skb, GFP_KERNEL);
3849aebfd4aSSean Wang 		if (!bdev->evt_skb) {
3859aebfd4aSSean Wang 			err = -ENOMEM;
3869aebfd4aSSean Wang 			goto err_out;
3879aebfd4aSSean Wang 		}
3889aebfd4aSSean Wang 	}
3899aebfd4aSSean Wang 
3909aebfd4aSSean Wang 	err = hci_recv_frame(hdev, skb);
3919aebfd4aSSean Wang 	if (err < 0)
3929aebfd4aSSean Wang 		goto err_free_skb;
3939aebfd4aSSean Wang 
3949aebfd4aSSean Wang 	if (hdr->evt == HCI_EV_VENDOR) {
3959aebfd4aSSean Wang 		if (test_and_clear_bit(BTMTKSDIO_TX_WAIT_VND_EVT,
3969aebfd4aSSean Wang 				       &bdev->tx_state)) {
3979aebfd4aSSean Wang 			/* Barrier to sync with other CPUs */
3989aebfd4aSSean Wang 			smp_mb__after_atomic();
3999aebfd4aSSean Wang 			wake_up_bit(&bdev->tx_state, BTMTKSDIO_TX_WAIT_VND_EVT);
4009aebfd4aSSean Wang 		}
4019aebfd4aSSean Wang 	}
4029aebfd4aSSean Wang 
4039aebfd4aSSean Wang 	return 0;
4049aebfd4aSSean Wang 
4059aebfd4aSSean Wang err_free_skb:
4069aebfd4aSSean Wang 	kfree_skb(bdev->evt_skb);
4079aebfd4aSSean Wang 	bdev->evt_skb = NULL;
4089aebfd4aSSean Wang 
4099aebfd4aSSean Wang err_out:
4109aebfd4aSSean Wang 	return err;
4119aebfd4aSSean Wang }
4129aebfd4aSSean Wang 
413db57b625SSean Wang static int btmtksdio_recv_acl(struct hci_dev *hdev, struct sk_buff *skb)
414db57b625SSean Wang {
415db57b625SSean Wang 	struct btmtksdio_dev *bdev = hci_get_drvdata(hdev);
416db57b625SSean Wang 	u16 handle = le16_to_cpu(hci_acl_hdr(skb)->handle);
417db57b625SSean Wang 
418db57b625SSean Wang 	switch (handle) {
419db57b625SSean Wang 	case 0xfc6f:
420db57b625SSean Wang 		/* Firmware dump from device: when the firmware hangs, the
421db57b625SSean Wang 		 * device can no longer suspend and thus disable auto-suspend.
422db57b625SSean Wang 		 */
423db57b625SSean Wang 		pm_runtime_forbid(bdev->dev);
424db57b625SSean Wang 		fallthrough;
425db57b625SSean Wang 	case 0x05ff:
426db57b625SSean Wang 	case 0x05fe:
427db57b625SSean Wang 		/* Firmware debug logging */
428db57b625SSean Wang 		return hci_recv_diag(hdev, skb);
429db57b625SSean Wang 	}
430db57b625SSean Wang 
431db57b625SSean Wang 	return hci_recv_frame(hdev, skb);
432db57b625SSean Wang }
433db57b625SSean Wang 
4349aebfd4aSSean Wang static const struct h4_recv_pkt mtk_recv_pkts[] = {
435db57b625SSean Wang 	{ H4_RECV_ACL,      .recv = btmtksdio_recv_acl },
4369aebfd4aSSean Wang 	{ H4_RECV_SCO,      .recv = hci_recv_frame },
4379aebfd4aSSean Wang 	{ H4_RECV_EVENT,    .recv = btmtksdio_recv_event },
4389aebfd4aSSean Wang };
4399aebfd4aSSean Wang 
4409aebfd4aSSean Wang static int btmtksdio_rx_packet(struct btmtksdio_dev *bdev, u16 rx_size)
4419aebfd4aSSean Wang {
4429aebfd4aSSean Wang 	const struct h4_recv_pkt *pkts = mtk_recv_pkts;
4439aebfd4aSSean Wang 	int pkts_count = ARRAY_SIZE(mtk_recv_pkts);
4449aebfd4aSSean Wang 	struct mtkbtsdio_hdr *sdio_hdr;
4459aebfd4aSSean Wang 	int err, i, pad_size;
4469aebfd4aSSean Wang 	struct sk_buff *skb;
4479aebfd4aSSean Wang 	u16 dlen;
4489aebfd4aSSean Wang 
4499aebfd4aSSean Wang 	if (rx_size < sizeof(*sdio_hdr))
4509aebfd4aSSean Wang 		return -EILSEQ;
4519aebfd4aSSean Wang 
4529aebfd4aSSean Wang 	/* A SDIO packet is exactly containing a Bluetooth packet */
4539aebfd4aSSean Wang 	skb = bt_skb_alloc(rx_size, GFP_KERNEL);
4549aebfd4aSSean Wang 	if (!skb)
4559aebfd4aSSean Wang 		return -ENOMEM;
4569aebfd4aSSean Wang 
4579aebfd4aSSean Wang 	skb_put(skb, rx_size);
4589aebfd4aSSean Wang 
4599aebfd4aSSean Wang 	err = sdio_readsb(bdev->func, skb->data, MTK_REG_CRDR, rx_size);
4609aebfd4aSSean Wang 	if (err < 0)
4619aebfd4aSSean Wang 		goto err_kfree_skb;
4629aebfd4aSSean Wang 
4639aebfd4aSSean Wang 	sdio_hdr = (void *)skb->data;
4649aebfd4aSSean Wang 
4659aebfd4aSSean Wang 	/* We assume the default error as -EILSEQ simply to make the error path
4669aebfd4aSSean Wang 	 * be cleaner.
4679aebfd4aSSean Wang 	 */
4689aebfd4aSSean Wang 	err = -EILSEQ;
4699aebfd4aSSean Wang 
4709aebfd4aSSean Wang 	if (rx_size != le16_to_cpu(sdio_hdr->len)) {
4719aebfd4aSSean Wang 		bt_dev_err(bdev->hdev, "Rx size in sdio header is mismatched ");
4729aebfd4aSSean Wang 		goto err_kfree_skb;
4739aebfd4aSSean Wang 	}
4749aebfd4aSSean Wang 
4759aebfd4aSSean Wang 	hci_skb_pkt_type(skb) = sdio_hdr->bt_type;
4769aebfd4aSSean Wang 
4779aebfd4aSSean Wang 	/* Remove MediaTek SDIO header */
4789aebfd4aSSean Wang 	skb_pull(skb, sizeof(*sdio_hdr));
4799aebfd4aSSean Wang 
4809aebfd4aSSean Wang 	/* We have to dig into the packet to get payload size and then know how
4819aebfd4aSSean Wang 	 * many padding bytes at the tail, these padding bytes should be removed
4829aebfd4aSSean Wang 	 * before the packet is indicated to the core layer.
4839aebfd4aSSean Wang 	 */
4849aebfd4aSSean Wang 	for (i = 0; i < pkts_count; i++) {
4859aebfd4aSSean Wang 		if (sdio_hdr->bt_type == (&pkts[i])->type)
4869aebfd4aSSean Wang 			break;
4879aebfd4aSSean Wang 	}
4889aebfd4aSSean Wang 
4899aebfd4aSSean Wang 	if (i >= pkts_count) {
4909aebfd4aSSean Wang 		bt_dev_err(bdev->hdev, "Invalid bt type 0x%02x",
4919aebfd4aSSean Wang 			   sdio_hdr->bt_type);
4929aebfd4aSSean Wang 		goto err_kfree_skb;
4939aebfd4aSSean Wang 	}
4949aebfd4aSSean Wang 
4959aebfd4aSSean Wang 	/* Remaining bytes cannot hold a header*/
4969aebfd4aSSean Wang 	if (skb->len < (&pkts[i])->hlen) {
4979aebfd4aSSean Wang 		bt_dev_err(bdev->hdev, "The size of bt header is mismatched");
4989aebfd4aSSean Wang 		goto err_kfree_skb;
4999aebfd4aSSean Wang 	}
5009aebfd4aSSean Wang 
5019aebfd4aSSean Wang 	switch ((&pkts[i])->lsize) {
5029aebfd4aSSean Wang 	case 1:
5039aebfd4aSSean Wang 		dlen = skb->data[(&pkts[i])->loff];
5049aebfd4aSSean Wang 		break;
5059aebfd4aSSean Wang 	case 2:
5069aebfd4aSSean Wang 		dlen = get_unaligned_le16(skb->data +
5079aebfd4aSSean Wang 						  (&pkts[i])->loff);
5089aebfd4aSSean Wang 		break;
5099aebfd4aSSean Wang 	default:
5109aebfd4aSSean Wang 		goto err_kfree_skb;
5119aebfd4aSSean Wang 	}
5129aebfd4aSSean Wang 
5139aebfd4aSSean Wang 	pad_size = skb->len - (&pkts[i])->hlen -  dlen;
5149aebfd4aSSean Wang 
5159aebfd4aSSean Wang 	/* Remaining bytes cannot hold a payload */
5169aebfd4aSSean Wang 	if (pad_size < 0) {
5179aebfd4aSSean Wang 		bt_dev_err(bdev->hdev, "The size of bt payload is mismatched");
5189aebfd4aSSean Wang 		goto err_kfree_skb;
5199aebfd4aSSean Wang 	}
5209aebfd4aSSean Wang 
5219aebfd4aSSean Wang 	/* Remove padding bytes */
5229aebfd4aSSean Wang 	skb_trim(skb, skb->len - pad_size);
5239aebfd4aSSean Wang 
5249aebfd4aSSean Wang 	/* Complete frame */
5259aebfd4aSSean Wang 	(&pkts[i])->recv(bdev->hdev, skb);
5269aebfd4aSSean Wang 
527bcaa7d72SSean Wang 	bdev->hdev->stat.byte_rx += rx_size;
528bcaa7d72SSean Wang 
5299aebfd4aSSean Wang 	return 0;
5309aebfd4aSSean Wang 
5319aebfd4aSSean Wang err_kfree_skb:
5329aebfd4aSSean Wang 	kfree_skb(skb);
5339aebfd4aSSean Wang 
5349aebfd4aSSean Wang 	return err;
5359aebfd4aSSean Wang }
5369aebfd4aSSean Wang 
53726270bc1SSean Wang static void btmtksdio_txrx_work(struct work_struct *work)
5389aebfd4aSSean Wang {
53926270bc1SSean Wang 	struct btmtksdio_dev *bdev = container_of(work, struct btmtksdio_dev,
54026270bc1SSean Wang 						  txrx_work);
54126270bc1SSean Wang 	unsigned long txrx_timeout;
542184ea403SSean Wang 	u32 int_status, rx_size;
54326270bc1SSean Wang 	struct sk_buff *skb;
54426270bc1SSean Wang 	int err;
5457f3c563cSSean Wang 
5467f3c563cSSean Wang 	pm_runtime_get_sync(bdev->dev);
5477f3c563cSSean Wang 
5487f3c563cSSean Wang 	sdio_claim_host(bdev->func);
5497f3c563cSSean Wang 
5509aebfd4aSSean Wang 	/* Disable interrupt */
55126270bc1SSean Wang 	sdio_writel(bdev->func, C_INT_EN_CLR, MTK_REG_CHLPCR, 0);
5529aebfd4aSSean Wang 
55326270bc1SSean Wang 	txrx_timeout = jiffies + 5 * HZ;
55426270bc1SSean Wang 
55526270bc1SSean Wang 	do {
55626270bc1SSean Wang 		int_status = sdio_readl(bdev->func, MTK_REG_CHISR, NULL);
5579aebfd4aSSean Wang 
5589aebfd4aSSean Wang 		/* Ack an interrupt as soon as possible before any operation on
5599aebfd4aSSean Wang 		 * hardware.
5609aebfd4aSSean Wang 		 *
5619aebfd4aSSean Wang 		 * Note that we don't ack any status during operations to avoid race
5629aebfd4aSSean Wang 		 * condition between the host and the device such as it's possible to
5639aebfd4aSSean Wang 		 * mistakenly ack RX_DONE for the next packet and then cause interrupts
5649aebfd4aSSean Wang 		 * not be raised again but there is still pending data in the hardware
5659aebfd4aSSean Wang 		 * FIFO.
5669aebfd4aSSean Wang 		 */
56726270bc1SSean Wang 		sdio_writel(bdev->func, int_status, MTK_REG_CHISR, NULL);
5689aebfd4aSSean Wang 
5692fc967ccSMark Chen 		if ((int_status & FW_MAILBOX_INT) &&
5702fc967ccSMark Chen 		    bdev->data->chipid == 0x7921) {
5712fc967ccSMark Chen 			sdio_writel(bdev->func, PH2DSM0R_DRIVER_OWN,
5722fc967ccSMark Chen 				    MTK_REG_PH2DSM0R, 0);
5732fc967ccSMark Chen 		}
5742fc967ccSMark Chen 
5759aebfd4aSSean Wang 		if (int_status & FW_OWN_BACK_INT)
576e1052fb2SSean Wang 			bt_dev_dbg(bdev->hdev, "Get fw own back");
5779aebfd4aSSean Wang 
5789aebfd4aSSean Wang 		if (int_status & TX_EMPTY)
579d555b1f2SSean Wang 			set_bit(BTMTKSDIO_HW_TX_READY, &bdev->tx_state);
580d555b1f2SSean Wang 
5819aebfd4aSSean Wang 		else if (unlikely(int_status & TX_FIFO_OVERFLOW))
582e1052fb2SSean Wang 			bt_dev_warn(bdev->hdev, "Tx fifo overflow");
5839aebfd4aSSean Wang 
584d555b1f2SSean Wang 		if (test_bit(BTMTKSDIO_HW_TX_READY, &bdev->tx_state)) {
58510fe40e1SMark-yw Chen 			skb = skb_dequeue(&bdev->txq);
58610fe40e1SMark-yw Chen 			if (skb) {
58710fe40e1SMark-yw Chen 				err = btmtksdio_tx_packet(bdev, skb);
58810fe40e1SMark-yw Chen 				if (err < 0) {
58910fe40e1SMark-yw Chen 					bdev->hdev->stat.err_tx++;
59010fe40e1SMark-yw Chen 					skb_queue_head(&bdev->txq, skb);
59110fe40e1SMark-yw Chen 				}
59210fe40e1SMark-yw Chen 			}
59310fe40e1SMark-yw Chen 		}
59410fe40e1SMark-yw Chen 
5959aebfd4aSSean Wang 		if (int_status & RX_DONE_INT) {
596184ea403SSean Wang 			rx_size = sdio_readl(bdev->func, MTK_REG_CRPLR, NULL);
597184ea403SSean Wang 			rx_size = (rx_size & RX_PKT_LEN) >> 16;
5989aebfd4aSSean Wang 			if (btmtksdio_rx_packet(bdev, rx_size) < 0)
5999aebfd4aSSean Wang 				bdev->hdev->stat.err_rx++;
6009aebfd4aSSean Wang 		}
60126270bc1SSean Wang 	} while (int_status || time_is_before_jiffies(txrx_timeout));
60226270bc1SSean Wang 
6039aebfd4aSSean Wang 	/* Enable interrupt */
60426270bc1SSean Wang 	sdio_writel(bdev->func, C_INT_EN_SET, MTK_REG_CHLPCR, 0);
60526270bc1SSean Wang 
60626270bc1SSean Wang 	sdio_release_host(bdev->func);
6077f3c563cSSean Wang 
6087f3c563cSSean Wang 	pm_runtime_mark_last_busy(bdev->dev);
6097f3c563cSSean Wang 	pm_runtime_put_autosuspend(bdev->dev);
6109aebfd4aSSean Wang }
6119aebfd4aSSean Wang 
61226270bc1SSean Wang static void btmtksdio_interrupt(struct sdio_func *func)
61326270bc1SSean Wang {
61426270bc1SSean Wang 	struct btmtksdio_dev *bdev = sdio_get_drvdata(func);
61526270bc1SSean Wang 
61626270bc1SSean Wang 	/* Disable interrupt */
61726270bc1SSean Wang 	sdio_writel(bdev->func, C_INT_EN_CLR, MTK_REG_CHLPCR, 0);
61826270bc1SSean Wang 
61926270bc1SSean Wang 	schedule_work(&bdev->txrx_work);
62026270bc1SSean Wang }
62126270bc1SSean Wang 
6229aebfd4aSSean Wang static int btmtksdio_open(struct hci_dev *hdev)
6239aebfd4aSSean Wang {
6249aebfd4aSSean Wang 	struct btmtksdio_dev *bdev = hci_get_drvdata(hdev);
625c7e301d7SMark Chen 	u32 val;
6269aebfd4aSSean Wang 	int err;
6279aebfd4aSSean Wang 
6289aebfd4aSSean Wang 	sdio_claim_host(bdev->func);
6299aebfd4aSSean Wang 
6309aebfd4aSSean Wang 	err = sdio_enable_func(bdev->func);
6319aebfd4aSSean Wang 	if (err < 0)
6329aebfd4aSSean Wang 		goto err_release_host;
6339aebfd4aSSean Wang 
6344b4b2228SSean Wang 	set_bit(BTMTKSDIO_FUNC_ENABLED, &bdev->tx_state);
6354b4b2228SSean Wang 
636c7e301d7SMark Chen 	err = btmtksdio_drv_pmctrl(bdev);
6379aebfd4aSSean Wang 	if (err < 0)
6389aebfd4aSSean Wang 		goto err_disable_func;
6399aebfd4aSSean Wang 
6409aebfd4aSSean Wang 	/* Disable interrupt & mask out all interrupt sources */
6419aebfd4aSSean Wang 	sdio_writel(bdev->func, C_INT_EN_CLR, MTK_REG_CHLPCR, &err);
6429aebfd4aSSean Wang 	if (err < 0)
6439aebfd4aSSean Wang 		goto err_disable_func;
6449aebfd4aSSean Wang 
6459aebfd4aSSean Wang 	sdio_writel(bdev->func, 0, MTK_REG_CHIER, &err);
6469aebfd4aSSean Wang 	if (err < 0)
6479aebfd4aSSean Wang 		goto err_disable_func;
6489aebfd4aSSean Wang 
6499aebfd4aSSean Wang 	err = sdio_claim_irq(bdev->func, btmtksdio_interrupt);
6509aebfd4aSSean Wang 	if (err < 0)
6519aebfd4aSSean Wang 		goto err_disable_func;
6529aebfd4aSSean Wang 
6539aebfd4aSSean Wang 	err = sdio_set_block_size(bdev->func, MTK_SDIO_BLOCK_SIZE);
6549aebfd4aSSean Wang 	if (err < 0)
6559aebfd4aSSean Wang 		goto err_release_irq;
6569aebfd4aSSean Wang 
6579aebfd4aSSean Wang 	/* SDIO CMD 5 allows the SDIO device back to idle state an
6589aebfd4aSSean Wang 	 * synchronous interrupt is supported in SDIO 4-bit mode
6599aebfd4aSSean Wang 	 */
6605b23ac1aSSean Wang 	val = sdio_readl(bdev->func, MTK_REG_CSDIOCSR, &err);
6615b23ac1aSSean Wang 	if (err < 0)
6625b23ac1aSSean Wang 		goto err_release_irq;
6635b23ac1aSSean Wang 
6645b23ac1aSSean Wang 	val |= SDIO_INT_CTL;
6655b23ac1aSSean Wang 	sdio_writel(bdev->func, val, MTK_REG_CSDIOCSR, &err);
6669aebfd4aSSean Wang 	if (err < 0)
6679aebfd4aSSean Wang 		goto err_release_irq;
6689aebfd4aSSean Wang 
66977b210d1SSean Wang 	/* Explitly set write-1-clear method */
67077b210d1SSean Wang 	val = sdio_readl(bdev->func, MTK_REG_CHCR, &err);
67177b210d1SSean Wang 	if (err < 0)
67277b210d1SSean Wang 		goto err_release_irq;
67377b210d1SSean Wang 
67477b210d1SSean Wang 	val |= C_INT_CLR_CTRL;
67577b210d1SSean Wang 	sdio_writel(bdev->func, val, MTK_REG_CHCR, &err);
6769aebfd4aSSean Wang 	if (err < 0)
6779aebfd4aSSean Wang 		goto err_release_irq;
6789aebfd4aSSean Wang 
6799aebfd4aSSean Wang 	/* Setup interrupt sources */
6809aebfd4aSSean Wang 	sdio_writel(bdev->func, RX_DONE_INT | TX_EMPTY | TX_FIFO_OVERFLOW,
6819aebfd4aSSean Wang 		    MTK_REG_CHIER, &err);
6829aebfd4aSSean Wang 	if (err < 0)
6839aebfd4aSSean Wang 		goto err_release_irq;
6849aebfd4aSSean Wang 
6859aebfd4aSSean Wang 	/* Enable interrupt */
6869aebfd4aSSean Wang 	sdio_writel(bdev->func, C_INT_EN_SET, MTK_REG_CHLPCR, &err);
6879aebfd4aSSean Wang 	if (err < 0)
6889aebfd4aSSean Wang 		goto err_release_irq;
6899aebfd4aSSean Wang 
6909aebfd4aSSean Wang 	sdio_release_host(bdev->func);
6919aebfd4aSSean Wang 
6929aebfd4aSSean Wang 	return 0;
6939aebfd4aSSean Wang 
6949aebfd4aSSean Wang err_release_irq:
6959aebfd4aSSean Wang 	sdio_release_irq(bdev->func);
6969aebfd4aSSean Wang 
6979aebfd4aSSean Wang err_disable_func:
6989aebfd4aSSean Wang 	sdio_disable_func(bdev->func);
6999aebfd4aSSean Wang 
7009aebfd4aSSean Wang err_release_host:
7019aebfd4aSSean Wang 	sdio_release_host(bdev->func);
7029aebfd4aSSean Wang 
7039aebfd4aSSean Wang 	return err;
7049aebfd4aSSean Wang }
7059aebfd4aSSean Wang 
7069aebfd4aSSean Wang static int btmtksdio_close(struct hci_dev *hdev)
7079aebfd4aSSean Wang {
7089aebfd4aSSean Wang 	struct btmtksdio_dev *bdev = hci_get_drvdata(hdev);
7099aebfd4aSSean Wang 
7109aebfd4aSSean Wang 	sdio_claim_host(bdev->func);
7119aebfd4aSSean Wang 
7129aebfd4aSSean Wang 	/* Disable interrupt */
7139aebfd4aSSean Wang 	sdio_writel(bdev->func, C_INT_EN_CLR, MTK_REG_CHLPCR, NULL);
7149aebfd4aSSean Wang 
7159aebfd4aSSean Wang 	sdio_release_irq(bdev->func);
7169aebfd4aSSean Wang 
71726270bc1SSean Wang 	cancel_work_sync(&bdev->txrx_work);
71826270bc1SSean Wang 
719c7e301d7SMark Chen 	btmtksdio_fw_pmctrl(bdev);
7209aebfd4aSSean Wang 
7214b4b2228SSean Wang 	clear_bit(BTMTKSDIO_FUNC_ENABLED, &bdev->tx_state);
7229aebfd4aSSean Wang 	sdio_disable_func(bdev->func);
7239aebfd4aSSean Wang 
7249aebfd4aSSean Wang 	sdio_release_host(bdev->func);
7259aebfd4aSSean Wang 
7269aebfd4aSSean Wang 	return 0;
7279aebfd4aSSean Wang }
7289aebfd4aSSean Wang 
7299aebfd4aSSean Wang static int btmtksdio_flush(struct hci_dev *hdev)
7309aebfd4aSSean Wang {
7319aebfd4aSSean Wang 	struct btmtksdio_dev *bdev = hci_get_drvdata(hdev);
7329aebfd4aSSean Wang 
7339aebfd4aSSean Wang 	skb_queue_purge(&bdev->txq);
7349aebfd4aSSean Wang 
73526270bc1SSean Wang 	cancel_work_sync(&bdev->txrx_work);
7369aebfd4aSSean Wang 
7379aebfd4aSSean Wang 	return 0;
7389aebfd4aSSean Wang }
7399aebfd4aSSean Wang 
7409aebfd4aSSean Wang static int btmtksdio_func_query(struct hci_dev *hdev)
7419aebfd4aSSean Wang {
7429aebfd4aSSean Wang 	struct btmtk_hci_wmt_params wmt_params;
7439aebfd4aSSean Wang 	int status, err;
7449aebfd4aSSean Wang 	u8 param = 0;
7459aebfd4aSSean Wang 
7469aebfd4aSSean Wang 	/* Query whether the function is enabled */
7473a722044SSean Wang 	wmt_params.op = BTMTK_WMT_FUNC_CTRL;
7489aebfd4aSSean Wang 	wmt_params.flag = 4;
7499aebfd4aSSean Wang 	wmt_params.dlen = sizeof(param);
7509aebfd4aSSean Wang 	wmt_params.data = &param;
7519aebfd4aSSean Wang 	wmt_params.status = &status;
7529aebfd4aSSean Wang 
7539aebfd4aSSean Wang 	err = mtk_hci_wmt_sync(hdev, &wmt_params);
7549aebfd4aSSean Wang 	if (err < 0) {
7559aebfd4aSSean Wang 		bt_dev_err(hdev, "Failed to query function status (%d)", err);
7569aebfd4aSSean Wang 		return err;
7579aebfd4aSSean Wang 	}
7589aebfd4aSSean Wang 
7599aebfd4aSSean Wang 	return status;
7609aebfd4aSSean Wang }
7619aebfd4aSSean Wang 
762c603bf1fSSean Wang static int mt76xx_setup(struct hci_dev *hdev, const char *fwname)
7639aebfd4aSSean Wang {
76401ecc177SMark Chen 	struct btmtksdio_dev *bdev = hci_get_drvdata(hdev);
7659aebfd4aSSean Wang 	struct btmtk_hci_wmt_params wmt_params;
7669aebfd4aSSean Wang 	struct btmtk_tci_sleep tci_sleep;
7679aebfd4aSSean Wang 	struct sk_buff *skb;
7689aebfd4aSSean Wang 	int err, status;
7699aebfd4aSSean Wang 	u8 param = 0x1;
7709aebfd4aSSean Wang 
7719aebfd4aSSean Wang 	/* Query whether the firmware is already download */
7723a722044SSean Wang 	wmt_params.op = BTMTK_WMT_SEMAPHORE;
7739aebfd4aSSean Wang 	wmt_params.flag = 1;
7749aebfd4aSSean Wang 	wmt_params.dlen = 0;
7759aebfd4aSSean Wang 	wmt_params.data = NULL;
7769aebfd4aSSean Wang 	wmt_params.status = &status;
7779aebfd4aSSean Wang 
7789aebfd4aSSean Wang 	err = mtk_hci_wmt_sync(hdev, &wmt_params);
7799aebfd4aSSean Wang 	if (err < 0) {
7809aebfd4aSSean Wang 		bt_dev_err(hdev, "Failed to query firmware status (%d)", err);
7819aebfd4aSSean Wang 		return err;
7829aebfd4aSSean Wang 	}
7839aebfd4aSSean Wang 
7849aebfd4aSSean Wang 	if (status == BTMTK_WMT_PATCH_DONE) {
7859aebfd4aSSean Wang 		bt_dev_info(hdev, "Firmware already downloaded");
7869aebfd4aSSean Wang 		goto ignore_setup_fw;
7879aebfd4aSSean Wang 	}
7889aebfd4aSSean Wang 
7899aebfd4aSSean Wang 	/* Setup a firmware which the device definitely requires */
790c603bf1fSSean Wang 	err = btmtk_setup_firmware(hdev, fwname, mtk_hci_wmt_sync);
7919aebfd4aSSean Wang 	if (err < 0)
7929aebfd4aSSean Wang 		return err;
7939aebfd4aSSean Wang 
7949aebfd4aSSean Wang ignore_setup_fw:
7959aebfd4aSSean Wang 	/* Query whether the device is already enabled */
7969aebfd4aSSean Wang 	err = readx_poll_timeout(btmtksdio_func_query, hdev, status,
7979aebfd4aSSean Wang 				 status < 0 || status != BTMTK_WMT_ON_PROGRESS,
7989aebfd4aSSean Wang 				 2000, 5000000);
7999aebfd4aSSean Wang 	/* -ETIMEDOUT happens */
8009aebfd4aSSean Wang 	if (err < 0)
8019aebfd4aSSean Wang 		return err;
8029aebfd4aSSean Wang 
8039aebfd4aSSean Wang 	/* The other errors happen in btusb_mtk_func_query */
8049aebfd4aSSean Wang 	if (status < 0)
8059aebfd4aSSean Wang 		return status;
8069aebfd4aSSean Wang 
8079aebfd4aSSean Wang 	if (status == BTMTK_WMT_ON_DONE) {
8089aebfd4aSSean Wang 		bt_dev_info(hdev, "function already on");
8099aebfd4aSSean Wang 		goto ignore_func_on;
8109aebfd4aSSean Wang 	}
8119aebfd4aSSean Wang 
8129aebfd4aSSean Wang 	/* Enable Bluetooth protocol */
8133a722044SSean Wang 	wmt_params.op = BTMTK_WMT_FUNC_CTRL;
8149aebfd4aSSean Wang 	wmt_params.flag = 0;
8159aebfd4aSSean Wang 	wmt_params.dlen = sizeof(param);
8169aebfd4aSSean Wang 	wmt_params.data = &param;
8179aebfd4aSSean Wang 	wmt_params.status = NULL;
8189aebfd4aSSean Wang 
8199aebfd4aSSean Wang 	err = mtk_hci_wmt_sync(hdev, &wmt_params);
8209aebfd4aSSean Wang 	if (err < 0) {
8219aebfd4aSSean Wang 		bt_dev_err(hdev, "Failed to send wmt func ctrl (%d)", err);
8229aebfd4aSSean Wang 		return err;
8239aebfd4aSSean Wang 	}
8249aebfd4aSSean Wang 
82501ecc177SMark Chen 	set_bit(BTMTKSDIO_PATCH_ENABLED, &bdev->tx_state);
82601ecc177SMark Chen 
8279aebfd4aSSean Wang ignore_func_on:
8289aebfd4aSSean Wang 	/* Apply the low power environment setup */
8299aebfd4aSSean Wang 	tci_sleep.mode = 0x5;
8309aebfd4aSSean Wang 	tci_sleep.duration = cpu_to_le16(0x640);
8319aebfd4aSSean Wang 	tci_sleep.host_duration = cpu_to_le16(0x640);
8329aebfd4aSSean Wang 	tci_sleep.host_wakeup_pin = 0;
8339aebfd4aSSean Wang 	tci_sleep.time_compensation = 0;
8349aebfd4aSSean Wang 
8359aebfd4aSSean Wang 	skb = __hci_cmd_sync(hdev, 0xfc7a, sizeof(tci_sleep), &tci_sleep,
8369aebfd4aSSean Wang 			     HCI_INIT_TIMEOUT);
8379aebfd4aSSean Wang 	if (IS_ERR(skb)) {
8389aebfd4aSSean Wang 		err = PTR_ERR(skb);
8399aebfd4aSSean Wang 		bt_dev_err(hdev, "Failed to apply low power setting (%d)", err);
8409aebfd4aSSean Wang 		return err;
8419aebfd4aSSean Wang 	}
8429aebfd4aSSean Wang 	kfree_skb(skb);
8439aebfd4aSSean Wang 
844c603bf1fSSean Wang 	return 0;
845c603bf1fSSean Wang }
846c603bf1fSSean Wang 
847c603bf1fSSean Wang static int mt79xx_setup(struct hci_dev *hdev, const char *fwname)
848c603bf1fSSean Wang {
84901ecc177SMark Chen 	struct btmtksdio_dev *bdev = hci_get_drvdata(hdev);
850c603bf1fSSean Wang 	struct btmtk_hci_wmt_params wmt_params;
851c603bf1fSSean Wang 	u8 param = 0x1;
852c603bf1fSSean Wang 	int err;
853c603bf1fSSean Wang 
854c603bf1fSSean Wang 	err = btmtk_setup_firmware_79xx(hdev, fwname, mtk_hci_wmt_sync);
855c603bf1fSSean Wang 	if (err < 0) {
856c603bf1fSSean Wang 		bt_dev_err(hdev, "Failed to setup 79xx firmware (%d)", err);
857c603bf1fSSean Wang 		return err;
858c603bf1fSSean Wang 	}
859c603bf1fSSean Wang 
860c603bf1fSSean Wang 	/* Enable Bluetooth protocol */
861c603bf1fSSean Wang 	wmt_params.op = BTMTK_WMT_FUNC_CTRL;
862c603bf1fSSean Wang 	wmt_params.flag = 0;
863c603bf1fSSean Wang 	wmt_params.dlen = sizeof(param);
864c603bf1fSSean Wang 	wmt_params.data = &param;
865c603bf1fSSean Wang 	wmt_params.status = NULL;
866c603bf1fSSean Wang 
867c603bf1fSSean Wang 	err = mtk_hci_wmt_sync(hdev, &wmt_params);
868c603bf1fSSean Wang 	if (err < 0) {
869c603bf1fSSean Wang 		bt_dev_err(hdev, "Failed to send wmt func ctrl (%d)", err);
870c603bf1fSSean Wang 		return err;
871c603bf1fSSean Wang 	}
872c603bf1fSSean Wang 
873630491ffSŁukasz Bartosik 	hci_set_msft_opcode(hdev, 0xFD30);
87416ada83bSSean Wang 	hci_set_aosp_capable(hdev);
87501ecc177SMark Chen 	set_bit(BTMTKSDIO_PATCH_ENABLED, &bdev->tx_state);
876630491ffSŁukasz Bartosik 
877c603bf1fSSean Wang 	return err;
878c603bf1fSSean Wang }
879c603bf1fSSean Wang 
8804b685879SSean Wang static int btmtksdio_mtk_reg_read(struct hci_dev *hdev, u32 reg, u32 *val)
881c603bf1fSSean Wang {
882c603bf1fSSean Wang 	struct btmtk_hci_wmt_params wmt_params;
8835677bcf6SSean Wang 	struct reg_read_cmd reg_read = {
884c603bf1fSSean Wang 		.type = 1,
885c603bf1fSSean Wang 		.num = 1,
886c603bf1fSSean Wang 	};
887c603bf1fSSean Wang 	u32 status;
888c603bf1fSSean Wang 	int err;
889c603bf1fSSean Wang 
890c603bf1fSSean Wang 	reg_read.addr = cpu_to_le32(reg);
891c603bf1fSSean Wang 	wmt_params.op = BTMTK_WMT_REGISTER;
892c603bf1fSSean Wang 	wmt_params.flag = BTMTK_WMT_REG_READ;
893c603bf1fSSean Wang 	wmt_params.dlen = sizeof(reg_read);
894c603bf1fSSean Wang 	wmt_params.data = &reg_read;
895c603bf1fSSean Wang 	wmt_params.status = &status;
896c603bf1fSSean Wang 
897c603bf1fSSean Wang 	err = mtk_hci_wmt_sync(hdev, &wmt_params);
898c603bf1fSSean Wang 	if (err < 0) {
899c603bf1fSSean Wang 		bt_dev_err(hdev, "Failed to read reg (%d)", err);
900c603bf1fSSean Wang 		return err;
901c603bf1fSSean Wang 	}
902c603bf1fSSean Wang 
903c603bf1fSSean Wang 	*val = status;
904c603bf1fSSean Wang 
905c603bf1fSSean Wang 	return err;
906c603bf1fSSean Wang }
907c603bf1fSSean Wang 
908191c8723SMark Chen static int btmtksdio_mtk_reg_write(struct hci_dev *hdev, u32 reg, u32 val, u32 mask)
909191c8723SMark Chen {
910191c8723SMark Chen 	struct btmtk_hci_wmt_params wmt_params;
911191c8723SMark Chen 	const struct reg_write_cmd reg_write = {
912191c8723SMark Chen 		.type = 1,
913191c8723SMark Chen 		.num = 1,
914191c8723SMark Chen 		.addr = cpu_to_le32(reg),
915191c8723SMark Chen 		.data = cpu_to_le32(val),
916191c8723SMark Chen 		.mask = cpu_to_le32(mask),
917191c8723SMark Chen 	};
918191c8723SMark Chen 	int err, status;
919191c8723SMark Chen 
920191c8723SMark Chen 	wmt_params.op = BTMTK_WMT_REGISTER;
921191c8723SMark Chen 	wmt_params.flag = BTMTK_WMT_REG_WRITE;
922191c8723SMark Chen 	wmt_params.dlen = sizeof(reg_write);
923191c8723SMark Chen 	wmt_params.data = &reg_write;
924191c8723SMark Chen 	wmt_params.status = &status;
925191c8723SMark Chen 
926191c8723SMark Chen 	err = mtk_hci_wmt_sync(hdev, &wmt_params);
927191c8723SMark Chen 	if (err < 0)
928191c8723SMark Chen 		bt_dev_err(hdev, "Failed to write reg (%d)", err);
929191c8723SMark Chen 
930191c8723SMark Chen 	return err;
931191c8723SMark Chen }
932191c8723SMark Chen 
933191c8723SMark Chen static int btmtksdio_sco_setting(struct hci_dev *hdev)
934191c8723SMark Chen {
935191c8723SMark Chen 	const struct btmtk_sco sco_setting = {
936191c8723SMark Chen 		.clock_config = 0x49,
937191c8723SMark Chen 		.channel_format_config = 0x80,
938191c8723SMark Chen 	};
939191c8723SMark Chen 	struct sk_buff *skb;
940191c8723SMark Chen 	u32 val;
941191c8723SMark Chen 	int err;
942191c8723SMark Chen 
943191c8723SMark Chen 	/* Enable SCO over I2S/PCM for MediaTek chipset */
944191c8723SMark Chen 	skb =  __hci_cmd_sync(hdev, 0xfc72, sizeof(sco_setting),
945191c8723SMark Chen 			      &sco_setting, HCI_CMD_TIMEOUT);
946191c8723SMark Chen 	if (IS_ERR(skb))
947191c8723SMark Chen 		return PTR_ERR(skb);
948191c8723SMark Chen 
949191c8723SMark Chen 	kfree_skb(skb);
950191c8723SMark Chen 
951191c8723SMark Chen 	err = btmtksdio_mtk_reg_read(hdev, MT7921_PINMUX_0, &val);
952191c8723SMark Chen 	if (err < 0)
953191c8723SMark Chen 		return err;
954191c8723SMark Chen 
955191c8723SMark Chen 	val |= 0x11000000;
956191c8723SMark Chen 	err = btmtksdio_mtk_reg_write(hdev, MT7921_PINMUX_0, val, ~0);
957191c8723SMark Chen 	if (err < 0)
958191c8723SMark Chen 		return err;
959191c8723SMark Chen 
960191c8723SMark Chen 	err = btmtksdio_mtk_reg_read(hdev, MT7921_PINMUX_1, &val);
961191c8723SMark Chen 	if (err < 0)
962191c8723SMark Chen 		return err;
963191c8723SMark Chen 
964191c8723SMark Chen 	val |= 0x00000101;
965191c8723SMark Chen 	return btmtksdio_mtk_reg_write(hdev, MT7921_PINMUX_1, val, ~0);
966191c8723SMark Chen }
967191c8723SMark Chen 
968c603bf1fSSean Wang static int btmtksdio_setup(struct hci_dev *hdev)
969c603bf1fSSean Wang {
970c603bf1fSSean Wang 	struct btmtksdio_dev *bdev = hci_get_drvdata(hdev);
971c603bf1fSSean Wang 	ktime_t calltime, delta, rettime;
972c603bf1fSSean Wang 	unsigned long long duration;
973c603bf1fSSean Wang 	char fwname[64];
974c603bf1fSSean Wang 	int err, dev_id;
975c603bf1fSSean Wang 	u32 fw_version = 0;
976c603bf1fSSean Wang 
977c603bf1fSSean Wang 	calltime = ktime_get();
978d555b1f2SSean Wang 	set_bit(BTMTKSDIO_HW_TX_READY, &bdev->tx_state);
979c603bf1fSSean Wang 
980c603bf1fSSean Wang 	switch (bdev->data->chipid) {
981c603bf1fSSean Wang 	case 0x7921:
9824b685879SSean Wang 		err = btmtksdio_mtk_reg_read(hdev, 0x70010200, &dev_id);
983c603bf1fSSean Wang 		if (err < 0) {
984c603bf1fSSean Wang 			bt_dev_err(hdev, "Failed to get device id (%d)", err);
985c603bf1fSSean Wang 			return err;
986c603bf1fSSean Wang 		}
987c603bf1fSSean Wang 
9884b685879SSean Wang 		err = btmtksdio_mtk_reg_read(hdev, 0x80021004, &fw_version);
989c603bf1fSSean Wang 		if (err < 0) {
990c603bf1fSSean Wang 			bt_dev_err(hdev, "Failed to get fw version (%d)", err);
991c603bf1fSSean Wang 			return err;
992c603bf1fSSean Wang 		}
993c603bf1fSSean Wang 
994c603bf1fSSean Wang 		snprintf(fwname, sizeof(fwname),
995c603bf1fSSean Wang 			 "mediatek/BT_RAM_CODE_MT%04x_1_%x_hdr.bin",
996c603bf1fSSean Wang 			 dev_id & 0xffff, (fw_version & 0xff) + 1);
997c603bf1fSSean Wang 		err = mt79xx_setup(hdev, fwname);
998c603bf1fSSean Wang 		if (err < 0)
999c603bf1fSSean Wang 			return err;
1000191c8723SMark Chen 
1001752aea58SMark Chen 		err = btmtksdio_fw_pmctrl(bdev);
1002752aea58SMark Chen 		if (err < 0)
1003752aea58SMark Chen 			return err;
1004752aea58SMark Chen 
1005752aea58SMark Chen 		err = btmtksdio_drv_pmctrl(bdev);
1006752aea58SMark Chen 		if (err < 0)
1007752aea58SMark Chen 			return err;
1008752aea58SMark Chen 
1009191c8723SMark Chen 		/* Enable SCO over I2S/PCM */
1010191c8723SMark Chen 		err = btmtksdio_sco_setting(hdev);
1011191c8723SMark Chen 		if (err < 0) {
1012191c8723SMark Chen 			bt_dev_err(hdev, "Failed to enable SCO setting (%d)", err);
1013191c8723SMark Chen 			return err;
1014191c8723SMark Chen 		}
1015191c8723SMark Chen 
1016c603bf1fSSean Wang 		break;
1017c603bf1fSSean Wang 	case 0x7663:
1018c603bf1fSSean Wang 	case 0x7668:
1019c603bf1fSSean Wang 		err = mt76xx_setup(hdev, bdev->data->fwname);
1020c603bf1fSSean Wang 		if (err < 0)
1021c603bf1fSSean Wang 			return err;
1022c603bf1fSSean Wang 		break;
1023c603bf1fSSean Wang 	default:
1024c603bf1fSSean Wang 		return -ENODEV;
1025c603bf1fSSean Wang 	}
1026c603bf1fSSean Wang 
10279aebfd4aSSean Wang 	rettime = ktime_get();
10289aebfd4aSSean Wang 	delta = ktime_sub(rettime, calltime);
10299aebfd4aSSean Wang 	duration = (unsigned long long)ktime_to_ns(delta) >> 10;
10309aebfd4aSSean Wang 
10317f3c563cSSean Wang 	pm_runtime_set_autosuspend_delay(bdev->dev,
10327f3c563cSSean Wang 					 MTKBTSDIO_AUTOSUSPEND_DELAY);
10337f3c563cSSean Wang 	pm_runtime_use_autosuspend(bdev->dev);
10347f3c563cSSean Wang 
10357f3c563cSSean Wang 	err = pm_runtime_set_active(bdev->dev);
10367f3c563cSSean Wang 	if (err < 0)
10377f3c563cSSean Wang 		return err;
10387f3c563cSSean Wang 
10397f3c563cSSean Wang 	/* Default forbid runtime auto suspend, that can be allowed by
10407f3c563cSSean Wang 	 * enable_autosuspend flag or the PM runtime entry under sysfs.
10417f3c563cSSean Wang 	 */
10427f3c563cSSean Wang 	pm_runtime_forbid(bdev->dev);
10437f3c563cSSean Wang 	pm_runtime_enable(bdev->dev);
10447f3c563cSSean Wang 
10457f3c563cSSean Wang 	if (enable_autosuspend)
10467f3c563cSSean Wang 		pm_runtime_allow(bdev->dev);
10477f3c563cSSean Wang 
10489aebfd4aSSean Wang 	bt_dev_info(hdev, "Device setup in %llu usecs", duration);
10499aebfd4aSSean Wang 
10509aebfd4aSSean Wang 	return 0;
10519aebfd4aSSean Wang }
10529aebfd4aSSean Wang 
10539aebfd4aSSean Wang static int btmtksdio_shutdown(struct hci_dev *hdev)
10549aebfd4aSSean Wang {
10557f3c563cSSean Wang 	struct btmtksdio_dev *bdev = hci_get_drvdata(hdev);
10569aebfd4aSSean Wang 	struct btmtk_hci_wmt_params wmt_params;
10579aebfd4aSSean Wang 	u8 param = 0x0;
10589aebfd4aSSean Wang 	int err;
10599aebfd4aSSean Wang 
10607f3c563cSSean Wang 	/* Get back the state to be consistent with the state
10617f3c563cSSean Wang 	 * in btmtksdio_setup.
10627f3c563cSSean Wang 	 */
10637f3c563cSSean Wang 	pm_runtime_get_sync(bdev->dev);
10647f3c563cSSean Wang 
10659aebfd4aSSean Wang 	/* Disable the device */
10663a722044SSean Wang 	wmt_params.op = BTMTK_WMT_FUNC_CTRL;
10679aebfd4aSSean Wang 	wmt_params.flag = 0;
10689aebfd4aSSean Wang 	wmt_params.dlen = sizeof(param);
10699aebfd4aSSean Wang 	wmt_params.data = &param;
10709aebfd4aSSean Wang 	wmt_params.status = NULL;
10719aebfd4aSSean Wang 
10729aebfd4aSSean Wang 	err = mtk_hci_wmt_sync(hdev, &wmt_params);
10739aebfd4aSSean Wang 	if (err < 0) {
10749aebfd4aSSean Wang 		bt_dev_err(hdev, "Failed to send wmt func ctrl (%d)", err);
10759aebfd4aSSean Wang 		return err;
10769aebfd4aSSean Wang 	}
10779aebfd4aSSean Wang 
10787f3c563cSSean Wang 	pm_runtime_put_noidle(bdev->dev);
10797f3c563cSSean Wang 	pm_runtime_disable(bdev->dev);
10807f3c563cSSean Wang 
10819aebfd4aSSean Wang 	return 0;
10829aebfd4aSSean Wang }
10839aebfd4aSSean Wang 
10849aebfd4aSSean Wang static int btmtksdio_send_frame(struct hci_dev *hdev, struct sk_buff *skb)
10859aebfd4aSSean Wang {
10869aebfd4aSSean Wang 	struct btmtksdio_dev *bdev = hci_get_drvdata(hdev);
10879aebfd4aSSean Wang 
10889aebfd4aSSean Wang 	switch (hci_skb_pkt_type(skb)) {
10899aebfd4aSSean Wang 	case HCI_COMMAND_PKT:
10909aebfd4aSSean Wang 		hdev->stat.cmd_tx++;
10919aebfd4aSSean Wang 		break;
10929aebfd4aSSean Wang 
10939aebfd4aSSean Wang 	case HCI_ACLDATA_PKT:
10949aebfd4aSSean Wang 		hdev->stat.acl_tx++;
10959aebfd4aSSean Wang 		break;
10969aebfd4aSSean Wang 
10979aebfd4aSSean Wang 	case HCI_SCODATA_PKT:
10989aebfd4aSSean Wang 		hdev->stat.sco_tx++;
10999aebfd4aSSean Wang 		break;
11009aebfd4aSSean Wang 
11019aebfd4aSSean Wang 	default:
11029aebfd4aSSean Wang 		return -EILSEQ;
11039aebfd4aSSean Wang 	}
11049aebfd4aSSean Wang 
11059aebfd4aSSean Wang 	skb_queue_tail(&bdev->txq, skb);
11069aebfd4aSSean Wang 
110726270bc1SSean Wang 	schedule_work(&bdev->txrx_work);
11089aebfd4aSSean Wang 
11099aebfd4aSSean Wang 	return 0;
11109aebfd4aSSean Wang }
11119aebfd4aSSean Wang 
1112ce64b3e9SMark Chen static bool btmtksdio_sdio_wakeup(struct hci_dev *hdev)
1113ce64b3e9SMark Chen {
1114ce64b3e9SMark Chen 	struct btmtksdio_dev *bdev = hci_get_drvdata(hdev);
1115ce64b3e9SMark Chen 	bool may_wakeup = device_may_wakeup(bdev->dev);
1116ce64b3e9SMark Chen 	const struct btmtk_wakeon bt_awake = {
1117ce64b3e9SMark Chen 		.mode = 0x1,
1118ce64b3e9SMark Chen 		.gpo = 0,
1119ce64b3e9SMark Chen 		.active_high = 0x1,
1120ce64b3e9SMark Chen 		.enable_delay = cpu_to_le16(0xc80),
1121ce64b3e9SMark Chen 		.wakeup_delay = cpu_to_le16(0x20),
1122ce64b3e9SMark Chen 	};
1123ce64b3e9SMark Chen 
1124ce64b3e9SMark Chen 	if (may_wakeup && bdev->data->chipid == 0x7921) {
1125ce64b3e9SMark Chen 		struct sk_buff *skb;
1126ce64b3e9SMark Chen 
1127ce64b3e9SMark Chen 		skb =  __hci_cmd_sync(hdev, 0xfc27, sizeof(bt_awake),
1128ce64b3e9SMark Chen 				      &bt_awake, HCI_CMD_TIMEOUT);
1129ce64b3e9SMark Chen 		if (IS_ERR(skb))
1130ce64b3e9SMark Chen 			may_wakeup = false;
1131ce64b3e9SMark Chen 
1132ce64b3e9SMark Chen 		kfree_skb(skb);
1133ce64b3e9SMark Chen 	}
1134ce64b3e9SMark Chen 
1135ce64b3e9SMark Chen 	return may_wakeup;
1136ce64b3e9SMark Chen }
1137ce64b3e9SMark Chen 
11389aebfd4aSSean Wang static int btmtksdio_probe(struct sdio_func *func,
11399aebfd4aSSean Wang 			   const struct sdio_device_id *id)
11409aebfd4aSSean Wang {
11419aebfd4aSSean Wang 	struct btmtksdio_dev *bdev;
11429aebfd4aSSean Wang 	struct hci_dev *hdev;
11439aebfd4aSSean Wang 	int err;
11449aebfd4aSSean Wang 
11459aebfd4aSSean Wang 	bdev = devm_kzalloc(&func->dev, sizeof(*bdev), GFP_KERNEL);
11469aebfd4aSSean Wang 	if (!bdev)
11479aebfd4aSSean Wang 		return -ENOMEM;
11489aebfd4aSSean Wang 
11499aebfd4aSSean Wang 	bdev->data = (void *)id->driver_data;
11509aebfd4aSSean Wang 	if (!bdev->data)
11519aebfd4aSSean Wang 		return -ENODEV;
11529aebfd4aSSean Wang 
11537f3c563cSSean Wang 	bdev->dev = &func->dev;
11549aebfd4aSSean Wang 	bdev->func = func;
11559aebfd4aSSean Wang 
115626270bc1SSean Wang 	INIT_WORK(&bdev->txrx_work, btmtksdio_txrx_work);
11579aebfd4aSSean Wang 	skb_queue_head_init(&bdev->txq);
11589aebfd4aSSean Wang 
11599aebfd4aSSean Wang 	/* Initialize and register HCI device */
11609aebfd4aSSean Wang 	hdev = hci_alloc_dev();
11619aebfd4aSSean Wang 	if (!hdev) {
11629aebfd4aSSean Wang 		dev_err(&func->dev, "Can't allocate HCI device\n");
11639aebfd4aSSean Wang 		return -ENOMEM;
11649aebfd4aSSean Wang 	}
11659aebfd4aSSean Wang 
11669aebfd4aSSean Wang 	bdev->hdev = hdev;
11679aebfd4aSSean Wang 
11689aebfd4aSSean Wang 	hdev->bus = HCI_SDIO;
11699aebfd4aSSean Wang 	hci_set_drvdata(hdev, bdev);
11709aebfd4aSSean Wang 
11719aebfd4aSSean Wang 	hdev->open     = btmtksdio_open;
11729aebfd4aSSean Wang 	hdev->close    = btmtksdio_close;
11739aebfd4aSSean Wang 	hdev->flush    = btmtksdio_flush;
11749aebfd4aSSean Wang 	hdev->setup    = btmtksdio_setup;
11759aebfd4aSSean Wang 	hdev->shutdown = btmtksdio_shutdown;
11769aebfd4aSSean Wang 	hdev->send     = btmtksdio_send_frame;
1177ce64b3e9SMark Chen 	hdev->wakeup   = btmtksdio_sdio_wakeup;
1178877ec9e1SSean Wang 	hdev->set_bdaddr = btmtk_set_bdaddr;
1179877ec9e1SSean Wang 
11809aebfd4aSSean Wang 	SET_HCIDEV_DEV(hdev, &func->dev);
11819aebfd4aSSean Wang 
11829aebfd4aSSean Wang 	hdev->manufacturer = 70;
11839aebfd4aSSean Wang 	set_bit(HCI_QUIRK_NON_PERSISTENT_SETUP, &hdev->quirks);
11849aebfd4aSSean Wang 
11859aebfd4aSSean Wang 	err = hci_register_dev(hdev);
11869aebfd4aSSean Wang 	if (err < 0) {
11879aebfd4aSSean Wang 		dev_err(&func->dev, "Can't register HCI device\n");
11889aebfd4aSSean Wang 		hci_free_dev(hdev);
11899aebfd4aSSean Wang 		return err;
11909aebfd4aSSean Wang 	}
11919aebfd4aSSean Wang 
11929aebfd4aSSean Wang 	sdio_set_drvdata(func, bdev);
11939aebfd4aSSean Wang 
11947f3c563cSSean Wang 	/* pm_runtime_enable would be done after the firmware is being
11957f3c563cSSean Wang 	 * downloaded because the core layer probably already enables
11967f3c563cSSean Wang 	 * runtime PM for this func such as the case host->caps &
11977f3c563cSSean Wang 	 * MMC_CAP_POWER_OFF_CARD.
11987f3c563cSSean Wang 	 */
11997f3c563cSSean Wang 	if (pm_runtime_enabled(bdev->dev))
12007f3c563cSSean Wang 		pm_runtime_disable(bdev->dev);
12017f3c563cSSean Wang 
12027f3c563cSSean Wang 	/* As explaination in drivers/mmc/core/sdio_bus.c tells us:
12037f3c563cSSean Wang 	 * Unbound SDIO functions are always suspended.
12047f3c563cSSean Wang 	 * During probe, the function is set active and the usage count
12057f3c563cSSean Wang 	 * is incremented.  If the driver supports runtime PM,
12067f3c563cSSean Wang 	 * it should call pm_runtime_put_noidle() in its probe routine and
12077f3c563cSSean Wang 	 * pm_runtime_get_noresume() in its remove routine.
12087f3c563cSSean Wang 	 *
12097f3c563cSSean Wang 	 * So, put a pm_runtime_put_noidle here !
12107f3c563cSSean Wang 	 */
12117f3c563cSSean Wang 	pm_runtime_put_noidle(bdev->dev);
12127f3c563cSSean Wang 
1213ce64b3e9SMark Chen 	err = device_init_wakeup(bdev->dev, true);
1214ce64b3e9SMark Chen 	if (err)
1215ce64b3e9SMark Chen 		bt_dev_err(hdev, "failed to initialize device wakeup");
1216ce64b3e9SMark Chen 
1217ce64b3e9SMark Chen 	return err;
12189aebfd4aSSean Wang }
12199aebfd4aSSean Wang 
12209aebfd4aSSean Wang static void btmtksdio_remove(struct sdio_func *func)
12219aebfd4aSSean Wang {
12229aebfd4aSSean Wang 	struct btmtksdio_dev *bdev = sdio_get_drvdata(func);
12239aebfd4aSSean Wang 	struct hci_dev *hdev;
12249aebfd4aSSean Wang 
12259aebfd4aSSean Wang 	if (!bdev)
12269aebfd4aSSean Wang 		return;
12279aebfd4aSSean Wang 
12287f3c563cSSean Wang 	/* Be consistent the state in btmtksdio_probe */
12297f3c563cSSean Wang 	pm_runtime_get_noresume(bdev->dev);
12307f3c563cSSean Wang 
12319aebfd4aSSean Wang 	hdev = bdev->hdev;
12329aebfd4aSSean Wang 
12339aebfd4aSSean Wang 	sdio_set_drvdata(func, NULL);
12349aebfd4aSSean Wang 	hci_unregister_dev(hdev);
12359aebfd4aSSean Wang 	hci_free_dev(hdev);
12369aebfd4aSSean Wang }
12379aebfd4aSSean Wang 
12387f3c563cSSean Wang #ifdef CONFIG_PM
12397f3c563cSSean Wang static int btmtksdio_runtime_suspend(struct device *dev)
12407f3c563cSSean Wang {
12417f3c563cSSean Wang 	struct sdio_func *func = dev_to_sdio_func(dev);
12427f3c563cSSean Wang 	struct btmtksdio_dev *bdev;
12437f3c563cSSean Wang 	int err;
12447f3c563cSSean Wang 
12457f3c563cSSean Wang 	bdev = sdio_get_drvdata(func);
12467f3c563cSSean Wang 	if (!bdev)
12477f3c563cSSean Wang 		return 0;
12487f3c563cSSean Wang 
12494b4b2228SSean Wang 	if (!test_bit(BTMTKSDIO_FUNC_ENABLED, &bdev->tx_state))
12504b4b2228SSean Wang 		return 0;
12514b4b2228SSean Wang 
1252561ae1d4SSean Wang 	sdio_set_host_pm_flags(func, MMC_PM_KEEP_POWER);
1253561ae1d4SSean Wang 
1254c7e301d7SMark Chen 	err = btmtksdio_fw_pmctrl(bdev);
12557f3c563cSSean Wang 
1256*095519deSSean Wang 	bt_dev_dbg(bdev->hdev, "status (%d) return ownership to device", err);
12577f3c563cSSean Wang 
12587f3c563cSSean Wang 	return err;
12597f3c563cSSean Wang }
12607f3c563cSSean Wang 
12617f3c563cSSean Wang static int btmtksdio_runtime_resume(struct device *dev)
12627f3c563cSSean Wang {
12637f3c563cSSean Wang 	struct sdio_func *func = dev_to_sdio_func(dev);
12647f3c563cSSean Wang 	struct btmtksdio_dev *bdev;
12657f3c563cSSean Wang 	int err;
12667f3c563cSSean Wang 
12677f3c563cSSean Wang 	bdev = sdio_get_drvdata(func);
12687f3c563cSSean Wang 	if (!bdev)
12697f3c563cSSean Wang 		return 0;
12707f3c563cSSean Wang 
12714b4b2228SSean Wang 	if (!test_bit(BTMTKSDIO_FUNC_ENABLED, &bdev->tx_state))
12724b4b2228SSean Wang 		return 0;
12734b4b2228SSean Wang 
1274c7e301d7SMark Chen 	err = btmtksdio_drv_pmctrl(bdev);
12757f3c563cSSean Wang 
1276*095519deSSean Wang 	bt_dev_dbg(bdev->hdev, "status (%d) get ownership from device", err);
12777f3c563cSSean Wang 
12787f3c563cSSean Wang 	return err;
12797f3c563cSSean Wang }
12807f3c563cSSean Wang 
12817f3c563cSSean Wang static UNIVERSAL_DEV_PM_OPS(btmtksdio_pm_ops, btmtksdio_runtime_suspend,
12827f3c563cSSean Wang 			    btmtksdio_runtime_resume, NULL);
12837f3c563cSSean Wang #define BTMTKSDIO_PM_OPS (&btmtksdio_pm_ops)
12847f3c563cSSean Wang #else	/* CONFIG_PM */
12857f3c563cSSean Wang #define BTMTKSDIO_PM_OPS NULL
12867f3c563cSSean Wang #endif	/* CONFIG_PM */
12877f3c563cSSean Wang 
12889aebfd4aSSean Wang static struct sdio_driver btmtksdio_driver = {
12899aebfd4aSSean Wang 	.name		= "btmtksdio",
12909aebfd4aSSean Wang 	.probe		= btmtksdio_probe,
12919aebfd4aSSean Wang 	.remove		= btmtksdio_remove,
12929aebfd4aSSean Wang 	.id_table	= btmtksdio_table,
12937f3c563cSSean Wang 	.drv = {
12947f3c563cSSean Wang 		.owner = THIS_MODULE,
12957f3c563cSSean Wang 		.pm = BTMTKSDIO_PM_OPS,
12967f3c563cSSean Wang 	}
12979aebfd4aSSean Wang };
12989aebfd4aSSean Wang 
1299a6094a46SSean Wang module_sdio_driver(btmtksdio_driver);
13009aebfd4aSSean Wang 
13017f3c563cSSean Wang module_param(enable_autosuspend, bool, 0644);
13027f3c563cSSean Wang MODULE_PARM_DESC(enable_autosuspend, "Enable autosuspend by default");
13037f3c563cSSean Wang 
13049aebfd4aSSean Wang MODULE_AUTHOR("Sean Wang <sean.wang@mediatek.com>");
13059aebfd4aSSean Wang MODULE_DESCRIPTION("MediaTek Bluetooth SDIO driver ver " VERSION);
13069aebfd4aSSean Wang MODULE_VERSION(VERSION);
13079aebfd4aSSean Wang MODULE_LICENSE("GPL");
1308