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> 15*8fafe702SChih-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> 20*8fafe702SChih-Ying Chiang #include <linux/of.h> 217f3c563cSSean Wang #include <linux/pm_runtime.h> 229aebfd4aSSean Wang #include <linux/skbuff.h> 239aebfd4aSSean Wang 249aebfd4aSSean Wang #include <linux/mmc/host.h> 259aebfd4aSSean Wang #include <linux/mmc/sdio_ids.h> 269aebfd4aSSean Wang #include <linux/mmc/sdio_func.h> 279aebfd4aSSean Wang 289aebfd4aSSean Wang #include <net/bluetooth/bluetooth.h> 299aebfd4aSSean Wang #include <net/bluetooth/hci_core.h> 309aebfd4aSSean Wang 319aebfd4aSSean Wang #include "h4_recv.h" 323a722044SSean Wang #include "btmtk.h" 339aebfd4aSSean Wang 349aebfd4aSSean Wang #define VERSION "0.1" 359aebfd4aSSean Wang 36e98aa38cSSean Wang #define MTKBTSDIO_AUTOSUSPEND_DELAY 1000 377f3c563cSSean Wang 38e98aa38cSSean Wang static bool enable_autosuspend = true; 397f3c563cSSean Wang 409aebfd4aSSean Wang struct btmtksdio_data { 419aebfd4aSSean Wang const char *fwname; 42c603bf1fSSean Wang u16 chipid; 4301ecc177SMark Chen bool lp_mbox_supported; 449aebfd4aSSean Wang }; 459aebfd4aSSean Wang 469aebfd4aSSean Wang static const struct btmtksdio_data mt7663_data = { 479aebfd4aSSean Wang .fwname = FIRMWARE_MT7663, 48c603bf1fSSean Wang .chipid = 0x7663, 4901ecc177SMark Chen .lp_mbox_supported = false, 509aebfd4aSSean Wang }; 519aebfd4aSSean Wang 529aebfd4aSSean Wang static const struct btmtksdio_data mt7668_data = { 539aebfd4aSSean Wang .fwname = FIRMWARE_MT7668, 54c603bf1fSSean Wang .chipid = 0x7668, 5501ecc177SMark Chen .lp_mbox_supported = false, 56c603bf1fSSean Wang }; 57c603bf1fSSean Wang 58c603bf1fSSean Wang static const struct btmtksdio_data mt7921_data = { 59c603bf1fSSean Wang .fwname = FIRMWARE_MT7961, 60c603bf1fSSean Wang .chipid = 0x7921, 6101ecc177SMark Chen .lp_mbox_supported = true, 629aebfd4aSSean Wang }; 639aebfd4aSSean Wang 649aebfd4aSSean Wang static const struct sdio_device_id btmtksdio_table[] = { 65baaa110dSPali Rohár {SDIO_DEVICE(SDIO_VENDOR_ID_MEDIATEK, SDIO_DEVICE_ID_MEDIATEK_MT7663), 669aebfd4aSSean Wang .driver_data = (kernel_ulong_t)&mt7663_data }, 67baaa110dSPali Rohár {SDIO_DEVICE(SDIO_VENDOR_ID_MEDIATEK, SDIO_DEVICE_ID_MEDIATEK_MT7668), 689aebfd4aSSean Wang .driver_data = (kernel_ulong_t)&mt7668_data }, 69c603bf1fSSean Wang {SDIO_DEVICE(SDIO_VENDOR_ID_MEDIATEK, SDIO_DEVICE_ID_MEDIATEK_MT7961), 70c603bf1fSSean Wang .driver_data = (kernel_ulong_t)&mt7921_data }, 719aebfd4aSSean Wang { } /* Terminating entry */ 729aebfd4aSSean Wang }; 7353121a7cSBartosz Golaszewski MODULE_DEVICE_TABLE(sdio, btmtksdio_table); 749aebfd4aSSean Wang 759aebfd4aSSean Wang #define MTK_REG_CHLPCR 0x4 /* W1S */ 769aebfd4aSSean Wang #define C_INT_EN_SET BIT(0) 779aebfd4aSSean Wang #define C_INT_EN_CLR BIT(1) 782e47cc2bSSean Wang #define C_FW_OWN_REQ_SET BIT(8) /* For write */ 792e47cc2bSSean Wang #define C_COM_DRV_OWN BIT(8) /* For read */ 809aebfd4aSSean Wang #define C_FW_OWN_REQ_CLR BIT(9) 819aebfd4aSSean Wang 829aebfd4aSSean Wang #define MTK_REG_CSDIOCSR 0x8 839aebfd4aSSean Wang #define SDIO_RE_INIT_EN BIT(0) 849aebfd4aSSean Wang #define SDIO_INT_CTL BIT(2) 859aebfd4aSSean Wang 869aebfd4aSSean Wang #define MTK_REG_CHCR 0xc 879aebfd4aSSean Wang #define C_INT_CLR_CTRL BIT(1) 88*8fafe702SChih-Ying Chiang #define BT_RST_DONE BIT(8) 899aebfd4aSSean Wang 909aebfd4aSSean Wang /* CHISR have the same bits field definition with CHIER */ 919aebfd4aSSean Wang #define MTK_REG_CHISR 0x10 929aebfd4aSSean Wang #define MTK_REG_CHIER 0x14 939aebfd4aSSean Wang #define FW_OWN_BACK_INT BIT(0) 949aebfd4aSSean Wang #define RX_DONE_INT BIT(1) 959aebfd4aSSean Wang #define TX_EMPTY BIT(2) 969aebfd4aSSean Wang #define TX_FIFO_OVERFLOW BIT(8) 972fc967ccSMark Chen #define FW_MAILBOX_INT BIT(15) 98db3f1f9bSSean Wang #define INT_MASK GENMASK(15, 0) 999aebfd4aSSean Wang #define RX_PKT_LEN GENMASK(31, 16) 1009aebfd4aSSean Wang 10101ecc177SMark Chen #define MTK_REG_CSICR 0xc0 10201ecc177SMark Chen #define CSICR_CLR_MBOX_ACK BIT(0) 1032fc967ccSMark Chen #define MTK_REG_PH2DSM0R 0xc4 1042fc967ccSMark Chen #define PH2DSM0R_DRIVER_OWN BIT(0) 10501ecc177SMark Chen #define MTK_REG_PD2HRM0R 0xdc 10601ecc177SMark Chen #define PD2HRM0R_DRV_OWN BIT(0) 1072fc967ccSMark Chen 1089aebfd4aSSean Wang #define MTK_REG_CTDR 0x18 1099aebfd4aSSean Wang 1109aebfd4aSSean Wang #define MTK_REG_CRDR 0x1c 1119aebfd4aSSean Wang 112184ea403SSean Wang #define MTK_REG_CRPLR 0x24 113184ea403SSean Wang 1149aebfd4aSSean Wang #define MTK_SDIO_BLOCK_SIZE 256 1159aebfd4aSSean Wang 1169aebfd4aSSean Wang #define BTMTKSDIO_TX_WAIT_VND_EVT 1 117d555b1f2SSean Wang #define BTMTKSDIO_HW_TX_READY 2 1184b4b2228SSean Wang #define BTMTKSDIO_FUNC_ENABLED 3 11901ecc177SMark Chen #define BTMTKSDIO_PATCH_ENABLED 4 120*8fafe702SChih-Ying Chiang #define BTMTKSDIO_HW_RESET_ACTIVE 5 1219aebfd4aSSean Wang 1229aebfd4aSSean Wang struct mtkbtsdio_hdr { 1239aebfd4aSSean Wang __le16 len; 1249aebfd4aSSean Wang __le16 reserved; 1259aebfd4aSSean Wang u8 bt_type; 1269aebfd4aSSean Wang } __packed; 1279aebfd4aSSean Wang 1289aebfd4aSSean Wang struct btmtksdio_dev { 1299aebfd4aSSean Wang struct hci_dev *hdev; 1309aebfd4aSSean Wang struct sdio_func *func; 1317f3c563cSSean Wang struct device *dev; 1329aebfd4aSSean Wang 13326270bc1SSean Wang struct work_struct txrx_work; 1349aebfd4aSSean Wang unsigned long tx_state; 1359aebfd4aSSean Wang struct sk_buff_head txq; 1369aebfd4aSSean Wang 1379aebfd4aSSean Wang struct sk_buff *evt_skb; 1389aebfd4aSSean Wang 1399aebfd4aSSean Wang const struct btmtksdio_data *data; 140*8fafe702SChih-Ying Chiang 141*8fafe702SChih-Ying Chiang struct gpio_desc *reset; 1429aebfd4aSSean Wang }; 1439aebfd4aSSean Wang 1449aebfd4aSSean Wang static int mtk_hci_wmt_sync(struct hci_dev *hdev, 1459aebfd4aSSean Wang struct btmtk_hci_wmt_params *wmt_params) 1469aebfd4aSSean Wang { 1479aebfd4aSSean Wang struct btmtksdio_dev *bdev = hci_get_drvdata(hdev); 1489aebfd4aSSean Wang struct btmtk_hci_wmt_evt_funcc *wmt_evt_funcc; 149c603bf1fSSean Wang struct btmtk_hci_wmt_evt_reg *wmt_evt_reg; 1509aebfd4aSSean Wang u32 hlen, status = BTMTK_WMT_INVALID; 1519aebfd4aSSean Wang struct btmtk_hci_wmt_evt *wmt_evt; 1523a722044SSean Wang struct btmtk_hci_wmt_cmd *wc; 1533a722044SSean Wang struct btmtk_wmt_hdr *hdr; 1549aebfd4aSSean Wang int err; 1559aebfd4aSSean Wang 1563a722044SSean Wang /* Send the WMT command and wait until the WMT event returns */ 1579aebfd4aSSean Wang hlen = sizeof(*hdr) + wmt_params->dlen; 1589aebfd4aSSean Wang if (hlen > 255) 1599aebfd4aSSean Wang return -EINVAL; 1609aebfd4aSSean Wang 1613a722044SSean Wang wc = kzalloc(hlen, GFP_KERNEL); 1623a722044SSean Wang if (!wc) 1633a722044SSean Wang return -ENOMEM; 1643a722044SSean Wang 1653a722044SSean Wang hdr = &wc->hdr; 1669aebfd4aSSean Wang hdr->dir = 1; 1679aebfd4aSSean Wang hdr->op = wmt_params->op; 1689aebfd4aSSean Wang hdr->dlen = cpu_to_le16(wmt_params->dlen + 1); 1699aebfd4aSSean Wang hdr->flag = wmt_params->flag; 1703a722044SSean Wang memcpy(wc->data, wmt_params->data, wmt_params->dlen); 1719aebfd4aSSean Wang 1729aebfd4aSSean Wang set_bit(BTMTKSDIO_TX_WAIT_VND_EVT, &bdev->tx_state); 1739aebfd4aSSean Wang 1743a722044SSean Wang err = __hci_cmd_send(hdev, 0xfc6f, hlen, wc); 1759aebfd4aSSean Wang if (err < 0) { 1769aebfd4aSSean Wang clear_bit(BTMTKSDIO_TX_WAIT_VND_EVT, &bdev->tx_state); 1773a722044SSean Wang goto err_free_wc; 1789aebfd4aSSean Wang } 1799aebfd4aSSean Wang 1809aebfd4aSSean Wang /* The vendor specific WMT commands are all answered by a vendor 1819aebfd4aSSean Wang * specific event and will not have the Command Status or Command 1829aebfd4aSSean Wang * Complete as with usual HCI command flow control. 1839aebfd4aSSean Wang * 1849aebfd4aSSean Wang * After sending the command, wait for BTMTKSDIO_TX_WAIT_VND_EVT 1859aebfd4aSSean Wang * state to be cleared. The driver specific event receive routine 1869aebfd4aSSean Wang * will clear that state and with that indicate completion of the 1879aebfd4aSSean Wang * WMT command. 1889aebfd4aSSean Wang */ 1899aebfd4aSSean Wang err = wait_on_bit_timeout(&bdev->tx_state, BTMTKSDIO_TX_WAIT_VND_EVT, 1909aebfd4aSSean Wang TASK_INTERRUPTIBLE, HCI_INIT_TIMEOUT); 1919aebfd4aSSean Wang if (err == -EINTR) { 1929aebfd4aSSean Wang bt_dev_err(hdev, "Execution of wmt command interrupted"); 1939aebfd4aSSean Wang clear_bit(BTMTKSDIO_TX_WAIT_VND_EVT, &bdev->tx_state); 1943a722044SSean Wang goto err_free_wc; 1959aebfd4aSSean Wang } 1969aebfd4aSSean Wang 1979aebfd4aSSean Wang if (err) { 1989aebfd4aSSean Wang bt_dev_err(hdev, "Execution of wmt command timed out"); 1999aebfd4aSSean Wang clear_bit(BTMTKSDIO_TX_WAIT_VND_EVT, &bdev->tx_state); 2003a722044SSean Wang err = -ETIMEDOUT; 2013a722044SSean Wang goto err_free_wc; 2029aebfd4aSSean Wang } 2039aebfd4aSSean Wang 2049aebfd4aSSean Wang /* Parse and handle the return WMT event */ 2059aebfd4aSSean Wang wmt_evt = (struct btmtk_hci_wmt_evt *)bdev->evt_skb->data; 2069aebfd4aSSean Wang if (wmt_evt->whdr.op != hdr->op) { 2079aebfd4aSSean Wang bt_dev_err(hdev, "Wrong op received %d expected %d", 2089aebfd4aSSean Wang wmt_evt->whdr.op, hdr->op); 2099aebfd4aSSean Wang err = -EIO; 2109aebfd4aSSean Wang goto err_free_skb; 2119aebfd4aSSean Wang } 2129aebfd4aSSean Wang 2139aebfd4aSSean Wang switch (wmt_evt->whdr.op) { 2143a722044SSean Wang case BTMTK_WMT_SEMAPHORE: 2159aebfd4aSSean Wang if (wmt_evt->whdr.flag == 2) 2169aebfd4aSSean Wang status = BTMTK_WMT_PATCH_UNDONE; 2179aebfd4aSSean Wang else 2189aebfd4aSSean Wang status = BTMTK_WMT_PATCH_DONE; 2199aebfd4aSSean Wang break; 2203a722044SSean Wang case BTMTK_WMT_FUNC_CTRL: 2219aebfd4aSSean Wang wmt_evt_funcc = (struct btmtk_hci_wmt_evt_funcc *)wmt_evt; 2229aebfd4aSSean Wang if (be16_to_cpu(wmt_evt_funcc->status) == 0x404) 2239aebfd4aSSean Wang status = BTMTK_WMT_ON_DONE; 2249aebfd4aSSean Wang else if (be16_to_cpu(wmt_evt_funcc->status) == 0x420) 2259aebfd4aSSean Wang status = BTMTK_WMT_ON_PROGRESS; 2269aebfd4aSSean Wang else 2279aebfd4aSSean Wang status = BTMTK_WMT_ON_UNDONE; 2289aebfd4aSSean Wang break; 229c603bf1fSSean Wang case BTMTK_WMT_PATCH_DWNLD: 230c603bf1fSSean Wang if (wmt_evt->whdr.flag == 2) 231c603bf1fSSean Wang status = BTMTK_WMT_PATCH_DONE; 232c603bf1fSSean Wang else if (wmt_evt->whdr.flag == 1) 233c603bf1fSSean Wang status = BTMTK_WMT_PATCH_PROGRESS; 234c603bf1fSSean Wang else 235c603bf1fSSean Wang status = BTMTK_WMT_PATCH_UNDONE; 236c603bf1fSSean Wang break; 237c603bf1fSSean Wang case BTMTK_WMT_REGISTER: 238c603bf1fSSean Wang wmt_evt_reg = (struct btmtk_hci_wmt_evt_reg *)wmt_evt; 239c603bf1fSSean Wang if (le16_to_cpu(wmt_evt->whdr.dlen) == 12) 240c603bf1fSSean Wang status = le32_to_cpu(wmt_evt_reg->val); 241c603bf1fSSean Wang break; 2429aebfd4aSSean Wang } 2439aebfd4aSSean Wang 2449aebfd4aSSean Wang if (wmt_params->status) 2459aebfd4aSSean Wang *wmt_params->status = status; 2469aebfd4aSSean Wang 2479aebfd4aSSean Wang err_free_skb: 2489aebfd4aSSean Wang kfree_skb(bdev->evt_skb); 2499aebfd4aSSean Wang bdev->evt_skb = NULL; 2503a722044SSean Wang err_free_wc: 2513a722044SSean Wang kfree(wc); 2529aebfd4aSSean Wang 2539aebfd4aSSean Wang return err; 2549aebfd4aSSean Wang } 2559aebfd4aSSean Wang 2569aebfd4aSSean Wang static int btmtksdio_tx_packet(struct btmtksdio_dev *bdev, 2579aebfd4aSSean Wang struct sk_buff *skb) 2589aebfd4aSSean Wang { 2599aebfd4aSSean Wang struct mtkbtsdio_hdr *sdio_hdr; 2609aebfd4aSSean Wang int err; 2619aebfd4aSSean Wang 2629aebfd4aSSean Wang /* Make sure that there are enough rooms for SDIO header */ 2639aebfd4aSSean Wang if (unlikely(skb_headroom(skb) < sizeof(*sdio_hdr))) { 2649aebfd4aSSean Wang err = pskb_expand_head(skb, sizeof(*sdio_hdr), 0, 2659aebfd4aSSean Wang GFP_ATOMIC); 2669aebfd4aSSean Wang if (err < 0) 2679aebfd4aSSean Wang return err; 2689aebfd4aSSean Wang } 2699aebfd4aSSean Wang 2709aebfd4aSSean Wang /* Prepend MediaTek SDIO Specific Header */ 2719aebfd4aSSean Wang skb_push(skb, sizeof(*sdio_hdr)); 2729aebfd4aSSean Wang 2739aebfd4aSSean Wang sdio_hdr = (void *)skb->data; 2749aebfd4aSSean Wang sdio_hdr->len = cpu_to_le16(skb->len); 2759aebfd4aSSean Wang sdio_hdr->reserved = cpu_to_le16(0); 2769aebfd4aSSean Wang sdio_hdr->bt_type = hci_skb_pkt_type(skb); 2779aebfd4aSSean Wang 278d555b1f2SSean Wang clear_bit(BTMTKSDIO_HW_TX_READY, &bdev->tx_state); 2799aebfd4aSSean Wang err = sdio_writesb(bdev->func, MTK_REG_CTDR, skb->data, 2809aebfd4aSSean Wang round_up(skb->len, MTK_SDIO_BLOCK_SIZE)); 2819aebfd4aSSean Wang if (err < 0) 2829aebfd4aSSean Wang goto err_skb_pull; 2839aebfd4aSSean Wang 2849aebfd4aSSean Wang bdev->hdev->stat.byte_tx += skb->len; 2859aebfd4aSSean Wang 2869aebfd4aSSean Wang kfree_skb(skb); 2879aebfd4aSSean Wang 2889aebfd4aSSean Wang return 0; 2899aebfd4aSSean Wang 2909aebfd4aSSean Wang err_skb_pull: 2919aebfd4aSSean Wang skb_pull(skb, sizeof(*sdio_hdr)); 2929aebfd4aSSean Wang 2939aebfd4aSSean Wang return err; 2949aebfd4aSSean Wang } 2959aebfd4aSSean Wang 2969aebfd4aSSean Wang static u32 btmtksdio_drv_own_query(struct btmtksdio_dev *bdev) 2979aebfd4aSSean Wang { 2989aebfd4aSSean Wang return sdio_readl(bdev->func, MTK_REG_CHLPCR, NULL); 2999aebfd4aSSean Wang } 3009aebfd4aSSean Wang 30101ecc177SMark Chen static u32 btmtksdio_drv_own_query_79xx(struct btmtksdio_dev *bdev) 30201ecc177SMark Chen { 30301ecc177SMark Chen return sdio_readl(bdev->func, MTK_REG_PD2HRM0R, NULL); 30401ecc177SMark Chen } 30501ecc177SMark Chen 306*8fafe702SChih-Ying Chiang static u32 btmtksdio_chcr_query(struct btmtksdio_dev *bdev) 307*8fafe702SChih-Ying Chiang { 308*8fafe702SChih-Ying Chiang return sdio_readl(bdev->func, MTK_REG_CHCR, NULL); 309*8fafe702SChih-Ying Chiang } 310*8fafe702SChih-Ying Chiang 311c7e301d7SMark Chen static int btmtksdio_fw_pmctrl(struct btmtksdio_dev *bdev) 312c7e301d7SMark Chen { 313c7e301d7SMark Chen u32 status; 314c7e301d7SMark Chen int err; 315c7e301d7SMark Chen 316c7e301d7SMark Chen sdio_claim_host(bdev->func); 317c7e301d7SMark Chen 31801ecc177SMark Chen if (bdev->data->lp_mbox_supported && 31901ecc177SMark Chen test_bit(BTMTKSDIO_PATCH_ENABLED, &bdev->tx_state)) { 32001ecc177SMark Chen sdio_writel(bdev->func, CSICR_CLR_MBOX_ACK, MTK_REG_CSICR, 32101ecc177SMark Chen &err); 32201ecc177SMark Chen err = readx_poll_timeout(btmtksdio_drv_own_query_79xx, bdev, 32301ecc177SMark Chen status, !(status & PD2HRM0R_DRV_OWN), 32401ecc177SMark Chen 2000, 1000000); 32501ecc177SMark Chen if (err < 0) { 32601ecc177SMark Chen bt_dev_err(bdev->hdev, "mailbox ACK not cleared"); 32701ecc177SMark Chen goto out; 32801ecc177SMark Chen } 32901ecc177SMark Chen } 33001ecc177SMark Chen 331c7e301d7SMark Chen /* Return ownership to the device */ 332c7e301d7SMark Chen sdio_writel(bdev->func, C_FW_OWN_REQ_SET, MTK_REG_CHLPCR, &err); 333c7e301d7SMark Chen if (err < 0) 334c7e301d7SMark Chen goto out; 335c7e301d7SMark Chen 336c7e301d7SMark Chen err = readx_poll_timeout(btmtksdio_drv_own_query, bdev, status, 337c7e301d7SMark Chen !(status & C_COM_DRV_OWN), 2000, 1000000); 338c7e301d7SMark Chen 339c7e301d7SMark Chen out: 340c7e301d7SMark Chen sdio_release_host(bdev->func); 341c7e301d7SMark Chen 342c7e301d7SMark Chen if (err < 0) 343c7e301d7SMark Chen bt_dev_err(bdev->hdev, "Cannot return ownership to device"); 344c7e301d7SMark Chen 345c7e301d7SMark Chen return err; 346c7e301d7SMark Chen } 347c7e301d7SMark Chen 348c7e301d7SMark Chen static int btmtksdio_drv_pmctrl(struct btmtksdio_dev *bdev) 349c7e301d7SMark Chen { 350c7e301d7SMark Chen u32 status; 351c7e301d7SMark Chen int err; 352c7e301d7SMark Chen 353c7e301d7SMark Chen sdio_claim_host(bdev->func); 354c7e301d7SMark Chen 355c7e301d7SMark Chen /* Get ownership from the device */ 356c7e301d7SMark Chen sdio_writel(bdev->func, C_FW_OWN_REQ_CLR, MTK_REG_CHLPCR, &err); 357c7e301d7SMark Chen if (err < 0) 358c7e301d7SMark Chen goto out; 359c7e301d7SMark Chen 360c7e301d7SMark Chen err = readx_poll_timeout(btmtksdio_drv_own_query, bdev, status, 361c7e301d7SMark Chen status & C_COM_DRV_OWN, 2000, 1000000); 362c7e301d7SMark Chen 36301ecc177SMark Chen if (!err && bdev->data->lp_mbox_supported && 36401ecc177SMark Chen test_bit(BTMTKSDIO_PATCH_ENABLED, &bdev->tx_state)) 36501ecc177SMark Chen err = readx_poll_timeout(btmtksdio_drv_own_query_79xx, bdev, 36601ecc177SMark Chen status, status & PD2HRM0R_DRV_OWN, 36701ecc177SMark Chen 2000, 1000000); 36801ecc177SMark Chen 369c7e301d7SMark Chen out: 370c7e301d7SMark Chen sdio_release_host(bdev->func); 371c7e301d7SMark Chen 372c7e301d7SMark Chen if (err < 0) 373c7e301d7SMark Chen bt_dev_err(bdev->hdev, "Cannot get ownership from device"); 374c7e301d7SMark Chen 375c7e301d7SMark Chen return err; 376c7e301d7SMark Chen } 377c7e301d7SMark Chen 3789aebfd4aSSean Wang static int btmtksdio_recv_event(struct hci_dev *hdev, struct sk_buff *skb) 3799aebfd4aSSean Wang { 3809aebfd4aSSean Wang struct btmtksdio_dev *bdev = hci_get_drvdata(hdev); 3819aebfd4aSSean Wang struct hci_event_hdr *hdr = (void *)skb->data; 3829aebfd4aSSean Wang int err; 3839aebfd4aSSean Wang 3849aebfd4aSSean Wang /* Fix up the vendor event id with 0xff for vendor specific instead 3859aebfd4aSSean Wang * of 0xe4 so that event send via monitoring socket can be parsed 3869aebfd4aSSean Wang * properly. 3879aebfd4aSSean Wang */ 3889aebfd4aSSean Wang if (hdr->evt == 0xe4) 3899aebfd4aSSean Wang hdr->evt = HCI_EV_VENDOR; 3909aebfd4aSSean Wang 3919aebfd4aSSean Wang /* When someone waits for the WMT event, the skb is being cloned 3929aebfd4aSSean Wang * and being processed the events from there then. 3939aebfd4aSSean Wang */ 3949aebfd4aSSean Wang if (test_bit(BTMTKSDIO_TX_WAIT_VND_EVT, &bdev->tx_state)) { 3959aebfd4aSSean Wang bdev->evt_skb = skb_clone(skb, GFP_KERNEL); 3969aebfd4aSSean Wang if (!bdev->evt_skb) { 3979aebfd4aSSean Wang err = -ENOMEM; 3989aebfd4aSSean Wang goto err_out; 3999aebfd4aSSean Wang } 4009aebfd4aSSean Wang } 4019aebfd4aSSean Wang 4029aebfd4aSSean Wang err = hci_recv_frame(hdev, skb); 4039aebfd4aSSean Wang if (err < 0) 4049aebfd4aSSean Wang goto err_free_skb; 4059aebfd4aSSean Wang 4069aebfd4aSSean Wang if (hdr->evt == HCI_EV_VENDOR) { 4079aebfd4aSSean Wang if (test_and_clear_bit(BTMTKSDIO_TX_WAIT_VND_EVT, 4089aebfd4aSSean Wang &bdev->tx_state)) { 4099aebfd4aSSean Wang /* Barrier to sync with other CPUs */ 4109aebfd4aSSean Wang smp_mb__after_atomic(); 4119aebfd4aSSean Wang wake_up_bit(&bdev->tx_state, BTMTKSDIO_TX_WAIT_VND_EVT); 4129aebfd4aSSean Wang } 4139aebfd4aSSean Wang } 4149aebfd4aSSean Wang 4159aebfd4aSSean Wang return 0; 4169aebfd4aSSean Wang 4179aebfd4aSSean Wang err_free_skb: 4189aebfd4aSSean Wang kfree_skb(bdev->evt_skb); 4199aebfd4aSSean Wang bdev->evt_skb = NULL; 4209aebfd4aSSean Wang 4219aebfd4aSSean Wang err_out: 4229aebfd4aSSean Wang return err; 4239aebfd4aSSean Wang } 4249aebfd4aSSean Wang 425db57b625SSean Wang static int btmtksdio_recv_acl(struct hci_dev *hdev, struct sk_buff *skb) 426db57b625SSean Wang { 427db57b625SSean Wang struct btmtksdio_dev *bdev = hci_get_drvdata(hdev); 428db57b625SSean Wang u16 handle = le16_to_cpu(hci_acl_hdr(skb)->handle); 429db57b625SSean Wang 430db57b625SSean Wang switch (handle) { 431db57b625SSean Wang case 0xfc6f: 432db57b625SSean Wang /* Firmware dump from device: when the firmware hangs, the 433db57b625SSean Wang * device can no longer suspend and thus disable auto-suspend. 434db57b625SSean Wang */ 435db57b625SSean Wang pm_runtime_forbid(bdev->dev); 436db57b625SSean Wang fallthrough; 437db57b625SSean Wang case 0x05ff: 438db57b625SSean Wang case 0x05fe: 439db57b625SSean Wang /* Firmware debug logging */ 440db57b625SSean Wang return hci_recv_diag(hdev, skb); 441db57b625SSean Wang } 442db57b625SSean Wang 443db57b625SSean Wang return hci_recv_frame(hdev, skb); 444db57b625SSean Wang } 445db57b625SSean Wang 4469aebfd4aSSean Wang static const struct h4_recv_pkt mtk_recv_pkts[] = { 447db57b625SSean Wang { H4_RECV_ACL, .recv = btmtksdio_recv_acl }, 4489aebfd4aSSean Wang { H4_RECV_SCO, .recv = hci_recv_frame }, 4499aebfd4aSSean Wang { H4_RECV_EVENT, .recv = btmtksdio_recv_event }, 4509aebfd4aSSean Wang }; 4519aebfd4aSSean Wang 4529aebfd4aSSean Wang static int btmtksdio_rx_packet(struct btmtksdio_dev *bdev, u16 rx_size) 4539aebfd4aSSean Wang { 4549aebfd4aSSean Wang const struct h4_recv_pkt *pkts = mtk_recv_pkts; 4559aebfd4aSSean Wang int pkts_count = ARRAY_SIZE(mtk_recv_pkts); 4569aebfd4aSSean Wang struct mtkbtsdio_hdr *sdio_hdr; 4579aebfd4aSSean Wang int err, i, pad_size; 4589aebfd4aSSean Wang struct sk_buff *skb; 4599aebfd4aSSean Wang u16 dlen; 4609aebfd4aSSean Wang 4619aebfd4aSSean Wang if (rx_size < sizeof(*sdio_hdr)) 4629aebfd4aSSean Wang return -EILSEQ; 4639aebfd4aSSean Wang 4649aebfd4aSSean Wang /* A SDIO packet is exactly containing a Bluetooth packet */ 4659aebfd4aSSean Wang skb = bt_skb_alloc(rx_size, GFP_KERNEL); 4669aebfd4aSSean Wang if (!skb) 4679aebfd4aSSean Wang return -ENOMEM; 4689aebfd4aSSean Wang 4699aebfd4aSSean Wang skb_put(skb, rx_size); 4709aebfd4aSSean Wang 4719aebfd4aSSean Wang err = sdio_readsb(bdev->func, skb->data, MTK_REG_CRDR, rx_size); 4729aebfd4aSSean Wang if (err < 0) 4739aebfd4aSSean Wang goto err_kfree_skb; 4749aebfd4aSSean Wang 4759aebfd4aSSean Wang sdio_hdr = (void *)skb->data; 4769aebfd4aSSean Wang 4779aebfd4aSSean Wang /* We assume the default error as -EILSEQ simply to make the error path 4789aebfd4aSSean Wang * be cleaner. 4799aebfd4aSSean Wang */ 4809aebfd4aSSean Wang err = -EILSEQ; 4819aebfd4aSSean Wang 4829aebfd4aSSean Wang if (rx_size != le16_to_cpu(sdio_hdr->len)) { 4839aebfd4aSSean Wang bt_dev_err(bdev->hdev, "Rx size in sdio header is mismatched "); 4849aebfd4aSSean Wang goto err_kfree_skb; 4859aebfd4aSSean Wang } 4869aebfd4aSSean Wang 4879aebfd4aSSean Wang hci_skb_pkt_type(skb) = sdio_hdr->bt_type; 4889aebfd4aSSean Wang 4899aebfd4aSSean Wang /* Remove MediaTek SDIO header */ 4909aebfd4aSSean Wang skb_pull(skb, sizeof(*sdio_hdr)); 4919aebfd4aSSean Wang 4929aebfd4aSSean Wang /* We have to dig into the packet to get payload size and then know how 4939aebfd4aSSean Wang * many padding bytes at the tail, these padding bytes should be removed 4949aebfd4aSSean Wang * before the packet is indicated to the core layer. 4959aebfd4aSSean Wang */ 4969aebfd4aSSean Wang for (i = 0; i < pkts_count; i++) { 4979aebfd4aSSean Wang if (sdio_hdr->bt_type == (&pkts[i])->type) 4989aebfd4aSSean Wang break; 4999aebfd4aSSean Wang } 5009aebfd4aSSean Wang 5019aebfd4aSSean Wang if (i >= pkts_count) { 5029aebfd4aSSean Wang bt_dev_err(bdev->hdev, "Invalid bt type 0x%02x", 5039aebfd4aSSean Wang sdio_hdr->bt_type); 5049aebfd4aSSean Wang goto err_kfree_skb; 5059aebfd4aSSean Wang } 5069aebfd4aSSean Wang 5079aebfd4aSSean Wang /* Remaining bytes cannot hold a header*/ 5089aebfd4aSSean Wang if (skb->len < (&pkts[i])->hlen) { 5099aebfd4aSSean Wang bt_dev_err(bdev->hdev, "The size of bt header is mismatched"); 5109aebfd4aSSean Wang goto err_kfree_skb; 5119aebfd4aSSean Wang } 5129aebfd4aSSean Wang 5139aebfd4aSSean Wang switch ((&pkts[i])->lsize) { 5149aebfd4aSSean Wang case 1: 5159aebfd4aSSean Wang dlen = skb->data[(&pkts[i])->loff]; 5169aebfd4aSSean Wang break; 5179aebfd4aSSean Wang case 2: 5189aebfd4aSSean Wang dlen = get_unaligned_le16(skb->data + 5199aebfd4aSSean Wang (&pkts[i])->loff); 5209aebfd4aSSean Wang break; 5219aebfd4aSSean Wang default: 5229aebfd4aSSean Wang goto err_kfree_skb; 5239aebfd4aSSean Wang } 5249aebfd4aSSean Wang 5259aebfd4aSSean Wang pad_size = skb->len - (&pkts[i])->hlen - dlen; 5269aebfd4aSSean Wang 5279aebfd4aSSean Wang /* Remaining bytes cannot hold a payload */ 5289aebfd4aSSean Wang if (pad_size < 0) { 5299aebfd4aSSean Wang bt_dev_err(bdev->hdev, "The size of bt payload is mismatched"); 5309aebfd4aSSean Wang goto err_kfree_skb; 5319aebfd4aSSean Wang } 5329aebfd4aSSean Wang 5339aebfd4aSSean Wang /* Remove padding bytes */ 5349aebfd4aSSean Wang skb_trim(skb, skb->len - pad_size); 5359aebfd4aSSean Wang 5369aebfd4aSSean Wang /* Complete frame */ 5379aebfd4aSSean Wang (&pkts[i])->recv(bdev->hdev, skb); 5389aebfd4aSSean Wang 539bcaa7d72SSean Wang bdev->hdev->stat.byte_rx += rx_size; 540bcaa7d72SSean Wang 5419aebfd4aSSean Wang return 0; 5429aebfd4aSSean Wang 5439aebfd4aSSean Wang err_kfree_skb: 5449aebfd4aSSean Wang kfree_skb(skb); 5459aebfd4aSSean Wang 5469aebfd4aSSean Wang return err; 5479aebfd4aSSean Wang } 5489aebfd4aSSean Wang 54926270bc1SSean Wang static void btmtksdio_txrx_work(struct work_struct *work) 5509aebfd4aSSean Wang { 55126270bc1SSean Wang struct btmtksdio_dev *bdev = container_of(work, struct btmtksdio_dev, 55226270bc1SSean Wang txrx_work); 55326270bc1SSean Wang unsigned long txrx_timeout; 554184ea403SSean Wang u32 int_status, rx_size; 55526270bc1SSean Wang struct sk_buff *skb; 55626270bc1SSean Wang int err; 5577f3c563cSSean Wang 5587f3c563cSSean Wang pm_runtime_get_sync(bdev->dev); 5597f3c563cSSean Wang 5607f3c563cSSean Wang sdio_claim_host(bdev->func); 5617f3c563cSSean Wang 5629aebfd4aSSean Wang /* Disable interrupt */ 56326270bc1SSean Wang sdio_writel(bdev->func, C_INT_EN_CLR, MTK_REG_CHLPCR, 0); 5649aebfd4aSSean Wang 56526270bc1SSean Wang txrx_timeout = jiffies + 5 * HZ; 56626270bc1SSean Wang 56726270bc1SSean Wang do { 56826270bc1SSean Wang int_status = sdio_readl(bdev->func, MTK_REG_CHISR, NULL); 5699aebfd4aSSean Wang 5709aebfd4aSSean Wang /* Ack an interrupt as soon as possible before any operation on 5719aebfd4aSSean Wang * hardware. 5729aebfd4aSSean Wang * 5739aebfd4aSSean Wang * Note that we don't ack any status during operations to avoid race 5749aebfd4aSSean Wang * condition between the host and the device such as it's possible to 5759aebfd4aSSean Wang * mistakenly ack RX_DONE for the next packet and then cause interrupts 5769aebfd4aSSean Wang * not be raised again but there is still pending data in the hardware 5779aebfd4aSSean Wang * FIFO. 5789aebfd4aSSean Wang */ 57926270bc1SSean Wang sdio_writel(bdev->func, int_status, MTK_REG_CHISR, NULL); 580db3f1f9bSSean Wang int_status &= INT_MASK; 5819aebfd4aSSean Wang 5822fc967ccSMark Chen if ((int_status & FW_MAILBOX_INT) && 5832fc967ccSMark Chen bdev->data->chipid == 0x7921) { 5842fc967ccSMark Chen sdio_writel(bdev->func, PH2DSM0R_DRIVER_OWN, 5852fc967ccSMark Chen MTK_REG_PH2DSM0R, 0); 5862fc967ccSMark Chen } 5872fc967ccSMark Chen 5889aebfd4aSSean Wang if (int_status & FW_OWN_BACK_INT) 589e1052fb2SSean Wang bt_dev_dbg(bdev->hdev, "Get fw own back"); 5909aebfd4aSSean Wang 5919aebfd4aSSean Wang if (int_status & TX_EMPTY) 592d555b1f2SSean Wang set_bit(BTMTKSDIO_HW_TX_READY, &bdev->tx_state); 593d555b1f2SSean Wang 5949aebfd4aSSean Wang else if (unlikely(int_status & TX_FIFO_OVERFLOW)) 595e1052fb2SSean Wang bt_dev_warn(bdev->hdev, "Tx fifo overflow"); 5969aebfd4aSSean Wang 597d555b1f2SSean Wang if (test_bit(BTMTKSDIO_HW_TX_READY, &bdev->tx_state)) { 59810fe40e1SMark-yw Chen skb = skb_dequeue(&bdev->txq); 59910fe40e1SMark-yw Chen if (skb) { 60010fe40e1SMark-yw Chen err = btmtksdio_tx_packet(bdev, skb); 60110fe40e1SMark-yw Chen if (err < 0) { 60210fe40e1SMark-yw Chen bdev->hdev->stat.err_tx++; 60310fe40e1SMark-yw Chen skb_queue_head(&bdev->txq, skb); 60410fe40e1SMark-yw Chen } 60510fe40e1SMark-yw Chen } 60610fe40e1SMark-yw Chen } 60710fe40e1SMark-yw Chen 6089aebfd4aSSean Wang if (int_status & RX_DONE_INT) { 609184ea403SSean Wang rx_size = sdio_readl(bdev->func, MTK_REG_CRPLR, NULL); 610184ea403SSean Wang rx_size = (rx_size & RX_PKT_LEN) >> 16; 6119aebfd4aSSean Wang if (btmtksdio_rx_packet(bdev, rx_size) < 0) 6129aebfd4aSSean Wang bdev->hdev->stat.err_rx++; 6139aebfd4aSSean Wang } 61426270bc1SSean Wang } while (int_status || time_is_before_jiffies(txrx_timeout)); 61526270bc1SSean Wang 6169aebfd4aSSean Wang /* Enable interrupt */ 61726270bc1SSean Wang sdio_writel(bdev->func, C_INT_EN_SET, MTK_REG_CHLPCR, 0); 61826270bc1SSean Wang 61926270bc1SSean Wang sdio_release_host(bdev->func); 6207f3c563cSSean Wang 6217f3c563cSSean Wang pm_runtime_mark_last_busy(bdev->dev); 6227f3c563cSSean Wang pm_runtime_put_autosuspend(bdev->dev); 6239aebfd4aSSean Wang } 6249aebfd4aSSean Wang 62526270bc1SSean Wang static void btmtksdio_interrupt(struct sdio_func *func) 62626270bc1SSean Wang { 62726270bc1SSean Wang struct btmtksdio_dev *bdev = sdio_get_drvdata(func); 62826270bc1SSean Wang 62926270bc1SSean Wang /* Disable interrupt */ 63026270bc1SSean Wang sdio_writel(bdev->func, C_INT_EN_CLR, MTK_REG_CHLPCR, 0); 63126270bc1SSean Wang 63226270bc1SSean Wang schedule_work(&bdev->txrx_work); 63326270bc1SSean Wang } 63426270bc1SSean Wang 6359aebfd4aSSean Wang static int btmtksdio_open(struct hci_dev *hdev) 6369aebfd4aSSean Wang { 6379aebfd4aSSean Wang struct btmtksdio_dev *bdev = hci_get_drvdata(hdev); 638c7e301d7SMark Chen u32 val; 6399aebfd4aSSean Wang int err; 6409aebfd4aSSean Wang 6419aebfd4aSSean Wang sdio_claim_host(bdev->func); 6429aebfd4aSSean Wang 6439aebfd4aSSean Wang err = sdio_enable_func(bdev->func); 6449aebfd4aSSean Wang if (err < 0) 6459aebfd4aSSean Wang goto err_release_host; 6469aebfd4aSSean Wang 6474b4b2228SSean Wang set_bit(BTMTKSDIO_FUNC_ENABLED, &bdev->tx_state); 6484b4b2228SSean Wang 649c7e301d7SMark Chen err = btmtksdio_drv_pmctrl(bdev); 6509aebfd4aSSean Wang if (err < 0) 6519aebfd4aSSean Wang goto err_disable_func; 6529aebfd4aSSean Wang 6539aebfd4aSSean Wang /* Disable interrupt & mask out all interrupt sources */ 6549aebfd4aSSean Wang sdio_writel(bdev->func, C_INT_EN_CLR, MTK_REG_CHLPCR, &err); 6559aebfd4aSSean Wang if (err < 0) 6569aebfd4aSSean Wang goto err_disable_func; 6579aebfd4aSSean Wang 6589aebfd4aSSean Wang sdio_writel(bdev->func, 0, MTK_REG_CHIER, &err); 6599aebfd4aSSean Wang if (err < 0) 6609aebfd4aSSean Wang goto err_disable_func; 6619aebfd4aSSean Wang 6629aebfd4aSSean Wang err = sdio_claim_irq(bdev->func, btmtksdio_interrupt); 6639aebfd4aSSean Wang if (err < 0) 6649aebfd4aSSean Wang goto err_disable_func; 6659aebfd4aSSean Wang 6669aebfd4aSSean Wang err = sdio_set_block_size(bdev->func, MTK_SDIO_BLOCK_SIZE); 6679aebfd4aSSean Wang if (err < 0) 6689aebfd4aSSean Wang goto err_release_irq; 6699aebfd4aSSean Wang 6709aebfd4aSSean Wang /* SDIO CMD 5 allows the SDIO device back to idle state an 6719aebfd4aSSean Wang * synchronous interrupt is supported in SDIO 4-bit mode 6729aebfd4aSSean Wang */ 6735b23ac1aSSean Wang val = sdio_readl(bdev->func, MTK_REG_CSDIOCSR, &err); 6745b23ac1aSSean Wang if (err < 0) 6755b23ac1aSSean Wang goto err_release_irq; 6765b23ac1aSSean Wang 6775b23ac1aSSean Wang val |= SDIO_INT_CTL; 6785b23ac1aSSean Wang sdio_writel(bdev->func, val, MTK_REG_CSDIOCSR, &err); 6799aebfd4aSSean Wang if (err < 0) 6809aebfd4aSSean Wang goto err_release_irq; 6819aebfd4aSSean Wang 68277b210d1SSean Wang /* Explitly set write-1-clear method */ 68377b210d1SSean Wang val = sdio_readl(bdev->func, MTK_REG_CHCR, &err); 68477b210d1SSean Wang if (err < 0) 68577b210d1SSean Wang goto err_release_irq; 68677b210d1SSean Wang 68777b210d1SSean Wang val |= C_INT_CLR_CTRL; 68877b210d1SSean Wang sdio_writel(bdev->func, val, MTK_REG_CHCR, &err); 6899aebfd4aSSean Wang if (err < 0) 6909aebfd4aSSean Wang goto err_release_irq; 6919aebfd4aSSean Wang 6929aebfd4aSSean Wang /* Setup interrupt sources */ 6939aebfd4aSSean Wang sdio_writel(bdev->func, RX_DONE_INT | TX_EMPTY | TX_FIFO_OVERFLOW, 6949aebfd4aSSean Wang MTK_REG_CHIER, &err); 6959aebfd4aSSean Wang if (err < 0) 6969aebfd4aSSean Wang goto err_release_irq; 6979aebfd4aSSean Wang 6989aebfd4aSSean Wang /* Enable interrupt */ 6999aebfd4aSSean Wang sdio_writel(bdev->func, C_INT_EN_SET, MTK_REG_CHLPCR, &err); 7009aebfd4aSSean Wang if (err < 0) 7019aebfd4aSSean Wang goto err_release_irq; 7029aebfd4aSSean Wang 7039aebfd4aSSean Wang sdio_release_host(bdev->func); 7049aebfd4aSSean Wang 7059aebfd4aSSean Wang return 0; 7069aebfd4aSSean Wang 7079aebfd4aSSean Wang err_release_irq: 7089aebfd4aSSean Wang sdio_release_irq(bdev->func); 7099aebfd4aSSean Wang 7109aebfd4aSSean Wang err_disable_func: 7119aebfd4aSSean Wang sdio_disable_func(bdev->func); 7129aebfd4aSSean Wang 7139aebfd4aSSean Wang err_release_host: 7149aebfd4aSSean Wang sdio_release_host(bdev->func); 7159aebfd4aSSean Wang 7169aebfd4aSSean Wang return err; 7179aebfd4aSSean Wang } 7189aebfd4aSSean Wang 7199aebfd4aSSean Wang static int btmtksdio_close(struct hci_dev *hdev) 7209aebfd4aSSean Wang { 7219aebfd4aSSean Wang struct btmtksdio_dev *bdev = hci_get_drvdata(hdev); 7229aebfd4aSSean Wang 7239aebfd4aSSean Wang sdio_claim_host(bdev->func); 7249aebfd4aSSean Wang 7259aebfd4aSSean Wang /* Disable interrupt */ 7269aebfd4aSSean Wang sdio_writel(bdev->func, C_INT_EN_CLR, MTK_REG_CHLPCR, NULL); 7279aebfd4aSSean Wang 7289aebfd4aSSean Wang sdio_release_irq(bdev->func); 7299aebfd4aSSean Wang 73026270bc1SSean Wang cancel_work_sync(&bdev->txrx_work); 73126270bc1SSean Wang 732c7e301d7SMark Chen btmtksdio_fw_pmctrl(bdev); 7339aebfd4aSSean Wang 7344b4b2228SSean Wang clear_bit(BTMTKSDIO_FUNC_ENABLED, &bdev->tx_state); 7359aebfd4aSSean Wang sdio_disable_func(bdev->func); 7369aebfd4aSSean Wang 7379aebfd4aSSean Wang sdio_release_host(bdev->func); 7389aebfd4aSSean Wang 7399aebfd4aSSean Wang return 0; 7409aebfd4aSSean Wang } 7419aebfd4aSSean Wang 7429aebfd4aSSean Wang static int btmtksdio_flush(struct hci_dev *hdev) 7439aebfd4aSSean Wang { 7449aebfd4aSSean Wang struct btmtksdio_dev *bdev = hci_get_drvdata(hdev); 7459aebfd4aSSean Wang 7469aebfd4aSSean Wang skb_queue_purge(&bdev->txq); 7479aebfd4aSSean Wang 74826270bc1SSean Wang cancel_work_sync(&bdev->txrx_work); 7499aebfd4aSSean Wang 7509aebfd4aSSean Wang return 0; 7519aebfd4aSSean Wang } 7529aebfd4aSSean Wang 7539aebfd4aSSean Wang static int btmtksdio_func_query(struct hci_dev *hdev) 7549aebfd4aSSean Wang { 7559aebfd4aSSean Wang struct btmtk_hci_wmt_params wmt_params; 7569aebfd4aSSean Wang int status, err; 7579aebfd4aSSean Wang u8 param = 0; 7589aebfd4aSSean Wang 7599aebfd4aSSean Wang /* Query whether the function is enabled */ 7603a722044SSean Wang wmt_params.op = BTMTK_WMT_FUNC_CTRL; 7619aebfd4aSSean Wang wmt_params.flag = 4; 7629aebfd4aSSean Wang wmt_params.dlen = sizeof(param); 7639aebfd4aSSean Wang wmt_params.data = ¶m; 7649aebfd4aSSean Wang wmt_params.status = &status; 7659aebfd4aSSean Wang 7669aebfd4aSSean Wang err = mtk_hci_wmt_sync(hdev, &wmt_params); 7679aebfd4aSSean Wang if (err < 0) { 7689aebfd4aSSean Wang bt_dev_err(hdev, "Failed to query function status (%d)", err); 7699aebfd4aSSean Wang return err; 7709aebfd4aSSean Wang } 7719aebfd4aSSean Wang 7729aebfd4aSSean Wang return status; 7739aebfd4aSSean Wang } 7749aebfd4aSSean Wang 775c603bf1fSSean Wang static int mt76xx_setup(struct hci_dev *hdev, const char *fwname) 7769aebfd4aSSean Wang { 77701ecc177SMark Chen struct btmtksdio_dev *bdev = hci_get_drvdata(hdev); 7789aebfd4aSSean Wang struct btmtk_hci_wmt_params wmt_params; 7799aebfd4aSSean Wang struct btmtk_tci_sleep tci_sleep; 7809aebfd4aSSean Wang struct sk_buff *skb; 7819aebfd4aSSean Wang int err, status; 7829aebfd4aSSean Wang u8 param = 0x1; 7839aebfd4aSSean Wang 7849aebfd4aSSean Wang /* Query whether the firmware is already download */ 7853a722044SSean Wang wmt_params.op = BTMTK_WMT_SEMAPHORE; 7869aebfd4aSSean Wang wmt_params.flag = 1; 7879aebfd4aSSean Wang wmt_params.dlen = 0; 7889aebfd4aSSean Wang wmt_params.data = NULL; 7899aebfd4aSSean Wang wmt_params.status = &status; 7909aebfd4aSSean Wang 7919aebfd4aSSean Wang err = mtk_hci_wmt_sync(hdev, &wmt_params); 7929aebfd4aSSean Wang if (err < 0) { 7939aebfd4aSSean Wang bt_dev_err(hdev, "Failed to query firmware status (%d)", err); 7949aebfd4aSSean Wang return err; 7959aebfd4aSSean Wang } 7969aebfd4aSSean Wang 7979aebfd4aSSean Wang if (status == BTMTK_WMT_PATCH_DONE) { 7989aebfd4aSSean Wang bt_dev_info(hdev, "Firmware already downloaded"); 7999aebfd4aSSean Wang goto ignore_setup_fw; 8009aebfd4aSSean Wang } 8019aebfd4aSSean Wang 8029aebfd4aSSean Wang /* Setup a firmware which the device definitely requires */ 803c603bf1fSSean Wang err = btmtk_setup_firmware(hdev, fwname, mtk_hci_wmt_sync); 8049aebfd4aSSean Wang if (err < 0) 8059aebfd4aSSean Wang return err; 8069aebfd4aSSean Wang 8079aebfd4aSSean Wang ignore_setup_fw: 8089aebfd4aSSean Wang /* Query whether the device is already enabled */ 8099aebfd4aSSean Wang err = readx_poll_timeout(btmtksdio_func_query, hdev, status, 8109aebfd4aSSean Wang status < 0 || status != BTMTK_WMT_ON_PROGRESS, 8119aebfd4aSSean Wang 2000, 5000000); 8129aebfd4aSSean Wang /* -ETIMEDOUT happens */ 8139aebfd4aSSean Wang if (err < 0) 8149aebfd4aSSean Wang return err; 8159aebfd4aSSean Wang 8169aebfd4aSSean Wang /* The other errors happen in btusb_mtk_func_query */ 8179aebfd4aSSean Wang if (status < 0) 8189aebfd4aSSean Wang return status; 8199aebfd4aSSean Wang 8209aebfd4aSSean Wang if (status == BTMTK_WMT_ON_DONE) { 8219aebfd4aSSean Wang bt_dev_info(hdev, "function already on"); 8229aebfd4aSSean Wang goto ignore_func_on; 8239aebfd4aSSean Wang } 8249aebfd4aSSean Wang 8259aebfd4aSSean Wang /* Enable Bluetooth protocol */ 8263a722044SSean Wang wmt_params.op = BTMTK_WMT_FUNC_CTRL; 8279aebfd4aSSean Wang wmt_params.flag = 0; 8289aebfd4aSSean Wang wmt_params.dlen = sizeof(param); 8299aebfd4aSSean Wang wmt_params.data = ¶m; 8309aebfd4aSSean Wang wmt_params.status = NULL; 8319aebfd4aSSean Wang 8329aebfd4aSSean Wang err = mtk_hci_wmt_sync(hdev, &wmt_params); 8339aebfd4aSSean Wang if (err < 0) { 8349aebfd4aSSean Wang bt_dev_err(hdev, "Failed to send wmt func ctrl (%d)", err); 8359aebfd4aSSean Wang return err; 8369aebfd4aSSean Wang } 8379aebfd4aSSean Wang 83801ecc177SMark Chen set_bit(BTMTKSDIO_PATCH_ENABLED, &bdev->tx_state); 83901ecc177SMark Chen 8409aebfd4aSSean Wang ignore_func_on: 8419aebfd4aSSean Wang /* Apply the low power environment setup */ 8429aebfd4aSSean Wang tci_sleep.mode = 0x5; 8439aebfd4aSSean Wang tci_sleep.duration = cpu_to_le16(0x640); 8449aebfd4aSSean Wang tci_sleep.host_duration = cpu_to_le16(0x640); 8459aebfd4aSSean Wang tci_sleep.host_wakeup_pin = 0; 8469aebfd4aSSean Wang tci_sleep.time_compensation = 0; 8479aebfd4aSSean Wang 8489aebfd4aSSean Wang skb = __hci_cmd_sync(hdev, 0xfc7a, sizeof(tci_sleep), &tci_sleep, 8499aebfd4aSSean Wang HCI_INIT_TIMEOUT); 8509aebfd4aSSean Wang if (IS_ERR(skb)) { 8519aebfd4aSSean Wang err = PTR_ERR(skb); 8529aebfd4aSSean Wang bt_dev_err(hdev, "Failed to apply low power setting (%d)", err); 8539aebfd4aSSean Wang return err; 8549aebfd4aSSean Wang } 8559aebfd4aSSean Wang kfree_skb(skb); 8569aebfd4aSSean Wang 857c603bf1fSSean Wang return 0; 858c603bf1fSSean Wang } 859c603bf1fSSean Wang 860c603bf1fSSean Wang static int mt79xx_setup(struct hci_dev *hdev, const char *fwname) 861c603bf1fSSean Wang { 86201ecc177SMark Chen struct btmtksdio_dev *bdev = hci_get_drvdata(hdev); 863c603bf1fSSean Wang struct btmtk_hci_wmt_params wmt_params; 864c603bf1fSSean Wang u8 param = 0x1; 865c603bf1fSSean Wang int err; 866c603bf1fSSean Wang 867c603bf1fSSean Wang err = btmtk_setup_firmware_79xx(hdev, fwname, mtk_hci_wmt_sync); 868c603bf1fSSean Wang if (err < 0) { 869c603bf1fSSean Wang bt_dev_err(hdev, "Failed to setup 79xx firmware (%d)", err); 870c603bf1fSSean Wang return err; 871c603bf1fSSean Wang } 872c603bf1fSSean Wang 873c603bf1fSSean Wang /* Enable Bluetooth protocol */ 874c603bf1fSSean Wang wmt_params.op = BTMTK_WMT_FUNC_CTRL; 875c603bf1fSSean Wang wmt_params.flag = 0; 876c603bf1fSSean Wang wmt_params.dlen = sizeof(param); 877c603bf1fSSean Wang wmt_params.data = ¶m; 878c603bf1fSSean Wang wmt_params.status = NULL; 879c603bf1fSSean Wang 880c603bf1fSSean Wang err = mtk_hci_wmt_sync(hdev, &wmt_params); 881c603bf1fSSean Wang if (err < 0) { 882c603bf1fSSean Wang bt_dev_err(hdev, "Failed to send wmt func ctrl (%d)", err); 883c603bf1fSSean Wang return err; 884c603bf1fSSean Wang } 885c603bf1fSSean Wang 886630491ffSŁukasz Bartosik hci_set_msft_opcode(hdev, 0xFD30); 88716ada83bSSean Wang hci_set_aosp_capable(hdev); 88801ecc177SMark Chen set_bit(BTMTKSDIO_PATCH_ENABLED, &bdev->tx_state); 889630491ffSŁukasz Bartosik 890c603bf1fSSean Wang return err; 891c603bf1fSSean Wang } 892c603bf1fSSean Wang 8934b685879SSean Wang static int btmtksdio_mtk_reg_read(struct hci_dev *hdev, u32 reg, u32 *val) 894c603bf1fSSean Wang { 895c603bf1fSSean Wang struct btmtk_hci_wmt_params wmt_params; 8965677bcf6SSean Wang struct reg_read_cmd reg_read = { 897c603bf1fSSean Wang .type = 1, 898c603bf1fSSean Wang .num = 1, 899c603bf1fSSean Wang }; 900c603bf1fSSean Wang u32 status; 901c603bf1fSSean Wang int err; 902c603bf1fSSean Wang 903c603bf1fSSean Wang reg_read.addr = cpu_to_le32(reg); 904c603bf1fSSean Wang wmt_params.op = BTMTK_WMT_REGISTER; 905c603bf1fSSean Wang wmt_params.flag = BTMTK_WMT_REG_READ; 906c603bf1fSSean Wang wmt_params.dlen = sizeof(reg_read); 907c603bf1fSSean Wang wmt_params.data = ®_read; 908c603bf1fSSean Wang wmt_params.status = &status; 909c603bf1fSSean Wang 910c603bf1fSSean Wang err = mtk_hci_wmt_sync(hdev, &wmt_params); 911c603bf1fSSean Wang if (err < 0) { 912c603bf1fSSean Wang bt_dev_err(hdev, "Failed to read reg (%d)", err); 913c603bf1fSSean Wang return err; 914c603bf1fSSean Wang } 915c603bf1fSSean Wang 916c603bf1fSSean Wang *val = status; 917c603bf1fSSean Wang 918c603bf1fSSean Wang return err; 919c603bf1fSSean Wang } 920c603bf1fSSean Wang 921191c8723SMark Chen static int btmtksdio_mtk_reg_write(struct hci_dev *hdev, u32 reg, u32 val, u32 mask) 922191c8723SMark Chen { 923191c8723SMark Chen struct btmtk_hci_wmt_params wmt_params; 924191c8723SMark Chen const struct reg_write_cmd reg_write = { 925191c8723SMark Chen .type = 1, 926191c8723SMark Chen .num = 1, 927191c8723SMark Chen .addr = cpu_to_le32(reg), 928191c8723SMark Chen .data = cpu_to_le32(val), 929191c8723SMark Chen .mask = cpu_to_le32(mask), 930191c8723SMark Chen }; 931191c8723SMark Chen int err, status; 932191c8723SMark Chen 933191c8723SMark Chen wmt_params.op = BTMTK_WMT_REGISTER; 934191c8723SMark Chen wmt_params.flag = BTMTK_WMT_REG_WRITE; 935191c8723SMark Chen wmt_params.dlen = sizeof(reg_write); 936191c8723SMark Chen wmt_params.data = ®_write; 937191c8723SMark Chen wmt_params.status = &status; 938191c8723SMark Chen 939191c8723SMark Chen err = mtk_hci_wmt_sync(hdev, &wmt_params); 940191c8723SMark Chen if (err < 0) 941191c8723SMark Chen bt_dev_err(hdev, "Failed to write reg (%d)", err); 942191c8723SMark Chen 943191c8723SMark Chen return err; 944191c8723SMark Chen } 945191c8723SMark Chen 946191c8723SMark Chen static int btmtksdio_sco_setting(struct hci_dev *hdev) 947191c8723SMark Chen { 948191c8723SMark Chen const struct btmtk_sco sco_setting = { 949191c8723SMark Chen .clock_config = 0x49, 950191c8723SMark Chen .channel_format_config = 0x80, 951191c8723SMark Chen }; 952191c8723SMark Chen struct sk_buff *skb; 953191c8723SMark Chen u32 val; 954191c8723SMark Chen int err; 955191c8723SMark Chen 956191c8723SMark Chen /* Enable SCO over I2S/PCM for MediaTek chipset */ 957191c8723SMark Chen skb = __hci_cmd_sync(hdev, 0xfc72, sizeof(sco_setting), 958191c8723SMark Chen &sco_setting, HCI_CMD_TIMEOUT); 959191c8723SMark Chen if (IS_ERR(skb)) 960191c8723SMark Chen return PTR_ERR(skb); 961191c8723SMark Chen 962191c8723SMark Chen kfree_skb(skb); 963191c8723SMark Chen 964191c8723SMark Chen err = btmtksdio_mtk_reg_read(hdev, MT7921_PINMUX_0, &val); 965191c8723SMark Chen if (err < 0) 966191c8723SMark Chen return err; 967191c8723SMark Chen 968191c8723SMark Chen val |= 0x11000000; 969191c8723SMark Chen err = btmtksdio_mtk_reg_write(hdev, MT7921_PINMUX_0, val, ~0); 970191c8723SMark Chen if (err < 0) 971191c8723SMark Chen return err; 972191c8723SMark Chen 973191c8723SMark Chen err = btmtksdio_mtk_reg_read(hdev, MT7921_PINMUX_1, &val); 974191c8723SMark Chen if (err < 0) 975191c8723SMark Chen return err; 976191c8723SMark Chen 977191c8723SMark Chen val |= 0x00000101; 978191c8723SMark Chen return btmtksdio_mtk_reg_write(hdev, MT7921_PINMUX_1, val, ~0); 979191c8723SMark Chen } 980191c8723SMark Chen 981*8fafe702SChih-Ying Chiang static int btmtksdio_reset_setting(struct hci_dev *hdev) 982*8fafe702SChih-Ying Chiang { 983*8fafe702SChih-Ying Chiang int err; 984*8fafe702SChih-Ying Chiang u32 val; 985*8fafe702SChih-Ying Chiang 986*8fafe702SChih-Ying Chiang err = btmtksdio_mtk_reg_read(hdev, MT7921_PINMUX_1, &val); 987*8fafe702SChih-Ying Chiang if (err < 0) 988*8fafe702SChih-Ying Chiang return err; 989*8fafe702SChih-Ying Chiang 990*8fafe702SChih-Ying Chiang val |= 0x20; /* set the pin (bit field 11:8) work as GPIO mode */ 991*8fafe702SChih-Ying Chiang err = btmtksdio_mtk_reg_write(hdev, MT7921_PINMUX_1, val, ~0); 992*8fafe702SChih-Ying Chiang if (err < 0) 993*8fafe702SChih-Ying Chiang return err; 994*8fafe702SChih-Ying Chiang 995*8fafe702SChih-Ying Chiang err = btmtksdio_mtk_reg_read(hdev, MT7921_BTSYS_RST, &val); 996*8fafe702SChih-Ying Chiang if (err < 0) 997*8fafe702SChih-Ying Chiang return err; 998*8fafe702SChih-Ying Chiang 999*8fafe702SChih-Ying Chiang val |= MT7921_BTSYS_RST_WITH_GPIO; 1000*8fafe702SChih-Ying Chiang return btmtksdio_mtk_reg_write(hdev, MT7921_BTSYS_RST, val, ~0); 1001*8fafe702SChih-Ying Chiang } 1002*8fafe702SChih-Ying Chiang 1003c603bf1fSSean Wang static int btmtksdio_setup(struct hci_dev *hdev) 1004c603bf1fSSean Wang { 1005c603bf1fSSean Wang struct btmtksdio_dev *bdev = hci_get_drvdata(hdev); 1006c603bf1fSSean Wang ktime_t calltime, delta, rettime; 1007c603bf1fSSean Wang unsigned long long duration; 1008c603bf1fSSean Wang char fwname[64]; 1009c603bf1fSSean Wang int err, dev_id; 1010*8fafe702SChih-Ying Chiang u32 fw_version = 0, val; 1011c603bf1fSSean Wang 1012c603bf1fSSean Wang calltime = ktime_get(); 1013d555b1f2SSean Wang set_bit(BTMTKSDIO_HW_TX_READY, &bdev->tx_state); 1014c603bf1fSSean Wang 1015c603bf1fSSean Wang switch (bdev->data->chipid) { 1016c603bf1fSSean Wang case 0x7921: 1017*8fafe702SChih-Ying Chiang if (test_bit(BTMTKSDIO_HW_RESET_ACTIVE, &bdev->tx_state)) { 1018*8fafe702SChih-Ying Chiang err = btmtksdio_mtk_reg_read(hdev, MT7921_DLSTATUS, 1019*8fafe702SChih-Ying Chiang &val); 1020*8fafe702SChih-Ying Chiang if (err < 0) 1021*8fafe702SChih-Ying Chiang return err; 1022*8fafe702SChih-Ying Chiang 1023*8fafe702SChih-Ying Chiang val &= ~BT_DL_STATE; 1024*8fafe702SChih-Ying Chiang err = btmtksdio_mtk_reg_write(hdev, MT7921_DLSTATUS, 1025*8fafe702SChih-Ying Chiang val, ~0); 1026*8fafe702SChih-Ying Chiang if (err < 0) 1027*8fafe702SChih-Ying Chiang return err; 1028*8fafe702SChih-Ying Chiang 1029*8fafe702SChih-Ying Chiang btmtksdio_fw_pmctrl(bdev); 1030*8fafe702SChih-Ying Chiang msleep(20); 1031*8fafe702SChih-Ying Chiang btmtksdio_drv_pmctrl(bdev); 1032*8fafe702SChih-Ying Chiang 1033*8fafe702SChih-Ying Chiang clear_bit(BTMTKSDIO_HW_RESET_ACTIVE, &bdev->tx_state); 1034*8fafe702SChih-Ying Chiang } 1035*8fafe702SChih-Ying Chiang 10364b685879SSean Wang err = btmtksdio_mtk_reg_read(hdev, 0x70010200, &dev_id); 1037c603bf1fSSean Wang if (err < 0) { 1038c603bf1fSSean Wang bt_dev_err(hdev, "Failed to get device id (%d)", err); 1039c603bf1fSSean Wang return err; 1040c603bf1fSSean Wang } 1041c603bf1fSSean Wang 10424b685879SSean Wang err = btmtksdio_mtk_reg_read(hdev, 0x80021004, &fw_version); 1043c603bf1fSSean Wang if (err < 0) { 1044c603bf1fSSean Wang bt_dev_err(hdev, "Failed to get fw version (%d)", err); 1045c603bf1fSSean Wang return err; 1046c603bf1fSSean Wang } 1047c603bf1fSSean Wang 1048c603bf1fSSean Wang snprintf(fwname, sizeof(fwname), 1049c603bf1fSSean Wang "mediatek/BT_RAM_CODE_MT%04x_1_%x_hdr.bin", 1050c603bf1fSSean Wang dev_id & 0xffff, (fw_version & 0xff) + 1); 1051c603bf1fSSean Wang err = mt79xx_setup(hdev, fwname); 1052c603bf1fSSean Wang if (err < 0) 1053c603bf1fSSean Wang return err; 1054191c8723SMark Chen 1055752aea58SMark Chen err = btmtksdio_fw_pmctrl(bdev); 1056752aea58SMark Chen if (err < 0) 1057752aea58SMark Chen return err; 1058752aea58SMark Chen 1059752aea58SMark Chen err = btmtksdio_drv_pmctrl(bdev); 1060752aea58SMark Chen if (err < 0) 1061752aea58SMark Chen return err; 1062752aea58SMark Chen 1063191c8723SMark Chen /* Enable SCO over I2S/PCM */ 1064191c8723SMark Chen err = btmtksdio_sco_setting(hdev); 1065191c8723SMark Chen if (err < 0) { 1066191c8723SMark Chen bt_dev_err(hdev, "Failed to enable SCO setting (%d)", err); 1067191c8723SMark Chen return err; 1068191c8723SMark Chen } 1069191c8723SMark Chen 1070*8fafe702SChih-Ying Chiang /* Enable GPIO reset mechanism */ 1071*8fafe702SChih-Ying Chiang if (bdev->reset) { 1072*8fafe702SChih-Ying Chiang err = btmtksdio_reset_setting(hdev); 1073*8fafe702SChih-Ying Chiang if (err < 0) { 1074*8fafe702SChih-Ying Chiang bt_dev_err(hdev, "Failed to enable Reset setting (%d)", err); 1075*8fafe702SChih-Ying Chiang devm_gpiod_put(bdev->dev, bdev->reset); 1076*8fafe702SChih-Ying Chiang bdev->reset = NULL; 1077*8fafe702SChih-Ying Chiang } 1078*8fafe702SChih-Ying Chiang } 1079*8fafe702SChih-Ying Chiang 1080c603bf1fSSean Wang break; 1081c603bf1fSSean Wang case 0x7663: 1082c603bf1fSSean Wang case 0x7668: 1083c603bf1fSSean Wang err = mt76xx_setup(hdev, bdev->data->fwname); 1084c603bf1fSSean Wang if (err < 0) 1085c603bf1fSSean Wang return err; 1086c603bf1fSSean Wang break; 1087c603bf1fSSean Wang default: 1088c603bf1fSSean Wang return -ENODEV; 1089c603bf1fSSean Wang } 1090c603bf1fSSean Wang 10919aebfd4aSSean Wang rettime = ktime_get(); 10929aebfd4aSSean Wang delta = ktime_sub(rettime, calltime); 10939aebfd4aSSean Wang duration = (unsigned long long)ktime_to_ns(delta) >> 10; 10949aebfd4aSSean Wang 10957f3c563cSSean Wang pm_runtime_set_autosuspend_delay(bdev->dev, 10967f3c563cSSean Wang MTKBTSDIO_AUTOSUSPEND_DELAY); 10977f3c563cSSean Wang pm_runtime_use_autosuspend(bdev->dev); 10987f3c563cSSean Wang 10997f3c563cSSean Wang err = pm_runtime_set_active(bdev->dev); 11007f3c563cSSean Wang if (err < 0) 11017f3c563cSSean Wang return err; 11027f3c563cSSean Wang 11037f3c563cSSean Wang /* Default forbid runtime auto suspend, that can be allowed by 11047f3c563cSSean Wang * enable_autosuspend flag or the PM runtime entry under sysfs. 11057f3c563cSSean Wang */ 11067f3c563cSSean Wang pm_runtime_forbid(bdev->dev); 11077f3c563cSSean Wang pm_runtime_enable(bdev->dev); 11087f3c563cSSean Wang 11097f3c563cSSean Wang if (enable_autosuspend) 11107f3c563cSSean Wang pm_runtime_allow(bdev->dev); 11117f3c563cSSean Wang 11129aebfd4aSSean Wang bt_dev_info(hdev, "Device setup in %llu usecs", duration); 11139aebfd4aSSean Wang 11149aebfd4aSSean Wang return 0; 11159aebfd4aSSean Wang } 11169aebfd4aSSean Wang 11179aebfd4aSSean Wang static int btmtksdio_shutdown(struct hci_dev *hdev) 11189aebfd4aSSean Wang { 11197f3c563cSSean Wang struct btmtksdio_dev *bdev = hci_get_drvdata(hdev); 11209aebfd4aSSean Wang struct btmtk_hci_wmt_params wmt_params; 11219aebfd4aSSean Wang u8 param = 0x0; 11229aebfd4aSSean Wang int err; 11239aebfd4aSSean Wang 11247f3c563cSSean Wang /* Get back the state to be consistent with the state 11257f3c563cSSean Wang * in btmtksdio_setup. 11267f3c563cSSean Wang */ 11277f3c563cSSean Wang pm_runtime_get_sync(bdev->dev); 11287f3c563cSSean Wang 11299aebfd4aSSean Wang /* Disable the device */ 11303a722044SSean Wang wmt_params.op = BTMTK_WMT_FUNC_CTRL; 11319aebfd4aSSean Wang wmt_params.flag = 0; 11329aebfd4aSSean Wang wmt_params.dlen = sizeof(param); 11339aebfd4aSSean Wang wmt_params.data = ¶m; 11349aebfd4aSSean Wang wmt_params.status = NULL; 11359aebfd4aSSean Wang 11369aebfd4aSSean Wang err = mtk_hci_wmt_sync(hdev, &wmt_params); 11379aebfd4aSSean Wang if (err < 0) { 11389aebfd4aSSean Wang bt_dev_err(hdev, "Failed to send wmt func ctrl (%d)", err); 11399aebfd4aSSean Wang return err; 11409aebfd4aSSean Wang } 11419aebfd4aSSean Wang 11427f3c563cSSean Wang pm_runtime_put_noidle(bdev->dev); 11437f3c563cSSean Wang pm_runtime_disable(bdev->dev); 11447f3c563cSSean Wang 11459aebfd4aSSean Wang return 0; 11469aebfd4aSSean Wang } 11479aebfd4aSSean Wang 11489aebfd4aSSean Wang static int btmtksdio_send_frame(struct hci_dev *hdev, struct sk_buff *skb) 11499aebfd4aSSean Wang { 11509aebfd4aSSean Wang struct btmtksdio_dev *bdev = hci_get_drvdata(hdev); 11519aebfd4aSSean Wang 11529aebfd4aSSean Wang switch (hci_skb_pkt_type(skb)) { 11539aebfd4aSSean Wang case HCI_COMMAND_PKT: 11549aebfd4aSSean Wang hdev->stat.cmd_tx++; 11559aebfd4aSSean Wang break; 11569aebfd4aSSean Wang 11579aebfd4aSSean Wang case HCI_ACLDATA_PKT: 11589aebfd4aSSean Wang hdev->stat.acl_tx++; 11599aebfd4aSSean Wang break; 11609aebfd4aSSean Wang 11619aebfd4aSSean Wang case HCI_SCODATA_PKT: 11629aebfd4aSSean Wang hdev->stat.sco_tx++; 11639aebfd4aSSean Wang break; 11649aebfd4aSSean Wang 11659aebfd4aSSean Wang default: 11669aebfd4aSSean Wang return -EILSEQ; 11679aebfd4aSSean Wang } 11689aebfd4aSSean Wang 11699aebfd4aSSean Wang skb_queue_tail(&bdev->txq, skb); 11709aebfd4aSSean Wang 117126270bc1SSean Wang schedule_work(&bdev->txrx_work); 11729aebfd4aSSean Wang 11739aebfd4aSSean Wang return 0; 11749aebfd4aSSean Wang } 11759aebfd4aSSean Wang 1176*8fafe702SChih-Ying Chiang static void btmtksdio_cmd_timeout(struct hci_dev *hdev) 1177*8fafe702SChih-Ying Chiang { 1178*8fafe702SChih-Ying Chiang struct btmtksdio_dev *bdev = hci_get_drvdata(hdev); 1179*8fafe702SChih-Ying Chiang u32 status; 1180*8fafe702SChih-Ying Chiang int err; 1181*8fafe702SChih-Ying Chiang 1182*8fafe702SChih-Ying Chiang if (!bdev->reset || bdev->data->chipid != 0x7921) 1183*8fafe702SChih-Ying Chiang return; 1184*8fafe702SChih-Ying Chiang 1185*8fafe702SChih-Ying Chiang pm_runtime_get_sync(bdev->dev); 1186*8fafe702SChih-Ying Chiang 1187*8fafe702SChih-Ying Chiang if (test_and_set_bit(BTMTKSDIO_HW_RESET_ACTIVE, &bdev->tx_state)) 1188*8fafe702SChih-Ying Chiang return; 1189*8fafe702SChih-Ying Chiang 1190*8fafe702SChih-Ying Chiang sdio_claim_host(bdev->func); 1191*8fafe702SChih-Ying Chiang 1192*8fafe702SChih-Ying Chiang sdio_writel(bdev->func, C_INT_EN_CLR, MTK_REG_CHLPCR, NULL); 1193*8fafe702SChih-Ying Chiang skb_queue_purge(&bdev->txq); 1194*8fafe702SChih-Ying Chiang cancel_work_sync(&bdev->txrx_work); 1195*8fafe702SChih-Ying Chiang 1196*8fafe702SChih-Ying Chiang gpiod_set_value_cansleep(bdev->reset, 1); 1197*8fafe702SChih-Ying Chiang msleep(100); 1198*8fafe702SChih-Ying Chiang gpiod_set_value_cansleep(bdev->reset, 0); 1199*8fafe702SChih-Ying Chiang 1200*8fafe702SChih-Ying Chiang err = readx_poll_timeout(btmtksdio_chcr_query, bdev, status, 1201*8fafe702SChih-Ying Chiang status & BT_RST_DONE, 100000, 2000000); 1202*8fafe702SChih-Ying Chiang if (err < 0) { 1203*8fafe702SChih-Ying Chiang bt_dev_err(hdev, "Failed to reset (%d)", err); 1204*8fafe702SChih-Ying Chiang goto err; 1205*8fafe702SChih-Ying Chiang } 1206*8fafe702SChih-Ying Chiang 1207*8fafe702SChih-Ying Chiang clear_bit(BTMTKSDIO_PATCH_ENABLED, &bdev->tx_state); 1208*8fafe702SChih-Ying Chiang err: 1209*8fafe702SChih-Ying Chiang sdio_release_host(bdev->func); 1210*8fafe702SChih-Ying Chiang 1211*8fafe702SChih-Ying Chiang pm_runtime_put_noidle(bdev->dev); 1212*8fafe702SChih-Ying Chiang pm_runtime_disable(bdev->dev); 1213*8fafe702SChih-Ying Chiang 1214*8fafe702SChih-Ying Chiang hci_reset_dev(hdev); 1215*8fafe702SChih-Ying Chiang } 1216*8fafe702SChih-Ying Chiang 1217ce64b3e9SMark Chen static bool btmtksdio_sdio_wakeup(struct hci_dev *hdev) 1218ce64b3e9SMark Chen { 1219ce64b3e9SMark Chen struct btmtksdio_dev *bdev = hci_get_drvdata(hdev); 1220ce64b3e9SMark Chen bool may_wakeup = device_may_wakeup(bdev->dev); 1221ce64b3e9SMark Chen const struct btmtk_wakeon bt_awake = { 1222ce64b3e9SMark Chen .mode = 0x1, 1223ce64b3e9SMark Chen .gpo = 0, 1224ce64b3e9SMark Chen .active_high = 0x1, 1225ce64b3e9SMark Chen .enable_delay = cpu_to_le16(0xc80), 1226ce64b3e9SMark Chen .wakeup_delay = cpu_to_le16(0x20), 1227ce64b3e9SMark Chen }; 1228ce64b3e9SMark Chen 1229ce64b3e9SMark Chen if (may_wakeup && bdev->data->chipid == 0x7921) { 1230ce64b3e9SMark Chen struct sk_buff *skb; 1231ce64b3e9SMark Chen 1232ce64b3e9SMark Chen skb = __hci_cmd_sync(hdev, 0xfc27, sizeof(bt_awake), 1233ce64b3e9SMark Chen &bt_awake, HCI_CMD_TIMEOUT); 1234ce64b3e9SMark Chen if (IS_ERR(skb)) 1235ce64b3e9SMark Chen may_wakeup = false; 1236ce64b3e9SMark Chen 1237ce64b3e9SMark Chen kfree_skb(skb); 1238ce64b3e9SMark Chen } 1239ce64b3e9SMark Chen 1240ce64b3e9SMark Chen return may_wakeup; 1241ce64b3e9SMark Chen } 1242ce64b3e9SMark Chen 12439aebfd4aSSean Wang static int btmtksdio_probe(struct sdio_func *func, 12449aebfd4aSSean Wang const struct sdio_device_id *id) 12459aebfd4aSSean Wang { 12469aebfd4aSSean Wang struct btmtksdio_dev *bdev; 12479aebfd4aSSean Wang struct hci_dev *hdev; 12489aebfd4aSSean Wang int err; 12499aebfd4aSSean Wang 12509aebfd4aSSean Wang bdev = devm_kzalloc(&func->dev, sizeof(*bdev), GFP_KERNEL); 12519aebfd4aSSean Wang if (!bdev) 12529aebfd4aSSean Wang return -ENOMEM; 12539aebfd4aSSean Wang 12549aebfd4aSSean Wang bdev->data = (void *)id->driver_data; 12559aebfd4aSSean Wang if (!bdev->data) 12569aebfd4aSSean Wang return -ENODEV; 12579aebfd4aSSean Wang 12587f3c563cSSean Wang bdev->dev = &func->dev; 12599aebfd4aSSean Wang bdev->func = func; 12609aebfd4aSSean Wang 126126270bc1SSean Wang INIT_WORK(&bdev->txrx_work, btmtksdio_txrx_work); 12629aebfd4aSSean Wang skb_queue_head_init(&bdev->txq); 12639aebfd4aSSean Wang 12649aebfd4aSSean Wang /* Initialize and register HCI device */ 12659aebfd4aSSean Wang hdev = hci_alloc_dev(); 12669aebfd4aSSean Wang if (!hdev) { 12679aebfd4aSSean Wang dev_err(&func->dev, "Can't allocate HCI device\n"); 12689aebfd4aSSean Wang return -ENOMEM; 12699aebfd4aSSean Wang } 12709aebfd4aSSean Wang 12719aebfd4aSSean Wang bdev->hdev = hdev; 12729aebfd4aSSean Wang 12739aebfd4aSSean Wang hdev->bus = HCI_SDIO; 12749aebfd4aSSean Wang hci_set_drvdata(hdev, bdev); 12759aebfd4aSSean Wang 12769aebfd4aSSean Wang hdev->open = btmtksdio_open; 12779aebfd4aSSean Wang hdev->close = btmtksdio_close; 1278*8fafe702SChih-Ying Chiang hdev->cmd_timeout = btmtksdio_cmd_timeout; 12799aebfd4aSSean Wang hdev->flush = btmtksdio_flush; 12809aebfd4aSSean Wang hdev->setup = btmtksdio_setup; 12819aebfd4aSSean Wang hdev->shutdown = btmtksdio_shutdown; 12829aebfd4aSSean Wang hdev->send = btmtksdio_send_frame; 1283ce64b3e9SMark Chen hdev->wakeup = btmtksdio_sdio_wakeup; 1284877ec9e1SSean Wang hdev->set_bdaddr = btmtk_set_bdaddr; 1285877ec9e1SSean Wang 12869aebfd4aSSean Wang SET_HCIDEV_DEV(hdev, &func->dev); 12879aebfd4aSSean Wang 12889aebfd4aSSean Wang hdev->manufacturer = 70; 12899aebfd4aSSean Wang set_bit(HCI_QUIRK_NON_PERSISTENT_SETUP, &hdev->quirks); 12909aebfd4aSSean Wang 12919aebfd4aSSean Wang err = hci_register_dev(hdev); 12929aebfd4aSSean Wang if (err < 0) { 12939aebfd4aSSean Wang dev_err(&func->dev, "Can't register HCI device\n"); 12949aebfd4aSSean Wang hci_free_dev(hdev); 12959aebfd4aSSean Wang return err; 12969aebfd4aSSean Wang } 12979aebfd4aSSean Wang 12989aebfd4aSSean Wang sdio_set_drvdata(func, bdev); 12999aebfd4aSSean Wang 13007f3c563cSSean Wang /* pm_runtime_enable would be done after the firmware is being 13017f3c563cSSean Wang * downloaded because the core layer probably already enables 13027f3c563cSSean Wang * runtime PM for this func such as the case host->caps & 13037f3c563cSSean Wang * MMC_CAP_POWER_OFF_CARD. 13047f3c563cSSean Wang */ 13057f3c563cSSean Wang if (pm_runtime_enabled(bdev->dev)) 13067f3c563cSSean Wang pm_runtime_disable(bdev->dev); 13077f3c563cSSean Wang 13087f3c563cSSean Wang /* As explaination in drivers/mmc/core/sdio_bus.c tells us: 13097f3c563cSSean Wang * Unbound SDIO functions are always suspended. 13107f3c563cSSean Wang * During probe, the function is set active and the usage count 13117f3c563cSSean Wang * is incremented. If the driver supports runtime PM, 13127f3c563cSSean Wang * it should call pm_runtime_put_noidle() in its probe routine and 13137f3c563cSSean Wang * pm_runtime_get_noresume() in its remove routine. 13147f3c563cSSean Wang * 13157f3c563cSSean Wang * So, put a pm_runtime_put_noidle here ! 13167f3c563cSSean Wang */ 13177f3c563cSSean Wang pm_runtime_put_noidle(bdev->dev); 13187f3c563cSSean Wang 1319ce64b3e9SMark Chen err = device_init_wakeup(bdev->dev, true); 1320ce64b3e9SMark Chen if (err) 1321ce64b3e9SMark Chen bt_dev_err(hdev, "failed to initialize device wakeup"); 1322ce64b3e9SMark Chen 1323*8fafe702SChih-Ying Chiang bdev->dev->of_node = of_find_compatible_node(NULL, NULL, 1324*8fafe702SChih-Ying Chiang "mediatek,mt7921s-bluetooth"); 1325*8fafe702SChih-Ying Chiang bdev->reset = devm_gpiod_get_optional(bdev->dev, "reset", 1326*8fafe702SChih-Ying Chiang GPIOD_OUT_LOW); 1327*8fafe702SChih-Ying Chiang if (IS_ERR(bdev->reset)) 1328*8fafe702SChih-Ying Chiang err = PTR_ERR(bdev->reset); 1329*8fafe702SChih-Ying Chiang 1330ce64b3e9SMark Chen return err; 13319aebfd4aSSean Wang } 13329aebfd4aSSean Wang 13339aebfd4aSSean Wang static void btmtksdio_remove(struct sdio_func *func) 13349aebfd4aSSean Wang { 13359aebfd4aSSean Wang struct btmtksdio_dev *bdev = sdio_get_drvdata(func); 13369aebfd4aSSean Wang struct hci_dev *hdev; 13379aebfd4aSSean Wang 13389aebfd4aSSean Wang if (!bdev) 13399aebfd4aSSean Wang return; 13409aebfd4aSSean Wang 13417f3c563cSSean Wang /* Be consistent the state in btmtksdio_probe */ 13427f3c563cSSean Wang pm_runtime_get_noresume(bdev->dev); 13437f3c563cSSean Wang 13449aebfd4aSSean Wang hdev = bdev->hdev; 13459aebfd4aSSean Wang 13469aebfd4aSSean Wang sdio_set_drvdata(func, NULL); 13479aebfd4aSSean Wang hci_unregister_dev(hdev); 13489aebfd4aSSean Wang hci_free_dev(hdev); 13499aebfd4aSSean Wang } 13509aebfd4aSSean Wang 13517f3c563cSSean Wang #ifdef CONFIG_PM 13527f3c563cSSean Wang static int btmtksdio_runtime_suspend(struct device *dev) 13537f3c563cSSean Wang { 13547f3c563cSSean Wang struct sdio_func *func = dev_to_sdio_func(dev); 13557f3c563cSSean Wang struct btmtksdio_dev *bdev; 13567f3c563cSSean Wang int err; 13577f3c563cSSean Wang 13587f3c563cSSean Wang bdev = sdio_get_drvdata(func); 13597f3c563cSSean Wang if (!bdev) 13607f3c563cSSean Wang return 0; 13617f3c563cSSean Wang 13624b4b2228SSean Wang if (!test_bit(BTMTKSDIO_FUNC_ENABLED, &bdev->tx_state)) 13634b4b2228SSean Wang return 0; 13644b4b2228SSean Wang 1365561ae1d4SSean Wang sdio_set_host_pm_flags(func, MMC_PM_KEEP_POWER); 1366561ae1d4SSean Wang 1367c7e301d7SMark Chen err = btmtksdio_fw_pmctrl(bdev); 13687f3c563cSSean Wang 1369095519deSSean Wang bt_dev_dbg(bdev->hdev, "status (%d) return ownership to device", err); 13707f3c563cSSean Wang 13717f3c563cSSean Wang return err; 13727f3c563cSSean Wang } 13737f3c563cSSean Wang 13747f3c563cSSean Wang static int btmtksdio_runtime_resume(struct device *dev) 13757f3c563cSSean Wang { 13767f3c563cSSean Wang struct sdio_func *func = dev_to_sdio_func(dev); 13777f3c563cSSean Wang struct btmtksdio_dev *bdev; 13787f3c563cSSean Wang int err; 13797f3c563cSSean Wang 13807f3c563cSSean Wang bdev = sdio_get_drvdata(func); 13817f3c563cSSean Wang if (!bdev) 13827f3c563cSSean Wang return 0; 13837f3c563cSSean Wang 13844b4b2228SSean Wang if (!test_bit(BTMTKSDIO_FUNC_ENABLED, &bdev->tx_state)) 13854b4b2228SSean Wang return 0; 13864b4b2228SSean Wang 1387c7e301d7SMark Chen err = btmtksdio_drv_pmctrl(bdev); 13887f3c563cSSean Wang 1389095519deSSean Wang bt_dev_dbg(bdev->hdev, "status (%d) get ownership from device", err); 13907f3c563cSSean Wang 13917f3c563cSSean Wang return err; 13927f3c563cSSean Wang } 13937f3c563cSSean Wang 13947f3c563cSSean Wang static UNIVERSAL_DEV_PM_OPS(btmtksdio_pm_ops, btmtksdio_runtime_suspend, 13957f3c563cSSean Wang btmtksdio_runtime_resume, NULL); 13967f3c563cSSean Wang #define BTMTKSDIO_PM_OPS (&btmtksdio_pm_ops) 13977f3c563cSSean Wang #else /* CONFIG_PM */ 13987f3c563cSSean Wang #define BTMTKSDIO_PM_OPS NULL 13997f3c563cSSean Wang #endif /* CONFIG_PM */ 14007f3c563cSSean Wang 14019aebfd4aSSean Wang static struct sdio_driver btmtksdio_driver = { 14029aebfd4aSSean Wang .name = "btmtksdio", 14039aebfd4aSSean Wang .probe = btmtksdio_probe, 14049aebfd4aSSean Wang .remove = btmtksdio_remove, 14059aebfd4aSSean Wang .id_table = btmtksdio_table, 14067f3c563cSSean Wang .drv = { 14077f3c563cSSean Wang .owner = THIS_MODULE, 14087f3c563cSSean Wang .pm = BTMTKSDIO_PM_OPS, 14097f3c563cSSean Wang } 14109aebfd4aSSean Wang }; 14119aebfd4aSSean Wang 1412a6094a46SSean Wang module_sdio_driver(btmtksdio_driver); 14139aebfd4aSSean Wang 14147f3c563cSSean Wang module_param(enable_autosuspend, bool, 0644); 14157f3c563cSSean Wang MODULE_PARM_DESC(enable_autosuspend, "Enable autosuspend by default"); 14167f3c563cSSean Wang 14179aebfd4aSSean Wang MODULE_AUTHOR("Sean Wang <sean.wang@mediatek.com>"); 14189aebfd4aSSean Wang MODULE_DESCRIPTION("MediaTek Bluetooth SDIO driver ver " VERSION); 14199aebfd4aSSean Wang MODULE_VERSION(VERSION); 14209aebfd4aSSean Wang MODULE_LICENSE("GPL"); 1421