17237c4c9SSean Wang // SPDX-License-Identifier: GPL-2.0 27237c4c9SSean Wang // Copyright (c) 2018 MediaTek Inc. 37237c4c9SSean Wang 47237c4c9SSean Wang /* 57237c4c9SSean Wang * Bluetooth support for MediaTek serial devices 67237c4c9SSean Wang * 77237c4c9SSean Wang * Author: Sean Wang <sean.wang@mediatek.com> 87237c4c9SSean Wang * 97237c4c9SSean Wang */ 107237c4c9SSean Wang 117237c4c9SSean Wang #include <asm/unaligned.h> 127237c4c9SSean Wang #include <linux/atomic.h> 137237c4c9SSean Wang #include <linux/clk.h> 147237c4c9SSean Wang #include <linux/firmware.h> 1522eaf6c9SSean Wang #include <linux/gpio/consumer.h> 16e0b67035SSean Wang #include <linux/iopoll.h> 177237c4c9SSean Wang #include <linux/kernel.h> 187237c4c9SSean Wang #include <linux/module.h> 197237c4c9SSean Wang #include <linux/of.h> 2022eaf6c9SSean Wang #include <linux/of_device.h> 2122eaf6c9SSean Wang #include <linux/pinctrl/consumer.h> 227237c4c9SSean Wang #include <linux/pm_runtime.h> 2322eaf6c9SSean Wang #include <linux/regulator/consumer.h> 247237c4c9SSean Wang #include <linux/serdev.h> 257237c4c9SSean Wang #include <linux/skbuff.h> 267237c4c9SSean Wang 277237c4c9SSean Wang #include <net/bluetooth/bluetooth.h> 287237c4c9SSean Wang #include <net/bluetooth/hci_core.h> 297237c4c9SSean Wang 307237c4c9SSean Wang #include "h4_recv.h" 31*f5c3f989SSean Wang #include "btmtk.h" 327237c4c9SSean Wang 3322eaf6c9SSean Wang #define VERSION "0.2" 347237c4c9SSean Wang 357237c4c9SSean Wang #define MTK_STP_TLR_SIZE 2 367237c4c9SSean Wang 377237c4c9SSean Wang #define BTMTKUART_TX_STATE_ACTIVE 1 387237c4c9SSean Wang #define BTMTKUART_TX_STATE_WAKEUP 2 397237c4c9SSean Wang #define BTMTKUART_TX_WAIT_VND_EVT 3 4022eaf6c9SSean Wang #define BTMTKUART_REQUIRED_WAKEUP 4 4122eaf6c9SSean Wang 4222eaf6c9SSean Wang #define BTMTKUART_FLAG_STANDALONE_HW BIT(0) 437237c4c9SSean Wang 447237c4c9SSean Wang struct mtk_stp_hdr { 457237c4c9SSean Wang u8 prefix; 467237c4c9SSean Wang __be16 dlen; 477237c4c9SSean Wang u8 cs; 487237c4c9SSean Wang } __packed; 497237c4c9SSean Wang 5022eaf6c9SSean Wang struct btmtkuart_data { 5122eaf6c9SSean Wang unsigned int flags; 5222eaf6c9SSean Wang const char *fwname; 5322eaf6c9SSean Wang }; 5422eaf6c9SSean Wang 557237c4c9SSean Wang struct btmtkuart_dev { 567237c4c9SSean Wang struct hci_dev *hdev; 577237c4c9SSean Wang struct serdev_device *serdev; 587237c4c9SSean Wang 5905582561SSean Wang struct clk *clk; 6005582561SSean Wang struct clk *osc; 6122eaf6c9SSean Wang struct regulator *vcc; 6222eaf6c9SSean Wang struct gpio_desc *reset; 63a3cb6d60SSean Wang struct gpio_desc *boot; 6422eaf6c9SSean Wang struct pinctrl *pinctrl; 6522eaf6c9SSean Wang struct pinctrl_state *pins_runtime; 6622eaf6c9SSean Wang struct pinctrl_state *pins_boot; 6722eaf6c9SSean Wang speed_t desired_speed; 6822eaf6c9SSean Wang speed_t curr_speed; 6922eaf6c9SSean Wang 707237c4c9SSean Wang struct work_struct tx_work; 717237c4c9SSean Wang unsigned long tx_state; 727237c4c9SSean Wang struct sk_buff_head txq; 737237c4c9SSean Wang 747237c4c9SSean Wang struct sk_buff *rx_skb; 75e0b67035SSean Wang struct sk_buff *evt_skb; 767237c4c9SSean Wang 777237c4c9SSean Wang u8 stp_pad[6]; 787237c4c9SSean Wang u8 stp_cursor; 797237c4c9SSean Wang u16 stp_dlen; 8022eaf6c9SSean Wang 8122eaf6c9SSean Wang const struct btmtkuart_data *data; 827237c4c9SSean Wang }; 837237c4c9SSean Wang 8422eaf6c9SSean Wang #define btmtkuart_is_standalone(bdev) \ 8522eaf6c9SSean Wang ((bdev)->data->flags & BTMTKUART_FLAG_STANDALONE_HW) 8622eaf6c9SSean Wang #define btmtkuart_is_builtin_soc(bdev) \ 8722eaf6c9SSean Wang !((bdev)->data->flags & BTMTKUART_FLAG_STANDALONE_HW) 8822eaf6c9SSean Wang 8988e5f366SSean Wang static int mtk_hci_wmt_sync(struct hci_dev *hdev, 9088e5f366SSean Wang struct btmtk_hci_wmt_params *wmt_params) 917237c4c9SSean Wang { 927237c4c9SSean Wang struct btmtkuart_dev *bdev = hci_get_drvdata(hdev); 93e0b67035SSean Wang struct btmtk_hci_wmt_evt_funcc *wmt_evt_funcc; 94e0b67035SSean Wang u32 hlen, status = BTMTK_WMT_INVALID; 95e0b67035SSean Wang struct btmtk_hci_wmt_evt *wmt_evt; 96*f5c3f989SSean Wang struct btmtk_hci_wmt_cmd *wc; 97*f5c3f989SSean Wang struct btmtk_wmt_hdr *hdr; 987237c4c9SSean Wang int err; 997237c4c9SSean Wang 100*f5c3f989SSean Wang /* Send the WMT command and wait until the WMT event returns */ 10188e5f366SSean Wang hlen = sizeof(*hdr) + wmt_params->dlen; 1023e5f2d90SDinghao Liu if (hlen > 255) { 1033e5f2d90SDinghao Liu err = -EINVAL; 1043e5f2d90SDinghao Liu goto err_free_skb; 1053e5f2d90SDinghao Liu } 1067237c4c9SSean Wang 107*f5c3f989SSean Wang wc = kzalloc(hlen, GFP_KERNEL); 108*f5c3f989SSean Wang if (!wc) 109*f5c3f989SSean Wang return -ENOMEM; 110*f5c3f989SSean Wang 111*f5c3f989SSean Wang hdr = &wc->hdr; 1127237c4c9SSean Wang hdr->dir = 1; 11388e5f366SSean Wang hdr->op = wmt_params->op; 11488e5f366SSean Wang hdr->dlen = cpu_to_le16(wmt_params->dlen + 1); 11588e5f366SSean Wang hdr->flag = wmt_params->flag; 116*f5c3f989SSean Wang memcpy(wc->data, wmt_params->data, wmt_params->dlen); 1177237c4c9SSean Wang 1187237c4c9SSean Wang set_bit(BTMTKUART_TX_WAIT_VND_EVT, &bdev->tx_state); 1197237c4c9SSean Wang 120*f5c3f989SSean Wang err = __hci_cmd_send(hdev, 0xfc6f, hlen, wc); 1217237c4c9SSean Wang if (err < 0) { 1227237c4c9SSean Wang clear_bit(BTMTKUART_TX_WAIT_VND_EVT, &bdev->tx_state); 123*f5c3f989SSean Wang goto err_free_wc; 1247237c4c9SSean Wang } 1257237c4c9SSean Wang 1267237c4c9SSean Wang /* The vendor specific WMT commands are all answered by a vendor 1277237c4c9SSean Wang * specific event and will not have the Command Status or Command 1287237c4c9SSean Wang * Complete as with usual HCI command flow control. 1297237c4c9SSean Wang * 1307237c4c9SSean Wang * After sending the command, wait for BTMTKUART_TX_WAIT_VND_EVT 131adf5d730SSean Wang * state to be cleared. The driver specific event receive routine 1327237c4c9SSean Wang * will clear that state and with that indicate completion of the 1337237c4c9SSean Wang * WMT command. 1347237c4c9SSean Wang */ 1357237c4c9SSean Wang err = wait_on_bit_timeout(&bdev->tx_state, BTMTKUART_TX_WAIT_VND_EVT, 1367237c4c9SSean Wang TASK_INTERRUPTIBLE, HCI_INIT_TIMEOUT); 1377237c4c9SSean Wang if (err == -EINTR) { 1387237c4c9SSean Wang bt_dev_err(hdev, "Execution of wmt command interrupted"); 13977f328dbSSean Wang clear_bit(BTMTKUART_TX_WAIT_VND_EVT, &bdev->tx_state); 140*f5c3f989SSean Wang goto err_free_wc; 1417237c4c9SSean Wang } 1427237c4c9SSean Wang 1437237c4c9SSean Wang if (err) { 1447237c4c9SSean Wang bt_dev_err(hdev, "Execution of wmt command timed out"); 14577f328dbSSean Wang clear_bit(BTMTKUART_TX_WAIT_VND_EVT, &bdev->tx_state); 1463e5f2d90SDinghao Liu err = -ETIMEDOUT; 147*f5c3f989SSean Wang goto err_free_wc; 1487237c4c9SSean Wang } 1497237c4c9SSean Wang 150e0b67035SSean Wang /* Parse and handle the return WMT event */ 151e0b67035SSean Wang wmt_evt = (struct btmtk_hci_wmt_evt *)bdev->evt_skb->data; 152e0b67035SSean Wang if (wmt_evt->whdr.op != hdr->op) { 153e0b67035SSean Wang bt_dev_err(hdev, "Wrong op received %d expected %d", 154e0b67035SSean Wang wmt_evt->whdr.op, hdr->op); 155e0b67035SSean Wang err = -EIO; 156e0b67035SSean Wang goto err_free_skb; 157e0b67035SSean Wang } 158e0b67035SSean Wang 159e0b67035SSean Wang switch (wmt_evt->whdr.op) { 160*f5c3f989SSean Wang case BTMTK_WMT_SEMAPHORE: 161e0b67035SSean Wang if (wmt_evt->whdr.flag == 2) 162e0b67035SSean Wang status = BTMTK_WMT_PATCH_UNDONE; 163e0b67035SSean Wang else 164e0b67035SSean Wang status = BTMTK_WMT_PATCH_DONE; 165e0b67035SSean Wang break; 166*f5c3f989SSean Wang case BTMTK_WMT_FUNC_CTRL: 167e0b67035SSean Wang wmt_evt_funcc = (struct btmtk_hci_wmt_evt_funcc *)wmt_evt; 168e0b67035SSean Wang if (be16_to_cpu(wmt_evt_funcc->status) == 0x404) 169e0b67035SSean Wang status = BTMTK_WMT_ON_DONE; 170e0b67035SSean Wang else if (be16_to_cpu(wmt_evt_funcc->status) == 0x420) 171e0b67035SSean Wang status = BTMTK_WMT_ON_PROGRESS; 172e0b67035SSean Wang else 173e0b67035SSean Wang status = BTMTK_WMT_ON_UNDONE; 174e0b67035SSean Wang break; 175e0b67035SSean Wang } 176e0b67035SSean Wang 177e0b67035SSean Wang if (wmt_params->status) 178e0b67035SSean Wang *wmt_params->status = status; 179e0b67035SSean Wang 180e0b67035SSean Wang err_free_skb: 181e0b67035SSean Wang kfree_skb(bdev->evt_skb); 182e0b67035SSean Wang bdev->evt_skb = NULL; 183*f5c3f989SSean Wang err_free_wc: 184*f5c3f989SSean Wang kfree(wc); 185e0b67035SSean Wang 186e0b67035SSean Wang return err; 1877237c4c9SSean Wang } 1887237c4c9SSean Wang 1897237c4c9SSean Wang static int btmtkuart_recv_event(struct hci_dev *hdev, struct sk_buff *skb) 1907237c4c9SSean Wang { 1917237c4c9SSean Wang struct btmtkuart_dev *bdev = hci_get_drvdata(hdev); 1927237c4c9SSean Wang struct hci_event_hdr *hdr = (void *)skb->data; 1937237c4c9SSean Wang int err; 1947237c4c9SSean Wang 1957237c4c9SSean Wang /* Fix up the vendor event id with 0xff for vendor specific instead 1967237c4c9SSean Wang * of 0xe4 so that event send via monitoring socket can be parsed 1977237c4c9SSean Wang * properly. 1987237c4c9SSean Wang */ 1997237c4c9SSean Wang if (hdr->evt == 0xe4) 2007237c4c9SSean Wang hdr->evt = HCI_EV_VENDOR; 2017237c4c9SSean Wang 202e0b67035SSean Wang /* When someone waits for the WMT event, the skb is being cloned 203e0b67035SSean Wang * and being processed the events from there then. 204e0b67035SSean Wang */ 205e0b67035SSean Wang if (test_bit(BTMTKUART_TX_WAIT_VND_EVT, &bdev->tx_state)) { 206e0b67035SSean Wang bdev->evt_skb = skb_clone(skb, GFP_KERNEL); 207e0b67035SSean Wang if (!bdev->evt_skb) { 208e0b67035SSean Wang err = -ENOMEM; 209e0b67035SSean Wang goto err_out; 210e0b67035SSean Wang } 211e0b67035SSean Wang } 212e0b67035SSean Wang 2137237c4c9SSean Wang err = hci_recv_frame(hdev, skb); 214e0b67035SSean Wang if (err < 0) 215e0b67035SSean Wang goto err_free_skb; 2167237c4c9SSean Wang 2177237c4c9SSean Wang if (hdr->evt == HCI_EV_VENDOR) { 2187237c4c9SSean Wang if (test_and_clear_bit(BTMTKUART_TX_WAIT_VND_EVT, 2197237c4c9SSean Wang &bdev->tx_state)) { 2207237c4c9SSean Wang /* Barrier to sync with other CPUs */ 2217237c4c9SSean Wang smp_mb__after_atomic(); 2227237c4c9SSean Wang wake_up_bit(&bdev->tx_state, BTMTKUART_TX_WAIT_VND_EVT); 2237237c4c9SSean Wang } 2247237c4c9SSean Wang } 2257237c4c9SSean Wang 226e0b67035SSean Wang return 0; 227e0b67035SSean Wang 228e0b67035SSean Wang err_free_skb: 229e0b67035SSean Wang kfree_skb(bdev->evt_skb); 230e0b67035SSean Wang bdev->evt_skb = NULL; 231e0b67035SSean Wang 232e0b67035SSean Wang err_out: 2337237c4c9SSean Wang return err; 2347237c4c9SSean Wang } 2357237c4c9SSean Wang 2367237c4c9SSean Wang static const struct h4_recv_pkt mtk_recv_pkts[] = { 2377237c4c9SSean Wang { H4_RECV_ACL, .recv = hci_recv_frame }, 2387237c4c9SSean Wang { H4_RECV_SCO, .recv = hci_recv_frame }, 2397237c4c9SSean Wang { H4_RECV_EVENT, .recv = btmtkuart_recv_event }, 2407237c4c9SSean Wang }; 2417237c4c9SSean Wang 2427237c4c9SSean Wang static void btmtkuart_tx_work(struct work_struct *work) 2437237c4c9SSean Wang { 2447237c4c9SSean Wang struct btmtkuart_dev *bdev = container_of(work, struct btmtkuart_dev, 2457237c4c9SSean Wang tx_work); 2467237c4c9SSean Wang struct serdev_device *serdev = bdev->serdev; 2477237c4c9SSean Wang struct hci_dev *hdev = bdev->hdev; 2487237c4c9SSean Wang 2497237c4c9SSean Wang while (1) { 2507237c4c9SSean Wang clear_bit(BTMTKUART_TX_STATE_WAKEUP, &bdev->tx_state); 2517237c4c9SSean Wang 2527237c4c9SSean Wang while (1) { 2537237c4c9SSean Wang struct sk_buff *skb = skb_dequeue(&bdev->txq); 2547237c4c9SSean Wang int len; 2557237c4c9SSean Wang 2567237c4c9SSean Wang if (!skb) 2577237c4c9SSean Wang break; 2587237c4c9SSean Wang 2597237c4c9SSean Wang len = serdev_device_write_buf(serdev, skb->data, 2607237c4c9SSean Wang skb->len); 2617237c4c9SSean Wang hdev->stat.byte_tx += len; 2627237c4c9SSean Wang 2637237c4c9SSean Wang skb_pull(skb, len); 2647237c4c9SSean Wang if (skb->len > 0) { 2657237c4c9SSean Wang skb_queue_head(&bdev->txq, skb); 2667237c4c9SSean Wang break; 2677237c4c9SSean Wang } 2687237c4c9SSean Wang 2697237c4c9SSean Wang switch (hci_skb_pkt_type(skb)) { 2707237c4c9SSean Wang case HCI_COMMAND_PKT: 2717237c4c9SSean Wang hdev->stat.cmd_tx++; 2727237c4c9SSean Wang break; 2737237c4c9SSean Wang case HCI_ACLDATA_PKT: 2747237c4c9SSean Wang hdev->stat.acl_tx++; 2757237c4c9SSean Wang break; 2767237c4c9SSean Wang case HCI_SCODATA_PKT: 2777237c4c9SSean Wang hdev->stat.sco_tx++; 2787237c4c9SSean Wang break; 2797237c4c9SSean Wang } 2807237c4c9SSean Wang 2817237c4c9SSean Wang kfree_skb(skb); 2827237c4c9SSean Wang } 2837237c4c9SSean Wang 2847237c4c9SSean Wang if (!test_bit(BTMTKUART_TX_STATE_WAKEUP, &bdev->tx_state)) 2857237c4c9SSean Wang break; 2867237c4c9SSean Wang } 2877237c4c9SSean Wang 2887237c4c9SSean Wang clear_bit(BTMTKUART_TX_STATE_ACTIVE, &bdev->tx_state); 2897237c4c9SSean Wang } 2907237c4c9SSean Wang 2917237c4c9SSean Wang static void btmtkuart_tx_wakeup(struct btmtkuart_dev *bdev) 2927237c4c9SSean Wang { 2937237c4c9SSean Wang if (test_and_set_bit(BTMTKUART_TX_STATE_ACTIVE, &bdev->tx_state)) 2947237c4c9SSean Wang set_bit(BTMTKUART_TX_STATE_WAKEUP, &bdev->tx_state); 2957237c4c9SSean Wang 2967237c4c9SSean Wang schedule_work(&bdev->tx_work); 2977237c4c9SSean Wang } 2987237c4c9SSean Wang 2997237c4c9SSean Wang static const unsigned char * 3007237c4c9SSean Wang mtk_stp_split(struct btmtkuart_dev *bdev, const unsigned char *data, int count, 3017237c4c9SSean Wang int *sz_h4) 3027237c4c9SSean Wang { 3037237c4c9SSean Wang struct mtk_stp_hdr *shdr; 3047237c4c9SSean Wang 3057237c4c9SSean Wang /* The cursor is reset when all the data of STP is consumed out */ 3067237c4c9SSean Wang if (!bdev->stp_dlen && bdev->stp_cursor >= 6) 3077237c4c9SSean Wang bdev->stp_cursor = 0; 3087237c4c9SSean Wang 3097237c4c9SSean Wang /* Filling pad until all STP info is obtained */ 3107237c4c9SSean Wang while (bdev->stp_cursor < 6 && count > 0) { 3117237c4c9SSean Wang bdev->stp_pad[bdev->stp_cursor] = *data; 3127237c4c9SSean Wang bdev->stp_cursor++; 3137237c4c9SSean Wang data++; 3147237c4c9SSean Wang count--; 3157237c4c9SSean Wang } 3167237c4c9SSean Wang 3177237c4c9SSean Wang /* Retrieve STP info and have a sanity check */ 3187237c4c9SSean Wang if (!bdev->stp_dlen && bdev->stp_cursor >= 6) { 3197237c4c9SSean Wang shdr = (struct mtk_stp_hdr *)&bdev->stp_pad[2]; 3207237c4c9SSean Wang bdev->stp_dlen = be16_to_cpu(shdr->dlen) & 0x0fff; 3217237c4c9SSean Wang 3227237c4c9SSean Wang /* Resync STP when unexpected data is being read */ 3237237c4c9SSean Wang if (shdr->prefix != 0x80 || bdev->stp_dlen > 2048) { 3247237c4c9SSean Wang bt_dev_err(bdev->hdev, "stp format unexpect (%d, %d)", 3257237c4c9SSean Wang shdr->prefix, bdev->stp_dlen); 3267237c4c9SSean Wang bdev->stp_cursor = 2; 3277237c4c9SSean Wang bdev->stp_dlen = 0; 3287237c4c9SSean Wang } 3297237c4c9SSean Wang } 3307237c4c9SSean Wang 3317237c4c9SSean Wang /* Directly quit when there's no data found for H4 can process */ 3327237c4c9SSean Wang if (count <= 0) 3337237c4c9SSean Wang return NULL; 3347237c4c9SSean Wang 3357237c4c9SSean Wang /* Tranlate to how much the size of data H4 can handle so far */ 3367237c4c9SSean Wang *sz_h4 = min_t(int, count, bdev->stp_dlen); 3377237c4c9SSean Wang 3387237c4c9SSean Wang /* Update the remaining size of STP packet */ 3397237c4c9SSean Wang bdev->stp_dlen -= *sz_h4; 3407237c4c9SSean Wang 3417237c4c9SSean Wang /* Data points to STP payload which can be handled by H4 */ 3427237c4c9SSean Wang return data; 3437237c4c9SSean Wang } 3447237c4c9SSean Wang 3457237c4c9SSean Wang static int btmtkuart_recv(struct hci_dev *hdev, const u8 *data, size_t count) 3467237c4c9SSean Wang { 3477237c4c9SSean Wang struct btmtkuart_dev *bdev = hci_get_drvdata(hdev); 3487237c4c9SSean Wang const unsigned char *p_left = data, *p_h4; 3497237c4c9SSean Wang int sz_left = count, sz_h4, adv; 3507237c4c9SSean Wang int err; 3517237c4c9SSean Wang 3527237c4c9SSean Wang while (sz_left > 0) { 3537237c4c9SSean Wang /* The serial data received from MT7622 BT controller is 3547237c4c9SSean Wang * at all time padded around with the STP header and tailer. 3557237c4c9SSean Wang * 3567237c4c9SSean Wang * A full STP packet is looking like 3577237c4c9SSean Wang * ----------------------------------- 3587237c4c9SSean Wang * | STP header | H:4 | STP tailer | 3597237c4c9SSean Wang * ----------------------------------- 3607237c4c9SSean Wang * but it doesn't guarantee to contain a full H:4 packet which 3617237c4c9SSean Wang * means that it's possible for multiple STP packets forms a 3627237c4c9SSean Wang * full H:4 packet that means extra STP header + length doesn't 3637237c4c9SSean Wang * indicate a full H:4 frame, things can fragment. Whose length 3647237c4c9SSean Wang * recorded in STP header just shows up the most length the 3657237c4c9SSean Wang * H:4 engine can handle currently. 3667237c4c9SSean Wang */ 3677237c4c9SSean Wang 3687237c4c9SSean Wang p_h4 = mtk_stp_split(bdev, p_left, sz_left, &sz_h4); 3697237c4c9SSean Wang if (!p_h4) 3707237c4c9SSean Wang break; 3717237c4c9SSean Wang 3727237c4c9SSean Wang adv = p_h4 - p_left; 3737237c4c9SSean Wang sz_left -= adv; 3747237c4c9SSean Wang p_left += adv; 3757237c4c9SSean Wang 3767237c4c9SSean Wang bdev->rx_skb = h4_recv_buf(bdev->hdev, bdev->rx_skb, p_h4, 3777237c4c9SSean Wang sz_h4, mtk_recv_pkts, 378330ad75fSDan Carpenter ARRAY_SIZE(mtk_recv_pkts)); 3797237c4c9SSean Wang if (IS_ERR(bdev->rx_skb)) { 3807237c4c9SSean Wang err = PTR_ERR(bdev->rx_skb); 3817237c4c9SSean Wang bt_dev_err(bdev->hdev, 3827237c4c9SSean Wang "Frame reassembly failed (%d)", err); 3837237c4c9SSean Wang bdev->rx_skb = NULL; 3847237c4c9SSean Wang return err; 3857237c4c9SSean Wang } 3867237c4c9SSean Wang 3877237c4c9SSean Wang sz_left -= sz_h4; 3887237c4c9SSean Wang p_left += sz_h4; 3897237c4c9SSean Wang } 3907237c4c9SSean Wang 3917237c4c9SSean Wang return 0; 3927237c4c9SSean Wang } 3937237c4c9SSean Wang 3947237c4c9SSean Wang static int btmtkuart_receive_buf(struct serdev_device *serdev, const u8 *data, 3957237c4c9SSean Wang size_t count) 3967237c4c9SSean Wang { 3977237c4c9SSean Wang struct btmtkuart_dev *bdev = serdev_device_get_drvdata(serdev); 3987237c4c9SSean Wang int err; 3997237c4c9SSean Wang 4007237c4c9SSean Wang err = btmtkuart_recv(bdev->hdev, data, count); 4017237c4c9SSean Wang if (err < 0) 4027237c4c9SSean Wang return err; 4037237c4c9SSean Wang 4047237c4c9SSean Wang bdev->hdev->stat.byte_rx += count; 4057237c4c9SSean Wang 4067237c4c9SSean Wang return count; 4077237c4c9SSean Wang } 4087237c4c9SSean Wang 4097237c4c9SSean Wang static void btmtkuart_write_wakeup(struct serdev_device *serdev) 4107237c4c9SSean Wang { 4117237c4c9SSean Wang struct btmtkuart_dev *bdev = serdev_device_get_drvdata(serdev); 4127237c4c9SSean Wang 4137237c4c9SSean Wang btmtkuart_tx_wakeup(bdev); 4147237c4c9SSean Wang } 4157237c4c9SSean Wang 4167237c4c9SSean Wang static const struct serdev_device_ops btmtkuart_client_ops = { 4177237c4c9SSean Wang .receive_buf = btmtkuart_receive_buf, 4187237c4c9SSean Wang .write_wakeup = btmtkuart_write_wakeup, 4197237c4c9SSean Wang }; 4207237c4c9SSean Wang 4217237c4c9SSean Wang static int btmtkuart_open(struct hci_dev *hdev) 4227237c4c9SSean Wang { 4237237c4c9SSean Wang struct btmtkuart_dev *bdev = hci_get_drvdata(hdev); 4247237c4c9SSean Wang struct device *dev; 4257237c4c9SSean Wang int err; 4267237c4c9SSean Wang 4277237c4c9SSean Wang err = serdev_device_open(bdev->serdev); 4287237c4c9SSean Wang if (err) { 4297237c4c9SSean Wang bt_dev_err(hdev, "Unable to open UART device %s", 4307237c4c9SSean Wang dev_name(&bdev->serdev->dev)); 4317237c4c9SSean Wang goto err_open; 4327237c4c9SSean Wang } 4337237c4c9SSean Wang 43422eaf6c9SSean Wang if (btmtkuart_is_standalone(bdev)) { 43522eaf6c9SSean Wang if (bdev->curr_speed != bdev->desired_speed) 43622eaf6c9SSean Wang err = serdev_device_set_baudrate(bdev->serdev, 43722eaf6c9SSean Wang 115200); 43822eaf6c9SSean Wang else 43922eaf6c9SSean Wang err = serdev_device_set_baudrate(bdev->serdev, 44022eaf6c9SSean Wang bdev->desired_speed); 44122eaf6c9SSean Wang 44222eaf6c9SSean Wang if (err < 0) { 44322eaf6c9SSean Wang bt_dev_err(hdev, "Unable to set baudrate UART device %s", 44422eaf6c9SSean Wang dev_name(&bdev->serdev->dev)); 44522eaf6c9SSean Wang goto err_serdev_close; 44622eaf6c9SSean Wang } 44722eaf6c9SSean Wang 44822eaf6c9SSean Wang serdev_device_set_flow_control(bdev->serdev, false); 44922eaf6c9SSean Wang } 45022eaf6c9SSean Wang 4517237c4c9SSean Wang bdev->stp_cursor = 2; 4527237c4c9SSean Wang bdev->stp_dlen = 0; 4537237c4c9SSean Wang 4547237c4c9SSean Wang dev = &bdev->serdev->dev; 4557237c4c9SSean Wang 4567237c4c9SSean Wang /* Enable the power domain and clock the device requires */ 4577237c4c9SSean Wang pm_runtime_enable(dev); 458a1b2fdf9SZhang Qilong err = pm_runtime_resume_and_get(dev); 459a1b2fdf9SZhang Qilong if (err < 0) 4607237c4c9SSean Wang goto err_disable_rpm; 4617237c4c9SSean Wang 4627237c4c9SSean Wang err = clk_prepare_enable(bdev->clk); 4637237c4c9SSean Wang if (err < 0) 4647237c4c9SSean Wang goto err_put_rpm; 4657237c4c9SSean Wang 4667237c4c9SSean Wang return 0; 4677237c4c9SSean Wang 4687237c4c9SSean Wang err_put_rpm: 4697237c4c9SSean Wang pm_runtime_put_sync(dev); 4707237c4c9SSean Wang err_disable_rpm: 4717237c4c9SSean Wang pm_runtime_disable(dev); 47222eaf6c9SSean Wang err_serdev_close: 47322eaf6c9SSean Wang serdev_device_close(bdev->serdev); 4747237c4c9SSean Wang err_open: 4757237c4c9SSean Wang return err; 4767237c4c9SSean Wang } 4777237c4c9SSean Wang 4787237c4c9SSean Wang static int btmtkuart_close(struct hci_dev *hdev) 4797237c4c9SSean Wang { 4807237c4c9SSean Wang struct btmtkuart_dev *bdev = hci_get_drvdata(hdev); 4817237c4c9SSean Wang struct device *dev = &bdev->serdev->dev; 4827237c4c9SSean Wang 4837237c4c9SSean Wang /* Shutdown the clock and power domain the device requires */ 4847237c4c9SSean Wang clk_disable_unprepare(bdev->clk); 4857237c4c9SSean Wang pm_runtime_put_sync(dev); 4867237c4c9SSean Wang pm_runtime_disable(dev); 4877237c4c9SSean Wang 4887237c4c9SSean Wang serdev_device_close(bdev->serdev); 4897237c4c9SSean Wang 4907237c4c9SSean Wang return 0; 4917237c4c9SSean Wang } 4927237c4c9SSean Wang 4937237c4c9SSean Wang static int btmtkuart_flush(struct hci_dev *hdev) 4947237c4c9SSean Wang { 4957237c4c9SSean Wang struct btmtkuart_dev *bdev = hci_get_drvdata(hdev); 4967237c4c9SSean Wang 4977237c4c9SSean Wang /* Flush any pending characters */ 4987237c4c9SSean Wang serdev_device_write_flush(bdev->serdev); 4997237c4c9SSean Wang skb_queue_purge(&bdev->txq); 5007237c4c9SSean Wang 5017237c4c9SSean Wang cancel_work_sync(&bdev->tx_work); 5027237c4c9SSean Wang 5037237c4c9SSean Wang kfree_skb(bdev->rx_skb); 5047237c4c9SSean Wang bdev->rx_skb = NULL; 5057237c4c9SSean Wang 5067237c4c9SSean Wang bdev->stp_cursor = 2; 5077237c4c9SSean Wang bdev->stp_dlen = 0; 5087237c4c9SSean Wang 5097237c4c9SSean Wang return 0; 5107237c4c9SSean Wang } 5117237c4c9SSean Wang 512e0b67035SSean Wang static int btmtkuart_func_query(struct hci_dev *hdev) 513e0b67035SSean Wang { 514e0b67035SSean Wang struct btmtk_hci_wmt_params wmt_params; 515e0b67035SSean Wang int status, err; 516e0b67035SSean Wang u8 param = 0; 517e0b67035SSean Wang 518e0b67035SSean Wang /* Query whether the function is enabled */ 519*f5c3f989SSean Wang wmt_params.op = BTMTK_WMT_FUNC_CTRL; 520e0b67035SSean Wang wmt_params.flag = 4; 521e0b67035SSean Wang wmt_params.dlen = sizeof(param); 522e0b67035SSean Wang wmt_params.data = ¶m; 523e0b67035SSean Wang wmt_params.status = &status; 524e0b67035SSean Wang 525e0b67035SSean Wang err = mtk_hci_wmt_sync(hdev, &wmt_params); 526e0b67035SSean Wang if (err < 0) { 527e0b67035SSean Wang bt_dev_err(hdev, "Failed to query function status (%d)", err); 528e0b67035SSean Wang return err; 529e0b67035SSean Wang } 530e0b67035SSean Wang 531e0b67035SSean Wang return status; 532e0b67035SSean Wang } 533e0b67035SSean Wang 53422eaf6c9SSean Wang static int btmtkuart_change_baudrate(struct hci_dev *hdev) 53522eaf6c9SSean Wang { 53622eaf6c9SSean Wang struct btmtkuart_dev *bdev = hci_get_drvdata(hdev); 53722eaf6c9SSean Wang struct btmtk_hci_wmt_params wmt_params; 538cac63f9bSSean Wang __le32 baudrate; 53922eaf6c9SSean Wang u8 param; 54022eaf6c9SSean Wang int err; 54122eaf6c9SSean Wang 54222eaf6c9SSean Wang /* Indicate the device to enter the probe state the host is 54322eaf6c9SSean Wang * ready to change a new baudrate. 54422eaf6c9SSean Wang */ 54522eaf6c9SSean Wang baudrate = cpu_to_le32(bdev->desired_speed); 546*f5c3f989SSean Wang wmt_params.op = BTMTK_WMT_HIF; 54722eaf6c9SSean Wang wmt_params.flag = 1; 54822eaf6c9SSean Wang wmt_params.dlen = 4; 54922eaf6c9SSean Wang wmt_params.data = &baudrate; 55022eaf6c9SSean Wang wmt_params.status = NULL; 55122eaf6c9SSean Wang 55222eaf6c9SSean Wang err = mtk_hci_wmt_sync(hdev, &wmt_params); 55322eaf6c9SSean Wang if (err < 0) { 55422eaf6c9SSean Wang bt_dev_err(hdev, "Failed to device baudrate (%d)", err); 55522eaf6c9SSean Wang return err; 55622eaf6c9SSean Wang } 55722eaf6c9SSean Wang 55822eaf6c9SSean Wang err = serdev_device_set_baudrate(bdev->serdev, 55922eaf6c9SSean Wang bdev->desired_speed); 56022eaf6c9SSean Wang if (err < 0) { 56122eaf6c9SSean Wang bt_dev_err(hdev, "Failed to set up host baudrate (%d)", 56222eaf6c9SSean Wang err); 56322eaf6c9SSean Wang return err; 56422eaf6c9SSean Wang } 56522eaf6c9SSean Wang 56622eaf6c9SSean Wang serdev_device_set_flow_control(bdev->serdev, false); 56722eaf6c9SSean Wang 56822eaf6c9SSean Wang /* Send a dummy byte 0xff to activate the new baudrate */ 56922eaf6c9SSean Wang param = 0xff; 570d3a0fe6bSZijun Hu err = serdev_device_write_buf(bdev->serdev, ¶m, sizeof(param)); 57122eaf6c9SSean Wang if (err < 0 || err < sizeof(param)) 57222eaf6c9SSean Wang return err; 57322eaf6c9SSean Wang 57422eaf6c9SSean Wang serdev_device_wait_until_sent(bdev->serdev, 0); 57522eaf6c9SSean Wang 57622eaf6c9SSean Wang /* Wait some time for the device changing baudrate done */ 57722eaf6c9SSean Wang usleep_range(20000, 22000); 57822eaf6c9SSean Wang 57922eaf6c9SSean Wang /* Test the new baudrate */ 580*f5c3f989SSean Wang wmt_params.op = BTMTK_WMT_TEST; 58122eaf6c9SSean Wang wmt_params.flag = 7; 58222eaf6c9SSean Wang wmt_params.dlen = 0; 58322eaf6c9SSean Wang wmt_params.data = NULL; 58422eaf6c9SSean Wang wmt_params.status = NULL; 58522eaf6c9SSean Wang 58622eaf6c9SSean Wang err = mtk_hci_wmt_sync(hdev, &wmt_params); 58722eaf6c9SSean Wang if (err < 0) { 58822eaf6c9SSean Wang bt_dev_err(hdev, "Failed to test new baudrate (%d)", 58922eaf6c9SSean Wang err); 59022eaf6c9SSean Wang return err; 59122eaf6c9SSean Wang } 59222eaf6c9SSean Wang 59322eaf6c9SSean Wang bdev->curr_speed = bdev->desired_speed; 59422eaf6c9SSean Wang 59522eaf6c9SSean Wang return 0; 59622eaf6c9SSean Wang } 59722eaf6c9SSean Wang 5987237c4c9SSean Wang static int btmtkuart_setup(struct hci_dev *hdev) 5997237c4c9SSean Wang { 60022eaf6c9SSean Wang struct btmtkuart_dev *bdev = hci_get_drvdata(hdev); 60188e5f366SSean Wang struct btmtk_hci_wmt_params wmt_params; 602e0b67035SSean Wang ktime_t calltime, delta, rettime; 603e0b67035SSean Wang struct btmtk_tci_sleep tci_sleep; 604e0b67035SSean Wang unsigned long long duration; 605e0b67035SSean Wang struct sk_buff *skb; 606e0b67035SSean Wang int err, status; 6077237c4c9SSean Wang u8 param = 0x1; 608e0b67035SSean Wang 609e0b67035SSean Wang calltime = ktime_get(); 610e0b67035SSean Wang 61122eaf6c9SSean Wang /* Wakeup MCUSYS is required for certain devices before we start to 61222eaf6c9SSean Wang * do any setups. 61322eaf6c9SSean Wang */ 61422eaf6c9SSean Wang if (test_bit(BTMTKUART_REQUIRED_WAKEUP, &bdev->tx_state)) { 615*f5c3f989SSean Wang wmt_params.op = BTMTK_WMT_WAKEUP; 61622eaf6c9SSean Wang wmt_params.flag = 3; 61722eaf6c9SSean Wang wmt_params.dlen = 0; 61822eaf6c9SSean Wang wmt_params.data = NULL; 61922eaf6c9SSean Wang wmt_params.status = NULL; 62022eaf6c9SSean Wang 62122eaf6c9SSean Wang err = mtk_hci_wmt_sync(hdev, &wmt_params); 62222eaf6c9SSean Wang if (err < 0) { 62322eaf6c9SSean Wang bt_dev_err(hdev, "Failed to wakeup the chip (%d)", err); 62422eaf6c9SSean Wang return err; 62522eaf6c9SSean Wang } 62622eaf6c9SSean Wang 62722eaf6c9SSean Wang clear_bit(BTMTKUART_REQUIRED_WAKEUP, &bdev->tx_state); 62822eaf6c9SSean Wang } 62922eaf6c9SSean Wang 63022eaf6c9SSean Wang if (btmtkuart_is_standalone(bdev)) 63122eaf6c9SSean Wang btmtkuart_change_baudrate(hdev); 63222eaf6c9SSean Wang 633e0b67035SSean Wang /* Query whether the firmware is already download */ 634*f5c3f989SSean Wang wmt_params.op = BTMTK_WMT_SEMAPHORE; 635e0b67035SSean Wang wmt_params.flag = 1; 636e0b67035SSean Wang wmt_params.dlen = 0; 637e0b67035SSean Wang wmt_params.data = NULL; 638e0b67035SSean Wang wmt_params.status = &status; 639e0b67035SSean Wang 640e0b67035SSean Wang err = mtk_hci_wmt_sync(hdev, &wmt_params); 641e0b67035SSean Wang if (err < 0) { 642e0b67035SSean Wang bt_dev_err(hdev, "Failed to query firmware status (%d)", err); 643e0b67035SSean Wang return err; 644e0b67035SSean Wang } 645e0b67035SSean Wang 646e0b67035SSean Wang if (status == BTMTK_WMT_PATCH_DONE) { 647e0b67035SSean Wang bt_dev_info(hdev, "Firmware already downloaded"); 648e0b67035SSean Wang goto ignore_setup_fw; 649e0b67035SSean Wang } 6507237c4c9SSean Wang 6517237c4c9SSean Wang /* Setup a firmware which the device definitely requires */ 652*f5c3f989SSean Wang err = btmtk_setup_firmware(hdev, bdev->data->fwname, mtk_hci_wmt_sync); 6537237c4c9SSean Wang if (err < 0) 6547237c4c9SSean Wang return err; 6557237c4c9SSean Wang 656e0b67035SSean Wang ignore_setup_fw: 657e0b67035SSean Wang /* Query whether the device is already enabled */ 658e0b67035SSean Wang err = readx_poll_timeout(btmtkuart_func_query, hdev, status, 659e0b67035SSean Wang status < 0 || status != BTMTK_WMT_ON_PROGRESS, 660e0b67035SSean Wang 2000, 5000000); 661e0b67035SSean Wang /* -ETIMEDOUT happens */ 662e0b67035SSean Wang if (err < 0) 6637237c4c9SSean Wang return err; 664e0b67035SSean Wang 665e0b67035SSean Wang /* The other errors happen in btusb_mtk_func_query */ 666e0b67035SSean Wang if (status < 0) 667e0b67035SSean Wang return status; 668e0b67035SSean Wang 669e0b67035SSean Wang if (status == BTMTK_WMT_ON_DONE) { 670e0b67035SSean Wang bt_dev_info(hdev, "function already on"); 671e0b67035SSean Wang goto ignore_func_on; 6727237c4c9SSean Wang } 6737237c4c9SSean Wang 6747237c4c9SSean Wang /* Enable Bluetooth protocol */ 675*f5c3f989SSean Wang wmt_params.op = BTMTK_WMT_FUNC_CTRL; 67688e5f366SSean Wang wmt_params.flag = 0; 67788e5f366SSean Wang wmt_params.dlen = sizeof(param); 67888e5f366SSean Wang wmt_params.data = ¶m; 67988e5f366SSean Wang wmt_params.status = NULL; 68088e5f366SSean Wang 68188e5f366SSean Wang err = mtk_hci_wmt_sync(hdev, &wmt_params); 6827237c4c9SSean Wang if (err < 0) { 6837237c4c9SSean Wang bt_dev_err(hdev, "Failed to send wmt func ctrl (%d)", err); 6847237c4c9SSean Wang return err; 6857237c4c9SSean Wang } 6867237c4c9SSean Wang 687e0b67035SSean Wang ignore_func_on: 688e0b67035SSean Wang /* Apply the low power environment setup */ 689e0b67035SSean Wang tci_sleep.mode = 0x5; 690e0b67035SSean Wang tci_sleep.duration = cpu_to_le16(0x640); 691e0b67035SSean Wang tci_sleep.host_duration = cpu_to_le16(0x640); 692e0b67035SSean Wang tci_sleep.host_wakeup_pin = 0; 693e0b67035SSean Wang tci_sleep.time_compensation = 0; 694e0b67035SSean Wang 695e0b67035SSean Wang skb = __hci_cmd_sync(hdev, 0xfc7a, sizeof(tci_sleep), &tci_sleep, 696e0b67035SSean Wang HCI_INIT_TIMEOUT); 697e0b67035SSean Wang if (IS_ERR(skb)) { 698e0b67035SSean Wang err = PTR_ERR(skb); 699e0b67035SSean Wang bt_dev_err(hdev, "Failed to apply low power setting (%d)", err); 700e0b67035SSean Wang return err; 701e0b67035SSean Wang } 702e0b67035SSean Wang kfree_skb(skb); 703e0b67035SSean Wang 704e0b67035SSean Wang rettime = ktime_get(); 705e0b67035SSean Wang delta = ktime_sub(rettime, calltime); 706e0b67035SSean Wang duration = (unsigned long long)ktime_to_ns(delta) >> 10; 707e0b67035SSean Wang 708e0b67035SSean Wang bt_dev_info(hdev, "Device setup in %llu usecs", duration); 709e0b67035SSean Wang 7107237c4c9SSean Wang return 0; 7117237c4c9SSean Wang } 7127237c4c9SSean Wang 7137237c4c9SSean Wang static int btmtkuart_shutdown(struct hci_dev *hdev) 7147237c4c9SSean Wang { 71588e5f366SSean Wang struct btmtk_hci_wmt_params wmt_params; 7167237c4c9SSean Wang u8 param = 0x0; 7177237c4c9SSean Wang int err; 7187237c4c9SSean Wang 7197237c4c9SSean Wang /* Disable the device */ 720*f5c3f989SSean Wang wmt_params.op = BTMTK_WMT_FUNC_CTRL; 72188e5f366SSean Wang wmt_params.flag = 0; 72288e5f366SSean Wang wmt_params.dlen = sizeof(param); 72388e5f366SSean Wang wmt_params.data = ¶m; 72488e5f366SSean Wang wmt_params.status = NULL; 72588e5f366SSean Wang 72688e5f366SSean Wang err = mtk_hci_wmt_sync(hdev, &wmt_params); 7277237c4c9SSean Wang if (err < 0) { 7287237c4c9SSean Wang bt_dev_err(hdev, "Failed to send wmt func ctrl (%d)", err); 7297237c4c9SSean Wang return err; 7307237c4c9SSean Wang } 7317237c4c9SSean Wang 7327237c4c9SSean Wang return 0; 7337237c4c9SSean Wang } 7347237c4c9SSean Wang 7357237c4c9SSean Wang static int btmtkuart_send_frame(struct hci_dev *hdev, struct sk_buff *skb) 7367237c4c9SSean Wang { 7377237c4c9SSean Wang struct btmtkuart_dev *bdev = hci_get_drvdata(hdev); 7387237c4c9SSean Wang struct mtk_stp_hdr *shdr; 7397237c4c9SSean Wang int err, dlen, type = 0; 7407237c4c9SSean Wang 7417237c4c9SSean Wang /* Prepend skb with frame type */ 7427237c4c9SSean Wang memcpy(skb_push(skb, 1), &hci_skb_pkt_type(skb), 1); 7437237c4c9SSean Wang 7447237c4c9SSean Wang /* Make sure that there is enough rooms for STP header and trailer */ 7457237c4c9SSean Wang if (unlikely(skb_headroom(skb) < sizeof(*shdr)) || 7467237c4c9SSean Wang (skb_tailroom(skb) < MTK_STP_TLR_SIZE)) { 7477237c4c9SSean Wang err = pskb_expand_head(skb, sizeof(*shdr), MTK_STP_TLR_SIZE, 7487237c4c9SSean Wang GFP_ATOMIC); 7497237c4c9SSean Wang if (err < 0) 7507237c4c9SSean Wang return err; 7517237c4c9SSean Wang } 7527237c4c9SSean Wang 7537237c4c9SSean Wang /* Add the STP header */ 7547237c4c9SSean Wang dlen = skb->len; 7557237c4c9SSean Wang shdr = skb_push(skb, sizeof(*shdr)); 7567237c4c9SSean Wang shdr->prefix = 0x80; 7577237c4c9SSean Wang shdr->dlen = cpu_to_be16((dlen & 0x0fff) | (type << 12)); 7587237c4c9SSean Wang shdr->cs = 0; /* MT7622 doesn't care about checksum value */ 7597237c4c9SSean Wang 7607237c4c9SSean Wang /* Add the STP trailer */ 7617237c4c9SSean Wang skb_put_zero(skb, MTK_STP_TLR_SIZE); 7627237c4c9SSean Wang 7637237c4c9SSean Wang skb_queue_tail(&bdev->txq, skb); 7647237c4c9SSean Wang 7657237c4c9SSean Wang btmtkuart_tx_wakeup(bdev); 7667237c4c9SSean Wang return 0; 7677237c4c9SSean Wang } 7687237c4c9SSean Wang 76922eaf6c9SSean Wang static int btmtkuart_parse_dt(struct serdev_device *serdev) 77022eaf6c9SSean Wang { 77122eaf6c9SSean Wang struct btmtkuart_dev *bdev = serdev_device_get_drvdata(serdev); 77222eaf6c9SSean Wang struct device_node *node = serdev->dev.of_node; 77322eaf6c9SSean Wang u32 speed = 921600; 77422eaf6c9SSean Wang int err; 77522eaf6c9SSean Wang 77622eaf6c9SSean Wang if (btmtkuart_is_standalone(bdev)) { 77722eaf6c9SSean Wang of_property_read_u32(node, "current-speed", &speed); 77822eaf6c9SSean Wang 77922eaf6c9SSean Wang bdev->desired_speed = speed; 78022eaf6c9SSean Wang 78122eaf6c9SSean Wang bdev->vcc = devm_regulator_get(&serdev->dev, "vcc"); 78222eaf6c9SSean Wang if (IS_ERR(bdev->vcc)) { 78322eaf6c9SSean Wang err = PTR_ERR(bdev->vcc); 78422eaf6c9SSean Wang return err; 78522eaf6c9SSean Wang } 78622eaf6c9SSean Wang 78705582561SSean Wang bdev->osc = devm_clk_get_optional(&serdev->dev, "osc"); 78805582561SSean Wang if (IS_ERR(bdev->osc)) { 78905582561SSean Wang err = PTR_ERR(bdev->osc); 79005582561SSean Wang return err; 79105582561SSean Wang } 79205582561SSean Wang 793a3cb6d60SSean Wang bdev->boot = devm_gpiod_get_optional(&serdev->dev, "boot", 794a3cb6d60SSean Wang GPIOD_OUT_LOW); 795a3cb6d60SSean Wang if (IS_ERR(bdev->boot)) { 796a3cb6d60SSean Wang err = PTR_ERR(bdev->boot); 797a3cb6d60SSean Wang return err; 798a3cb6d60SSean Wang } 799a3cb6d60SSean Wang 80022eaf6c9SSean Wang bdev->pinctrl = devm_pinctrl_get(&serdev->dev); 80122eaf6c9SSean Wang if (IS_ERR(bdev->pinctrl)) { 80222eaf6c9SSean Wang err = PTR_ERR(bdev->pinctrl); 80322eaf6c9SSean Wang return err; 80422eaf6c9SSean Wang } 80522eaf6c9SSean Wang 80622eaf6c9SSean Wang bdev->pins_boot = pinctrl_lookup_state(bdev->pinctrl, 80722eaf6c9SSean Wang "default"); 808a3cb6d60SSean Wang if (IS_ERR(bdev->pins_boot) && !bdev->boot) { 80922eaf6c9SSean Wang err = PTR_ERR(bdev->pins_boot); 810a3cb6d60SSean Wang dev_err(&serdev->dev, 811a3cb6d60SSean Wang "Should assign RXD to LOW at boot stage\n"); 81222eaf6c9SSean Wang return err; 81322eaf6c9SSean Wang } 81422eaf6c9SSean Wang 81522eaf6c9SSean Wang bdev->pins_runtime = pinctrl_lookup_state(bdev->pinctrl, 81622eaf6c9SSean Wang "runtime"); 81722eaf6c9SSean Wang if (IS_ERR(bdev->pins_runtime)) { 81822eaf6c9SSean Wang err = PTR_ERR(bdev->pins_runtime); 81922eaf6c9SSean Wang return err; 82022eaf6c9SSean Wang } 82122eaf6c9SSean Wang 82222eaf6c9SSean Wang bdev->reset = devm_gpiod_get_optional(&serdev->dev, "reset", 82322eaf6c9SSean Wang GPIOD_OUT_LOW); 82422eaf6c9SSean Wang if (IS_ERR(bdev->reset)) { 82522eaf6c9SSean Wang err = PTR_ERR(bdev->reset); 82622eaf6c9SSean Wang return err; 82722eaf6c9SSean Wang } 82822eaf6c9SSean Wang } else if (btmtkuart_is_builtin_soc(bdev)) { 82922eaf6c9SSean Wang bdev->clk = devm_clk_get(&serdev->dev, "ref"); 83022eaf6c9SSean Wang if (IS_ERR(bdev->clk)) 83122eaf6c9SSean Wang return PTR_ERR(bdev->clk); 83222eaf6c9SSean Wang } 83322eaf6c9SSean Wang 83422eaf6c9SSean Wang return 0; 83522eaf6c9SSean Wang } 83622eaf6c9SSean Wang 8377237c4c9SSean Wang static int btmtkuart_probe(struct serdev_device *serdev) 8387237c4c9SSean Wang { 8397237c4c9SSean Wang struct btmtkuart_dev *bdev; 8407237c4c9SSean Wang struct hci_dev *hdev; 84122eaf6c9SSean Wang int err; 8427237c4c9SSean Wang 8437237c4c9SSean Wang bdev = devm_kzalloc(&serdev->dev, sizeof(*bdev), GFP_KERNEL); 8447237c4c9SSean Wang if (!bdev) 8457237c4c9SSean Wang return -ENOMEM; 8467237c4c9SSean Wang 84722eaf6c9SSean Wang bdev->data = of_device_get_match_data(&serdev->dev); 84822eaf6c9SSean Wang if (!bdev->data) 84922eaf6c9SSean Wang return -ENODEV; 8507237c4c9SSean Wang 8517237c4c9SSean Wang bdev->serdev = serdev; 8527237c4c9SSean Wang serdev_device_set_drvdata(serdev, bdev); 8537237c4c9SSean Wang 8547237c4c9SSean Wang serdev_device_set_client_ops(serdev, &btmtkuart_client_ops); 8557237c4c9SSean Wang 85622eaf6c9SSean Wang err = btmtkuart_parse_dt(serdev); 85722eaf6c9SSean Wang if (err < 0) 85822eaf6c9SSean Wang return err; 85922eaf6c9SSean Wang 8607237c4c9SSean Wang INIT_WORK(&bdev->tx_work, btmtkuart_tx_work); 8617237c4c9SSean Wang skb_queue_head_init(&bdev->txq); 8627237c4c9SSean Wang 8637237c4c9SSean Wang /* Initialize and register HCI device */ 8647237c4c9SSean Wang hdev = hci_alloc_dev(); 8657237c4c9SSean Wang if (!hdev) { 8667237c4c9SSean Wang dev_err(&serdev->dev, "Can't allocate HCI device\n"); 8677237c4c9SSean Wang return -ENOMEM; 8687237c4c9SSean Wang } 8697237c4c9SSean Wang 8707237c4c9SSean Wang bdev->hdev = hdev; 8717237c4c9SSean Wang 8727237c4c9SSean Wang hdev->bus = HCI_UART; 8737237c4c9SSean Wang hci_set_drvdata(hdev, bdev); 8747237c4c9SSean Wang 8757237c4c9SSean Wang hdev->open = btmtkuart_open; 8767237c4c9SSean Wang hdev->close = btmtkuart_close; 8777237c4c9SSean Wang hdev->flush = btmtkuart_flush; 8787237c4c9SSean Wang hdev->setup = btmtkuart_setup; 8797237c4c9SSean Wang hdev->shutdown = btmtkuart_shutdown; 8807237c4c9SSean Wang hdev->send = btmtkuart_send_frame; 8817237c4c9SSean Wang SET_HCIDEV_DEV(hdev, &serdev->dev); 8827237c4c9SSean Wang 8837237c4c9SSean Wang hdev->manufacturer = 70; 8847237c4c9SSean Wang set_bit(HCI_QUIRK_NON_PERSISTENT_SETUP, &hdev->quirks); 8857237c4c9SSean Wang 88622eaf6c9SSean Wang if (btmtkuart_is_standalone(bdev)) { 88705582561SSean Wang err = clk_prepare_enable(bdev->osc); 88805582561SSean Wang if (err < 0) 8894803c54cSChuhong Yuan goto err_hci_free_dev; 89005582561SSean Wang 891a3cb6d60SSean Wang if (bdev->boot) { 892a3cb6d60SSean Wang gpiod_set_value_cansleep(bdev->boot, 1); 893a3cb6d60SSean Wang } else { 894a3cb6d60SSean Wang /* Switch to the specific pin state for the booting 895a3cb6d60SSean Wang * requires. 896a3cb6d60SSean Wang */ 89722eaf6c9SSean Wang pinctrl_select_state(bdev->pinctrl, bdev->pins_boot); 898a3cb6d60SSean Wang } 89922eaf6c9SSean Wang 90022eaf6c9SSean Wang /* Power on */ 90122eaf6c9SSean Wang err = regulator_enable(bdev->vcc); 9024803c54cSChuhong Yuan if (err < 0) 9034803c54cSChuhong Yuan goto err_clk_disable_unprepare; 90422eaf6c9SSean Wang 90522eaf6c9SSean Wang /* Reset if the reset-gpios is available otherwise the board 90622eaf6c9SSean Wang * -level design should be guaranteed. 90722eaf6c9SSean Wang */ 90822eaf6c9SSean Wang if (bdev->reset) { 90922eaf6c9SSean Wang gpiod_set_value_cansleep(bdev->reset, 1); 91022eaf6c9SSean Wang usleep_range(1000, 2000); 91122eaf6c9SSean Wang gpiod_set_value_cansleep(bdev->reset, 0); 91222eaf6c9SSean Wang } 91322eaf6c9SSean Wang 91422eaf6c9SSean Wang /* Wait some time until device got ready and switch to the pin 91522eaf6c9SSean Wang * mode the device requires for UART transfers. 91622eaf6c9SSean Wang */ 91722eaf6c9SSean Wang msleep(50); 918a3cb6d60SSean Wang 919a3cb6d60SSean Wang if (bdev->boot) 920a3cb6d60SSean Wang devm_gpiod_put(&serdev->dev, bdev->boot); 921a3cb6d60SSean Wang 92222eaf6c9SSean Wang pinctrl_select_state(bdev->pinctrl, bdev->pins_runtime); 92322eaf6c9SSean Wang 92422eaf6c9SSean Wang /* A standalone device doesn't depends on power domain on SoC, 92522eaf6c9SSean Wang * so mark it as no callbacks. 92622eaf6c9SSean Wang */ 92722eaf6c9SSean Wang pm_runtime_no_callbacks(&serdev->dev); 92822eaf6c9SSean Wang 92922eaf6c9SSean Wang set_bit(BTMTKUART_REQUIRED_WAKEUP, &bdev->tx_state); 93022eaf6c9SSean Wang } 93122eaf6c9SSean Wang 93222eaf6c9SSean Wang err = hci_register_dev(hdev); 93322eaf6c9SSean Wang if (err < 0) { 9347237c4c9SSean Wang dev_err(&serdev->dev, "Can't register HCI device\n"); 93522eaf6c9SSean Wang goto err_regulator_disable; 9367237c4c9SSean Wang } 9377237c4c9SSean Wang 9387237c4c9SSean Wang return 0; 93922eaf6c9SSean Wang 94022eaf6c9SSean Wang err_regulator_disable: 941a3cb6d60SSean Wang if (btmtkuart_is_standalone(bdev)) 94222eaf6c9SSean Wang regulator_disable(bdev->vcc); 9434803c54cSChuhong Yuan err_clk_disable_unprepare: 9444803c54cSChuhong Yuan if (btmtkuart_is_standalone(bdev)) 9454803c54cSChuhong Yuan clk_disable_unprepare(bdev->osc); 9464803c54cSChuhong Yuan err_hci_free_dev: 9474803c54cSChuhong Yuan hci_free_dev(hdev); 94822eaf6c9SSean Wang 94922eaf6c9SSean Wang return err; 9507237c4c9SSean Wang } 9517237c4c9SSean Wang 9527237c4c9SSean Wang static void btmtkuart_remove(struct serdev_device *serdev) 9537237c4c9SSean Wang { 9547237c4c9SSean Wang struct btmtkuart_dev *bdev = serdev_device_get_drvdata(serdev); 9557237c4c9SSean Wang struct hci_dev *hdev = bdev->hdev; 9567237c4c9SSean Wang 95705582561SSean Wang if (btmtkuart_is_standalone(bdev)) { 95822eaf6c9SSean Wang regulator_disable(bdev->vcc); 95905582561SSean Wang clk_disable_unprepare(bdev->osc); 96005582561SSean Wang } 96122eaf6c9SSean Wang 9627237c4c9SSean Wang hci_unregister_dev(hdev); 9637237c4c9SSean Wang hci_free_dev(hdev); 9647237c4c9SSean Wang } 9657237c4c9SSean Wang 96622eaf6c9SSean Wang static const struct btmtkuart_data mt7622_data = { 96722eaf6c9SSean Wang .fwname = FIRMWARE_MT7622, 96822eaf6c9SSean Wang }; 96922eaf6c9SSean Wang 97022eaf6c9SSean Wang static const struct btmtkuart_data mt7663_data = { 97122eaf6c9SSean Wang .flags = BTMTKUART_FLAG_STANDALONE_HW, 97222eaf6c9SSean Wang .fwname = FIRMWARE_MT7663, 97322eaf6c9SSean Wang }; 97422eaf6c9SSean Wang 97522eaf6c9SSean Wang static const struct btmtkuart_data mt7668_data = { 97622eaf6c9SSean Wang .flags = BTMTKUART_FLAG_STANDALONE_HW, 97722eaf6c9SSean Wang .fwname = FIRMWARE_MT7668, 97822eaf6c9SSean Wang }; 97922eaf6c9SSean Wang 9807237c4c9SSean Wang #ifdef CONFIG_OF 9817237c4c9SSean Wang static const struct of_device_id mtk_of_match_table[] = { 98222eaf6c9SSean Wang { .compatible = "mediatek,mt7622-bluetooth", .data = &mt7622_data}, 98322eaf6c9SSean Wang { .compatible = "mediatek,mt7663u-bluetooth", .data = &mt7663_data}, 98422eaf6c9SSean Wang { .compatible = "mediatek,mt7668u-bluetooth", .data = &mt7668_data}, 9857237c4c9SSean Wang { } 9867237c4c9SSean Wang }; 9877237c4c9SSean Wang MODULE_DEVICE_TABLE(of, mtk_of_match_table); 9887237c4c9SSean Wang #endif 9897237c4c9SSean Wang 9907237c4c9SSean Wang static struct serdev_device_driver btmtkuart_driver = { 9917237c4c9SSean Wang .probe = btmtkuart_probe, 9927237c4c9SSean Wang .remove = btmtkuart_remove, 9937237c4c9SSean Wang .driver = { 9947237c4c9SSean Wang .name = "btmtkuart", 9957237c4c9SSean Wang .of_match_table = of_match_ptr(mtk_of_match_table), 9967237c4c9SSean Wang }, 9977237c4c9SSean Wang }; 9987237c4c9SSean Wang 9997237c4c9SSean Wang module_serdev_device_driver(btmtkuart_driver); 10007237c4c9SSean Wang 10017237c4c9SSean Wang MODULE_AUTHOR("Sean Wang <sean.wang@mediatek.com>"); 10027237c4c9SSean Wang MODULE_DESCRIPTION("MediaTek Bluetooth Serial driver ver " VERSION); 10037237c4c9SSean Wang MODULE_VERSION(VERSION); 10047237c4c9SSean Wang MODULE_LICENSE("GPL"); 1005