xref: /linux/drivers/bluetooth/btmtksdio.c (revision 7ec462100ef9142344ddbf86f2c3008b97acddbe)
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 
13*5f60d5f6SAl Viro #include <linux/unaligned.h>
149aebfd4aSSean Wang #include <linux/atomic.h>
158fafe702SChih-Ying Chiang #include <linux/gpio/consumer.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>
208fafe702SChih-Ying Chiang #include <linux/of.h>
217f3c563cSSean Wang #include <linux/pm_runtime.h>
229aebfd4aSSean Wang #include <linux/skbuff.h>
23d019930bSChris Lu #include <linux/usb.h>
249aebfd4aSSean Wang 
259aebfd4aSSean Wang #include <linux/mmc/host.h>
269aebfd4aSSean Wang #include <linux/mmc/sdio_ids.h>
279aebfd4aSSean Wang #include <linux/mmc/sdio_func.h>
289aebfd4aSSean Wang 
299aebfd4aSSean Wang #include <net/bluetooth/bluetooth.h>
309aebfd4aSSean Wang #include <net/bluetooth/hci_core.h>
319aebfd4aSSean Wang 
329aebfd4aSSean Wang #include "h4_recv.h"
333a722044SSean Wang #include "btmtk.h"
349aebfd4aSSean Wang 
359aebfd4aSSean Wang #define VERSION "0.1"
369aebfd4aSSean Wang 
37e98aa38cSSean Wang #define MTKBTSDIO_AUTOSUSPEND_DELAY	1000
387f3c563cSSean Wang 
39e98aa38cSSean Wang static bool enable_autosuspend = true;
407f3c563cSSean Wang 
419aebfd4aSSean Wang struct btmtksdio_data {
429aebfd4aSSean Wang 	const char *fwname;
43c603bf1fSSean Wang 	u16 chipid;
4401ecc177SMark Chen 	bool lp_mbox_supported;
459aebfd4aSSean Wang };
469aebfd4aSSean Wang 
479aebfd4aSSean Wang static const struct btmtksdio_data mt7663_data = {
489aebfd4aSSean Wang 	.fwname = FIRMWARE_MT7663,
49c603bf1fSSean Wang 	.chipid = 0x7663,
5001ecc177SMark Chen 	.lp_mbox_supported = false,
519aebfd4aSSean Wang };
529aebfd4aSSean Wang 
539aebfd4aSSean Wang static const struct btmtksdio_data mt7668_data = {
549aebfd4aSSean Wang 	.fwname = FIRMWARE_MT7668,
55c603bf1fSSean Wang 	.chipid = 0x7668,
5601ecc177SMark Chen 	.lp_mbox_supported = false,
57c603bf1fSSean Wang };
58c603bf1fSSean Wang 
59c603bf1fSSean Wang static const struct btmtksdio_data mt7921_data = {
60c603bf1fSSean Wang 	.fwname = FIRMWARE_MT7961,
61c603bf1fSSean Wang 	.chipid = 0x7921,
6201ecc177SMark Chen 	.lp_mbox_supported = true,
639aebfd4aSSean Wang };
649aebfd4aSSean Wang 
659aebfd4aSSean Wang static const struct sdio_device_id btmtksdio_table[] = {
66baaa110dSPali Rohár 	{SDIO_DEVICE(SDIO_VENDOR_ID_MEDIATEK, SDIO_DEVICE_ID_MEDIATEK_MT7663),
679aebfd4aSSean Wang 	 .driver_data = (kernel_ulong_t)&mt7663_data },
68baaa110dSPali Rohár 	{SDIO_DEVICE(SDIO_VENDOR_ID_MEDIATEK, SDIO_DEVICE_ID_MEDIATEK_MT7668),
699aebfd4aSSean Wang 	 .driver_data = (kernel_ulong_t)&mt7668_data },
70c603bf1fSSean Wang 	{SDIO_DEVICE(SDIO_VENDOR_ID_MEDIATEK, SDIO_DEVICE_ID_MEDIATEK_MT7961),
71c603bf1fSSean Wang 	 .driver_data = (kernel_ulong_t)&mt7921_data },
729aebfd4aSSean Wang 	{ }	/* Terminating entry */
739aebfd4aSSean Wang };
7453121a7cSBartosz Golaszewski MODULE_DEVICE_TABLE(sdio, btmtksdio_table);
759aebfd4aSSean Wang 
769aebfd4aSSean Wang #define MTK_REG_CHLPCR		0x4	/* W1S */
779aebfd4aSSean Wang #define C_INT_EN_SET		BIT(0)
789aebfd4aSSean Wang #define C_INT_EN_CLR		BIT(1)
792e47cc2bSSean Wang #define C_FW_OWN_REQ_SET	BIT(8)  /* For write */
802e47cc2bSSean Wang #define C_COM_DRV_OWN		BIT(8)  /* For read */
819aebfd4aSSean Wang #define C_FW_OWN_REQ_CLR	BIT(9)
829aebfd4aSSean Wang 
839aebfd4aSSean Wang #define MTK_REG_CSDIOCSR	0x8
849aebfd4aSSean Wang #define SDIO_RE_INIT_EN		BIT(0)
859aebfd4aSSean Wang #define SDIO_INT_CTL		BIT(2)
869aebfd4aSSean Wang 
879aebfd4aSSean Wang #define MTK_REG_CHCR		0xc
889aebfd4aSSean Wang #define C_INT_CLR_CTRL		BIT(1)
898fafe702SChih-Ying Chiang #define BT_RST_DONE		BIT(8)
909aebfd4aSSean Wang 
919aebfd4aSSean Wang /* CHISR have the same bits field definition with CHIER */
929aebfd4aSSean Wang #define MTK_REG_CHISR		0x10
939aebfd4aSSean Wang #define MTK_REG_CHIER		0x14
949aebfd4aSSean Wang #define FW_OWN_BACK_INT		BIT(0)
959aebfd4aSSean Wang #define RX_DONE_INT		BIT(1)
969aebfd4aSSean Wang #define TX_EMPTY		BIT(2)
979aebfd4aSSean Wang #define TX_FIFO_OVERFLOW	BIT(8)
982fc967ccSMark Chen #define FW_MAILBOX_INT		BIT(15)
99db3f1f9bSSean Wang #define INT_MASK		GENMASK(15, 0)
1009aebfd4aSSean Wang #define RX_PKT_LEN		GENMASK(31, 16)
1019aebfd4aSSean Wang 
10201ecc177SMark Chen #define MTK_REG_CSICR		0xc0
10301ecc177SMark Chen #define CSICR_CLR_MBOX_ACK BIT(0)
1042fc967ccSMark Chen #define MTK_REG_PH2DSM0R	0xc4
1052fc967ccSMark Chen #define PH2DSM0R_DRIVER_OWN	BIT(0)
10601ecc177SMark Chen #define MTK_REG_PD2HRM0R	0xdc
10701ecc177SMark Chen #define PD2HRM0R_DRV_OWN	BIT(0)
1082fc967ccSMark Chen 
1099aebfd4aSSean Wang #define MTK_REG_CTDR		0x18
1109aebfd4aSSean Wang 
1119aebfd4aSSean Wang #define MTK_REG_CRDR		0x1c
1129aebfd4aSSean Wang 
113184ea403SSean Wang #define MTK_REG_CRPLR		0x24
114184ea403SSean Wang 
1159aebfd4aSSean Wang #define MTK_SDIO_BLOCK_SIZE	256
1169aebfd4aSSean Wang 
1179aebfd4aSSean Wang #define BTMTKSDIO_TX_WAIT_VND_EVT	1
118d555b1f2SSean Wang #define BTMTKSDIO_HW_TX_READY		2
1194b4b2228SSean Wang #define BTMTKSDIO_FUNC_ENABLED		3
12001ecc177SMark Chen #define BTMTKSDIO_PATCH_ENABLED		4
1218fafe702SChih-Ying Chiang #define BTMTKSDIO_HW_RESET_ACTIVE	5
1224ed924fcSZhengping Jiang #define BTMTKSDIO_BT_WAKE_ENABLED	6
1239aebfd4aSSean Wang 
1249aebfd4aSSean Wang struct mtkbtsdio_hdr {
1259aebfd4aSSean Wang 	__le16	len;
1269aebfd4aSSean Wang 	__le16	reserved;
1279aebfd4aSSean Wang 	u8	bt_type;
1289aebfd4aSSean Wang } __packed;
1299aebfd4aSSean Wang 
1309aebfd4aSSean Wang struct btmtksdio_dev {
1319aebfd4aSSean Wang 	struct hci_dev *hdev;
1329aebfd4aSSean Wang 	struct sdio_func *func;
1337f3c563cSSean Wang 	struct device *dev;
1349aebfd4aSSean Wang 
13526270bc1SSean Wang 	struct work_struct txrx_work;
1369aebfd4aSSean Wang 	unsigned long tx_state;
1379aebfd4aSSean Wang 	struct sk_buff_head txq;
1389aebfd4aSSean Wang 
1399aebfd4aSSean Wang 	struct sk_buff *evt_skb;
1409aebfd4aSSean Wang 
1419aebfd4aSSean Wang 	const struct btmtksdio_data *data;
1428fafe702SChih-Ying Chiang 
1438fafe702SChih-Ying Chiang 	struct gpio_desc *reset;
1449aebfd4aSSean Wang };
1459aebfd4aSSean Wang 
mtk_hci_wmt_sync(struct hci_dev * hdev,struct btmtk_hci_wmt_params * wmt_params)1469aebfd4aSSean Wang static int mtk_hci_wmt_sync(struct hci_dev *hdev,
1479aebfd4aSSean Wang 			    struct btmtk_hci_wmt_params *wmt_params)
1489aebfd4aSSean Wang {
1499aebfd4aSSean Wang 	struct btmtksdio_dev *bdev = hci_get_drvdata(hdev);
1509aebfd4aSSean Wang 	struct btmtk_hci_wmt_evt_funcc *wmt_evt_funcc;
151c603bf1fSSean Wang 	struct btmtk_hci_wmt_evt_reg *wmt_evt_reg;
1529aebfd4aSSean Wang 	u32 hlen, status = BTMTK_WMT_INVALID;
1539aebfd4aSSean Wang 	struct btmtk_hci_wmt_evt *wmt_evt;
1543a722044SSean Wang 	struct btmtk_hci_wmt_cmd *wc;
1553a722044SSean Wang 	struct btmtk_wmt_hdr *hdr;
1569aebfd4aSSean Wang 	int err;
1579aebfd4aSSean Wang 
1583a722044SSean Wang 	/* Send the WMT command and wait until the WMT event returns */
1599aebfd4aSSean Wang 	hlen = sizeof(*hdr) + wmt_params->dlen;
1609aebfd4aSSean Wang 	if (hlen > 255)
1619aebfd4aSSean Wang 		return -EINVAL;
1629aebfd4aSSean Wang 
1633a722044SSean Wang 	wc = kzalloc(hlen, GFP_KERNEL);
1643a722044SSean Wang 	if (!wc)
1653a722044SSean Wang 		return -ENOMEM;
1663a722044SSean Wang 
1673a722044SSean Wang 	hdr = &wc->hdr;
1689aebfd4aSSean Wang 	hdr->dir = 1;
1699aebfd4aSSean Wang 	hdr->op = wmt_params->op;
1709aebfd4aSSean Wang 	hdr->dlen = cpu_to_le16(wmt_params->dlen + 1);
1719aebfd4aSSean Wang 	hdr->flag = wmt_params->flag;
1723a722044SSean Wang 	memcpy(wc->data, wmt_params->data, wmt_params->dlen);
1739aebfd4aSSean Wang 
1749aebfd4aSSean Wang 	set_bit(BTMTKSDIO_TX_WAIT_VND_EVT, &bdev->tx_state);
1759aebfd4aSSean Wang 
1763a722044SSean Wang 	err = __hci_cmd_send(hdev, 0xfc6f, hlen, wc);
1779aebfd4aSSean Wang 	if (err < 0) {
1789aebfd4aSSean Wang 		clear_bit(BTMTKSDIO_TX_WAIT_VND_EVT, &bdev->tx_state);
1793a722044SSean Wang 		goto err_free_wc;
1809aebfd4aSSean Wang 	}
1819aebfd4aSSean Wang 
1829aebfd4aSSean Wang 	/* The vendor specific WMT commands are all answered by a vendor
1839aebfd4aSSean Wang 	 * specific event and will not have the Command Status or Command
1849aebfd4aSSean Wang 	 * Complete as with usual HCI command flow control.
1859aebfd4aSSean Wang 	 *
1869aebfd4aSSean Wang 	 * After sending the command, wait for BTMTKSDIO_TX_WAIT_VND_EVT
1879aebfd4aSSean Wang 	 * state to be cleared. The driver specific event receive routine
1889aebfd4aSSean Wang 	 * will clear that state and with that indicate completion of the
1899aebfd4aSSean Wang 	 * WMT command.
1909aebfd4aSSean Wang 	 */
1919aebfd4aSSean Wang 	err = wait_on_bit_timeout(&bdev->tx_state, BTMTKSDIO_TX_WAIT_VND_EVT,
1929aebfd4aSSean Wang 				  TASK_INTERRUPTIBLE, HCI_INIT_TIMEOUT);
1939aebfd4aSSean Wang 	if (err == -EINTR) {
1949aebfd4aSSean Wang 		bt_dev_err(hdev, "Execution of wmt command interrupted");
1959aebfd4aSSean Wang 		clear_bit(BTMTKSDIO_TX_WAIT_VND_EVT, &bdev->tx_state);
1963a722044SSean Wang 		goto err_free_wc;
1979aebfd4aSSean Wang 	}
1989aebfd4aSSean Wang 
1999aebfd4aSSean Wang 	if (err) {
2009aebfd4aSSean Wang 		bt_dev_err(hdev, "Execution of wmt command timed out");
2019aebfd4aSSean Wang 		clear_bit(BTMTKSDIO_TX_WAIT_VND_EVT, &bdev->tx_state);
2023a722044SSean Wang 		err = -ETIMEDOUT;
2033a722044SSean Wang 		goto err_free_wc;
2049aebfd4aSSean Wang 	}
2059aebfd4aSSean Wang 
2069aebfd4aSSean Wang 	/* Parse and handle the return WMT event */
2079aebfd4aSSean Wang 	wmt_evt = (struct btmtk_hci_wmt_evt *)bdev->evt_skb->data;
2089aebfd4aSSean Wang 	if (wmt_evt->whdr.op != hdr->op) {
2099aebfd4aSSean Wang 		bt_dev_err(hdev, "Wrong op received %d expected %d",
2109aebfd4aSSean Wang 			   wmt_evt->whdr.op, hdr->op);
2119aebfd4aSSean Wang 		err = -EIO;
2129aebfd4aSSean Wang 		goto err_free_skb;
2139aebfd4aSSean Wang 	}
2149aebfd4aSSean Wang 
2159aebfd4aSSean Wang 	switch (wmt_evt->whdr.op) {
2163a722044SSean Wang 	case BTMTK_WMT_SEMAPHORE:
2179aebfd4aSSean Wang 		if (wmt_evt->whdr.flag == 2)
2189aebfd4aSSean Wang 			status = BTMTK_WMT_PATCH_UNDONE;
2199aebfd4aSSean Wang 		else
2209aebfd4aSSean Wang 			status = BTMTK_WMT_PATCH_DONE;
2219aebfd4aSSean Wang 		break;
2223a722044SSean Wang 	case BTMTK_WMT_FUNC_CTRL:
2239aebfd4aSSean Wang 		wmt_evt_funcc = (struct btmtk_hci_wmt_evt_funcc *)wmt_evt;
2249aebfd4aSSean Wang 		if (be16_to_cpu(wmt_evt_funcc->status) == 0x404)
2259aebfd4aSSean Wang 			status = BTMTK_WMT_ON_DONE;
2269aebfd4aSSean Wang 		else if (be16_to_cpu(wmt_evt_funcc->status) == 0x420)
2279aebfd4aSSean Wang 			status = BTMTK_WMT_ON_PROGRESS;
2289aebfd4aSSean Wang 		else
2299aebfd4aSSean Wang 			status = BTMTK_WMT_ON_UNDONE;
2309aebfd4aSSean Wang 		break;
231c603bf1fSSean Wang 	case BTMTK_WMT_PATCH_DWNLD:
232c603bf1fSSean Wang 		if (wmt_evt->whdr.flag == 2)
233c603bf1fSSean Wang 			status = BTMTK_WMT_PATCH_DONE;
234c603bf1fSSean Wang 		else if (wmt_evt->whdr.flag == 1)
235c603bf1fSSean Wang 			status = BTMTK_WMT_PATCH_PROGRESS;
236c603bf1fSSean Wang 		else
237c603bf1fSSean Wang 			status = BTMTK_WMT_PATCH_UNDONE;
238c603bf1fSSean Wang 		break;
239c603bf1fSSean Wang 	case BTMTK_WMT_REGISTER:
240c603bf1fSSean Wang 		wmt_evt_reg = (struct btmtk_hci_wmt_evt_reg *)wmt_evt;
241c603bf1fSSean Wang 		if (le16_to_cpu(wmt_evt->whdr.dlen) == 12)
242c603bf1fSSean Wang 			status = le32_to_cpu(wmt_evt_reg->val);
243c603bf1fSSean Wang 		break;
2449aebfd4aSSean Wang 	}
2459aebfd4aSSean Wang 
2469aebfd4aSSean Wang 	if (wmt_params->status)
2479aebfd4aSSean Wang 		*wmt_params->status = status;
2489aebfd4aSSean Wang 
2499aebfd4aSSean Wang err_free_skb:
2509aebfd4aSSean Wang 	kfree_skb(bdev->evt_skb);
2519aebfd4aSSean Wang 	bdev->evt_skb = NULL;
2523a722044SSean Wang err_free_wc:
2533a722044SSean Wang 	kfree(wc);
2549aebfd4aSSean Wang 
2559aebfd4aSSean Wang 	return err;
2569aebfd4aSSean Wang }
2579aebfd4aSSean Wang 
btmtksdio_tx_packet(struct btmtksdio_dev * bdev,struct sk_buff * skb)2589aebfd4aSSean Wang static int btmtksdio_tx_packet(struct btmtksdio_dev *bdev,
2599aebfd4aSSean Wang 			       struct sk_buff *skb)
2609aebfd4aSSean Wang {
2619aebfd4aSSean Wang 	struct mtkbtsdio_hdr *sdio_hdr;
2629aebfd4aSSean Wang 	int err;
2639aebfd4aSSean Wang 
2649aebfd4aSSean Wang 	/* Make sure that there are enough rooms for SDIO header */
2659aebfd4aSSean Wang 	if (unlikely(skb_headroom(skb) < sizeof(*sdio_hdr))) {
2669aebfd4aSSean Wang 		err = pskb_expand_head(skb, sizeof(*sdio_hdr), 0,
2679aebfd4aSSean Wang 				       GFP_ATOMIC);
2689aebfd4aSSean Wang 		if (err < 0)
2699aebfd4aSSean Wang 			return err;
2709aebfd4aSSean Wang 	}
2719aebfd4aSSean Wang 
2729aebfd4aSSean Wang 	/* Prepend MediaTek SDIO Specific Header */
2739aebfd4aSSean Wang 	skb_push(skb, sizeof(*sdio_hdr));
2749aebfd4aSSean Wang 
2759aebfd4aSSean Wang 	sdio_hdr = (void *)skb->data;
2769aebfd4aSSean Wang 	sdio_hdr->len = cpu_to_le16(skb->len);
2779aebfd4aSSean Wang 	sdio_hdr->reserved = cpu_to_le16(0);
2789aebfd4aSSean Wang 	sdio_hdr->bt_type = hci_skb_pkt_type(skb);
2799aebfd4aSSean Wang 
280d555b1f2SSean Wang 	clear_bit(BTMTKSDIO_HW_TX_READY, &bdev->tx_state);
2819aebfd4aSSean Wang 	err = sdio_writesb(bdev->func, MTK_REG_CTDR, skb->data,
2829aebfd4aSSean Wang 			   round_up(skb->len, MTK_SDIO_BLOCK_SIZE));
2839aebfd4aSSean Wang 	if (err < 0)
2849aebfd4aSSean Wang 		goto err_skb_pull;
2859aebfd4aSSean Wang 
2869aebfd4aSSean Wang 	bdev->hdev->stat.byte_tx += skb->len;
2879aebfd4aSSean Wang 
2889aebfd4aSSean Wang 	kfree_skb(skb);
2899aebfd4aSSean Wang 
2909aebfd4aSSean Wang 	return 0;
2919aebfd4aSSean Wang 
2929aebfd4aSSean Wang err_skb_pull:
2939aebfd4aSSean Wang 	skb_pull(skb, sizeof(*sdio_hdr));
2949aebfd4aSSean Wang 
2959aebfd4aSSean Wang 	return err;
2969aebfd4aSSean Wang }
2979aebfd4aSSean Wang 
btmtksdio_drv_own_query(struct btmtksdio_dev * bdev)2989aebfd4aSSean Wang static u32 btmtksdio_drv_own_query(struct btmtksdio_dev *bdev)
2999aebfd4aSSean Wang {
3009aebfd4aSSean Wang 	return sdio_readl(bdev->func, MTK_REG_CHLPCR, NULL);
3019aebfd4aSSean Wang }
3029aebfd4aSSean Wang 
btmtksdio_drv_own_query_79xx(struct btmtksdio_dev * bdev)30301ecc177SMark Chen static u32 btmtksdio_drv_own_query_79xx(struct btmtksdio_dev *bdev)
30401ecc177SMark Chen {
30501ecc177SMark Chen 	return sdio_readl(bdev->func, MTK_REG_PD2HRM0R, NULL);
30601ecc177SMark Chen }
30701ecc177SMark Chen 
btmtksdio_chcr_query(struct btmtksdio_dev * bdev)3088fafe702SChih-Ying Chiang static u32 btmtksdio_chcr_query(struct btmtksdio_dev *bdev)
3098fafe702SChih-Ying Chiang {
3108fafe702SChih-Ying Chiang 	return sdio_readl(bdev->func, MTK_REG_CHCR, NULL);
3118fafe702SChih-Ying Chiang }
3128fafe702SChih-Ying Chiang 
btmtksdio_fw_pmctrl(struct btmtksdio_dev * bdev)313c7e301d7SMark Chen static int btmtksdio_fw_pmctrl(struct btmtksdio_dev *bdev)
314c7e301d7SMark Chen {
315c7e301d7SMark Chen 	u32 status;
316c7e301d7SMark Chen 	int err;
317c7e301d7SMark Chen 
318c7e301d7SMark Chen 	sdio_claim_host(bdev->func);
319c7e301d7SMark Chen 
32001ecc177SMark Chen 	if (bdev->data->lp_mbox_supported &&
32101ecc177SMark Chen 	    test_bit(BTMTKSDIO_PATCH_ENABLED, &bdev->tx_state)) {
32201ecc177SMark Chen 		sdio_writel(bdev->func, CSICR_CLR_MBOX_ACK, MTK_REG_CSICR,
32301ecc177SMark Chen 			    &err);
32401ecc177SMark Chen 		err = readx_poll_timeout(btmtksdio_drv_own_query_79xx, bdev,
32501ecc177SMark Chen 					 status, !(status & PD2HRM0R_DRV_OWN),
32601ecc177SMark Chen 					 2000, 1000000);
32701ecc177SMark Chen 		if (err < 0) {
32801ecc177SMark Chen 			bt_dev_err(bdev->hdev, "mailbox ACK not cleared");
32901ecc177SMark Chen 			goto out;
33001ecc177SMark Chen 		}
33101ecc177SMark Chen 	}
33201ecc177SMark Chen 
333c7e301d7SMark Chen 	/* Return ownership to the device */
334c7e301d7SMark Chen 	sdio_writel(bdev->func, C_FW_OWN_REQ_SET, MTK_REG_CHLPCR, &err);
335c7e301d7SMark Chen 	if (err < 0)
336c7e301d7SMark Chen 		goto out;
337c7e301d7SMark Chen 
338c7e301d7SMark Chen 	err = readx_poll_timeout(btmtksdio_drv_own_query, bdev, status,
339c7e301d7SMark Chen 				 !(status & C_COM_DRV_OWN), 2000, 1000000);
340c7e301d7SMark Chen 
341c7e301d7SMark Chen out:
342c7e301d7SMark Chen 	sdio_release_host(bdev->func);
343c7e301d7SMark Chen 
344c7e301d7SMark Chen 	if (err < 0)
345c7e301d7SMark Chen 		bt_dev_err(bdev->hdev, "Cannot return ownership to device");
346c7e301d7SMark Chen 
347c7e301d7SMark Chen 	return err;
348c7e301d7SMark Chen }
349c7e301d7SMark Chen 
btmtksdio_drv_pmctrl(struct btmtksdio_dev * bdev)350c7e301d7SMark Chen static int btmtksdio_drv_pmctrl(struct btmtksdio_dev *bdev)
351c7e301d7SMark Chen {
352c7e301d7SMark Chen 	u32 status;
353c7e301d7SMark Chen 	int err;
354c7e301d7SMark Chen 
355c7e301d7SMark Chen 	sdio_claim_host(bdev->func);
356c7e301d7SMark Chen 
357c7e301d7SMark Chen 	/* Get ownership from the device */
358c7e301d7SMark Chen 	sdio_writel(bdev->func, C_FW_OWN_REQ_CLR, MTK_REG_CHLPCR, &err);
359c7e301d7SMark Chen 	if (err < 0)
360c7e301d7SMark Chen 		goto out;
361c7e301d7SMark Chen 
362c7e301d7SMark Chen 	err = readx_poll_timeout(btmtksdio_drv_own_query, bdev, status,
363c7e301d7SMark Chen 				 status & C_COM_DRV_OWN, 2000, 1000000);
364c7e301d7SMark Chen 
36501ecc177SMark Chen 	if (!err && bdev->data->lp_mbox_supported &&
36601ecc177SMark Chen 	    test_bit(BTMTKSDIO_PATCH_ENABLED, &bdev->tx_state))
36701ecc177SMark Chen 		err = readx_poll_timeout(btmtksdio_drv_own_query_79xx, bdev,
36801ecc177SMark Chen 					 status, status & PD2HRM0R_DRV_OWN,
36901ecc177SMark Chen 					 2000, 1000000);
37001ecc177SMark Chen 
371c7e301d7SMark Chen out:
372c7e301d7SMark Chen 	sdio_release_host(bdev->func);
373c7e301d7SMark Chen 
374c7e301d7SMark Chen 	if (err < 0)
375c7e301d7SMark Chen 		bt_dev_err(bdev->hdev, "Cannot get ownership from device");
376c7e301d7SMark Chen 
377c7e301d7SMark Chen 	return err;
378c7e301d7SMark Chen }
379c7e301d7SMark Chen 
btmtksdio_recv_event(struct hci_dev * hdev,struct sk_buff * skb)3809aebfd4aSSean Wang static int btmtksdio_recv_event(struct hci_dev *hdev, struct sk_buff *skb)
3819aebfd4aSSean Wang {
3829aebfd4aSSean Wang 	struct btmtksdio_dev *bdev = hci_get_drvdata(hdev);
3839aebfd4aSSean Wang 	struct hci_event_hdr *hdr = (void *)skb->data;
3840fab6361SSean Wang 	u8 evt = hdr->evt;
3859aebfd4aSSean Wang 	int err;
3869aebfd4aSSean Wang 
3879aebfd4aSSean Wang 	/* When someone waits for the WMT event, the skb is being cloned
3889aebfd4aSSean Wang 	 * and being processed the events from there then.
3899aebfd4aSSean Wang 	 */
3909aebfd4aSSean Wang 	if (test_bit(BTMTKSDIO_TX_WAIT_VND_EVT, &bdev->tx_state)) {
3919aebfd4aSSean Wang 		bdev->evt_skb = skb_clone(skb, GFP_KERNEL);
3929aebfd4aSSean Wang 		if (!bdev->evt_skb) {
3939aebfd4aSSean Wang 			err = -ENOMEM;
3949aebfd4aSSean Wang 			goto err_out;
3959aebfd4aSSean Wang 		}
3969aebfd4aSSean Wang 	}
3979aebfd4aSSean Wang 
3989aebfd4aSSean Wang 	err = hci_recv_frame(hdev, skb);
3999aebfd4aSSean Wang 	if (err < 0)
4009aebfd4aSSean Wang 		goto err_free_skb;
4019aebfd4aSSean Wang 
4020fab6361SSean Wang 	if (evt == HCI_EV_WMT) {
4039aebfd4aSSean Wang 		if (test_and_clear_bit(BTMTKSDIO_TX_WAIT_VND_EVT,
4049aebfd4aSSean Wang 				       &bdev->tx_state)) {
4059aebfd4aSSean Wang 			/* Barrier to sync with other CPUs */
4069aebfd4aSSean Wang 			smp_mb__after_atomic();
4079aebfd4aSSean Wang 			wake_up_bit(&bdev->tx_state, BTMTKSDIO_TX_WAIT_VND_EVT);
4089aebfd4aSSean Wang 		}
4099aebfd4aSSean Wang 	}
4109aebfd4aSSean Wang 
4119aebfd4aSSean Wang 	return 0;
4129aebfd4aSSean Wang 
4139aebfd4aSSean Wang err_free_skb:
4149aebfd4aSSean Wang 	kfree_skb(bdev->evt_skb);
4159aebfd4aSSean Wang 	bdev->evt_skb = NULL;
4169aebfd4aSSean Wang 
4179aebfd4aSSean Wang err_out:
4189aebfd4aSSean Wang 	return err;
4199aebfd4aSSean Wang }
4209aebfd4aSSean Wang 
btmtksdio_recv_acl(struct hci_dev * hdev,struct sk_buff * skb)421db57b625SSean Wang static int btmtksdio_recv_acl(struct hci_dev *hdev, struct sk_buff *skb)
422db57b625SSean Wang {
423db57b625SSean Wang 	struct btmtksdio_dev *bdev = hci_get_drvdata(hdev);
424db57b625SSean Wang 	u16 handle = le16_to_cpu(hci_acl_hdr(skb)->handle);
425db57b625SSean Wang 
426db57b625SSean Wang 	switch (handle) {
427db57b625SSean Wang 	case 0xfc6f:
428db57b625SSean Wang 		/* Firmware dump from device: when the firmware hangs, the
429db57b625SSean Wang 		 * device can no longer suspend and thus disable auto-suspend.
430db57b625SSean Wang 		 */
431db57b625SSean Wang 		pm_runtime_forbid(bdev->dev);
432db57b625SSean Wang 		fallthrough;
433db57b625SSean Wang 	case 0x05ff:
434db57b625SSean Wang 	case 0x05fe:
435db57b625SSean Wang 		/* Firmware debug logging */
436db57b625SSean Wang 		return hci_recv_diag(hdev, skb);
437db57b625SSean Wang 	}
438db57b625SSean Wang 
439db57b625SSean Wang 	return hci_recv_frame(hdev, skb);
440db57b625SSean Wang }
441db57b625SSean Wang 
4429aebfd4aSSean Wang static const struct h4_recv_pkt mtk_recv_pkts[] = {
443db57b625SSean Wang 	{ H4_RECV_ACL,      .recv = btmtksdio_recv_acl },
4449aebfd4aSSean Wang 	{ H4_RECV_SCO,      .recv = hci_recv_frame },
4459aebfd4aSSean Wang 	{ H4_RECV_EVENT,    .recv = btmtksdio_recv_event },
4469aebfd4aSSean Wang };
4479aebfd4aSSean Wang 
btmtksdio_rx_packet(struct btmtksdio_dev * bdev,u16 rx_size)4489aebfd4aSSean Wang static int btmtksdio_rx_packet(struct btmtksdio_dev *bdev, u16 rx_size)
4499aebfd4aSSean Wang {
4509aebfd4aSSean Wang 	const struct h4_recv_pkt *pkts = mtk_recv_pkts;
4519aebfd4aSSean Wang 	int pkts_count = ARRAY_SIZE(mtk_recv_pkts);
4529aebfd4aSSean Wang 	struct mtkbtsdio_hdr *sdio_hdr;
4539aebfd4aSSean Wang 	int err, i, pad_size;
4549aebfd4aSSean Wang 	struct sk_buff *skb;
4559aebfd4aSSean Wang 	u16 dlen;
4569aebfd4aSSean Wang 
4579aebfd4aSSean Wang 	if (rx_size < sizeof(*sdio_hdr))
4589aebfd4aSSean Wang 		return -EILSEQ;
4599aebfd4aSSean Wang 
4609aebfd4aSSean Wang 	/* A SDIO packet is exactly containing a Bluetooth packet */
4619aebfd4aSSean Wang 	skb = bt_skb_alloc(rx_size, GFP_KERNEL);
4629aebfd4aSSean Wang 	if (!skb)
4639aebfd4aSSean Wang 		return -ENOMEM;
4649aebfd4aSSean Wang 
4659aebfd4aSSean Wang 	skb_put(skb, rx_size);
4669aebfd4aSSean Wang 
4679aebfd4aSSean Wang 	err = sdio_readsb(bdev->func, skb->data, MTK_REG_CRDR, rx_size);
4689aebfd4aSSean Wang 	if (err < 0)
4699aebfd4aSSean Wang 		goto err_kfree_skb;
4709aebfd4aSSean Wang 
4719aebfd4aSSean Wang 	sdio_hdr = (void *)skb->data;
4729aebfd4aSSean Wang 
4739aebfd4aSSean Wang 	/* We assume the default error as -EILSEQ simply to make the error path
4749aebfd4aSSean Wang 	 * be cleaner.
4759aebfd4aSSean Wang 	 */
4769aebfd4aSSean Wang 	err = -EILSEQ;
4779aebfd4aSSean Wang 
4789aebfd4aSSean Wang 	if (rx_size != le16_to_cpu(sdio_hdr->len)) {
4799aebfd4aSSean Wang 		bt_dev_err(bdev->hdev, "Rx size in sdio header is mismatched ");
4809aebfd4aSSean Wang 		goto err_kfree_skb;
4819aebfd4aSSean Wang 	}
4829aebfd4aSSean Wang 
4839aebfd4aSSean Wang 	hci_skb_pkt_type(skb) = sdio_hdr->bt_type;
4849aebfd4aSSean Wang 
4859aebfd4aSSean Wang 	/* Remove MediaTek SDIO header */
4869aebfd4aSSean Wang 	skb_pull(skb, sizeof(*sdio_hdr));
4879aebfd4aSSean Wang 
4889aebfd4aSSean Wang 	/* We have to dig into the packet to get payload size and then know how
4899aebfd4aSSean Wang 	 * many padding bytes at the tail, these padding bytes should be removed
4909aebfd4aSSean Wang 	 * before the packet is indicated to the core layer.
4919aebfd4aSSean Wang 	 */
4929aebfd4aSSean Wang 	for (i = 0; i < pkts_count; i++) {
4939aebfd4aSSean Wang 		if (sdio_hdr->bt_type == (&pkts[i])->type)
4949aebfd4aSSean Wang 			break;
4959aebfd4aSSean Wang 	}
4969aebfd4aSSean Wang 
4979aebfd4aSSean Wang 	if (i >= pkts_count) {
4989aebfd4aSSean Wang 		bt_dev_err(bdev->hdev, "Invalid bt type 0x%02x",
4999aebfd4aSSean Wang 			   sdio_hdr->bt_type);
5009aebfd4aSSean Wang 		goto err_kfree_skb;
5019aebfd4aSSean Wang 	}
5029aebfd4aSSean Wang 
5039aebfd4aSSean Wang 	/* Remaining bytes cannot hold a header*/
5049aebfd4aSSean Wang 	if (skb->len < (&pkts[i])->hlen) {
5059aebfd4aSSean Wang 		bt_dev_err(bdev->hdev, "The size of bt header is mismatched");
5069aebfd4aSSean Wang 		goto err_kfree_skb;
5079aebfd4aSSean Wang 	}
5089aebfd4aSSean Wang 
5099aebfd4aSSean Wang 	switch ((&pkts[i])->lsize) {
5109aebfd4aSSean Wang 	case 1:
5119aebfd4aSSean Wang 		dlen = skb->data[(&pkts[i])->loff];
5129aebfd4aSSean Wang 		break;
5139aebfd4aSSean Wang 	case 2:
5149aebfd4aSSean Wang 		dlen = get_unaligned_le16(skb->data +
5159aebfd4aSSean Wang 						  (&pkts[i])->loff);
5169aebfd4aSSean Wang 		break;
5179aebfd4aSSean Wang 	default:
5189aebfd4aSSean Wang 		goto err_kfree_skb;
5199aebfd4aSSean Wang 	}
5209aebfd4aSSean Wang 
5219aebfd4aSSean Wang 	pad_size = skb->len - (&pkts[i])->hlen -  dlen;
5229aebfd4aSSean Wang 
5239aebfd4aSSean Wang 	/* Remaining bytes cannot hold a payload */
5249aebfd4aSSean Wang 	if (pad_size < 0) {
5259aebfd4aSSean Wang 		bt_dev_err(bdev->hdev, "The size of bt payload is mismatched");
5269aebfd4aSSean Wang 		goto err_kfree_skb;
5279aebfd4aSSean Wang 	}
5289aebfd4aSSean Wang 
5299aebfd4aSSean Wang 	/* Remove padding bytes */
5309aebfd4aSSean Wang 	skb_trim(skb, skb->len - pad_size);
5319aebfd4aSSean Wang 
5329aebfd4aSSean Wang 	/* Complete frame */
5339aebfd4aSSean Wang 	(&pkts[i])->recv(bdev->hdev, skb);
5349aebfd4aSSean Wang 
535bcaa7d72SSean Wang 	bdev->hdev->stat.byte_rx += rx_size;
536bcaa7d72SSean Wang 
5379aebfd4aSSean Wang 	return 0;
5389aebfd4aSSean Wang 
5399aebfd4aSSean Wang err_kfree_skb:
5409aebfd4aSSean Wang 	kfree_skb(skb);
5419aebfd4aSSean Wang 
5429aebfd4aSSean Wang 	return err;
5439aebfd4aSSean Wang }
5449aebfd4aSSean Wang 
btmtksdio_txrx_work(struct work_struct * work)54526270bc1SSean Wang static void btmtksdio_txrx_work(struct work_struct *work)
5469aebfd4aSSean Wang {
54726270bc1SSean Wang 	struct btmtksdio_dev *bdev = container_of(work, struct btmtksdio_dev,
54826270bc1SSean Wang 						  txrx_work);
54926270bc1SSean Wang 	unsigned long txrx_timeout;
550184ea403SSean Wang 	u32 int_status, rx_size;
55126270bc1SSean Wang 	struct sk_buff *skb;
55226270bc1SSean Wang 	int err;
5537f3c563cSSean Wang 
5547f3c563cSSean Wang 	pm_runtime_get_sync(bdev->dev);
5557f3c563cSSean Wang 
5567f3c563cSSean Wang 	sdio_claim_host(bdev->func);
5577f3c563cSSean Wang 
5589aebfd4aSSean Wang 	/* Disable interrupt */
5594ed924fcSZhengping Jiang 	sdio_writel(bdev->func, C_INT_EN_CLR, MTK_REG_CHLPCR, NULL);
5609aebfd4aSSean Wang 
56126270bc1SSean Wang 	txrx_timeout = jiffies + 5 * HZ;
56226270bc1SSean Wang 
56326270bc1SSean Wang 	do {
56426270bc1SSean Wang 		int_status = sdio_readl(bdev->func, MTK_REG_CHISR, NULL);
5659aebfd4aSSean Wang 
5669aebfd4aSSean Wang 		/* Ack an interrupt as soon as possible before any operation on
5679aebfd4aSSean Wang 		 * hardware.
5689aebfd4aSSean Wang 		 *
5699aebfd4aSSean Wang 		 * Note that we don't ack any status during operations to avoid race
5709aebfd4aSSean Wang 		 * condition between the host and the device such as it's possible to
5719aebfd4aSSean Wang 		 * mistakenly ack RX_DONE for the next packet and then cause interrupts
5729aebfd4aSSean Wang 		 * not be raised again but there is still pending data in the hardware
5739aebfd4aSSean Wang 		 * FIFO.
5749aebfd4aSSean Wang 		 */
57526270bc1SSean Wang 		sdio_writel(bdev->func, int_status, MTK_REG_CHISR, NULL);
576db3f1f9bSSean Wang 		int_status &= INT_MASK;
5779aebfd4aSSean Wang 
5782fc967ccSMark Chen 		if ((int_status & FW_MAILBOX_INT) &&
5792fc967ccSMark Chen 		    bdev->data->chipid == 0x7921) {
5802fc967ccSMark Chen 			sdio_writel(bdev->func, PH2DSM0R_DRIVER_OWN,
5814ed924fcSZhengping Jiang 				    MTK_REG_PH2DSM0R, NULL);
5822fc967ccSMark Chen 		}
5832fc967ccSMark Chen 
5849aebfd4aSSean Wang 		if (int_status & FW_OWN_BACK_INT)
585e1052fb2SSean Wang 			bt_dev_dbg(bdev->hdev, "Get fw own back");
5869aebfd4aSSean Wang 
5879aebfd4aSSean Wang 		if (int_status & TX_EMPTY)
588d555b1f2SSean Wang 			set_bit(BTMTKSDIO_HW_TX_READY, &bdev->tx_state);
589d555b1f2SSean Wang 
5909aebfd4aSSean Wang 		else if (unlikely(int_status & TX_FIFO_OVERFLOW))
591e1052fb2SSean Wang 			bt_dev_warn(bdev->hdev, "Tx fifo overflow");
5929aebfd4aSSean Wang 
593d555b1f2SSean Wang 		if (test_bit(BTMTKSDIO_HW_TX_READY, &bdev->tx_state)) {
59410fe40e1SMark-yw Chen 			skb = skb_dequeue(&bdev->txq);
59510fe40e1SMark-yw Chen 			if (skb) {
59610fe40e1SMark-yw Chen 				err = btmtksdio_tx_packet(bdev, skb);
59710fe40e1SMark-yw Chen 				if (err < 0) {
59810fe40e1SMark-yw Chen 					bdev->hdev->stat.err_tx++;
59910fe40e1SMark-yw Chen 					skb_queue_head(&bdev->txq, skb);
60010fe40e1SMark-yw Chen 				}
60110fe40e1SMark-yw Chen 			}
60210fe40e1SMark-yw Chen 		}
60310fe40e1SMark-yw Chen 
6049aebfd4aSSean Wang 		if (int_status & RX_DONE_INT) {
605184ea403SSean Wang 			rx_size = sdio_readl(bdev->func, MTK_REG_CRPLR, NULL);
606184ea403SSean Wang 			rx_size = (rx_size & RX_PKT_LEN) >> 16;
6079aebfd4aSSean Wang 			if (btmtksdio_rx_packet(bdev, rx_size) < 0)
6089aebfd4aSSean Wang 				bdev->hdev->stat.err_rx++;
6099aebfd4aSSean Wang 		}
61026270bc1SSean Wang 	} while (int_status || time_is_before_jiffies(txrx_timeout));
61126270bc1SSean Wang 
6129aebfd4aSSean Wang 	/* Enable interrupt */
6134ed924fcSZhengping Jiang 	sdio_writel(bdev->func, C_INT_EN_SET, MTK_REG_CHLPCR, NULL);
61426270bc1SSean Wang 
61526270bc1SSean Wang 	sdio_release_host(bdev->func);
6167f3c563cSSean Wang 
6177f3c563cSSean Wang 	pm_runtime_mark_last_busy(bdev->dev);
6187f3c563cSSean Wang 	pm_runtime_put_autosuspend(bdev->dev);
6199aebfd4aSSean Wang }
6209aebfd4aSSean Wang 
btmtksdio_interrupt(struct sdio_func * func)62126270bc1SSean Wang static void btmtksdio_interrupt(struct sdio_func *func)
62226270bc1SSean Wang {
62326270bc1SSean Wang 	struct btmtksdio_dev *bdev = sdio_get_drvdata(func);
62426270bc1SSean Wang 
6254ed924fcSZhengping Jiang 	if (test_bit(BTMTKSDIO_BT_WAKE_ENABLED, &bdev->tx_state)) {
6264ed924fcSZhengping Jiang 		if (bdev->hdev->suspended)
6274ed924fcSZhengping Jiang 			pm_wakeup_event(bdev->dev, 0);
6284ed924fcSZhengping Jiang 		clear_bit(BTMTKSDIO_BT_WAKE_ENABLED, &bdev->tx_state);
6294ed924fcSZhengping Jiang 	}
6304ed924fcSZhengping Jiang 
63126270bc1SSean Wang 	/* Disable interrupt */
6324ed924fcSZhengping Jiang 	sdio_writel(bdev->func, C_INT_EN_CLR, MTK_REG_CHLPCR, NULL);
63326270bc1SSean Wang 
63426270bc1SSean Wang 	schedule_work(&bdev->txrx_work);
63526270bc1SSean Wang }
63626270bc1SSean Wang 
btmtksdio_open(struct hci_dev * hdev)6379aebfd4aSSean Wang static int btmtksdio_open(struct hci_dev *hdev)
6389aebfd4aSSean Wang {
6399aebfd4aSSean Wang 	struct btmtksdio_dev *bdev = hci_get_drvdata(hdev);
640c7e301d7SMark Chen 	u32 val;
6419aebfd4aSSean Wang 	int err;
6429aebfd4aSSean Wang 
6439aebfd4aSSean Wang 	sdio_claim_host(bdev->func);
6449aebfd4aSSean Wang 
6459aebfd4aSSean Wang 	err = sdio_enable_func(bdev->func);
6469aebfd4aSSean Wang 	if (err < 0)
6479aebfd4aSSean Wang 		goto err_release_host;
6489aebfd4aSSean Wang 
6494b4b2228SSean Wang 	set_bit(BTMTKSDIO_FUNC_ENABLED, &bdev->tx_state);
6504b4b2228SSean Wang 
651c7e301d7SMark Chen 	err = btmtksdio_drv_pmctrl(bdev);
6529aebfd4aSSean Wang 	if (err < 0)
6539aebfd4aSSean Wang 		goto err_disable_func;
6549aebfd4aSSean Wang 
6559aebfd4aSSean Wang 	/* Disable interrupt & mask out all interrupt sources */
6569aebfd4aSSean Wang 	sdio_writel(bdev->func, C_INT_EN_CLR, MTK_REG_CHLPCR, &err);
6579aebfd4aSSean Wang 	if (err < 0)
6589aebfd4aSSean Wang 		goto err_disable_func;
6599aebfd4aSSean Wang 
6609aebfd4aSSean Wang 	sdio_writel(bdev->func, 0, MTK_REG_CHIER, &err);
6619aebfd4aSSean Wang 	if (err < 0)
6629aebfd4aSSean Wang 		goto err_disable_func;
6639aebfd4aSSean Wang 
6649aebfd4aSSean Wang 	err = sdio_claim_irq(bdev->func, btmtksdio_interrupt);
6659aebfd4aSSean Wang 	if (err < 0)
6669aebfd4aSSean Wang 		goto err_disable_func;
6679aebfd4aSSean Wang 
6689aebfd4aSSean Wang 	err = sdio_set_block_size(bdev->func, MTK_SDIO_BLOCK_SIZE);
6699aebfd4aSSean Wang 	if (err < 0)
6709aebfd4aSSean Wang 		goto err_release_irq;
6719aebfd4aSSean Wang 
6729aebfd4aSSean Wang 	/* SDIO CMD 5 allows the SDIO device back to idle state an
6739aebfd4aSSean Wang 	 * synchronous interrupt is supported in SDIO 4-bit mode
6749aebfd4aSSean Wang 	 */
6755b23ac1aSSean Wang 	val = sdio_readl(bdev->func, MTK_REG_CSDIOCSR, &err);
6765b23ac1aSSean Wang 	if (err < 0)
6775b23ac1aSSean Wang 		goto err_release_irq;
6785b23ac1aSSean Wang 
6795b23ac1aSSean Wang 	val |= SDIO_INT_CTL;
6805b23ac1aSSean Wang 	sdio_writel(bdev->func, val, MTK_REG_CSDIOCSR, &err);
6819aebfd4aSSean Wang 	if (err < 0)
6829aebfd4aSSean Wang 		goto err_release_irq;
6839aebfd4aSSean Wang 
68477b210d1SSean Wang 	/* Explitly set write-1-clear method */
68577b210d1SSean Wang 	val = sdio_readl(bdev->func, MTK_REG_CHCR, &err);
68677b210d1SSean Wang 	if (err < 0)
68777b210d1SSean Wang 		goto err_release_irq;
68877b210d1SSean Wang 
68977b210d1SSean Wang 	val |= C_INT_CLR_CTRL;
69077b210d1SSean Wang 	sdio_writel(bdev->func, val, MTK_REG_CHCR, &err);
6919aebfd4aSSean Wang 	if (err < 0)
6929aebfd4aSSean Wang 		goto err_release_irq;
6939aebfd4aSSean Wang 
6949aebfd4aSSean Wang 	/* Setup interrupt sources */
6959aebfd4aSSean Wang 	sdio_writel(bdev->func, RX_DONE_INT | TX_EMPTY | TX_FIFO_OVERFLOW,
6969aebfd4aSSean Wang 		    MTK_REG_CHIER, &err);
6979aebfd4aSSean Wang 	if (err < 0)
6989aebfd4aSSean Wang 		goto err_release_irq;
6999aebfd4aSSean Wang 
7009aebfd4aSSean Wang 	/* Enable interrupt */
7019aebfd4aSSean Wang 	sdio_writel(bdev->func, C_INT_EN_SET, MTK_REG_CHLPCR, &err);
7029aebfd4aSSean Wang 	if (err < 0)
7039aebfd4aSSean Wang 		goto err_release_irq;
7049aebfd4aSSean Wang 
7059aebfd4aSSean Wang 	sdio_release_host(bdev->func);
7069aebfd4aSSean Wang 
7079aebfd4aSSean Wang 	return 0;
7089aebfd4aSSean Wang 
7099aebfd4aSSean Wang err_release_irq:
7109aebfd4aSSean Wang 	sdio_release_irq(bdev->func);
7119aebfd4aSSean Wang 
7129aebfd4aSSean Wang err_disable_func:
7139aebfd4aSSean Wang 	sdio_disable_func(bdev->func);
7149aebfd4aSSean Wang 
7159aebfd4aSSean Wang err_release_host:
7169aebfd4aSSean Wang 	sdio_release_host(bdev->func);
7179aebfd4aSSean Wang 
7189aebfd4aSSean Wang 	return err;
7199aebfd4aSSean Wang }
7209aebfd4aSSean Wang 
btmtksdio_close(struct hci_dev * hdev)7219aebfd4aSSean Wang static int btmtksdio_close(struct hci_dev *hdev)
7229aebfd4aSSean Wang {
7239aebfd4aSSean Wang 	struct btmtksdio_dev *bdev = hci_get_drvdata(hdev);
7249aebfd4aSSean Wang 
7259aebfd4aSSean Wang 	sdio_claim_host(bdev->func);
7269aebfd4aSSean Wang 
7279aebfd4aSSean Wang 	/* Disable interrupt */
7289aebfd4aSSean Wang 	sdio_writel(bdev->func, C_INT_EN_CLR, MTK_REG_CHLPCR, NULL);
7299aebfd4aSSean Wang 
7309aebfd4aSSean Wang 	sdio_release_irq(bdev->func);
7319aebfd4aSSean Wang 
73226270bc1SSean Wang 	cancel_work_sync(&bdev->txrx_work);
73326270bc1SSean Wang 
734c7e301d7SMark Chen 	btmtksdio_fw_pmctrl(bdev);
7359aebfd4aSSean Wang 
7364b4b2228SSean Wang 	clear_bit(BTMTKSDIO_FUNC_ENABLED, &bdev->tx_state);
7379aebfd4aSSean Wang 	sdio_disable_func(bdev->func);
7389aebfd4aSSean Wang 
7399aebfd4aSSean Wang 	sdio_release_host(bdev->func);
7409aebfd4aSSean Wang 
7419aebfd4aSSean Wang 	return 0;
7429aebfd4aSSean Wang }
7439aebfd4aSSean Wang 
btmtksdio_flush(struct hci_dev * hdev)7449aebfd4aSSean Wang static int btmtksdio_flush(struct hci_dev *hdev)
7459aebfd4aSSean Wang {
7469aebfd4aSSean Wang 	struct btmtksdio_dev *bdev = hci_get_drvdata(hdev);
7479aebfd4aSSean Wang 
7489aebfd4aSSean Wang 	skb_queue_purge(&bdev->txq);
7499aebfd4aSSean Wang 
75026270bc1SSean Wang 	cancel_work_sync(&bdev->txrx_work);
7519aebfd4aSSean Wang 
7529aebfd4aSSean Wang 	return 0;
7539aebfd4aSSean Wang }
7549aebfd4aSSean Wang 
btmtksdio_func_query(struct hci_dev * hdev)7559aebfd4aSSean Wang static int btmtksdio_func_query(struct hci_dev *hdev)
7569aebfd4aSSean Wang {
7579aebfd4aSSean Wang 	struct btmtk_hci_wmt_params wmt_params;
7589aebfd4aSSean Wang 	int status, err;
7599aebfd4aSSean Wang 	u8 param = 0;
7609aebfd4aSSean Wang 
7619aebfd4aSSean Wang 	/* Query whether the function is enabled */
7623a722044SSean Wang 	wmt_params.op = BTMTK_WMT_FUNC_CTRL;
7639aebfd4aSSean Wang 	wmt_params.flag = 4;
7649aebfd4aSSean Wang 	wmt_params.dlen = sizeof(param);
7659aebfd4aSSean Wang 	wmt_params.data = &param;
7669aebfd4aSSean Wang 	wmt_params.status = &status;
7679aebfd4aSSean Wang 
7689aebfd4aSSean Wang 	err = mtk_hci_wmt_sync(hdev, &wmt_params);
7699aebfd4aSSean Wang 	if (err < 0) {
7709aebfd4aSSean Wang 		bt_dev_err(hdev, "Failed to query function status (%d)", err);
7719aebfd4aSSean Wang 		return err;
7729aebfd4aSSean Wang 	}
7739aebfd4aSSean Wang 
7749aebfd4aSSean Wang 	return status;
7759aebfd4aSSean Wang }
7769aebfd4aSSean Wang 
mt76xx_setup(struct hci_dev * hdev,const char * fwname)777c603bf1fSSean Wang static int mt76xx_setup(struct hci_dev *hdev, const char *fwname)
7789aebfd4aSSean Wang {
77901ecc177SMark Chen 	struct btmtksdio_dev *bdev = hci_get_drvdata(hdev);
7809aebfd4aSSean Wang 	struct btmtk_hci_wmt_params wmt_params;
7819aebfd4aSSean Wang 	struct btmtk_tci_sleep tci_sleep;
7829aebfd4aSSean Wang 	struct sk_buff *skb;
7839aebfd4aSSean Wang 	int err, status;
7849aebfd4aSSean Wang 	u8 param = 0x1;
7859aebfd4aSSean Wang 
7869aebfd4aSSean Wang 	/* Query whether the firmware is already download */
7873a722044SSean Wang 	wmt_params.op = BTMTK_WMT_SEMAPHORE;
7889aebfd4aSSean Wang 	wmt_params.flag = 1;
7899aebfd4aSSean Wang 	wmt_params.dlen = 0;
7909aebfd4aSSean Wang 	wmt_params.data = NULL;
7919aebfd4aSSean Wang 	wmt_params.status = &status;
7929aebfd4aSSean Wang 
7939aebfd4aSSean Wang 	err = mtk_hci_wmt_sync(hdev, &wmt_params);
7949aebfd4aSSean Wang 	if (err < 0) {
7959aebfd4aSSean Wang 		bt_dev_err(hdev, "Failed to query firmware status (%d)", err);
7969aebfd4aSSean Wang 		return err;
7979aebfd4aSSean Wang 	}
7989aebfd4aSSean Wang 
7999aebfd4aSSean Wang 	if (status == BTMTK_WMT_PATCH_DONE) {
8009aebfd4aSSean Wang 		bt_dev_info(hdev, "Firmware already downloaded");
8019aebfd4aSSean Wang 		goto ignore_setup_fw;
8029aebfd4aSSean Wang 	}
8039aebfd4aSSean Wang 
8049aebfd4aSSean Wang 	/* Setup a firmware which the device definitely requires */
805c603bf1fSSean Wang 	err = btmtk_setup_firmware(hdev, fwname, mtk_hci_wmt_sync);
8069aebfd4aSSean Wang 	if (err < 0)
8079aebfd4aSSean Wang 		return err;
8089aebfd4aSSean Wang 
8099aebfd4aSSean Wang ignore_setup_fw:
8109aebfd4aSSean Wang 	/* Query whether the device is already enabled */
8119aebfd4aSSean Wang 	err = readx_poll_timeout(btmtksdio_func_query, hdev, status,
8129aebfd4aSSean Wang 				 status < 0 || status != BTMTK_WMT_ON_PROGRESS,
8139aebfd4aSSean Wang 				 2000, 5000000);
8149aebfd4aSSean Wang 	/* -ETIMEDOUT happens */
8159aebfd4aSSean Wang 	if (err < 0)
8169aebfd4aSSean Wang 		return err;
8179aebfd4aSSean Wang 
8189aebfd4aSSean Wang 	/* The other errors happen in btusb_mtk_func_query */
8199aebfd4aSSean Wang 	if (status < 0)
8209aebfd4aSSean Wang 		return status;
8219aebfd4aSSean Wang 
8229aebfd4aSSean Wang 	if (status == BTMTK_WMT_ON_DONE) {
8239aebfd4aSSean Wang 		bt_dev_info(hdev, "function already on");
8249aebfd4aSSean Wang 		goto ignore_func_on;
8259aebfd4aSSean Wang 	}
8269aebfd4aSSean Wang 
8279aebfd4aSSean Wang 	/* Enable Bluetooth protocol */
8283a722044SSean Wang 	wmt_params.op = BTMTK_WMT_FUNC_CTRL;
8299aebfd4aSSean Wang 	wmt_params.flag = 0;
8309aebfd4aSSean Wang 	wmt_params.dlen = sizeof(param);
8319aebfd4aSSean Wang 	wmt_params.data = &param;
8329aebfd4aSSean Wang 	wmt_params.status = NULL;
8339aebfd4aSSean Wang 
8349aebfd4aSSean Wang 	err = mtk_hci_wmt_sync(hdev, &wmt_params);
8359aebfd4aSSean Wang 	if (err < 0) {
8369aebfd4aSSean Wang 		bt_dev_err(hdev, "Failed to send wmt func ctrl (%d)", err);
8379aebfd4aSSean Wang 		return err;
8389aebfd4aSSean Wang 	}
8399aebfd4aSSean Wang 
84001ecc177SMark Chen 	set_bit(BTMTKSDIO_PATCH_ENABLED, &bdev->tx_state);
84101ecc177SMark Chen 
8429aebfd4aSSean Wang ignore_func_on:
8439aebfd4aSSean Wang 	/* Apply the low power environment setup */
8449aebfd4aSSean Wang 	tci_sleep.mode = 0x5;
8459aebfd4aSSean Wang 	tci_sleep.duration = cpu_to_le16(0x640);
8469aebfd4aSSean Wang 	tci_sleep.host_duration = cpu_to_le16(0x640);
8479aebfd4aSSean Wang 	tci_sleep.host_wakeup_pin = 0;
8489aebfd4aSSean Wang 	tci_sleep.time_compensation = 0;
8499aebfd4aSSean Wang 
8509aebfd4aSSean Wang 	skb = __hci_cmd_sync(hdev, 0xfc7a, sizeof(tci_sleep), &tci_sleep,
8519aebfd4aSSean Wang 			     HCI_INIT_TIMEOUT);
8529aebfd4aSSean Wang 	if (IS_ERR(skb)) {
8539aebfd4aSSean Wang 		err = PTR_ERR(skb);
8549aebfd4aSSean Wang 		bt_dev_err(hdev, "Failed to apply low power setting (%d)", err);
8559aebfd4aSSean Wang 		return err;
8569aebfd4aSSean Wang 	}
8579aebfd4aSSean Wang 	kfree_skb(skb);
8589aebfd4aSSean Wang 
859c603bf1fSSean Wang 	return 0;
860c603bf1fSSean Wang }
861c603bf1fSSean Wang 
mt79xx_setup(struct hci_dev * hdev,const char * fwname)862c603bf1fSSean Wang static int mt79xx_setup(struct hci_dev *hdev, const char *fwname)
863c603bf1fSSean Wang {
86401ecc177SMark Chen 	struct btmtksdio_dev *bdev = hci_get_drvdata(hdev);
865c603bf1fSSean Wang 	struct btmtk_hci_wmt_params wmt_params;
866c603bf1fSSean Wang 	u8 param = 0x1;
867c603bf1fSSean Wang 	int err;
868c603bf1fSSean Wang 
869c603bf1fSSean Wang 	err = btmtk_setup_firmware_79xx(hdev, fwname, mtk_hci_wmt_sync);
870c603bf1fSSean Wang 	if (err < 0) {
871c603bf1fSSean Wang 		bt_dev_err(hdev, "Failed to setup 79xx firmware (%d)", err);
872c603bf1fSSean Wang 		return err;
873c603bf1fSSean Wang 	}
874c603bf1fSSean Wang 
87574697205SSean Wang 	err = btmtksdio_fw_pmctrl(bdev);
87674697205SSean Wang 	if (err < 0)
87774697205SSean Wang 		return err;
87874697205SSean Wang 
87974697205SSean Wang 	err = btmtksdio_drv_pmctrl(bdev);
88074697205SSean Wang 	if (err < 0)
88174697205SSean Wang 		return err;
88274697205SSean Wang 
883c603bf1fSSean Wang 	/* Enable Bluetooth protocol */
884c603bf1fSSean Wang 	wmt_params.op = BTMTK_WMT_FUNC_CTRL;
885c603bf1fSSean Wang 	wmt_params.flag = 0;
886c603bf1fSSean Wang 	wmt_params.dlen = sizeof(param);
887c603bf1fSSean Wang 	wmt_params.data = &param;
888c603bf1fSSean Wang 	wmt_params.status = NULL;
889c603bf1fSSean Wang 
890c603bf1fSSean Wang 	err = mtk_hci_wmt_sync(hdev, &wmt_params);
891c603bf1fSSean Wang 	if (err < 0) {
892c603bf1fSSean Wang 		bt_dev_err(hdev, "Failed to send wmt func ctrl (%d)", err);
893c603bf1fSSean Wang 		return err;
894c603bf1fSSean Wang 	}
895c603bf1fSSean Wang 
896630491ffSŁukasz Bartosik 	hci_set_msft_opcode(hdev, 0xFD30);
89716ada83bSSean Wang 	hci_set_aosp_capable(hdev);
89801ecc177SMark Chen 	set_bit(BTMTKSDIO_PATCH_ENABLED, &bdev->tx_state);
899630491ffSŁukasz Bartosik 
900c603bf1fSSean Wang 	return err;
901c603bf1fSSean Wang }
902c603bf1fSSean Wang 
btmtksdio_mtk_reg_read(struct hci_dev * hdev,u32 reg,u32 * val)9034b685879SSean Wang static int btmtksdio_mtk_reg_read(struct hci_dev *hdev, u32 reg, u32 *val)
904c603bf1fSSean Wang {
905c603bf1fSSean Wang 	struct btmtk_hci_wmt_params wmt_params;
9065677bcf6SSean Wang 	struct reg_read_cmd reg_read = {
907c603bf1fSSean Wang 		.type = 1,
908c603bf1fSSean Wang 		.num = 1,
909c603bf1fSSean Wang 	};
910c603bf1fSSean Wang 	u32 status;
911c603bf1fSSean Wang 	int err;
912c603bf1fSSean Wang 
913c603bf1fSSean Wang 	reg_read.addr = cpu_to_le32(reg);
914c603bf1fSSean Wang 	wmt_params.op = BTMTK_WMT_REGISTER;
915c603bf1fSSean Wang 	wmt_params.flag = BTMTK_WMT_REG_READ;
916c603bf1fSSean Wang 	wmt_params.dlen = sizeof(reg_read);
917c603bf1fSSean Wang 	wmt_params.data = &reg_read;
918c603bf1fSSean Wang 	wmt_params.status = &status;
919c603bf1fSSean Wang 
920c603bf1fSSean Wang 	err = mtk_hci_wmt_sync(hdev, &wmt_params);
921c603bf1fSSean Wang 	if (err < 0) {
922c603bf1fSSean Wang 		bt_dev_err(hdev, "Failed to read reg (%d)", err);
923c603bf1fSSean Wang 		return err;
924c603bf1fSSean Wang 	}
925c603bf1fSSean Wang 
926c603bf1fSSean Wang 	*val = status;
927c603bf1fSSean Wang 
928c603bf1fSSean Wang 	return err;
929c603bf1fSSean Wang }
930c603bf1fSSean Wang 
btmtksdio_mtk_reg_write(struct hci_dev * hdev,u32 reg,u32 val,u32 mask)931191c8723SMark Chen static int btmtksdio_mtk_reg_write(struct hci_dev *hdev, u32 reg, u32 val, u32 mask)
932191c8723SMark Chen {
933191c8723SMark Chen 	struct btmtk_hci_wmt_params wmt_params;
934191c8723SMark Chen 	const struct reg_write_cmd reg_write = {
935191c8723SMark Chen 		.type = 1,
936191c8723SMark Chen 		.num = 1,
937191c8723SMark Chen 		.addr = cpu_to_le32(reg),
938191c8723SMark Chen 		.data = cpu_to_le32(val),
939191c8723SMark Chen 		.mask = cpu_to_le32(mask),
940191c8723SMark Chen 	};
941191c8723SMark Chen 	int err, status;
942191c8723SMark Chen 
943191c8723SMark Chen 	wmt_params.op = BTMTK_WMT_REGISTER;
944191c8723SMark Chen 	wmt_params.flag = BTMTK_WMT_REG_WRITE;
945191c8723SMark Chen 	wmt_params.dlen = sizeof(reg_write);
946191c8723SMark Chen 	wmt_params.data = &reg_write;
947191c8723SMark Chen 	wmt_params.status = &status;
948191c8723SMark Chen 
949191c8723SMark Chen 	err = mtk_hci_wmt_sync(hdev, &wmt_params);
950191c8723SMark Chen 	if (err < 0)
951191c8723SMark Chen 		bt_dev_err(hdev, "Failed to write reg (%d)", err);
952191c8723SMark Chen 
953191c8723SMark Chen 	return err;
954191c8723SMark Chen }
955191c8723SMark Chen 
btmtksdio_get_data_path_id(struct hci_dev * hdev,__u8 * data_path_id)956d786105eSYake Yang static int btmtksdio_get_data_path_id(struct hci_dev *hdev, __u8 *data_path_id)
957d786105eSYake Yang {
958d786105eSYake Yang 	/* uses 1 as data path id for all the usecases */
959d786105eSYake Yang 	*data_path_id = 1;
960d786105eSYake Yang 	return 0;
961d786105eSYake Yang }
962d786105eSYake Yang 
btmtksdio_get_codec_config_data(struct hci_dev * hdev,__u8 link,struct bt_codec * codec,__u8 * ven_len,__u8 ** ven_data)963f41b91faSYake Yang static int btmtksdio_get_codec_config_data(struct hci_dev *hdev,
964f41b91faSYake Yang 					   __u8 link, struct bt_codec *codec,
965f41b91faSYake Yang 					   __u8 *ven_len, __u8 **ven_data)
966f41b91faSYake Yang {
967f41b91faSYake Yang 	int err = 0;
968f41b91faSYake Yang 
969f41b91faSYake Yang 	if (!ven_data || !ven_len)
970f41b91faSYake Yang 		return -EINVAL;
971f41b91faSYake Yang 
972f41b91faSYake Yang 	*ven_len = 0;
973f41b91faSYake Yang 	*ven_data = NULL;
974f41b91faSYake Yang 
975f41b91faSYake Yang 	if (link != ESCO_LINK) {
976f41b91faSYake Yang 		bt_dev_err(hdev, "Invalid link type(%u)", link);
977f41b91faSYake Yang 		return -EINVAL;
978f41b91faSYake Yang 	}
979f41b91faSYake Yang 
980f41b91faSYake Yang 	*ven_data = kmalloc(sizeof(__u8), GFP_KERNEL);
981789f6b8aSSean Wang 	if (!*ven_data) {
982f41b91faSYake Yang 		err = -ENOMEM;
983f41b91faSYake Yang 		goto error;
984f41b91faSYake Yang 	}
985f41b91faSYake Yang 
986f41b91faSYake Yang 	/* supports only CVSD and mSBC offload codecs */
987f41b91faSYake Yang 	switch (codec->id) {
988f41b91faSYake Yang 	case 0x02:
989f41b91faSYake Yang 		**ven_data = 0x00;
990f41b91faSYake Yang 		break;
991f41b91faSYake Yang 	case 0x05:
992f41b91faSYake Yang 		**ven_data = 0x01;
993f41b91faSYake Yang 		break;
994f41b91faSYake Yang 	default:
995f41b91faSYake Yang 		err = -EINVAL;
996f41b91faSYake Yang 		bt_dev_err(hdev, "Invalid codec id(%u)", codec->id);
997f41b91faSYake Yang 		goto error;
998f41b91faSYake Yang 	}
999f41b91faSYake Yang 	/* codec and its capabilities are pre-defined to ids
1000f41b91faSYake Yang 	 * preset id = 0x00 represents CVSD codec with sampling rate 8K
1001f41b91faSYake Yang 	 * preset id = 0x01 represents mSBC codec with sampling rate 16K
1002f41b91faSYake Yang 	 */
1003f41b91faSYake Yang 	*ven_len = sizeof(__u8);
1004f41b91faSYake Yang 	return err;
1005f41b91faSYake Yang 
1006f41b91faSYake Yang error:
1007f41b91faSYake Yang 	kfree(*ven_data);
1008f41b91faSYake Yang 	*ven_data = NULL;
1009f41b91faSYake Yang 	return err;
1010f41b91faSYake Yang }
1011f41b91faSYake Yang 
btmtksdio_sco_setting(struct hci_dev * hdev)1012191c8723SMark Chen static int btmtksdio_sco_setting(struct hci_dev *hdev)
1013191c8723SMark Chen {
1014191c8723SMark Chen 	const struct btmtk_sco sco_setting = {
1015191c8723SMark Chen 		.clock_config = 0x49,
1016191c8723SMark Chen 		.channel_format_config = 0x80,
1017191c8723SMark Chen 	};
1018191c8723SMark Chen 	struct sk_buff *skb;
1019191c8723SMark Chen 	u32 val;
1020191c8723SMark Chen 	int err;
1021191c8723SMark Chen 
1022191c8723SMark Chen 	/* Enable SCO over I2S/PCM for MediaTek chipset */
1023191c8723SMark Chen 	skb =  __hci_cmd_sync(hdev, 0xfc72, sizeof(sco_setting),
1024191c8723SMark Chen 			      &sco_setting, HCI_CMD_TIMEOUT);
1025191c8723SMark Chen 	if (IS_ERR(skb))
1026191c8723SMark Chen 		return PTR_ERR(skb);
1027191c8723SMark Chen 
1028191c8723SMark Chen 	kfree_skb(skb);
1029191c8723SMark Chen 
1030191c8723SMark Chen 	err = btmtksdio_mtk_reg_read(hdev, MT7921_PINMUX_0, &val);
1031191c8723SMark Chen 	if (err < 0)
1032191c8723SMark Chen 		return err;
1033191c8723SMark Chen 
1034191c8723SMark Chen 	val |= 0x11000000;
1035191c8723SMark Chen 	err = btmtksdio_mtk_reg_write(hdev, MT7921_PINMUX_0, val, ~0);
1036191c8723SMark Chen 	if (err < 0)
1037191c8723SMark Chen 		return err;
1038191c8723SMark Chen 
1039191c8723SMark Chen 	err = btmtksdio_mtk_reg_read(hdev, MT7921_PINMUX_1, &val);
1040191c8723SMark Chen 	if (err < 0)
1041191c8723SMark Chen 		return err;
1042191c8723SMark Chen 
1043191c8723SMark Chen 	val |= 0x00000101;
1044d786105eSYake Yang 	err =  btmtksdio_mtk_reg_write(hdev, MT7921_PINMUX_1, val, ~0);
1045d786105eSYake Yang 	if (err < 0)
1046d786105eSYake Yang 		return err;
1047d786105eSYake Yang 
1048d786105eSYake Yang 	hdev->get_data_path_id = btmtksdio_get_data_path_id;
1049f41b91faSYake Yang 	hdev->get_codec_config_data = btmtksdio_get_codec_config_data;
1050d786105eSYake Yang 
1051d786105eSYake Yang 	return err;
1052191c8723SMark Chen }
1053191c8723SMark Chen 
btmtksdio_reset_setting(struct hci_dev * hdev)10548fafe702SChih-Ying Chiang static int btmtksdio_reset_setting(struct hci_dev *hdev)
10558fafe702SChih-Ying Chiang {
10568fafe702SChih-Ying Chiang 	int err;
10578fafe702SChih-Ying Chiang 	u32 val;
10588fafe702SChih-Ying Chiang 
10598fafe702SChih-Ying Chiang 	err = btmtksdio_mtk_reg_read(hdev, MT7921_PINMUX_1, &val);
10608fafe702SChih-Ying Chiang 	if (err < 0)
10618fafe702SChih-Ying Chiang 		return err;
10628fafe702SChih-Ying Chiang 
10638fafe702SChih-Ying Chiang 	val |= 0x20; /* set the pin (bit field 11:8) work as GPIO mode */
10648fafe702SChih-Ying Chiang 	err = btmtksdio_mtk_reg_write(hdev, MT7921_PINMUX_1, val, ~0);
10658fafe702SChih-Ying Chiang 	if (err < 0)
10668fafe702SChih-Ying Chiang 		return err;
10678fafe702SChih-Ying Chiang 
10688fafe702SChih-Ying Chiang 	err = btmtksdio_mtk_reg_read(hdev, MT7921_BTSYS_RST, &val);
10698fafe702SChih-Ying Chiang 	if (err < 0)
10708fafe702SChih-Ying Chiang 		return err;
10718fafe702SChih-Ying Chiang 
10728fafe702SChih-Ying Chiang 	val |= MT7921_BTSYS_RST_WITH_GPIO;
10738fafe702SChih-Ying Chiang 	return btmtksdio_mtk_reg_write(hdev, MT7921_BTSYS_RST, val, ~0);
10748fafe702SChih-Ying Chiang }
10758fafe702SChih-Ying Chiang 
btmtksdio_setup(struct hci_dev * hdev)1076c603bf1fSSean Wang static int btmtksdio_setup(struct hci_dev *hdev)
1077c603bf1fSSean Wang {
1078c603bf1fSSean Wang 	struct btmtksdio_dev *bdev = hci_get_drvdata(hdev);
1079c603bf1fSSean Wang 	ktime_t calltime, delta, rettime;
1080c603bf1fSSean Wang 	unsigned long long duration;
1081c603bf1fSSean Wang 	char fwname[64];
1082c603bf1fSSean Wang 	int err, dev_id;
10838fafe702SChih-Ying Chiang 	u32 fw_version = 0, val;
1084c603bf1fSSean Wang 
1085c603bf1fSSean Wang 	calltime = ktime_get();
1086d555b1f2SSean Wang 	set_bit(BTMTKSDIO_HW_TX_READY, &bdev->tx_state);
1087c603bf1fSSean Wang 
1088c603bf1fSSean Wang 	switch (bdev->data->chipid) {
1089c603bf1fSSean Wang 	case 0x7921:
10908fafe702SChih-Ying Chiang 		if (test_bit(BTMTKSDIO_HW_RESET_ACTIVE, &bdev->tx_state)) {
10918fafe702SChih-Ying Chiang 			err = btmtksdio_mtk_reg_read(hdev, MT7921_DLSTATUS,
10928fafe702SChih-Ying Chiang 						     &val);
10938fafe702SChih-Ying Chiang 			if (err < 0)
10948fafe702SChih-Ying Chiang 				return err;
10958fafe702SChih-Ying Chiang 
10968fafe702SChih-Ying Chiang 			val &= ~BT_DL_STATE;
10978fafe702SChih-Ying Chiang 			err = btmtksdio_mtk_reg_write(hdev, MT7921_DLSTATUS,
10988fafe702SChih-Ying Chiang 						      val, ~0);
10998fafe702SChih-Ying Chiang 			if (err < 0)
11008fafe702SChih-Ying Chiang 				return err;
11018fafe702SChih-Ying Chiang 
11028fafe702SChih-Ying Chiang 			btmtksdio_fw_pmctrl(bdev);
11038fafe702SChih-Ying Chiang 			msleep(20);
11048fafe702SChih-Ying Chiang 			btmtksdio_drv_pmctrl(bdev);
11058fafe702SChih-Ying Chiang 
11068fafe702SChih-Ying Chiang 			clear_bit(BTMTKSDIO_HW_RESET_ACTIVE, &bdev->tx_state);
11078fafe702SChih-Ying Chiang 		}
11088fafe702SChih-Ying Chiang 
11094b685879SSean Wang 		err = btmtksdio_mtk_reg_read(hdev, 0x70010200, &dev_id);
1110c603bf1fSSean Wang 		if (err < 0) {
1111c603bf1fSSean Wang 			bt_dev_err(hdev, "Failed to get device id (%d)", err);
1112c603bf1fSSean Wang 			return err;
1113c603bf1fSSean Wang 		}
1114c603bf1fSSean Wang 
11154b685879SSean Wang 		err = btmtksdio_mtk_reg_read(hdev, 0x80021004, &fw_version);
1116c603bf1fSSean Wang 		if (err < 0) {
1117c603bf1fSSean Wang 			bt_dev_err(hdev, "Failed to get fw version (%d)", err);
1118c603bf1fSSean Wang 			return err;
1119c603bf1fSSean Wang 		}
1120c603bf1fSSean Wang 
11217f935b21SSean Wang 		btmtk_fw_get_filename(fwname, sizeof(fwname), dev_id,
11227f935b21SSean Wang 				      fw_version, 0);
11237f935b21SSean Wang 
1124c603bf1fSSean Wang 		snprintf(fwname, sizeof(fwname),
1125c603bf1fSSean Wang 			 "mediatek/BT_RAM_CODE_MT%04x_1_%x_hdr.bin",
1126c603bf1fSSean Wang 			 dev_id & 0xffff, (fw_version & 0xff) + 1);
1127c603bf1fSSean Wang 		err = mt79xx_setup(hdev, fwname);
1128c603bf1fSSean Wang 		if (err < 0)
1129c603bf1fSSean Wang 			return err;
1130191c8723SMark Chen 
1131191c8723SMark Chen 		/* Enable SCO over I2S/PCM */
1132191c8723SMark Chen 		err = btmtksdio_sco_setting(hdev);
1133191c8723SMark Chen 		if (err < 0) {
1134191c8723SMark Chen 			bt_dev_err(hdev, "Failed to enable SCO setting (%d)", err);
1135191c8723SMark Chen 			return err;
1136191c8723SMark Chen 		}
1137191c8723SMark Chen 
11385ad80cfcSYake Yang 		/* Enable WBS with mSBC codec */
11395ad80cfcSYake Yang 		set_bit(HCI_QUIRK_WIDEBAND_SPEECH_SUPPORTED, &hdev->quirks);
11405ad80cfcSYake Yang 
11418fafe702SChih-Ying Chiang 		/* Enable GPIO reset mechanism */
11428fafe702SChih-Ying Chiang 		if (bdev->reset) {
11438fafe702SChih-Ying Chiang 			err = btmtksdio_reset_setting(hdev);
11448fafe702SChih-Ying Chiang 			if (err < 0) {
11458fafe702SChih-Ying Chiang 				bt_dev_err(hdev, "Failed to enable Reset setting (%d)", err);
11468fafe702SChih-Ying Chiang 				devm_gpiod_put(bdev->dev, bdev->reset);
11478fafe702SChih-Ying Chiang 				bdev->reset = NULL;
11488fafe702SChih-Ying Chiang 			}
11498fafe702SChih-Ying Chiang 		}
11508fafe702SChih-Ying Chiang 
1151c603bf1fSSean Wang 		break;
1152c603bf1fSSean Wang 	case 0x7663:
1153c603bf1fSSean Wang 	case 0x7668:
1154c603bf1fSSean Wang 		err = mt76xx_setup(hdev, bdev->data->fwname);
1155c603bf1fSSean Wang 		if (err < 0)
1156c603bf1fSSean Wang 			return err;
1157c603bf1fSSean Wang 		break;
1158c603bf1fSSean Wang 	default:
1159c603bf1fSSean Wang 		return -ENODEV;
1160c603bf1fSSean Wang 	}
1161c603bf1fSSean Wang 
11629aebfd4aSSean Wang 	rettime = ktime_get();
11639aebfd4aSSean Wang 	delta = ktime_sub(rettime, calltime);
11649aebfd4aSSean Wang 	duration = (unsigned long long)ktime_to_ns(delta) >> 10;
11659aebfd4aSSean Wang 
11667f3c563cSSean Wang 	pm_runtime_set_autosuspend_delay(bdev->dev,
11677f3c563cSSean Wang 					 MTKBTSDIO_AUTOSUSPEND_DELAY);
11687f3c563cSSean Wang 	pm_runtime_use_autosuspend(bdev->dev);
11697f3c563cSSean Wang 
11707f3c563cSSean Wang 	err = pm_runtime_set_active(bdev->dev);
11717f3c563cSSean Wang 	if (err < 0)
11727f3c563cSSean Wang 		return err;
11737f3c563cSSean Wang 
11747f3c563cSSean Wang 	/* Default forbid runtime auto suspend, that can be allowed by
11757f3c563cSSean Wang 	 * enable_autosuspend flag or the PM runtime entry under sysfs.
11767f3c563cSSean Wang 	 */
11777f3c563cSSean Wang 	pm_runtime_forbid(bdev->dev);
11787f3c563cSSean Wang 	pm_runtime_enable(bdev->dev);
11797f3c563cSSean Wang 
11807f3c563cSSean Wang 	if (enable_autosuspend)
11817f3c563cSSean Wang 		pm_runtime_allow(bdev->dev);
11827f3c563cSSean Wang 
11839aebfd4aSSean Wang 	bt_dev_info(hdev, "Device setup in %llu usecs", duration);
11849aebfd4aSSean Wang 
11859aebfd4aSSean Wang 	return 0;
11869aebfd4aSSean Wang }
11879aebfd4aSSean Wang 
btmtksdio_shutdown(struct hci_dev * hdev)11889aebfd4aSSean Wang static int btmtksdio_shutdown(struct hci_dev *hdev)
11899aebfd4aSSean Wang {
11907f3c563cSSean Wang 	struct btmtksdio_dev *bdev = hci_get_drvdata(hdev);
11919aebfd4aSSean Wang 	struct btmtk_hci_wmt_params wmt_params;
11929aebfd4aSSean Wang 	u8 param = 0x0;
11939aebfd4aSSean Wang 	int err;
11949aebfd4aSSean Wang 
11957f3c563cSSean Wang 	/* Get back the state to be consistent with the state
11967f3c563cSSean Wang 	 * in btmtksdio_setup.
11977f3c563cSSean Wang 	 */
11987f3c563cSSean Wang 	pm_runtime_get_sync(bdev->dev);
11997f3c563cSSean Wang 
1200baabb7f5SSean Wang 	/* wmt command only works until the reset is complete */
1201baabb7f5SSean Wang 	if (test_bit(BTMTKSDIO_HW_RESET_ACTIVE, &bdev->tx_state))
1202baabb7f5SSean Wang 		goto ignore_wmt_cmd;
1203baabb7f5SSean Wang 
12049aebfd4aSSean Wang 	/* Disable the device */
12053a722044SSean Wang 	wmt_params.op = BTMTK_WMT_FUNC_CTRL;
12069aebfd4aSSean Wang 	wmt_params.flag = 0;
12079aebfd4aSSean Wang 	wmt_params.dlen = sizeof(param);
12089aebfd4aSSean Wang 	wmt_params.data = &param;
12099aebfd4aSSean Wang 	wmt_params.status = NULL;
12109aebfd4aSSean Wang 
12119aebfd4aSSean Wang 	err = mtk_hci_wmt_sync(hdev, &wmt_params);
12129aebfd4aSSean Wang 	if (err < 0) {
12139aebfd4aSSean Wang 		bt_dev_err(hdev, "Failed to send wmt func ctrl (%d)", err);
12149aebfd4aSSean Wang 		return err;
12159aebfd4aSSean Wang 	}
12169aebfd4aSSean Wang 
1217baabb7f5SSean Wang ignore_wmt_cmd:
12187f3c563cSSean Wang 	pm_runtime_put_noidle(bdev->dev);
12197f3c563cSSean Wang 	pm_runtime_disable(bdev->dev);
12207f3c563cSSean Wang 
12219aebfd4aSSean Wang 	return 0;
12229aebfd4aSSean Wang }
12239aebfd4aSSean Wang 
btmtksdio_send_frame(struct hci_dev * hdev,struct sk_buff * skb)12249aebfd4aSSean Wang static int btmtksdio_send_frame(struct hci_dev *hdev, struct sk_buff *skb)
12259aebfd4aSSean Wang {
12269aebfd4aSSean Wang 	struct btmtksdio_dev *bdev = hci_get_drvdata(hdev);
12279aebfd4aSSean Wang 
12289aebfd4aSSean Wang 	switch (hci_skb_pkt_type(skb)) {
12299aebfd4aSSean Wang 	case HCI_COMMAND_PKT:
12309aebfd4aSSean Wang 		hdev->stat.cmd_tx++;
12319aebfd4aSSean Wang 		break;
12329aebfd4aSSean Wang 
12339aebfd4aSSean Wang 	case HCI_ACLDATA_PKT:
12349aebfd4aSSean Wang 		hdev->stat.acl_tx++;
12359aebfd4aSSean Wang 		break;
12369aebfd4aSSean Wang 
12379aebfd4aSSean Wang 	case HCI_SCODATA_PKT:
12389aebfd4aSSean Wang 		hdev->stat.sco_tx++;
12399aebfd4aSSean Wang 		break;
12409aebfd4aSSean Wang 
12419aebfd4aSSean Wang 	default:
12429aebfd4aSSean Wang 		return -EILSEQ;
12439aebfd4aSSean Wang 	}
12449aebfd4aSSean Wang 
12459aebfd4aSSean Wang 	skb_queue_tail(&bdev->txq, skb);
12469aebfd4aSSean Wang 
124726270bc1SSean Wang 	schedule_work(&bdev->txrx_work);
12489aebfd4aSSean Wang 
12499aebfd4aSSean Wang 	return 0;
12509aebfd4aSSean Wang }
12519aebfd4aSSean Wang 
btmtksdio_cmd_timeout(struct hci_dev * hdev)12528fafe702SChih-Ying Chiang static void btmtksdio_cmd_timeout(struct hci_dev *hdev)
12538fafe702SChih-Ying Chiang {
12548fafe702SChih-Ying Chiang 	struct btmtksdio_dev *bdev = hci_get_drvdata(hdev);
12558fafe702SChih-Ying Chiang 	u32 status;
12568fafe702SChih-Ying Chiang 	int err;
12578fafe702SChih-Ying Chiang 
12588fafe702SChih-Ying Chiang 	if (!bdev->reset || bdev->data->chipid != 0x7921)
12598fafe702SChih-Ying Chiang 		return;
12608fafe702SChih-Ying Chiang 
12618fafe702SChih-Ying Chiang 	pm_runtime_get_sync(bdev->dev);
12628fafe702SChih-Ying Chiang 
12638fafe702SChih-Ying Chiang 	if (test_and_set_bit(BTMTKSDIO_HW_RESET_ACTIVE, &bdev->tx_state))
12648fafe702SChih-Ying Chiang 		return;
12658fafe702SChih-Ying Chiang 
12668fafe702SChih-Ying Chiang 	sdio_claim_host(bdev->func);
12678fafe702SChih-Ying Chiang 
12688fafe702SChih-Ying Chiang 	sdio_writel(bdev->func, C_INT_EN_CLR, MTK_REG_CHLPCR, NULL);
12698fafe702SChih-Ying Chiang 	skb_queue_purge(&bdev->txq);
12708fafe702SChih-Ying Chiang 	cancel_work_sync(&bdev->txrx_work);
12718fafe702SChih-Ying Chiang 
12728fafe702SChih-Ying Chiang 	gpiod_set_value_cansleep(bdev->reset, 1);
12738fafe702SChih-Ying Chiang 	msleep(100);
12748fafe702SChih-Ying Chiang 	gpiod_set_value_cansleep(bdev->reset, 0);
12758fafe702SChih-Ying Chiang 
12768fafe702SChih-Ying Chiang 	err = readx_poll_timeout(btmtksdio_chcr_query, bdev, status,
12778fafe702SChih-Ying Chiang 				 status & BT_RST_DONE, 100000, 2000000);
12788fafe702SChih-Ying Chiang 	if (err < 0) {
12798fafe702SChih-Ying Chiang 		bt_dev_err(hdev, "Failed to reset (%d)", err);
12808fafe702SChih-Ying Chiang 		goto err;
12818fafe702SChih-Ying Chiang 	}
12828fafe702SChih-Ying Chiang 
12838fafe702SChih-Ying Chiang 	clear_bit(BTMTKSDIO_PATCH_ENABLED, &bdev->tx_state);
12848fafe702SChih-Ying Chiang err:
12858fafe702SChih-Ying Chiang 	sdio_release_host(bdev->func);
12868fafe702SChih-Ying Chiang 
12878fafe702SChih-Ying Chiang 	pm_runtime_put_noidle(bdev->dev);
12888fafe702SChih-Ying Chiang 	pm_runtime_disable(bdev->dev);
12898fafe702SChih-Ying Chiang 
12908fafe702SChih-Ying Chiang 	hci_reset_dev(hdev);
12918fafe702SChih-Ying Chiang }
12928fafe702SChih-Ying Chiang 
btmtksdio_sdio_inband_wakeup(struct hci_dev * hdev)1293df332800SSean Wang static bool btmtksdio_sdio_inband_wakeup(struct hci_dev *hdev)
1294df332800SSean Wang {
1295df332800SSean Wang 	struct btmtksdio_dev *bdev = hci_get_drvdata(hdev);
1296df332800SSean Wang 
1297df332800SSean Wang 	return device_may_wakeup(bdev->dev);
1298df332800SSean Wang }
1299df332800SSean Wang 
btmtksdio_sdio_wakeup(struct hci_dev * hdev)1300ce64b3e9SMark Chen static bool btmtksdio_sdio_wakeup(struct hci_dev *hdev)
1301ce64b3e9SMark Chen {
1302ce64b3e9SMark Chen 	struct btmtksdio_dev *bdev = hci_get_drvdata(hdev);
1303ce64b3e9SMark Chen 	bool may_wakeup = device_may_wakeup(bdev->dev);
1304ce64b3e9SMark Chen 	const struct btmtk_wakeon bt_awake = {
1305ce64b3e9SMark Chen 		.mode = 0x1,
1306ce64b3e9SMark Chen 		.gpo = 0,
1307ce64b3e9SMark Chen 		.active_high = 0x1,
1308ce64b3e9SMark Chen 		.enable_delay = cpu_to_le16(0xc80),
1309ce64b3e9SMark Chen 		.wakeup_delay = cpu_to_le16(0x20),
1310ce64b3e9SMark Chen 	};
1311ce64b3e9SMark Chen 
1312ce64b3e9SMark Chen 	if (may_wakeup && bdev->data->chipid == 0x7921) {
1313ce64b3e9SMark Chen 		struct sk_buff *skb;
1314ce64b3e9SMark Chen 
1315ce64b3e9SMark Chen 		skb =  __hci_cmd_sync(hdev, 0xfc27, sizeof(bt_awake),
1316ce64b3e9SMark Chen 				      &bt_awake, HCI_CMD_TIMEOUT);
1317ce64b3e9SMark Chen 		if (IS_ERR(skb))
1318ce64b3e9SMark Chen 			may_wakeup = false;
1319eb3f0517SYake Yang 		else
1320ce64b3e9SMark Chen 			kfree_skb(skb);
1321ce64b3e9SMark Chen 	}
1322ce64b3e9SMark Chen 
1323ce64b3e9SMark Chen 	return may_wakeup;
1324ce64b3e9SMark Chen }
1325ce64b3e9SMark Chen 
btmtksdio_probe(struct sdio_func * func,const struct sdio_device_id * id)13269aebfd4aSSean Wang static int btmtksdio_probe(struct sdio_func *func,
13279aebfd4aSSean Wang 			   const struct sdio_device_id *id)
13289aebfd4aSSean Wang {
13299aebfd4aSSean Wang 	struct btmtksdio_dev *bdev;
13309aebfd4aSSean Wang 	struct hci_dev *hdev;
13319aebfd4aSSean Wang 	int err;
13329aebfd4aSSean Wang 
13339aebfd4aSSean Wang 	bdev = devm_kzalloc(&func->dev, sizeof(*bdev), GFP_KERNEL);
13349aebfd4aSSean Wang 	if (!bdev)
13359aebfd4aSSean Wang 		return -ENOMEM;
13369aebfd4aSSean Wang 
13379aebfd4aSSean Wang 	bdev->data = (void *)id->driver_data;
13389aebfd4aSSean Wang 	if (!bdev->data)
13399aebfd4aSSean Wang 		return -ENODEV;
13409aebfd4aSSean Wang 
13417f3c563cSSean Wang 	bdev->dev = &func->dev;
13429aebfd4aSSean Wang 	bdev->func = func;
13439aebfd4aSSean Wang 
134426270bc1SSean Wang 	INIT_WORK(&bdev->txrx_work, btmtksdio_txrx_work);
13459aebfd4aSSean Wang 	skb_queue_head_init(&bdev->txq);
13469aebfd4aSSean Wang 
13479aebfd4aSSean Wang 	/* Initialize and register HCI device */
13489aebfd4aSSean Wang 	hdev = hci_alloc_dev();
13499aebfd4aSSean Wang 	if (!hdev) {
13509aebfd4aSSean Wang 		dev_err(&func->dev, "Can't allocate HCI device\n");
13519aebfd4aSSean Wang 		return -ENOMEM;
13529aebfd4aSSean Wang 	}
13539aebfd4aSSean Wang 
13549aebfd4aSSean Wang 	bdev->hdev = hdev;
13559aebfd4aSSean Wang 
13569aebfd4aSSean Wang 	hdev->bus = HCI_SDIO;
13579aebfd4aSSean Wang 	hci_set_drvdata(hdev, bdev);
13589aebfd4aSSean Wang 
13599aebfd4aSSean Wang 	hdev->open     = btmtksdio_open;
13609aebfd4aSSean Wang 	hdev->close    = btmtksdio_close;
13618fafe702SChih-Ying Chiang 	hdev->cmd_timeout = btmtksdio_cmd_timeout;
13629aebfd4aSSean Wang 	hdev->flush    = btmtksdio_flush;
13639aebfd4aSSean Wang 	hdev->setup    = btmtksdio_setup;
13649aebfd4aSSean Wang 	hdev->shutdown = btmtksdio_shutdown;
13659aebfd4aSSean Wang 	hdev->send     = btmtksdio_send_frame;
1366ce64b3e9SMark Chen 	hdev->wakeup   = btmtksdio_sdio_wakeup;
1367df332800SSean Wang 	/*
1368df332800SSean Wang 	 * If SDIO controller supports wake on Bluetooth, sending a wakeon
1369df332800SSean Wang 	 * command is not necessary.
1370df332800SSean Wang 	 */
1371df332800SSean Wang 	if (device_can_wakeup(func->card->host->parent))
1372df332800SSean Wang 		hdev->wakeup = btmtksdio_sdio_inband_wakeup;
1373df332800SSean Wang 	else
1374df332800SSean Wang 		hdev->wakeup = btmtksdio_sdio_wakeup;
1375877ec9e1SSean Wang 	hdev->set_bdaddr = btmtk_set_bdaddr;
1376877ec9e1SSean Wang 
13779aebfd4aSSean Wang 	SET_HCIDEV_DEV(hdev, &func->dev);
13789aebfd4aSSean Wang 
13799aebfd4aSSean Wang 	hdev->manufacturer = 70;
13809aebfd4aSSean Wang 	set_bit(HCI_QUIRK_NON_PERSISTENT_SETUP, &hdev->quirks);
13819aebfd4aSSean Wang 
1382b062a0b9SYake Yang 	sdio_set_drvdata(func, bdev);
1383b062a0b9SYake Yang 
13849aebfd4aSSean Wang 	err = hci_register_dev(hdev);
13859aebfd4aSSean Wang 	if (err < 0) {
13869aebfd4aSSean Wang 		dev_err(&func->dev, "Can't register HCI device\n");
13879aebfd4aSSean Wang 		hci_free_dev(hdev);
13889aebfd4aSSean Wang 		return err;
13899aebfd4aSSean Wang 	}
13909aebfd4aSSean Wang 
13917f3c563cSSean Wang 	/* pm_runtime_enable would be done after the firmware is being
13927f3c563cSSean Wang 	 * downloaded because the core layer probably already enables
13937f3c563cSSean Wang 	 * runtime PM for this func such as the case host->caps &
13947f3c563cSSean Wang 	 * MMC_CAP_POWER_OFF_CARD.
13957f3c563cSSean Wang 	 */
13967f3c563cSSean Wang 	if (pm_runtime_enabled(bdev->dev))
13977f3c563cSSean Wang 		pm_runtime_disable(bdev->dev);
13987f3c563cSSean Wang 
13997f3c563cSSean Wang 	/* As explaination in drivers/mmc/core/sdio_bus.c tells us:
14007f3c563cSSean Wang 	 * Unbound SDIO functions are always suspended.
14017f3c563cSSean Wang 	 * During probe, the function is set active and the usage count
14027f3c563cSSean Wang 	 * is incremented.  If the driver supports runtime PM,
14037f3c563cSSean Wang 	 * it should call pm_runtime_put_noidle() in its probe routine and
14047f3c563cSSean Wang 	 * pm_runtime_get_noresume() in its remove routine.
14057f3c563cSSean Wang 	 *
14067f3c563cSSean Wang 	 * So, put a pm_runtime_put_noidle here !
14077f3c563cSSean Wang 	 */
14087f3c563cSSean Wang 	pm_runtime_put_noidle(bdev->dev);
14097f3c563cSSean Wang 
1410ce64b3e9SMark Chen 	err = device_init_wakeup(bdev->dev, true);
1411ce64b3e9SMark Chen 	if (err)
1412ce64b3e9SMark Chen 		bt_dev_err(hdev, "failed to initialize device wakeup");
1413ce64b3e9SMark Chen 
14148fafe702SChih-Ying Chiang 	bdev->dev->of_node = of_find_compatible_node(NULL, NULL,
14158fafe702SChih-Ying Chiang 						     "mediatek,mt7921s-bluetooth");
14168fafe702SChih-Ying Chiang 	bdev->reset = devm_gpiod_get_optional(bdev->dev, "reset",
14178fafe702SChih-Ying Chiang 					      GPIOD_OUT_LOW);
14188fafe702SChih-Ying Chiang 	if (IS_ERR(bdev->reset))
14198fafe702SChih-Ying Chiang 		err = PTR_ERR(bdev->reset);
14208fafe702SChih-Ying Chiang 
1421ce64b3e9SMark Chen 	return err;
14229aebfd4aSSean Wang }
14239aebfd4aSSean Wang 
btmtksdio_remove(struct sdio_func * func)14249aebfd4aSSean Wang static void btmtksdio_remove(struct sdio_func *func)
14259aebfd4aSSean Wang {
14269aebfd4aSSean Wang 	struct btmtksdio_dev *bdev = sdio_get_drvdata(func);
14279aebfd4aSSean Wang 	struct hci_dev *hdev;
14289aebfd4aSSean Wang 
14299aebfd4aSSean Wang 	if (!bdev)
14309aebfd4aSSean Wang 		return;
14319aebfd4aSSean Wang 
14327f3c563cSSean Wang 	/* Be consistent the state in btmtksdio_probe */
14337f3c563cSSean Wang 	pm_runtime_get_noresume(bdev->dev);
14347f3c563cSSean Wang 
14359aebfd4aSSean Wang 	hdev = bdev->hdev;
14369aebfd4aSSean Wang 
14379aebfd4aSSean Wang 	sdio_set_drvdata(func, NULL);
14389aebfd4aSSean Wang 	hci_unregister_dev(hdev);
14399aebfd4aSSean Wang 	hci_free_dev(hdev);
14409aebfd4aSSean Wang }
14419aebfd4aSSean Wang 
14427f3c563cSSean Wang #ifdef CONFIG_PM
btmtksdio_runtime_suspend(struct device * dev)14437f3c563cSSean Wang static int btmtksdio_runtime_suspend(struct device *dev)
14447f3c563cSSean Wang {
14457f3c563cSSean Wang 	struct sdio_func *func = dev_to_sdio_func(dev);
14467f3c563cSSean Wang 	struct btmtksdio_dev *bdev;
14477f3c563cSSean Wang 	int err;
14487f3c563cSSean Wang 
14497f3c563cSSean Wang 	bdev = sdio_get_drvdata(func);
14507f3c563cSSean Wang 	if (!bdev)
14517f3c563cSSean Wang 		return 0;
14527f3c563cSSean Wang 
14534b4b2228SSean Wang 	if (!test_bit(BTMTKSDIO_FUNC_ENABLED, &bdev->tx_state))
14544b4b2228SSean Wang 		return 0;
14554b4b2228SSean Wang 
1456561ae1d4SSean Wang 	sdio_set_host_pm_flags(func, MMC_PM_KEEP_POWER);
1457561ae1d4SSean Wang 
1458c7e301d7SMark Chen 	err = btmtksdio_fw_pmctrl(bdev);
14597f3c563cSSean Wang 
1460095519deSSean Wang 	bt_dev_dbg(bdev->hdev, "status (%d) return ownership to device", err);
14617f3c563cSSean Wang 
14627f3c563cSSean Wang 	return err;
14637f3c563cSSean Wang }
14647f3c563cSSean Wang 
btmtksdio_system_suspend(struct device * dev)14654ed924fcSZhengping Jiang static int btmtksdio_system_suspend(struct device *dev)
14664ed924fcSZhengping Jiang {
14674ed924fcSZhengping Jiang 	struct sdio_func *func = dev_to_sdio_func(dev);
14684ed924fcSZhengping Jiang 	struct btmtksdio_dev *bdev;
14694ed924fcSZhengping Jiang 
14704ed924fcSZhengping Jiang 	bdev = sdio_get_drvdata(func);
14714ed924fcSZhengping Jiang 	if (!bdev)
14724ed924fcSZhengping Jiang 		return 0;
14734ed924fcSZhengping Jiang 
14744ed924fcSZhengping Jiang 	if (!test_bit(BTMTKSDIO_FUNC_ENABLED, &bdev->tx_state))
14754ed924fcSZhengping Jiang 		return 0;
14764ed924fcSZhengping Jiang 
14774ed924fcSZhengping Jiang 	set_bit(BTMTKSDIO_BT_WAKE_ENABLED, &bdev->tx_state);
14784ed924fcSZhengping Jiang 
14794ed924fcSZhengping Jiang 	return btmtksdio_runtime_suspend(dev);
14804ed924fcSZhengping Jiang }
14814ed924fcSZhengping Jiang 
btmtksdio_runtime_resume(struct device * dev)14827f3c563cSSean Wang static int btmtksdio_runtime_resume(struct device *dev)
14837f3c563cSSean Wang {
14847f3c563cSSean Wang 	struct sdio_func *func = dev_to_sdio_func(dev);
14857f3c563cSSean Wang 	struct btmtksdio_dev *bdev;
14867f3c563cSSean Wang 	int err;
14877f3c563cSSean Wang 
14887f3c563cSSean Wang 	bdev = sdio_get_drvdata(func);
14897f3c563cSSean Wang 	if (!bdev)
14907f3c563cSSean Wang 		return 0;
14917f3c563cSSean Wang 
14924b4b2228SSean Wang 	if (!test_bit(BTMTKSDIO_FUNC_ENABLED, &bdev->tx_state))
14934b4b2228SSean Wang 		return 0;
14944b4b2228SSean Wang 
1495c7e301d7SMark Chen 	err = btmtksdio_drv_pmctrl(bdev);
14967f3c563cSSean Wang 
1497095519deSSean Wang 	bt_dev_dbg(bdev->hdev, "status (%d) get ownership from device", err);
14987f3c563cSSean Wang 
14997f3c563cSSean Wang 	return err;
15007f3c563cSSean Wang }
15017f3c563cSSean Wang 
btmtksdio_system_resume(struct device * dev)15024ed924fcSZhengping Jiang static int btmtksdio_system_resume(struct device *dev)
15034ed924fcSZhengping Jiang {
15044ed924fcSZhengping Jiang 	return btmtksdio_runtime_resume(dev);
15054ed924fcSZhengping Jiang }
15064ed924fcSZhengping Jiang 
15074ed924fcSZhengping Jiang static const struct dev_pm_ops btmtksdio_pm_ops = {
15084ed924fcSZhengping Jiang 	SYSTEM_SLEEP_PM_OPS(btmtksdio_system_suspend, btmtksdio_system_resume)
15094ed924fcSZhengping Jiang 	RUNTIME_PM_OPS(btmtksdio_runtime_suspend, btmtksdio_runtime_resume, NULL)
15104ed924fcSZhengping Jiang };
15114ed924fcSZhengping Jiang 
15127f3c563cSSean Wang #define BTMTKSDIO_PM_OPS (&btmtksdio_pm_ops)
15137f3c563cSSean Wang #else	/* CONFIG_PM */
15147f3c563cSSean Wang #define BTMTKSDIO_PM_OPS NULL
15157f3c563cSSean Wang #endif	/* CONFIG_PM */
15167f3c563cSSean Wang 
15179aebfd4aSSean Wang static struct sdio_driver btmtksdio_driver = {
15189aebfd4aSSean Wang 	.name		= "btmtksdio",
15199aebfd4aSSean Wang 	.probe		= btmtksdio_probe,
15209aebfd4aSSean Wang 	.remove		= btmtksdio_remove,
15219aebfd4aSSean Wang 	.id_table	= btmtksdio_table,
15227f3c563cSSean Wang 	.drv = {
15237f3c563cSSean Wang 		.pm = BTMTKSDIO_PM_OPS,
15247f3c563cSSean Wang 	}
15259aebfd4aSSean Wang };
15269aebfd4aSSean Wang 
1527a6094a46SSean Wang module_sdio_driver(btmtksdio_driver);
15289aebfd4aSSean Wang 
15297f3c563cSSean Wang module_param(enable_autosuspend, bool, 0644);
15307f3c563cSSean Wang MODULE_PARM_DESC(enable_autosuspend, "Enable autosuspend by default");
15317f3c563cSSean Wang 
15329aebfd4aSSean Wang MODULE_AUTHOR("Sean Wang <sean.wang@mediatek.com>");
15339aebfd4aSSean Wang MODULE_DESCRIPTION("MediaTek Bluetooth SDIO driver ver " VERSION);
15349aebfd4aSSean Wang MODULE_VERSION(VERSION);
15359aebfd4aSSean Wang MODULE_LICENSE("GPL");
1536