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> 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> 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) 888fafe702SChih-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 1208fafe702SChih-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; 1408fafe702SChih-Ying Chiang 1418fafe702SChih-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 3068fafe702SChih-Ying Chiang static u32 btmtksdio_chcr_query(struct btmtksdio_dev *bdev) 3078fafe702SChih-Ying Chiang { 3088fafe702SChih-Ying Chiang return sdio_readl(bdev->func, MTK_REG_CHCR, NULL); 3098fafe702SChih-Ying Chiang } 3108fafe702SChih-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 /* When someone waits for the WMT event, the skb is being cloned 3859aebfd4aSSean Wang * and being processed the events from there then. 3869aebfd4aSSean Wang */ 3879aebfd4aSSean Wang if (test_bit(BTMTKSDIO_TX_WAIT_VND_EVT, &bdev->tx_state)) { 3889aebfd4aSSean Wang bdev->evt_skb = skb_clone(skb, GFP_KERNEL); 3899aebfd4aSSean Wang if (!bdev->evt_skb) { 3909aebfd4aSSean Wang err = -ENOMEM; 3919aebfd4aSSean Wang goto err_out; 3929aebfd4aSSean Wang } 3939aebfd4aSSean Wang } 3949aebfd4aSSean Wang 3959aebfd4aSSean Wang err = hci_recv_frame(hdev, skb); 3969aebfd4aSSean Wang if (err < 0) 3979aebfd4aSSean Wang goto err_free_skb; 3989aebfd4aSSean Wang 399e4412654SSean Wang if (hdr->evt == HCI_EV_WMT) { 4009aebfd4aSSean Wang if (test_and_clear_bit(BTMTKSDIO_TX_WAIT_VND_EVT, 4019aebfd4aSSean Wang &bdev->tx_state)) { 4029aebfd4aSSean Wang /* Barrier to sync with other CPUs */ 4039aebfd4aSSean Wang smp_mb__after_atomic(); 4049aebfd4aSSean Wang wake_up_bit(&bdev->tx_state, BTMTKSDIO_TX_WAIT_VND_EVT); 4059aebfd4aSSean Wang } 4069aebfd4aSSean Wang } 4079aebfd4aSSean Wang 4089aebfd4aSSean Wang return 0; 4099aebfd4aSSean Wang 4109aebfd4aSSean Wang err_free_skb: 4119aebfd4aSSean Wang kfree_skb(bdev->evt_skb); 4129aebfd4aSSean Wang bdev->evt_skb = NULL; 4139aebfd4aSSean Wang 4149aebfd4aSSean Wang err_out: 4159aebfd4aSSean Wang return err; 4169aebfd4aSSean Wang } 4179aebfd4aSSean Wang 418db57b625SSean Wang static int btmtksdio_recv_acl(struct hci_dev *hdev, struct sk_buff *skb) 419db57b625SSean Wang { 420db57b625SSean Wang struct btmtksdio_dev *bdev = hci_get_drvdata(hdev); 421db57b625SSean Wang u16 handle = le16_to_cpu(hci_acl_hdr(skb)->handle); 422db57b625SSean Wang 423db57b625SSean Wang switch (handle) { 424db57b625SSean Wang case 0xfc6f: 425db57b625SSean Wang /* Firmware dump from device: when the firmware hangs, the 426db57b625SSean Wang * device can no longer suspend and thus disable auto-suspend. 427db57b625SSean Wang */ 428db57b625SSean Wang pm_runtime_forbid(bdev->dev); 429db57b625SSean Wang fallthrough; 430db57b625SSean Wang case 0x05ff: 431db57b625SSean Wang case 0x05fe: 432db57b625SSean Wang /* Firmware debug logging */ 433db57b625SSean Wang return hci_recv_diag(hdev, skb); 434db57b625SSean Wang } 435db57b625SSean Wang 436db57b625SSean Wang return hci_recv_frame(hdev, skb); 437db57b625SSean Wang } 438db57b625SSean Wang 4399aebfd4aSSean Wang static const struct h4_recv_pkt mtk_recv_pkts[] = { 440db57b625SSean Wang { H4_RECV_ACL, .recv = btmtksdio_recv_acl }, 4419aebfd4aSSean Wang { H4_RECV_SCO, .recv = hci_recv_frame }, 4429aebfd4aSSean Wang { H4_RECV_EVENT, .recv = btmtksdio_recv_event }, 4439aebfd4aSSean Wang }; 4449aebfd4aSSean Wang 4459aebfd4aSSean Wang static int btmtksdio_rx_packet(struct btmtksdio_dev *bdev, u16 rx_size) 4469aebfd4aSSean Wang { 4479aebfd4aSSean Wang const struct h4_recv_pkt *pkts = mtk_recv_pkts; 4489aebfd4aSSean Wang int pkts_count = ARRAY_SIZE(mtk_recv_pkts); 4499aebfd4aSSean Wang struct mtkbtsdio_hdr *sdio_hdr; 4509aebfd4aSSean Wang int err, i, pad_size; 4519aebfd4aSSean Wang struct sk_buff *skb; 4529aebfd4aSSean Wang u16 dlen; 4539aebfd4aSSean Wang 4549aebfd4aSSean Wang if (rx_size < sizeof(*sdio_hdr)) 4559aebfd4aSSean Wang return -EILSEQ; 4569aebfd4aSSean Wang 4579aebfd4aSSean Wang /* A SDIO packet is exactly containing a Bluetooth packet */ 4589aebfd4aSSean Wang skb = bt_skb_alloc(rx_size, GFP_KERNEL); 4599aebfd4aSSean Wang if (!skb) 4609aebfd4aSSean Wang return -ENOMEM; 4619aebfd4aSSean Wang 4629aebfd4aSSean Wang skb_put(skb, rx_size); 4639aebfd4aSSean Wang 4649aebfd4aSSean Wang err = sdio_readsb(bdev->func, skb->data, MTK_REG_CRDR, rx_size); 4659aebfd4aSSean Wang if (err < 0) 4669aebfd4aSSean Wang goto err_kfree_skb; 4679aebfd4aSSean Wang 4689aebfd4aSSean Wang sdio_hdr = (void *)skb->data; 4699aebfd4aSSean Wang 4709aebfd4aSSean Wang /* We assume the default error as -EILSEQ simply to make the error path 4719aebfd4aSSean Wang * be cleaner. 4729aebfd4aSSean Wang */ 4739aebfd4aSSean Wang err = -EILSEQ; 4749aebfd4aSSean Wang 4759aebfd4aSSean Wang if (rx_size != le16_to_cpu(sdio_hdr->len)) { 4769aebfd4aSSean Wang bt_dev_err(bdev->hdev, "Rx size in sdio header is mismatched "); 4779aebfd4aSSean Wang goto err_kfree_skb; 4789aebfd4aSSean Wang } 4799aebfd4aSSean Wang 4809aebfd4aSSean Wang hci_skb_pkt_type(skb) = sdio_hdr->bt_type; 4819aebfd4aSSean Wang 4829aebfd4aSSean Wang /* Remove MediaTek SDIO header */ 4839aebfd4aSSean Wang skb_pull(skb, sizeof(*sdio_hdr)); 4849aebfd4aSSean Wang 4859aebfd4aSSean Wang /* We have to dig into the packet to get payload size and then know how 4869aebfd4aSSean Wang * many padding bytes at the tail, these padding bytes should be removed 4879aebfd4aSSean Wang * before the packet is indicated to the core layer. 4889aebfd4aSSean Wang */ 4899aebfd4aSSean Wang for (i = 0; i < pkts_count; i++) { 4909aebfd4aSSean Wang if (sdio_hdr->bt_type == (&pkts[i])->type) 4919aebfd4aSSean Wang break; 4929aebfd4aSSean Wang } 4939aebfd4aSSean Wang 4949aebfd4aSSean Wang if (i >= pkts_count) { 4959aebfd4aSSean Wang bt_dev_err(bdev->hdev, "Invalid bt type 0x%02x", 4969aebfd4aSSean Wang sdio_hdr->bt_type); 4979aebfd4aSSean Wang goto err_kfree_skb; 4989aebfd4aSSean Wang } 4999aebfd4aSSean Wang 5009aebfd4aSSean Wang /* Remaining bytes cannot hold a header*/ 5019aebfd4aSSean Wang if (skb->len < (&pkts[i])->hlen) { 5029aebfd4aSSean Wang bt_dev_err(bdev->hdev, "The size of bt header is mismatched"); 5039aebfd4aSSean Wang goto err_kfree_skb; 5049aebfd4aSSean Wang } 5059aebfd4aSSean Wang 5069aebfd4aSSean Wang switch ((&pkts[i])->lsize) { 5079aebfd4aSSean Wang case 1: 5089aebfd4aSSean Wang dlen = skb->data[(&pkts[i])->loff]; 5099aebfd4aSSean Wang break; 5109aebfd4aSSean Wang case 2: 5119aebfd4aSSean Wang dlen = get_unaligned_le16(skb->data + 5129aebfd4aSSean Wang (&pkts[i])->loff); 5139aebfd4aSSean Wang break; 5149aebfd4aSSean Wang default: 5159aebfd4aSSean Wang goto err_kfree_skb; 5169aebfd4aSSean Wang } 5179aebfd4aSSean Wang 5189aebfd4aSSean Wang pad_size = skb->len - (&pkts[i])->hlen - dlen; 5199aebfd4aSSean Wang 5209aebfd4aSSean Wang /* Remaining bytes cannot hold a payload */ 5219aebfd4aSSean Wang if (pad_size < 0) { 5229aebfd4aSSean Wang bt_dev_err(bdev->hdev, "The size of bt payload is mismatched"); 5239aebfd4aSSean Wang goto err_kfree_skb; 5249aebfd4aSSean Wang } 5259aebfd4aSSean Wang 5269aebfd4aSSean Wang /* Remove padding bytes */ 5279aebfd4aSSean Wang skb_trim(skb, skb->len - pad_size); 5289aebfd4aSSean Wang 5299aebfd4aSSean Wang /* Complete frame */ 5309aebfd4aSSean Wang (&pkts[i])->recv(bdev->hdev, skb); 5319aebfd4aSSean Wang 532bcaa7d72SSean Wang bdev->hdev->stat.byte_rx += rx_size; 533bcaa7d72SSean Wang 5349aebfd4aSSean Wang return 0; 5359aebfd4aSSean Wang 5369aebfd4aSSean Wang err_kfree_skb: 5379aebfd4aSSean Wang kfree_skb(skb); 5389aebfd4aSSean Wang 5399aebfd4aSSean Wang return err; 5409aebfd4aSSean Wang } 5419aebfd4aSSean Wang 54226270bc1SSean Wang static void btmtksdio_txrx_work(struct work_struct *work) 5439aebfd4aSSean Wang { 54426270bc1SSean Wang struct btmtksdio_dev *bdev = container_of(work, struct btmtksdio_dev, 54526270bc1SSean Wang txrx_work); 54626270bc1SSean Wang unsigned long txrx_timeout; 547184ea403SSean Wang u32 int_status, rx_size; 54826270bc1SSean Wang struct sk_buff *skb; 54926270bc1SSean Wang int err; 5507f3c563cSSean Wang 5517f3c563cSSean Wang pm_runtime_get_sync(bdev->dev); 5527f3c563cSSean Wang 5537f3c563cSSean Wang sdio_claim_host(bdev->func); 5547f3c563cSSean Wang 5559aebfd4aSSean Wang /* Disable interrupt */ 55626270bc1SSean Wang sdio_writel(bdev->func, C_INT_EN_CLR, MTK_REG_CHLPCR, 0); 5579aebfd4aSSean Wang 55826270bc1SSean Wang txrx_timeout = jiffies + 5 * HZ; 55926270bc1SSean Wang 56026270bc1SSean Wang do { 56126270bc1SSean Wang int_status = sdio_readl(bdev->func, MTK_REG_CHISR, NULL); 5629aebfd4aSSean Wang 5639aebfd4aSSean Wang /* Ack an interrupt as soon as possible before any operation on 5649aebfd4aSSean Wang * hardware. 5659aebfd4aSSean Wang * 5669aebfd4aSSean Wang * Note that we don't ack any status during operations to avoid race 5679aebfd4aSSean Wang * condition between the host and the device such as it's possible to 5689aebfd4aSSean Wang * mistakenly ack RX_DONE for the next packet and then cause interrupts 5699aebfd4aSSean Wang * not be raised again but there is still pending data in the hardware 5709aebfd4aSSean Wang * FIFO. 5719aebfd4aSSean Wang */ 57226270bc1SSean Wang sdio_writel(bdev->func, int_status, MTK_REG_CHISR, NULL); 573db3f1f9bSSean Wang int_status &= INT_MASK; 5749aebfd4aSSean Wang 5752fc967ccSMark Chen if ((int_status & FW_MAILBOX_INT) && 5762fc967ccSMark Chen bdev->data->chipid == 0x7921) { 5772fc967ccSMark Chen sdio_writel(bdev->func, PH2DSM0R_DRIVER_OWN, 5782fc967ccSMark Chen MTK_REG_PH2DSM0R, 0); 5792fc967ccSMark Chen } 5802fc967ccSMark Chen 5819aebfd4aSSean Wang if (int_status & FW_OWN_BACK_INT) 582e1052fb2SSean Wang bt_dev_dbg(bdev->hdev, "Get fw own back"); 5839aebfd4aSSean Wang 5849aebfd4aSSean Wang if (int_status & TX_EMPTY) 585d555b1f2SSean Wang set_bit(BTMTKSDIO_HW_TX_READY, &bdev->tx_state); 586d555b1f2SSean Wang 5879aebfd4aSSean Wang else if (unlikely(int_status & TX_FIFO_OVERFLOW)) 588e1052fb2SSean Wang bt_dev_warn(bdev->hdev, "Tx fifo overflow"); 5899aebfd4aSSean Wang 590d555b1f2SSean Wang if (test_bit(BTMTKSDIO_HW_TX_READY, &bdev->tx_state)) { 59110fe40e1SMark-yw Chen skb = skb_dequeue(&bdev->txq); 59210fe40e1SMark-yw Chen if (skb) { 59310fe40e1SMark-yw Chen err = btmtksdio_tx_packet(bdev, skb); 59410fe40e1SMark-yw Chen if (err < 0) { 59510fe40e1SMark-yw Chen bdev->hdev->stat.err_tx++; 59610fe40e1SMark-yw Chen skb_queue_head(&bdev->txq, skb); 59710fe40e1SMark-yw Chen } 59810fe40e1SMark-yw Chen } 59910fe40e1SMark-yw Chen } 60010fe40e1SMark-yw Chen 6019aebfd4aSSean Wang if (int_status & RX_DONE_INT) { 602184ea403SSean Wang rx_size = sdio_readl(bdev->func, MTK_REG_CRPLR, NULL); 603184ea403SSean Wang rx_size = (rx_size & RX_PKT_LEN) >> 16; 6049aebfd4aSSean Wang if (btmtksdio_rx_packet(bdev, rx_size) < 0) 6059aebfd4aSSean Wang bdev->hdev->stat.err_rx++; 6069aebfd4aSSean Wang } 60726270bc1SSean Wang } while (int_status || time_is_before_jiffies(txrx_timeout)); 60826270bc1SSean Wang 6099aebfd4aSSean Wang /* Enable interrupt */ 61026270bc1SSean Wang sdio_writel(bdev->func, C_INT_EN_SET, MTK_REG_CHLPCR, 0); 61126270bc1SSean Wang 61226270bc1SSean Wang sdio_release_host(bdev->func); 6137f3c563cSSean Wang 6147f3c563cSSean Wang pm_runtime_mark_last_busy(bdev->dev); 6157f3c563cSSean Wang pm_runtime_put_autosuspend(bdev->dev); 6169aebfd4aSSean Wang } 6179aebfd4aSSean Wang 61826270bc1SSean Wang static void btmtksdio_interrupt(struct sdio_func *func) 61926270bc1SSean Wang { 62026270bc1SSean Wang struct btmtksdio_dev *bdev = sdio_get_drvdata(func); 62126270bc1SSean Wang 62226270bc1SSean Wang /* Disable interrupt */ 62326270bc1SSean Wang sdio_writel(bdev->func, C_INT_EN_CLR, MTK_REG_CHLPCR, 0); 62426270bc1SSean Wang 62526270bc1SSean Wang schedule_work(&bdev->txrx_work); 62626270bc1SSean Wang } 62726270bc1SSean Wang 6289aebfd4aSSean Wang static int btmtksdio_open(struct hci_dev *hdev) 6299aebfd4aSSean Wang { 6309aebfd4aSSean Wang struct btmtksdio_dev *bdev = hci_get_drvdata(hdev); 631c7e301d7SMark Chen u32 val; 6329aebfd4aSSean Wang int err; 6339aebfd4aSSean Wang 6349aebfd4aSSean Wang sdio_claim_host(bdev->func); 6359aebfd4aSSean Wang 6369aebfd4aSSean Wang err = sdio_enable_func(bdev->func); 6379aebfd4aSSean Wang if (err < 0) 6389aebfd4aSSean Wang goto err_release_host; 6399aebfd4aSSean Wang 6404b4b2228SSean Wang set_bit(BTMTKSDIO_FUNC_ENABLED, &bdev->tx_state); 6414b4b2228SSean Wang 642c7e301d7SMark Chen err = btmtksdio_drv_pmctrl(bdev); 6439aebfd4aSSean Wang if (err < 0) 6449aebfd4aSSean Wang goto err_disable_func; 6459aebfd4aSSean Wang 6469aebfd4aSSean Wang /* Disable interrupt & mask out all interrupt sources */ 6479aebfd4aSSean Wang sdio_writel(bdev->func, C_INT_EN_CLR, MTK_REG_CHLPCR, &err); 6489aebfd4aSSean Wang if (err < 0) 6499aebfd4aSSean Wang goto err_disable_func; 6509aebfd4aSSean Wang 6519aebfd4aSSean Wang sdio_writel(bdev->func, 0, MTK_REG_CHIER, &err); 6529aebfd4aSSean Wang if (err < 0) 6539aebfd4aSSean Wang goto err_disable_func; 6549aebfd4aSSean Wang 6559aebfd4aSSean Wang err = sdio_claim_irq(bdev->func, btmtksdio_interrupt); 6569aebfd4aSSean Wang if (err < 0) 6579aebfd4aSSean Wang goto err_disable_func; 6589aebfd4aSSean Wang 6599aebfd4aSSean Wang err = sdio_set_block_size(bdev->func, MTK_SDIO_BLOCK_SIZE); 6609aebfd4aSSean Wang if (err < 0) 6619aebfd4aSSean Wang goto err_release_irq; 6629aebfd4aSSean Wang 6639aebfd4aSSean Wang /* SDIO CMD 5 allows the SDIO device back to idle state an 6649aebfd4aSSean Wang * synchronous interrupt is supported in SDIO 4-bit mode 6659aebfd4aSSean Wang */ 6665b23ac1aSSean Wang val = sdio_readl(bdev->func, MTK_REG_CSDIOCSR, &err); 6675b23ac1aSSean Wang if (err < 0) 6685b23ac1aSSean Wang goto err_release_irq; 6695b23ac1aSSean Wang 6705b23ac1aSSean Wang val |= SDIO_INT_CTL; 6715b23ac1aSSean Wang sdio_writel(bdev->func, val, MTK_REG_CSDIOCSR, &err); 6729aebfd4aSSean Wang if (err < 0) 6739aebfd4aSSean Wang goto err_release_irq; 6749aebfd4aSSean Wang 67577b210d1SSean Wang /* Explitly set write-1-clear method */ 67677b210d1SSean Wang val = sdio_readl(bdev->func, MTK_REG_CHCR, &err); 67777b210d1SSean Wang if (err < 0) 67877b210d1SSean Wang goto err_release_irq; 67977b210d1SSean Wang 68077b210d1SSean Wang val |= C_INT_CLR_CTRL; 68177b210d1SSean Wang sdio_writel(bdev->func, val, MTK_REG_CHCR, &err); 6829aebfd4aSSean Wang if (err < 0) 6839aebfd4aSSean Wang goto err_release_irq; 6849aebfd4aSSean Wang 6859aebfd4aSSean Wang /* Setup interrupt sources */ 6869aebfd4aSSean Wang sdio_writel(bdev->func, RX_DONE_INT | TX_EMPTY | TX_FIFO_OVERFLOW, 6879aebfd4aSSean Wang MTK_REG_CHIER, &err); 6889aebfd4aSSean Wang if (err < 0) 6899aebfd4aSSean Wang goto err_release_irq; 6909aebfd4aSSean Wang 6919aebfd4aSSean Wang /* Enable interrupt */ 6929aebfd4aSSean Wang sdio_writel(bdev->func, C_INT_EN_SET, MTK_REG_CHLPCR, &err); 6939aebfd4aSSean Wang if (err < 0) 6949aebfd4aSSean Wang goto err_release_irq; 6959aebfd4aSSean Wang 6969aebfd4aSSean Wang sdio_release_host(bdev->func); 6979aebfd4aSSean Wang 6989aebfd4aSSean Wang return 0; 6999aebfd4aSSean Wang 7009aebfd4aSSean Wang err_release_irq: 7019aebfd4aSSean Wang sdio_release_irq(bdev->func); 7029aebfd4aSSean Wang 7039aebfd4aSSean Wang err_disable_func: 7049aebfd4aSSean Wang sdio_disable_func(bdev->func); 7059aebfd4aSSean Wang 7069aebfd4aSSean Wang err_release_host: 7079aebfd4aSSean Wang sdio_release_host(bdev->func); 7089aebfd4aSSean Wang 7099aebfd4aSSean Wang return err; 7109aebfd4aSSean Wang } 7119aebfd4aSSean Wang 7129aebfd4aSSean Wang static int btmtksdio_close(struct hci_dev *hdev) 7139aebfd4aSSean Wang { 7149aebfd4aSSean Wang struct btmtksdio_dev *bdev = hci_get_drvdata(hdev); 7159aebfd4aSSean Wang 7169aebfd4aSSean Wang sdio_claim_host(bdev->func); 7179aebfd4aSSean Wang 7189aebfd4aSSean Wang /* Disable interrupt */ 7199aebfd4aSSean Wang sdio_writel(bdev->func, C_INT_EN_CLR, MTK_REG_CHLPCR, NULL); 7209aebfd4aSSean Wang 7219aebfd4aSSean Wang sdio_release_irq(bdev->func); 7229aebfd4aSSean Wang 72326270bc1SSean Wang cancel_work_sync(&bdev->txrx_work); 72426270bc1SSean Wang 725c7e301d7SMark Chen btmtksdio_fw_pmctrl(bdev); 7269aebfd4aSSean Wang 7274b4b2228SSean Wang clear_bit(BTMTKSDIO_FUNC_ENABLED, &bdev->tx_state); 7289aebfd4aSSean Wang sdio_disable_func(bdev->func); 7299aebfd4aSSean Wang 7309aebfd4aSSean Wang sdio_release_host(bdev->func); 7319aebfd4aSSean Wang 7329aebfd4aSSean Wang return 0; 7339aebfd4aSSean Wang } 7349aebfd4aSSean Wang 7359aebfd4aSSean Wang static int btmtksdio_flush(struct hci_dev *hdev) 7369aebfd4aSSean Wang { 7379aebfd4aSSean Wang struct btmtksdio_dev *bdev = hci_get_drvdata(hdev); 7389aebfd4aSSean Wang 7399aebfd4aSSean Wang skb_queue_purge(&bdev->txq); 7409aebfd4aSSean Wang 74126270bc1SSean Wang cancel_work_sync(&bdev->txrx_work); 7429aebfd4aSSean Wang 7439aebfd4aSSean Wang return 0; 7449aebfd4aSSean Wang } 7459aebfd4aSSean Wang 7469aebfd4aSSean Wang static int btmtksdio_func_query(struct hci_dev *hdev) 7479aebfd4aSSean Wang { 7489aebfd4aSSean Wang struct btmtk_hci_wmt_params wmt_params; 7499aebfd4aSSean Wang int status, err; 7509aebfd4aSSean Wang u8 param = 0; 7519aebfd4aSSean Wang 7529aebfd4aSSean Wang /* Query whether the function is enabled */ 7533a722044SSean Wang wmt_params.op = BTMTK_WMT_FUNC_CTRL; 7549aebfd4aSSean Wang wmt_params.flag = 4; 7559aebfd4aSSean Wang wmt_params.dlen = sizeof(param); 7569aebfd4aSSean Wang wmt_params.data = ¶m; 7579aebfd4aSSean Wang wmt_params.status = &status; 7589aebfd4aSSean Wang 7599aebfd4aSSean Wang err = mtk_hci_wmt_sync(hdev, &wmt_params); 7609aebfd4aSSean Wang if (err < 0) { 7619aebfd4aSSean Wang bt_dev_err(hdev, "Failed to query function status (%d)", err); 7629aebfd4aSSean Wang return err; 7639aebfd4aSSean Wang } 7649aebfd4aSSean Wang 7659aebfd4aSSean Wang return status; 7669aebfd4aSSean Wang } 7679aebfd4aSSean Wang 768c603bf1fSSean Wang static int mt76xx_setup(struct hci_dev *hdev, const char *fwname) 7699aebfd4aSSean Wang { 77001ecc177SMark Chen struct btmtksdio_dev *bdev = hci_get_drvdata(hdev); 7719aebfd4aSSean Wang struct btmtk_hci_wmt_params wmt_params; 7729aebfd4aSSean Wang struct btmtk_tci_sleep tci_sleep; 7739aebfd4aSSean Wang struct sk_buff *skb; 7749aebfd4aSSean Wang int err, status; 7759aebfd4aSSean Wang u8 param = 0x1; 7769aebfd4aSSean Wang 7779aebfd4aSSean Wang /* Query whether the firmware is already download */ 7783a722044SSean Wang wmt_params.op = BTMTK_WMT_SEMAPHORE; 7799aebfd4aSSean Wang wmt_params.flag = 1; 7809aebfd4aSSean Wang wmt_params.dlen = 0; 7819aebfd4aSSean Wang wmt_params.data = NULL; 7829aebfd4aSSean Wang wmt_params.status = &status; 7839aebfd4aSSean Wang 7849aebfd4aSSean Wang err = mtk_hci_wmt_sync(hdev, &wmt_params); 7859aebfd4aSSean Wang if (err < 0) { 7869aebfd4aSSean Wang bt_dev_err(hdev, "Failed to query firmware status (%d)", err); 7879aebfd4aSSean Wang return err; 7889aebfd4aSSean Wang } 7899aebfd4aSSean Wang 7909aebfd4aSSean Wang if (status == BTMTK_WMT_PATCH_DONE) { 7919aebfd4aSSean Wang bt_dev_info(hdev, "Firmware already downloaded"); 7929aebfd4aSSean Wang goto ignore_setup_fw; 7939aebfd4aSSean Wang } 7949aebfd4aSSean Wang 7959aebfd4aSSean Wang /* Setup a firmware which the device definitely requires */ 796c603bf1fSSean Wang err = btmtk_setup_firmware(hdev, fwname, mtk_hci_wmt_sync); 7979aebfd4aSSean Wang if (err < 0) 7989aebfd4aSSean Wang return err; 7999aebfd4aSSean Wang 8009aebfd4aSSean Wang ignore_setup_fw: 8019aebfd4aSSean Wang /* Query whether the device is already enabled */ 8029aebfd4aSSean Wang err = readx_poll_timeout(btmtksdio_func_query, hdev, status, 8039aebfd4aSSean Wang status < 0 || status != BTMTK_WMT_ON_PROGRESS, 8049aebfd4aSSean Wang 2000, 5000000); 8059aebfd4aSSean Wang /* -ETIMEDOUT happens */ 8069aebfd4aSSean Wang if (err < 0) 8079aebfd4aSSean Wang return err; 8089aebfd4aSSean Wang 8099aebfd4aSSean Wang /* The other errors happen in btusb_mtk_func_query */ 8109aebfd4aSSean Wang if (status < 0) 8119aebfd4aSSean Wang return status; 8129aebfd4aSSean Wang 8139aebfd4aSSean Wang if (status == BTMTK_WMT_ON_DONE) { 8149aebfd4aSSean Wang bt_dev_info(hdev, "function already on"); 8159aebfd4aSSean Wang goto ignore_func_on; 8169aebfd4aSSean Wang } 8179aebfd4aSSean Wang 8189aebfd4aSSean Wang /* Enable Bluetooth protocol */ 8193a722044SSean Wang wmt_params.op = BTMTK_WMT_FUNC_CTRL; 8209aebfd4aSSean Wang wmt_params.flag = 0; 8219aebfd4aSSean Wang wmt_params.dlen = sizeof(param); 8229aebfd4aSSean Wang wmt_params.data = ¶m; 8239aebfd4aSSean Wang wmt_params.status = NULL; 8249aebfd4aSSean Wang 8259aebfd4aSSean Wang err = mtk_hci_wmt_sync(hdev, &wmt_params); 8269aebfd4aSSean Wang if (err < 0) { 8279aebfd4aSSean Wang bt_dev_err(hdev, "Failed to send wmt func ctrl (%d)", err); 8289aebfd4aSSean Wang return err; 8299aebfd4aSSean Wang } 8309aebfd4aSSean Wang 83101ecc177SMark Chen set_bit(BTMTKSDIO_PATCH_ENABLED, &bdev->tx_state); 83201ecc177SMark Chen 8339aebfd4aSSean Wang ignore_func_on: 8349aebfd4aSSean Wang /* Apply the low power environment setup */ 8359aebfd4aSSean Wang tci_sleep.mode = 0x5; 8369aebfd4aSSean Wang tci_sleep.duration = cpu_to_le16(0x640); 8379aebfd4aSSean Wang tci_sleep.host_duration = cpu_to_le16(0x640); 8389aebfd4aSSean Wang tci_sleep.host_wakeup_pin = 0; 8399aebfd4aSSean Wang tci_sleep.time_compensation = 0; 8409aebfd4aSSean Wang 8419aebfd4aSSean Wang skb = __hci_cmd_sync(hdev, 0xfc7a, sizeof(tci_sleep), &tci_sleep, 8429aebfd4aSSean Wang HCI_INIT_TIMEOUT); 8439aebfd4aSSean Wang if (IS_ERR(skb)) { 8449aebfd4aSSean Wang err = PTR_ERR(skb); 8459aebfd4aSSean Wang bt_dev_err(hdev, "Failed to apply low power setting (%d)", err); 8469aebfd4aSSean Wang return err; 8479aebfd4aSSean Wang } 8489aebfd4aSSean Wang kfree_skb(skb); 8499aebfd4aSSean Wang 850c603bf1fSSean Wang return 0; 851c603bf1fSSean Wang } 852c603bf1fSSean Wang 853c603bf1fSSean Wang static int mt79xx_setup(struct hci_dev *hdev, const char *fwname) 854c603bf1fSSean Wang { 85501ecc177SMark Chen struct btmtksdio_dev *bdev = hci_get_drvdata(hdev); 856c603bf1fSSean Wang struct btmtk_hci_wmt_params wmt_params; 857c603bf1fSSean Wang u8 param = 0x1; 858c603bf1fSSean Wang int err; 859c603bf1fSSean Wang 860c603bf1fSSean Wang err = btmtk_setup_firmware_79xx(hdev, fwname, mtk_hci_wmt_sync); 861c603bf1fSSean Wang if (err < 0) { 862c603bf1fSSean Wang bt_dev_err(hdev, "Failed to setup 79xx firmware (%d)", err); 863c603bf1fSSean Wang return err; 864c603bf1fSSean Wang } 865c603bf1fSSean Wang 866c603bf1fSSean Wang /* Enable Bluetooth protocol */ 867c603bf1fSSean Wang wmt_params.op = BTMTK_WMT_FUNC_CTRL; 868c603bf1fSSean Wang wmt_params.flag = 0; 869c603bf1fSSean Wang wmt_params.dlen = sizeof(param); 870c603bf1fSSean Wang wmt_params.data = ¶m; 871c603bf1fSSean Wang wmt_params.status = NULL; 872c603bf1fSSean Wang 873c603bf1fSSean Wang err = mtk_hci_wmt_sync(hdev, &wmt_params); 874c603bf1fSSean Wang if (err < 0) { 875c603bf1fSSean Wang bt_dev_err(hdev, "Failed to send wmt func ctrl (%d)", err); 876c603bf1fSSean Wang return err; 877c603bf1fSSean Wang } 878c603bf1fSSean Wang 879630491ffSŁukasz Bartosik hci_set_msft_opcode(hdev, 0xFD30); 88016ada83bSSean Wang hci_set_aosp_capable(hdev); 88101ecc177SMark Chen set_bit(BTMTKSDIO_PATCH_ENABLED, &bdev->tx_state); 882630491ffSŁukasz Bartosik 883c603bf1fSSean Wang return err; 884c603bf1fSSean Wang } 885c603bf1fSSean Wang 8864b685879SSean Wang static int btmtksdio_mtk_reg_read(struct hci_dev *hdev, u32 reg, u32 *val) 887c603bf1fSSean Wang { 888c603bf1fSSean Wang struct btmtk_hci_wmt_params wmt_params; 8895677bcf6SSean Wang struct reg_read_cmd reg_read = { 890c603bf1fSSean Wang .type = 1, 891c603bf1fSSean Wang .num = 1, 892c603bf1fSSean Wang }; 893c603bf1fSSean Wang u32 status; 894c603bf1fSSean Wang int err; 895c603bf1fSSean Wang 896c603bf1fSSean Wang reg_read.addr = cpu_to_le32(reg); 897c603bf1fSSean Wang wmt_params.op = BTMTK_WMT_REGISTER; 898c603bf1fSSean Wang wmt_params.flag = BTMTK_WMT_REG_READ; 899c603bf1fSSean Wang wmt_params.dlen = sizeof(reg_read); 900c603bf1fSSean Wang wmt_params.data = ®_read; 901c603bf1fSSean Wang wmt_params.status = &status; 902c603bf1fSSean Wang 903c603bf1fSSean Wang err = mtk_hci_wmt_sync(hdev, &wmt_params); 904c603bf1fSSean Wang if (err < 0) { 905c603bf1fSSean Wang bt_dev_err(hdev, "Failed to read reg (%d)", err); 906c603bf1fSSean Wang return err; 907c603bf1fSSean Wang } 908c603bf1fSSean Wang 909c603bf1fSSean Wang *val = status; 910c603bf1fSSean Wang 911c603bf1fSSean Wang return err; 912c603bf1fSSean Wang } 913c603bf1fSSean Wang 914191c8723SMark Chen static int btmtksdio_mtk_reg_write(struct hci_dev *hdev, u32 reg, u32 val, u32 mask) 915191c8723SMark Chen { 916191c8723SMark Chen struct btmtk_hci_wmt_params wmt_params; 917191c8723SMark Chen const struct reg_write_cmd reg_write = { 918191c8723SMark Chen .type = 1, 919191c8723SMark Chen .num = 1, 920191c8723SMark Chen .addr = cpu_to_le32(reg), 921191c8723SMark Chen .data = cpu_to_le32(val), 922191c8723SMark Chen .mask = cpu_to_le32(mask), 923191c8723SMark Chen }; 924191c8723SMark Chen int err, status; 925191c8723SMark Chen 926191c8723SMark Chen wmt_params.op = BTMTK_WMT_REGISTER; 927191c8723SMark Chen wmt_params.flag = BTMTK_WMT_REG_WRITE; 928191c8723SMark Chen wmt_params.dlen = sizeof(reg_write); 929191c8723SMark Chen wmt_params.data = ®_write; 930191c8723SMark Chen wmt_params.status = &status; 931191c8723SMark Chen 932191c8723SMark Chen err = mtk_hci_wmt_sync(hdev, &wmt_params); 933191c8723SMark Chen if (err < 0) 934191c8723SMark Chen bt_dev_err(hdev, "Failed to write reg (%d)", err); 935191c8723SMark Chen 936191c8723SMark Chen return err; 937191c8723SMark Chen } 938191c8723SMark Chen 939d786105eSYake Yang static int btmtksdio_get_data_path_id(struct hci_dev *hdev, __u8 *data_path_id) 940d786105eSYake Yang { 941d786105eSYake Yang /* uses 1 as data path id for all the usecases */ 942d786105eSYake Yang *data_path_id = 1; 943d786105eSYake Yang return 0; 944d786105eSYake Yang } 945d786105eSYake Yang 946*f41b91faSYake Yang static int btmtksdio_get_codec_config_data(struct hci_dev *hdev, 947*f41b91faSYake Yang __u8 link, struct bt_codec *codec, 948*f41b91faSYake Yang __u8 *ven_len, __u8 **ven_data) 949*f41b91faSYake Yang { 950*f41b91faSYake Yang int err = 0; 951*f41b91faSYake Yang 952*f41b91faSYake Yang if (!ven_data || !ven_len) 953*f41b91faSYake Yang return -EINVAL; 954*f41b91faSYake Yang 955*f41b91faSYake Yang *ven_len = 0; 956*f41b91faSYake Yang *ven_data = NULL; 957*f41b91faSYake Yang 958*f41b91faSYake Yang if (link != ESCO_LINK) { 959*f41b91faSYake Yang bt_dev_err(hdev, "Invalid link type(%u)", link); 960*f41b91faSYake Yang return -EINVAL; 961*f41b91faSYake Yang } 962*f41b91faSYake Yang 963*f41b91faSYake Yang *ven_data = kmalloc(sizeof(__u8), GFP_KERNEL); 964*f41b91faSYake Yang if (!ven_data) { 965*f41b91faSYake Yang err = -ENOMEM; 966*f41b91faSYake Yang goto error; 967*f41b91faSYake Yang } 968*f41b91faSYake Yang 969*f41b91faSYake Yang /* supports only CVSD and mSBC offload codecs */ 970*f41b91faSYake Yang switch (codec->id) { 971*f41b91faSYake Yang case 0x02: 972*f41b91faSYake Yang **ven_data = 0x00; 973*f41b91faSYake Yang break; 974*f41b91faSYake Yang case 0x05: 975*f41b91faSYake Yang **ven_data = 0x01; 976*f41b91faSYake Yang break; 977*f41b91faSYake Yang default: 978*f41b91faSYake Yang err = -EINVAL; 979*f41b91faSYake Yang bt_dev_err(hdev, "Invalid codec id(%u)", codec->id); 980*f41b91faSYake Yang goto error; 981*f41b91faSYake Yang } 982*f41b91faSYake Yang /* codec and its capabilities are pre-defined to ids 983*f41b91faSYake Yang * preset id = 0x00 represents CVSD codec with sampling rate 8K 984*f41b91faSYake Yang * preset id = 0x01 represents mSBC codec with sampling rate 16K 985*f41b91faSYake Yang */ 986*f41b91faSYake Yang *ven_len = sizeof(__u8); 987*f41b91faSYake Yang return err; 988*f41b91faSYake Yang 989*f41b91faSYake Yang error: 990*f41b91faSYake Yang kfree(*ven_data); 991*f41b91faSYake Yang *ven_data = NULL; 992*f41b91faSYake Yang return err; 993*f41b91faSYake Yang } 994*f41b91faSYake Yang 995191c8723SMark Chen static int btmtksdio_sco_setting(struct hci_dev *hdev) 996191c8723SMark Chen { 997191c8723SMark Chen const struct btmtk_sco sco_setting = { 998191c8723SMark Chen .clock_config = 0x49, 999191c8723SMark Chen .channel_format_config = 0x80, 1000191c8723SMark Chen }; 1001191c8723SMark Chen struct sk_buff *skb; 1002191c8723SMark Chen u32 val; 1003191c8723SMark Chen int err; 1004191c8723SMark Chen 1005191c8723SMark Chen /* Enable SCO over I2S/PCM for MediaTek chipset */ 1006191c8723SMark Chen skb = __hci_cmd_sync(hdev, 0xfc72, sizeof(sco_setting), 1007191c8723SMark Chen &sco_setting, HCI_CMD_TIMEOUT); 1008191c8723SMark Chen if (IS_ERR(skb)) 1009191c8723SMark Chen return PTR_ERR(skb); 1010191c8723SMark Chen 1011191c8723SMark Chen kfree_skb(skb); 1012191c8723SMark Chen 1013191c8723SMark Chen err = btmtksdio_mtk_reg_read(hdev, MT7921_PINMUX_0, &val); 1014191c8723SMark Chen if (err < 0) 1015191c8723SMark Chen return err; 1016191c8723SMark Chen 1017191c8723SMark Chen val |= 0x11000000; 1018191c8723SMark Chen err = btmtksdio_mtk_reg_write(hdev, MT7921_PINMUX_0, val, ~0); 1019191c8723SMark Chen if (err < 0) 1020191c8723SMark Chen return err; 1021191c8723SMark Chen 1022191c8723SMark Chen err = btmtksdio_mtk_reg_read(hdev, MT7921_PINMUX_1, &val); 1023191c8723SMark Chen if (err < 0) 1024191c8723SMark Chen return err; 1025191c8723SMark Chen 1026191c8723SMark Chen val |= 0x00000101; 1027d786105eSYake Yang err = btmtksdio_mtk_reg_write(hdev, MT7921_PINMUX_1, val, ~0); 1028d786105eSYake Yang if (err < 0) 1029d786105eSYake Yang return err; 1030d786105eSYake Yang 1031d786105eSYake Yang hdev->get_data_path_id = btmtksdio_get_data_path_id; 1032*f41b91faSYake Yang hdev->get_codec_config_data = btmtksdio_get_codec_config_data; 1033d786105eSYake Yang 1034d786105eSYake Yang return err; 1035191c8723SMark Chen } 1036191c8723SMark Chen 10378fafe702SChih-Ying Chiang static int btmtksdio_reset_setting(struct hci_dev *hdev) 10388fafe702SChih-Ying Chiang { 10398fafe702SChih-Ying Chiang int err; 10408fafe702SChih-Ying Chiang u32 val; 10418fafe702SChih-Ying Chiang 10428fafe702SChih-Ying Chiang err = btmtksdio_mtk_reg_read(hdev, MT7921_PINMUX_1, &val); 10438fafe702SChih-Ying Chiang if (err < 0) 10448fafe702SChih-Ying Chiang return err; 10458fafe702SChih-Ying Chiang 10468fafe702SChih-Ying Chiang val |= 0x20; /* set the pin (bit field 11:8) work as GPIO mode */ 10478fafe702SChih-Ying Chiang err = btmtksdio_mtk_reg_write(hdev, MT7921_PINMUX_1, val, ~0); 10488fafe702SChih-Ying Chiang if (err < 0) 10498fafe702SChih-Ying Chiang return err; 10508fafe702SChih-Ying Chiang 10518fafe702SChih-Ying Chiang err = btmtksdio_mtk_reg_read(hdev, MT7921_BTSYS_RST, &val); 10528fafe702SChih-Ying Chiang if (err < 0) 10538fafe702SChih-Ying Chiang return err; 10548fafe702SChih-Ying Chiang 10558fafe702SChih-Ying Chiang val |= MT7921_BTSYS_RST_WITH_GPIO; 10568fafe702SChih-Ying Chiang return btmtksdio_mtk_reg_write(hdev, MT7921_BTSYS_RST, val, ~0); 10578fafe702SChih-Ying Chiang } 10588fafe702SChih-Ying Chiang 1059c603bf1fSSean Wang static int btmtksdio_setup(struct hci_dev *hdev) 1060c603bf1fSSean Wang { 1061c603bf1fSSean Wang struct btmtksdio_dev *bdev = hci_get_drvdata(hdev); 1062c603bf1fSSean Wang ktime_t calltime, delta, rettime; 1063c603bf1fSSean Wang unsigned long long duration; 1064c603bf1fSSean Wang char fwname[64]; 1065c603bf1fSSean Wang int err, dev_id; 10668fafe702SChih-Ying Chiang u32 fw_version = 0, val; 1067c603bf1fSSean Wang 1068c603bf1fSSean Wang calltime = ktime_get(); 1069d555b1f2SSean Wang set_bit(BTMTKSDIO_HW_TX_READY, &bdev->tx_state); 1070c603bf1fSSean Wang 1071c603bf1fSSean Wang switch (bdev->data->chipid) { 1072c603bf1fSSean Wang case 0x7921: 10738fafe702SChih-Ying Chiang if (test_bit(BTMTKSDIO_HW_RESET_ACTIVE, &bdev->tx_state)) { 10748fafe702SChih-Ying Chiang err = btmtksdio_mtk_reg_read(hdev, MT7921_DLSTATUS, 10758fafe702SChih-Ying Chiang &val); 10768fafe702SChih-Ying Chiang if (err < 0) 10778fafe702SChih-Ying Chiang return err; 10788fafe702SChih-Ying Chiang 10798fafe702SChih-Ying Chiang val &= ~BT_DL_STATE; 10808fafe702SChih-Ying Chiang err = btmtksdio_mtk_reg_write(hdev, MT7921_DLSTATUS, 10818fafe702SChih-Ying Chiang val, ~0); 10828fafe702SChih-Ying Chiang if (err < 0) 10838fafe702SChih-Ying Chiang return err; 10848fafe702SChih-Ying Chiang 10858fafe702SChih-Ying Chiang btmtksdio_fw_pmctrl(bdev); 10868fafe702SChih-Ying Chiang msleep(20); 10878fafe702SChih-Ying Chiang btmtksdio_drv_pmctrl(bdev); 10888fafe702SChih-Ying Chiang 10898fafe702SChih-Ying Chiang clear_bit(BTMTKSDIO_HW_RESET_ACTIVE, &bdev->tx_state); 10908fafe702SChih-Ying Chiang } 10918fafe702SChih-Ying Chiang 10924b685879SSean Wang err = btmtksdio_mtk_reg_read(hdev, 0x70010200, &dev_id); 1093c603bf1fSSean Wang if (err < 0) { 1094c603bf1fSSean Wang bt_dev_err(hdev, "Failed to get device id (%d)", err); 1095c603bf1fSSean Wang return err; 1096c603bf1fSSean Wang } 1097c603bf1fSSean Wang 10984b685879SSean Wang err = btmtksdio_mtk_reg_read(hdev, 0x80021004, &fw_version); 1099c603bf1fSSean Wang if (err < 0) { 1100c603bf1fSSean Wang bt_dev_err(hdev, "Failed to get fw version (%d)", err); 1101c603bf1fSSean Wang return err; 1102c603bf1fSSean Wang } 1103c603bf1fSSean Wang 1104c603bf1fSSean Wang snprintf(fwname, sizeof(fwname), 1105c603bf1fSSean Wang "mediatek/BT_RAM_CODE_MT%04x_1_%x_hdr.bin", 1106c603bf1fSSean Wang dev_id & 0xffff, (fw_version & 0xff) + 1); 1107c603bf1fSSean Wang err = mt79xx_setup(hdev, fwname); 1108c603bf1fSSean Wang if (err < 0) 1109c603bf1fSSean Wang return err; 1110191c8723SMark Chen 1111752aea58SMark Chen err = btmtksdio_fw_pmctrl(bdev); 1112752aea58SMark Chen if (err < 0) 1113752aea58SMark Chen return err; 1114752aea58SMark Chen 1115752aea58SMark Chen err = btmtksdio_drv_pmctrl(bdev); 1116752aea58SMark Chen if (err < 0) 1117752aea58SMark Chen return err; 1118752aea58SMark Chen 1119191c8723SMark Chen /* Enable SCO over I2S/PCM */ 1120191c8723SMark Chen err = btmtksdio_sco_setting(hdev); 1121191c8723SMark Chen if (err < 0) { 1122191c8723SMark Chen bt_dev_err(hdev, "Failed to enable SCO setting (%d)", err); 1123191c8723SMark Chen return err; 1124191c8723SMark Chen } 1125191c8723SMark Chen 11268fafe702SChih-Ying Chiang /* Enable GPIO reset mechanism */ 11278fafe702SChih-Ying Chiang if (bdev->reset) { 11288fafe702SChih-Ying Chiang err = btmtksdio_reset_setting(hdev); 11298fafe702SChih-Ying Chiang if (err < 0) { 11308fafe702SChih-Ying Chiang bt_dev_err(hdev, "Failed to enable Reset setting (%d)", err); 11318fafe702SChih-Ying Chiang devm_gpiod_put(bdev->dev, bdev->reset); 11328fafe702SChih-Ying Chiang bdev->reset = NULL; 11338fafe702SChih-Ying Chiang } 11348fafe702SChih-Ying Chiang } 11358fafe702SChih-Ying Chiang 1136546ff98eSYake Yang /* Valid LE States quirk for MediaTek 7921 */ 1137546ff98eSYake Yang set_bit(HCI_QUIRK_VALID_LE_STATES, &hdev->quirks); 1138546ff98eSYake Yang 1139c603bf1fSSean Wang break; 1140c603bf1fSSean Wang case 0x7663: 1141c603bf1fSSean Wang case 0x7668: 1142c603bf1fSSean Wang err = mt76xx_setup(hdev, bdev->data->fwname); 1143c603bf1fSSean Wang if (err < 0) 1144c603bf1fSSean Wang return err; 1145c603bf1fSSean Wang break; 1146c603bf1fSSean Wang default: 1147c603bf1fSSean Wang return -ENODEV; 1148c603bf1fSSean Wang } 1149c603bf1fSSean Wang 11509aebfd4aSSean Wang rettime = ktime_get(); 11519aebfd4aSSean Wang delta = ktime_sub(rettime, calltime); 11529aebfd4aSSean Wang duration = (unsigned long long)ktime_to_ns(delta) >> 10; 11539aebfd4aSSean Wang 11547f3c563cSSean Wang pm_runtime_set_autosuspend_delay(bdev->dev, 11557f3c563cSSean Wang MTKBTSDIO_AUTOSUSPEND_DELAY); 11567f3c563cSSean Wang pm_runtime_use_autosuspend(bdev->dev); 11577f3c563cSSean Wang 11587f3c563cSSean Wang err = pm_runtime_set_active(bdev->dev); 11597f3c563cSSean Wang if (err < 0) 11607f3c563cSSean Wang return err; 11617f3c563cSSean Wang 11627f3c563cSSean Wang /* Default forbid runtime auto suspend, that can be allowed by 11637f3c563cSSean Wang * enable_autosuspend flag or the PM runtime entry under sysfs. 11647f3c563cSSean Wang */ 11657f3c563cSSean Wang pm_runtime_forbid(bdev->dev); 11667f3c563cSSean Wang pm_runtime_enable(bdev->dev); 11677f3c563cSSean Wang 11687f3c563cSSean Wang if (enable_autosuspend) 11697f3c563cSSean Wang pm_runtime_allow(bdev->dev); 11707f3c563cSSean Wang 11719aebfd4aSSean Wang bt_dev_info(hdev, "Device setup in %llu usecs", duration); 11729aebfd4aSSean Wang 11739aebfd4aSSean Wang return 0; 11749aebfd4aSSean Wang } 11759aebfd4aSSean Wang 11769aebfd4aSSean Wang static int btmtksdio_shutdown(struct hci_dev *hdev) 11779aebfd4aSSean Wang { 11787f3c563cSSean Wang struct btmtksdio_dev *bdev = hci_get_drvdata(hdev); 11799aebfd4aSSean Wang struct btmtk_hci_wmt_params wmt_params; 11809aebfd4aSSean Wang u8 param = 0x0; 11819aebfd4aSSean Wang int err; 11829aebfd4aSSean Wang 11837f3c563cSSean Wang /* Get back the state to be consistent with the state 11847f3c563cSSean Wang * in btmtksdio_setup. 11857f3c563cSSean Wang */ 11867f3c563cSSean Wang pm_runtime_get_sync(bdev->dev); 11877f3c563cSSean Wang 11889aebfd4aSSean Wang /* Disable the device */ 11893a722044SSean Wang wmt_params.op = BTMTK_WMT_FUNC_CTRL; 11909aebfd4aSSean Wang wmt_params.flag = 0; 11919aebfd4aSSean Wang wmt_params.dlen = sizeof(param); 11929aebfd4aSSean Wang wmt_params.data = ¶m; 11939aebfd4aSSean Wang wmt_params.status = NULL; 11949aebfd4aSSean Wang 11959aebfd4aSSean Wang err = mtk_hci_wmt_sync(hdev, &wmt_params); 11969aebfd4aSSean Wang if (err < 0) { 11979aebfd4aSSean Wang bt_dev_err(hdev, "Failed to send wmt func ctrl (%d)", err); 11989aebfd4aSSean Wang return err; 11999aebfd4aSSean Wang } 12009aebfd4aSSean Wang 12017f3c563cSSean Wang pm_runtime_put_noidle(bdev->dev); 12027f3c563cSSean Wang pm_runtime_disable(bdev->dev); 12037f3c563cSSean Wang 12049aebfd4aSSean Wang return 0; 12059aebfd4aSSean Wang } 12069aebfd4aSSean Wang 12079aebfd4aSSean Wang static int btmtksdio_send_frame(struct hci_dev *hdev, struct sk_buff *skb) 12089aebfd4aSSean Wang { 12099aebfd4aSSean Wang struct btmtksdio_dev *bdev = hci_get_drvdata(hdev); 12109aebfd4aSSean Wang 12119aebfd4aSSean Wang switch (hci_skb_pkt_type(skb)) { 12129aebfd4aSSean Wang case HCI_COMMAND_PKT: 12139aebfd4aSSean Wang hdev->stat.cmd_tx++; 12149aebfd4aSSean Wang break; 12159aebfd4aSSean Wang 12169aebfd4aSSean Wang case HCI_ACLDATA_PKT: 12179aebfd4aSSean Wang hdev->stat.acl_tx++; 12189aebfd4aSSean Wang break; 12199aebfd4aSSean Wang 12209aebfd4aSSean Wang case HCI_SCODATA_PKT: 12219aebfd4aSSean Wang hdev->stat.sco_tx++; 12229aebfd4aSSean Wang break; 12239aebfd4aSSean Wang 12249aebfd4aSSean Wang default: 12259aebfd4aSSean Wang return -EILSEQ; 12269aebfd4aSSean Wang } 12279aebfd4aSSean Wang 12289aebfd4aSSean Wang skb_queue_tail(&bdev->txq, skb); 12299aebfd4aSSean Wang 123026270bc1SSean Wang schedule_work(&bdev->txrx_work); 12319aebfd4aSSean Wang 12329aebfd4aSSean Wang return 0; 12339aebfd4aSSean Wang } 12349aebfd4aSSean Wang 12358fafe702SChih-Ying Chiang static void btmtksdio_cmd_timeout(struct hci_dev *hdev) 12368fafe702SChih-Ying Chiang { 12378fafe702SChih-Ying Chiang struct btmtksdio_dev *bdev = hci_get_drvdata(hdev); 12388fafe702SChih-Ying Chiang u32 status; 12398fafe702SChih-Ying Chiang int err; 12408fafe702SChih-Ying Chiang 12418fafe702SChih-Ying Chiang if (!bdev->reset || bdev->data->chipid != 0x7921) 12428fafe702SChih-Ying Chiang return; 12438fafe702SChih-Ying Chiang 12448fafe702SChih-Ying Chiang pm_runtime_get_sync(bdev->dev); 12458fafe702SChih-Ying Chiang 12468fafe702SChih-Ying Chiang if (test_and_set_bit(BTMTKSDIO_HW_RESET_ACTIVE, &bdev->tx_state)) 12478fafe702SChih-Ying Chiang return; 12488fafe702SChih-Ying Chiang 12498fafe702SChih-Ying Chiang sdio_claim_host(bdev->func); 12508fafe702SChih-Ying Chiang 12518fafe702SChih-Ying Chiang sdio_writel(bdev->func, C_INT_EN_CLR, MTK_REG_CHLPCR, NULL); 12528fafe702SChih-Ying Chiang skb_queue_purge(&bdev->txq); 12538fafe702SChih-Ying Chiang cancel_work_sync(&bdev->txrx_work); 12548fafe702SChih-Ying Chiang 12558fafe702SChih-Ying Chiang gpiod_set_value_cansleep(bdev->reset, 1); 12568fafe702SChih-Ying Chiang msleep(100); 12578fafe702SChih-Ying Chiang gpiod_set_value_cansleep(bdev->reset, 0); 12588fafe702SChih-Ying Chiang 12598fafe702SChih-Ying Chiang err = readx_poll_timeout(btmtksdio_chcr_query, bdev, status, 12608fafe702SChih-Ying Chiang status & BT_RST_DONE, 100000, 2000000); 12618fafe702SChih-Ying Chiang if (err < 0) { 12628fafe702SChih-Ying Chiang bt_dev_err(hdev, "Failed to reset (%d)", err); 12638fafe702SChih-Ying Chiang goto err; 12648fafe702SChih-Ying Chiang } 12658fafe702SChih-Ying Chiang 12668fafe702SChih-Ying Chiang clear_bit(BTMTKSDIO_PATCH_ENABLED, &bdev->tx_state); 12678fafe702SChih-Ying Chiang err: 12688fafe702SChih-Ying Chiang sdio_release_host(bdev->func); 12698fafe702SChih-Ying Chiang 12708fafe702SChih-Ying Chiang pm_runtime_put_noidle(bdev->dev); 12718fafe702SChih-Ying Chiang pm_runtime_disable(bdev->dev); 12728fafe702SChih-Ying Chiang 12738fafe702SChih-Ying Chiang hci_reset_dev(hdev); 12748fafe702SChih-Ying Chiang } 12758fafe702SChih-Ying Chiang 1276ce64b3e9SMark Chen static bool btmtksdio_sdio_wakeup(struct hci_dev *hdev) 1277ce64b3e9SMark Chen { 1278ce64b3e9SMark Chen struct btmtksdio_dev *bdev = hci_get_drvdata(hdev); 1279ce64b3e9SMark Chen bool may_wakeup = device_may_wakeup(bdev->dev); 1280ce64b3e9SMark Chen const struct btmtk_wakeon bt_awake = { 1281ce64b3e9SMark Chen .mode = 0x1, 1282ce64b3e9SMark Chen .gpo = 0, 1283ce64b3e9SMark Chen .active_high = 0x1, 1284ce64b3e9SMark Chen .enable_delay = cpu_to_le16(0xc80), 1285ce64b3e9SMark Chen .wakeup_delay = cpu_to_le16(0x20), 1286ce64b3e9SMark Chen }; 1287ce64b3e9SMark Chen 1288ce64b3e9SMark Chen if (may_wakeup && bdev->data->chipid == 0x7921) { 1289ce64b3e9SMark Chen struct sk_buff *skb; 1290ce64b3e9SMark Chen 1291ce64b3e9SMark Chen skb = __hci_cmd_sync(hdev, 0xfc27, sizeof(bt_awake), 1292ce64b3e9SMark Chen &bt_awake, HCI_CMD_TIMEOUT); 1293ce64b3e9SMark Chen if (IS_ERR(skb)) 1294ce64b3e9SMark Chen may_wakeup = false; 1295eb3f0517SYake Yang else 1296ce64b3e9SMark Chen kfree_skb(skb); 1297ce64b3e9SMark Chen } 1298ce64b3e9SMark Chen 1299ce64b3e9SMark Chen return may_wakeup; 1300ce64b3e9SMark Chen } 1301ce64b3e9SMark Chen 13029aebfd4aSSean Wang static int btmtksdio_probe(struct sdio_func *func, 13039aebfd4aSSean Wang const struct sdio_device_id *id) 13049aebfd4aSSean Wang { 13059aebfd4aSSean Wang struct btmtksdio_dev *bdev; 13069aebfd4aSSean Wang struct hci_dev *hdev; 13079aebfd4aSSean Wang int err; 13089aebfd4aSSean Wang 13099aebfd4aSSean Wang bdev = devm_kzalloc(&func->dev, sizeof(*bdev), GFP_KERNEL); 13109aebfd4aSSean Wang if (!bdev) 13119aebfd4aSSean Wang return -ENOMEM; 13129aebfd4aSSean Wang 13139aebfd4aSSean Wang bdev->data = (void *)id->driver_data; 13149aebfd4aSSean Wang if (!bdev->data) 13159aebfd4aSSean Wang return -ENODEV; 13169aebfd4aSSean Wang 13177f3c563cSSean Wang bdev->dev = &func->dev; 13189aebfd4aSSean Wang bdev->func = func; 13199aebfd4aSSean Wang 132026270bc1SSean Wang INIT_WORK(&bdev->txrx_work, btmtksdio_txrx_work); 13219aebfd4aSSean Wang skb_queue_head_init(&bdev->txq); 13229aebfd4aSSean Wang 13239aebfd4aSSean Wang /* Initialize and register HCI device */ 13249aebfd4aSSean Wang hdev = hci_alloc_dev(); 13259aebfd4aSSean Wang if (!hdev) { 13269aebfd4aSSean Wang dev_err(&func->dev, "Can't allocate HCI device\n"); 13279aebfd4aSSean Wang return -ENOMEM; 13289aebfd4aSSean Wang } 13299aebfd4aSSean Wang 13309aebfd4aSSean Wang bdev->hdev = hdev; 13319aebfd4aSSean Wang 13329aebfd4aSSean Wang hdev->bus = HCI_SDIO; 13339aebfd4aSSean Wang hci_set_drvdata(hdev, bdev); 13349aebfd4aSSean Wang 13359aebfd4aSSean Wang hdev->open = btmtksdio_open; 13369aebfd4aSSean Wang hdev->close = btmtksdio_close; 13378fafe702SChih-Ying Chiang hdev->cmd_timeout = btmtksdio_cmd_timeout; 13389aebfd4aSSean Wang hdev->flush = btmtksdio_flush; 13399aebfd4aSSean Wang hdev->setup = btmtksdio_setup; 13409aebfd4aSSean Wang hdev->shutdown = btmtksdio_shutdown; 13419aebfd4aSSean Wang hdev->send = btmtksdio_send_frame; 1342ce64b3e9SMark Chen hdev->wakeup = btmtksdio_sdio_wakeup; 1343877ec9e1SSean Wang hdev->set_bdaddr = btmtk_set_bdaddr; 1344877ec9e1SSean Wang 13459aebfd4aSSean Wang SET_HCIDEV_DEV(hdev, &func->dev); 13469aebfd4aSSean Wang 13479aebfd4aSSean Wang hdev->manufacturer = 70; 13489aebfd4aSSean Wang set_bit(HCI_QUIRK_NON_PERSISTENT_SETUP, &hdev->quirks); 13499aebfd4aSSean Wang 1350b062a0b9SYake Yang sdio_set_drvdata(func, bdev); 1351b062a0b9SYake Yang 13529aebfd4aSSean Wang err = hci_register_dev(hdev); 13539aebfd4aSSean Wang if (err < 0) { 13549aebfd4aSSean Wang dev_err(&func->dev, "Can't register HCI device\n"); 13559aebfd4aSSean Wang hci_free_dev(hdev); 13569aebfd4aSSean Wang return err; 13579aebfd4aSSean Wang } 13589aebfd4aSSean Wang 13597f3c563cSSean Wang /* pm_runtime_enable would be done after the firmware is being 13607f3c563cSSean Wang * downloaded because the core layer probably already enables 13617f3c563cSSean Wang * runtime PM for this func such as the case host->caps & 13627f3c563cSSean Wang * MMC_CAP_POWER_OFF_CARD. 13637f3c563cSSean Wang */ 13647f3c563cSSean Wang if (pm_runtime_enabled(bdev->dev)) 13657f3c563cSSean Wang pm_runtime_disable(bdev->dev); 13667f3c563cSSean Wang 13677f3c563cSSean Wang /* As explaination in drivers/mmc/core/sdio_bus.c tells us: 13687f3c563cSSean Wang * Unbound SDIO functions are always suspended. 13697f3c563cSSean Wang * During probe, the function is set active and the usage count 13707f3c563cSSean Wang * is incremented. If the driver supports runtime PM, 13717f3c563cSSean Wang * it should call pm_runtime_put_noidle() in its probe routine and 13727f3c563cSSean Wang * pm_runtime_get_noresume() in its remove routine. 13737f3c563cSSean Wang * 13747f3c563cSSean Wang * So, put a pm_runtime_put_noidle here ! 13757f3c563cSSean Wang */ 13767f3c563cSSean Wang pm_runtime_put_noidle(bdev->dev); 13777f3c563cSSean Wang 1378ce64b3e9SMark Chen err = device_init_wakeup(bdev->dev, true); 1379ce64b3e9SMark Chen if (err) 1380ce64b3e9SMark Chen bt_dev_err(hdev, "failed to initialize device wakeup"); 1381ce64b3e9SMark Chen 13828fafe702SChih-Ying Chiang bdev->dev->of_node = of_find_compatible_node(NULL, NULL, 13838fafe702SChih-Ying Chiang "mediatek,mt7921s-bluetooth"); 13848fafe702SChih-Ying Chiang bdev->reset = devm_gpiod_get_optional(bdev->dev, "reset", 13858fafe702SChih-Ying Chiang GPIOD_OUT_LOW); 13868fafe702SChih-Ying Chiang if (IS_ERR(bdev->reset)) 13878fafe702SChih-Ying Chiang err = PTR_ERR(bdev->reset); 13888fafe702SChih-Ying Chiang 1389ce64b3e9SMark Chen return err; 13909aebfd4aSSean Wang } 13919aebfd4aSSean Wang 13929aebfd4aSSean Wang static void btmtksdio_remove(struct sdio_func *func) 13939aebfd4aSSean Wang { 13949aebfd4aSSean Wang struct btmtksdio_dev *bdev = sdio_get_drvdata(func); 13959aebfd4aSSean Wang struct hci_dev *hdev; 13969aebfd4aSSean Wang 13979aebfd4aSSean Wang if (!bdev) 13989aebfd4aSSean Wang return; 13999aebfd4aSSean Wang 14007f3c563cSSean Wang /* Be consistent the state in btmtksdio_probe */ 14017f3c563cSSean Wang pm_runtime_get_noresume(bdev->dev); 14027f3c563cSSean Wang 14039aebfd4aSSean Wang hdev = bdev->hdev; 14049aebfd4aSSean Wang 14059aebfd4aSSean Wang sdio_set_drvdata(func, NULL); 14069aebfd4aSSean Wang hci_unregister_dev(hdev); 14079aebfd4aSSean Wang hci_free_dev(hdev); 14089aebfd4aSSean Wang } 14099aebfd4aSSean Wang 14107f3c563cSSean Wang #ifdef CONFIG_PM 14117f3c563cSSean Wang static int btmtksdio_runtime_suspend(struct device *dev) 14127f3c563cSSean Wang { 14137f3c563cSSean Wang struct sdio_func *func = dev_to_sdio_func(dev); 14147f3c563cSSean Wang struct btmtksdio_dev *bdev; 14157f3c563cSSean Wang int err; 14167f3c563cSSean Wang 14177f3c563cSSean Wang bdev = sdio_get_drvdata(func); 14187f3c563cSSean Wang if (!bdev) 14197f3c563cSSean Wang return 0; 14207f3c563cSSean Wang 14214b4b2228SSean Wang if (!test_bit(BTMTKSDIO_FUNC_ENABLED, &bdev->tx_state)) 14224b4b2228SSean Wang return 0; 14234b4b2228SSean Wang 1424561ae1d4SSean Wang sdio_set_host_pm_flags(func, MMC_PM_KEEP_POWER); 1425561ae1d4SSean Wang 1426c7e301d7SMark Chen err = btmtksdio_fw_pmctrl(bdev); 14277f3c563cSSean Wang 1428095519deSSean Wang bt_dev_dbg(bdev->hdev, "status (%d) return ownership to device", err); 14297f3c563cSSean Wang 14307f3c563cSSean Wang return err; 14317f3c563cSSean Wang } 14327f3c563cSSean Wang 14337f3c563cSSean Wang static int btmtksdio_runtime_resume(struct device *dev) 14347f3c563cSSean Wang { 14357f3c563cSSean Wang struct sdio_func *func = dev_to_sdio_func(dev); 14367f3c563cSSean Wang struct btmtksdio_dev *bdev; 14377f3c563cSSean Wang int err; 14387f3c563cSSean Wang 14397f3c563cSSean Wang bdev = sdio_get_drvdata(func); 14407f3c563cSSean Wang if (!bdev) 14417f3c563cSSean Wang return 0; 14427f3c563cSSean Wang 14434b4b2228SSean Wang if (!test_bit(BTMTKSDIO_FUNC_ENABLED, &bdev->tx_state)) 14444b4b2228SSean Wang return 0; 14454b4b2228SSean Wang 1446c7e301d7SMark Chen err = btmtksdio_drv_pmctrl(bdev); 14477f3c563cSSean Wang 1448095519deSSean Wang bt_dev_dbg(bdev->hdev, "status (%d) get ownership from device", err); 14497f3c563cSSean Wang 14507f3c563cSSean Wang return err; 14517f3c563cSSean Wang } 14527f3c563cSSean Wang 14537f3c563cSSean Wang static UNIVERSAL_DEV_PM_OPS(btmtksdio_pm_ops, btmtksdio_runtime_suspend, 14547f3c563cSSean Wang btmtksdio_runtime_resume, NULL); 14557f3c563cSSean Wang #define BTMTKSDIO_PM_OPS (&btmtksdio_pm_ops) 14567f3c563cSSean Wang #else /* CONFIG_PM */ 14577f3c563cSSean Wang #define BTMTKSDIO_PM_OPS NULL 14587f3c563cSSean Wang #endif /* CONFIG_PM */ 14597f3c563cSSean Wang 14609aebfd4aSSean Wang static struct sdio_driver btmtksdio_driver = { 14619aebfd4aSSean Wang .name = "btmtksdio", 14629aebfd4aSSean Wang .probe = btmtksdio_probe, 14639aebfd4aSSean Wang .remove = btmtksdio_remove, 14649aebfd4aSSean Wang .id_table = btmtksdio_table, 14657f3c563cSSean Wang .drv = { 14667f3c563cSSean Wang .owner = THIS_MODULE, 14677f3c563cSSean Wang .pm = BTMTKSDIO_PM_OPS, 14687f3c563cSSean Wang } 14699aebfd4aSSean Wang }; 14709aebfd4aSSean Wang 1471a6094a46SSean Wang module_sdio_driver(btmtksdio_driver); 14729aebfd4aSSean Wang 14737f3c563cSSean Wang module_param(enable_autosuspend, bool, 0644); 14747f3c563cSSean Wang MODULE_PARM_DESC(enable_autosuspend, "Enable autosuspend by default"); 14757f3c563cSSean Wang 14769aebfd4aSSean Wang MODULE_AUTHOR("Sean Wang <sean.wang@mediatek.com>"); 14779aebfd4aSSean Wang MODULE_DESCRIPTION("MediaTek Bluetooth SDIO driver ver " VERSION); 14789aebfd4aSSean Wang MODULE_VERSION(VERSION); 14799aebfd4aSSean Wang MODULE_LICENSE("GPL"); 1480