xref: /openbmc/linux/drivers/bluetooth/btmtkuart.c (revision 0f37a5c9)
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/pinctrl/consumer.h>
217237c4c9SSean Wang #include <linux/pm_runtime.h>
2222eaf6c9SSean Wang #include <linux/regulator/consumer.h>
237237c4c9SSean Wang #include <linux/serdev.h>
247237c4c9SSean Wang #include <linux/skbuff.h>
257237c4c9SSean Wang 
267237c4c9SSean Wang #include <net/bluetooth/bluetooth.h>
277237c4c9SSean Wang #include <net/bluetooth/hci_core.h>
287237c4c9SSean Wang 
297237c4c9SSean Wang #include "h4_recv.h"
30f5c3f989SSean Wang #include "btmtk.h"
317237c4c9SSean Wang 
3222eaf6c9SSean Wang #define VERSION "0.2"
337237c4c9SSean Wang 
347237c4c9SSean Wang #define MTK_STP_TLR_SIZE	2
357237c4c9SSean Wang 
367237c4c9SSean Wang #define BTMTKUART_TX_STATE_ACTIVE	1
377237c4c9SSean Wang #define BTMTKUART_TX_STATE_WAKEUP	2
387237c4c9SSean Wang #define BTMTKUART_TX_WAIT_VND_EVT	3
3922eaf6c9SSean Wang #define BTMTKUART_REQUIRED_WAKEUP	4
4022eaf6c9SSean Wang 
4122eaf6c9SSean Wang #define BTMTKUART_FLAG_STANDALONE_HW	 BIT(0)
427237c4c9SSean Wang 
437237c4c9SSean Wang struct mtk_stp_hdr {
447237c4c9SSean Wang 	u8	prefix;
457237c4c9SSean Wang 	__be16	dlen;
467237c4c9SSean Wang 	u8	cs;
477237c4c9SSean Wang } __packed;
487237c4c9SSean Wang 
4922eaf6c9SSean Wang struct btmtkuart_data {
5022eaf6c9SSean Wang 	unsigned int flags;
5122eaf6c9SSean Wang 	const char *fwname;
5222eaf6c9SSean Wang };
5322eaf6c9SSean Wang 
547237c4c9SSean Wang struct btmtkuart_dev {
557237c4c9SSean Wang 	struct hci_dev *hdev;
567237c4c9SSean Wang 	struct serdev_device *serdev;
577237c4c9SSean Wang 
5805582561SSean Wang 	struct clk *clk;
5905582561SSean Wang 	struct clk *osc;
6022eaf6c9SSean Wang 	struct regulator *vcc;
6122eaf6c9SSean Wang 	struct gpio_desc *reset;
62a3cb6d60SSean Wang 	struct gpio_desc *boot;
6322eaf6c9SSean Wang 	struct pinctrl *pinctrl;
6422eaf6c9SSean Wang 	struct pinctrl_state *pins_runtime;
6522eaf6c9SSean Wang 	struct pinctrl_state *pins_boot;
6622eaf6c9SSean Wang 	speed_t	desired_speed;
6722eaf6c9SSean Wang 	speed_t	curr_speed;
6822eaf6c9SSean Wang 
697237c4c9SSean Wang 	struct work_struct tx_work;
707237c4c9SSean Wang 	unsigned long tx_state;
717237c4c9SSean Wang 	struct sk_buff_head txq;
727237c4c9SSean Wang 
737237c4c9SSean Wang 	struct sk_buff *rx_skb;
74e0b67035SSean Wang 	struct sk_buff *evt_skb;
757237c4c9SSean Wang 
767237c4c9SSean Wang 	u8	stp_pad[6];
777237c4c9SSean Wang 	u8	stp_cursor;
787237c4c9SSean Wang 	u16	stp_dlen;
7922eaf6c9SSean Wang 
8022eaf6c9SSean Wang 	const struct btmtkuart_data *data;
817237c4c9SSean Wang };
827237c4c9SSean Wang 
8322eaf6c9SSean Wang #define btmtkuart_is_standalone(bdev)	\
8422eaf6c9SSean Wang 	((bdev)->data->flags & BTMTKUART_FLAG_STANDALONE_HW)
8522eaf6c9SSean Wang #define btmtkuart_is_builtin_soc(bdev)	\
8622eaf6c9SSean Wang 	!((bdev)->data->flags & BTMTKUART_FLAG_STANDALONE_HW)
8722eaf6c9SSean Wang 
mtk_hci_wmt_sync(struct hci_dev * hdev,struct btmtk_hci_wmt_params * wmt_params)8888e5f366SSean Wang static int mtk_hci_wmt_sync(struct hci_dev *hdev,
8988e5f366SSean Wang 			    struct btmtk_hci_wmt_params *wmt_params)
907237c4c9SSean Wang {
917237c4c9SSean Wang 	struct btmtkuart_dev *bdev = hci_get_drvdata(hdev);
92e0b67035SSean Wang 	struct btmtk_hci_wmt_evt_funcc *wmt_evt_funcc;
93e0b67035SSean Wang 	u32 hlen, status = BTMTK_WMT_INVALID;
94e0b67035SSean Wang 	struct btmtk_hci_wmt_evt *wmt_evt;
95f5c3f989SSean Wang 	struct btmtk_hci_wmt_cmd *wc;
96f5c3f989SSean Wang 	struct btmtk_wmt_hdr *hdr;
977237c4c9SSean Wang 	int err;
987237c4c9SSean Wang 
99f5c3f989SSean Wang 	/* Send the WMT command and wait until the WMT event returns */
10088e5f366SSean Wang 	hlen = sizeof(*hdr) + wmt_params->dlen;
1013e5f2d90SDinghao Liu 	if (hlen > 255) {
1023e5f2d90SDinghao Liu 		err = -EINVAL;
1033e5f2d90SDinghao Liu 		goto err_free_skb;
1043e5f2d90SDinghao Liu 	}
1057237c4c9SSean Wang 
106f5c3f989SSean Wang 	wc = kzalloc(hlen, GFP_KERNEL);
107a76d269aSDan Carpenter 	if (!wc) {
108a76d269aSDan Carpenter 		err = -ENOMEM;
109a76d269aSDan Carpenter 		goto err_free_skb;
110a76d269aSDan Carpenter 	}
111f5c3f989SSean Wang 
112f5c3f989SSean Wang 	hdr = &wc->hdr;
1137237c4c9SSean Wang 	hdr->dir = 1;
11488e5f366SSean Wang 	hdr->op = wmt_params->op;
11588e5f366SSean Wang 	hdr->dlen = cpu_to_le16(wmt_params->dlen + 1);
11688e5f366SSean Wang 	hdr->flag = wmt_params->flag;
117f5c3f989SSean Wang 	memcpy(wc->data, wmt_params->data, wmt_params->dlen);
1187237c4c9SSean Wang 
1197237c4c9SSean Wang 	set_bit(BTMTKUART_TX_WAIT_VND_EVT, &bdev->tx_state);
1207237c4c9SSean Wang 
121f5c3f989SSean Wang 	err = __hci_cmd_send(hdev, 0xfc6f, hlen, wc);
1227237c4c9SSean Wang 	if (err < 0) {
1237237c4c9SSean Wang 		clear_bit(BTMTKUART_TX_WAIT_VND_EVT, &bdev->tx_state);
124f5c3f989SSean Wang 		goto err_free_wc;
1257237c4c9SSean Wang 	}
1267237c4c9SSean Wang 
1277237c4c9SSean Wang 	/* The vendor specific WMT commands are all answered by a vendor
1287237c4c9SSean Wang 	 * specific event and will not have the Command Status or Command
1297237c4c9SSean Wang 	 * Complete as with usual HCI command flow control.
1307237c4c9SSean Wang 	 *
1317237c4c9SSean Wang 	 * After sending the command, wait for BTMTKUART_TX_WAIT_VND_EVT
132adf5d730SSean Wang 	 * state to be cleared. The driver specific event receive routine
1337237c4c9SSean Wang 	 * will clear that state and with that indicate completion of the
1347237c4c9SSean Wang 	 * WMT command.
1357237c4c9SSean Wang 	 */
1367237c4c9SSean Wang 	err = wait_on_bit_timeout(&bdev->tx_state, BTMTKUART_TX_WAIT_VND_EVT,
1377237c4c9SSean Wang 				  TASK_INTERRUPTIBLE, HCI_INIT_TIMEOUT);
1387237c4c9SSean Wang 	if (err == -EINTR) {
1397237c4c9SSean Wang 		bt_dev_err(hdev, "Execution of wmt command interrupted");
14077f328dbSSean Wang 		clear_bit(BTMTKUART_TX_WAIT_VND_EVT, &bdev->tx_state);
141f5c3f989SSean Wang 		goto err_free_wc;
1427237c4c9SSean Wang 	}
1437237c4c9SSean Wang 
1447237c4c9SSean Wang 	if (err) {
1457237c4c9SSean Wang 		bt_dev_err(hdev, "Execution of wmt command timed out");
14677f328dbSSean Wang 		clear_bit(BTMTKUART_TX_WAIT_VND_EVT, &bdev->tx_state);
1473e5f2d90SDinghao Liu 		err = -ETIMEDOUT;
148f5c3f989SSean Wang 		goto err_free_wc;
1497237c4c9SSean Wang 	}
1507237c4c9SSean Wang 
151e0b67035SSean Wang 	/* Parse and handle the return WMT event */
152e0b67035SSean Wang 	wmt_evt = (struct btmtk_hci_wmt_evt *)bdev->evt_skb->data;
153e0b67035SSean Wang 	if (wmt_evt->whdr.op != hdr->op) {
154e0b67035SSean Wang 		bt_dev_err(hdev, "Wrong op received %d expected %d",
155e0b67035SSean Wang 			   wmt_evt->whdr.op, hdr->op);
156e0b67035SSean Wang 		err = -EIO;
157a76d269aSDan Carpenter 		goto err_free_wc;
158e0b67035SSean Wang 	}
159e0b67035SSean Wang 
160e0b67035SSean Wang 	switch (wmt_evt->whdr.op) {
161f5c3f989SSean Wang 	case BTMTK_WMT_SEMAPHORE:
162e0b67035SSean Wang 		if (wmt_evt->whdr.flag == 2)
163e0b67035SSean Wang 			status = BTMTK_WMT_PATCH_UNDONE;
164e0b67035SSean Wang 		else
165e0b67035SSean Wang 			status = BTMTK_WMT_PATCH_DONE;
166e0b67035SSean Wang 		break;
167f5c3f989SSean Wang 	case BTMTK_WMT_FUNC_CTRL:
168e0b67035SSean Wang 		wmt_evt_funcc = (struct btmtk_hci_wmt_evt_funcc *)wmt_evt;
169e0b67035SSean Wang 		if (be16_to_cpu(wmt_evt_funcc->status) == 0x404)
170e0b67035SSean Wang 			status = BTMTK_WMT_ON_DONE;
171e0b67035SSean Wang 		else if (be16_to_cpu(wmt_evt_funcc->status) == 0x420)
172e0b67035SSean Wang 			status = BTMTK_WMT_ON_PROGRESS;
173e0b67035SSean Wang 		else
174e0b67035SSean Wang 			status = BTMTK_WMT_ON_UNDONE;
175e0b67035SSean Wang 		break;
176e0b67035SSean Wang 	}
177e0b67035SSean Wang 
178e0b67035SSean Wang 	if (wmt_params->status)
179e0b67035SSean Wang 		*wmt_params->status = status;
180e0b67035SSean Wang 
181a76d269aSDan Carpenter err_free_wc:
182a76d269aSDan Carpenter 	kfree(wc);
183e0b67035SSean Wang err_free_skb:
184e0b67035SSean Wang 	kfree_skb(bdev->evt_skb);
185e0b67035SSean Wang 	bdev->evt_skb = NULL;
186e0b67035SSean Wang 
187e0b67035SSean Wang 	return err;
1887237c4c9SSean Wang }
1897237c4c9SSean Wang 
btmtkuart_recv_event(struct hci_dev * hdev,struct sk_buff * skb)1907237c4c9SSean Wang static int btmtkuart_recv_event(struct hci_dev *hdev, struct sk_buff *skb)
1917237c4c9SSean Wang {
1927237c4c9SSean Wang 	struct btmtkuart_dev *bdev = hci_get_drvdata(hdev);
1937237c4c9SSean Wang 	struct hci_event_hdr *hdr = (void *)skb->data;
1947237c4c9SSean Wang 	int err;
1957237c4c9SSean Wang 
196e0b67035SSean Wang 	/* When someone waits for the WMT event, the skb is being cloned
197e0b67035SSean Wang 	 * and being processed the events from there then.
198e0b67035SSean Wang 	 */
199e0b67035SSean Wang 	if (test_bit(BTMTKUART_TX_WAIT_VND_EVT, &bdev->tx_state)) {
200e0b67035SSean Wang 		bdev->evt_skb = skb_clone(skb, GFP_KERNEL);
201e0b67035SSean Wang 		if (!bdev->evt_skb) {
202e0b67035SSean Wang 			err = -ENOMEM;
203e0b67035SSean Wang 			goto err_out;
204e0b67035SSean Wang 		}
205e0b67035SSean Wang 	}
206e0b67035SSean Wang 
2077237c4c9SSean Wang 	err = hci_recv_frame(hdev, skb);
208e0b67035SSean Wang 	if (err < 0)
209e0b67035SSean Wang 		goto err_free_skb;
2107237c4c9SSean Wang 
2116ac034a7SSean Wang 	if (hdr->evt == HCI_EV_WMT) {
2127237c4c9SSean Wang 		if (test_and_clear_bit(BTMTKUART_TX_WAIT_VND_EVT,
2137237c4c9SSean Wang 				       &bdev->tx_state)) {
2147237c4c9SSean Wang 			/* Barrier to sync with other CPUs */
2157237c4c9SSean Wang 			smp_mb__after_atomic();
2167237c4c9SSean Wang 			wake_up_bit(&bdev->tx_state, BTMTKUART_TX_WAIT_VND_EVT);
2177237c4c9SSean Wang 		}
2187237c4c9SSean Wang 	}
2197237c4c9SSean Wang 
220e0b67035SSean Wang 	return 0;
221e0b67035SSean Wang 
222e0b67035SSean Wang err_free_skb:
223e0b67035SSean Wang 	kfree_skb(bdev->evt_skb);
224e0b67035SSean Wang 	bdev->evt_skb = NULL;
225e0b67035SSean Wang 
226e0b67035SSean Wang err_out:
2277237c4c9SSean Wang 	return err;
2287237c4c9SSean Wang }
2297237c4c9SSean Wang 
2307237c4c9SSean Wang static const struct h4_recv_pkt mtk_recv_pkts[] = {
2317237c4c9SSean Wang 	{ H4_RECV_ACL,      .recv = hci_recv_frame },
2327237c4c9SSean Wang 	{ H4_RECV_SCO,      .recv = hci_recv_frame },
2337237c4c9SSean Wang 	{ H4_RECV_EVENT,    .recv = btmtkuart_recv_event },
2347237c4c9SSean Wang };
2357237c4c9SSean Wang 
btmtkuart_tx_work(struct work_struct * work)2367237c4c9SSean Wang static void btmtkuart_tx_work(struct work_struct *work)
2377237c4c9SSean Wang {
2387237c4c9SSean Wang 	struct btmtkuart_dev *bdev = container_of(work, struct btmtkuart_dev,
2397237c4c9SSean Wang 						   tx_work);
2407237c4c9SSean Wang 	struct serdev_device *serdev = bdev->serdev;
2417237c4c9SSean Wang 	struct hci_dev *hdev = bdev->hdev;
2427237c4c9SSean Wang 
2437237c4c9SSean Wang 	while (1) {
2447237c4c9SSean Wang 		clear_bit(BTMTKUART_TX_STATE_WAKEUP, &bdev->tx_state);
2457237c4c9SSean Wang 
2467237c4c9SSean Wang 		while (1) {
2477237c4c9SSean Wang 			struct sk_buff *skb = skb_dequeue(&bdev->txq);
2487237c4c9SSean Wang 			int len;
2497237c4c9SSean Wang 
2507237c4c9SSean Wang 			if (!skb)
2517237c4c9SSean Wang 				break;
2527237c4c9SSean Wang 
2537237c4c9SSean Wang 			len = serdev_device_write_buf(serdev, skb->data,
2547237c4c9SSean Wang 						      skb->len);
2557237c4c9SSean Wang 			hdev->stat.byte_tx += len;
2567237c4c9SSean Wang 
2577237c4c9SSean Wang 			skb_pull(skb, len);
2587237c4c9SSean Wang 			if (skb->len > 0) {
2597237c4c9SSean Wang 				skb_queue_head(&bdev->txq, skb);
2607237c4c9SSean Wang 				break;
2617237c4c9SSean Wang 			}
2627237c4c9SSean Wang 
2637237c4c9SSean Wang 			switch (hci_skb_pkt_type(skb)) {
2647237c4c9SSean Wang 			case HCI_COMMAND_PKT:
2657237c4c9SSean Wang 				hdev->stat.cmd_tx++;
2667237c4c9SSean Wang 				break;
2677237c4c9SSean Wang 			case HCI_ACLDATA_PKT:
2687237c4c9SSean Wang 				hdev->stat.acl_tx++;
2697237c4c9SSean Wang 				break;
2707237c4c9SSean Wang 			case HCI_SCODATA_PKT:
2717237c4c9SSean Wang 				hdev->stat.sco_tx++;
2727237c4c9SSean Wang 				break;
2737237c4c9SSean Wang 			}
2747237c4c9SSean Wang 
2757237c4c9SSean Wang 			kfree_skb(skb);
2767237c4c9SSean Wang 		}
2777237c4c9SSean Wang 
2787237c4c9SSean Wang 		if (!test_bit(BTMTKUART_TX_STATE_WAKEUP, &bdev->tx_state))
2797237c4c9SSean Wang 			break;
2807237c4c9SSean Wang 	}
2817237c4c9SSean Wang 
2827237c4c9SSean Wang 	clear_bit(BTMTKUART_TX_STATE_ACTIVE, &bdev->tx_state);
2837237c4c9SSean Wang }
2847237c4c9SSean Wang 
btmtkuart_tx_wakeup(struct btmtkuart_dev * bdev)2857237c4c9SSean Wang static void btmtkuart_tx_wakeup(struct btmtkuart_dev *bdev)
2867237c4c9SSean Wang {
2877237c4c9SSean Wang 	if (test_and_set_bit(BTMTKUART_TX_STATE_ACTIVE, &bdev->tx_state))
2887237c4c9SSean Wang 		set_bit(BTMTKUART_TX_STATE_WAKEUP, &bdev->tx_state);
2897237c4c9SSean Wang 
2907237c4c9SSean Wang 	schedule_work(&bdev->tx_work);
2917237c4c9SSean Wang }
2927237c4c9SSean Wang 
2937237c4c9SSean Wang static const unsigned char *
mtk_stp_split(struct btmtkuart_dev * bdev,const unsigned char * data,int count,int * sz_h4)2947237c4c9SSean Wang mtk_stp_split(struct btmtkuart_dev *bdev, const unsigned char *data, int count,
2957237c4c9SSean Wang 	      int *sz_h4)
2967237c4c9SSean Wang {
2977237c4c9SSean Wang 	struct mtk_stp_hdr *shdr;
2987237c4c9SSean Wang 
2997237c4c9SSean Wang 	/* The cursor is reset when all the data of STP is consumed out */
3007237c4c9SSean Wang 	if (!bdev->stp_dlen && bdev->stp_cursor >= 6)
3017237c4c9SSean Wang 		bdev->stp_cursor = 0;
3027237c4c9SSean Wang 
3037237c4c9SSean Wang 	/* Filling pad until all STP info is obtained */
3047237c4c9SSean Wang 	while (bdev->stp_cursor < 6 && count > 0) {
3057237c4c9SSean Wang 		bdev->stp_pad[bdev->stp_cursor] = *data;
3067237c4c9SSean Wang 		bdev->stp_cursor++;
3077237c4c9SSean Wang 		data++;
3087237c4c9SSean Wang 		count--;
3097237c4c9SSean Wang 	}
3107237c4c9SSean Wang 
3117237c4c9SSean Wang 	/* Retrieve STP info and have a sanity check */
3127237c4c9SSean Wang 	if (!bdev->stp_dlen && bdev->stp_cursor >= 6) {
3137237c4c9SSean Wang 		shdr = (struct mtk_stp_hdr *)&bdev->stp_pad[2];
3147237c4c9SSean Wang 		bdev->stp_dlen = be16_to_cpu(shdr->dlen) & 0x0fff;
3157237c4c9SSean Wang 
3167237c4c9SSean Wang 		/* Resync STP when unexpected data is being read */
3177237c4c9SSean Wang 		if (shdr->prefix != 0x80 || bdev->stp_dlen > 2048) {
3187237c4c9SSean Wang 			bt_dev_err(bdev->hdev, "stp format unexpect (%d, %d)",
3197237c4c9SSean Wang 				   shdr->prefix, bdev->stp_dlen);
3207237c4c9SSean Wang 			bdev->stp_cursor = 2;
3217237c4c9SSean Wang 			bdev->stp_dlen = 0;
3227237c4c9SSean Wang 		}
3237237c4c9SSean Wang 	}
3247237c4c9SSean Wang 
3257237c4c9SSean Wang 	/* Directly quit when there's no data found for H4 can process */
3267237c4c9SSean Wang 	if (count <= 0)
3277237c4c9SSean Wang 		return NULL;
3287237c4c9SSean Wang 
3297237c4c9SSean Wang 	/* Tranlate to how much the size of data H4 can handle so far */
3307237c4c9SSean Wang 	*sz_h4 = min_t(int, count, bdev->stp_dlen);
3317237c4c9SSean Wang 
3327237c4c9SSean Wang 	/* Update the remaining size of STP packet */
3337237c4c9SSean Wang 	bdev->stp_dlen -= *sz_h4;
3347237c4c9SSean Wang 
3357237c4c9SSean Wang 	/* Data points to STP payload which can be handled by H4 */
3367237c4c9SSean Wang 	return data;
3377237c4c9SSean Wang }
3387237c4c9SSean Wang 
btmtkuart_recv(struct hci_dev * hdev,const u8 * data,size_t count)339*0f37a5c9SFrancesco Dolcini static void btmtkuart_recv(struct hci_dev *hdev, const u8 *data, size_t count)
3407237c4c9SSean Wang {
3417237c4c9SSean Wang 	struct btmtkuart_dev *bdev = hci_get_drvdata(hdev);
3427237c4c9SSean Wang 	const unsigned char *p_left = data, *p_h4;
3437237c4c9SSean Wang 	int sz_left = count, sz_h4, adv;
3447237c4c9SSean Wang 	int err;
3457237c4c9SSean Wang 
3467237c4c9SSean Wang 	while (sz_left > 0) {
3477237c4c9SSean Wang 		/*  The serial data received from MT7622 BT controller is
3487237c4c9SSean Wang 		 *  at all time padded around with the STP header and tailer.
3497237c4c9SSean Wang 		 *
3507237c4c9SSean Wang 		 *  A full STP packet is looking like
3517237c4c9SSean Wang 		 *   -----------------------------------
3527237c4c9SSean Wang 		 *  | STP header  |  H:4   | STP tailer |
3537237c4c9SSean Wang 		 *   -----------------------------------
3547237c4c9SSean Wang 		 *  but it doesn't guarantee to contain a full H:4 packet which
3557237c4c9SSean Wang 		 *  means that it's possible for multiple STP packets forms a
3567237c4c9SSean Wang 		 *  full H:4 packet that means extra STP header + length doesn't
3577237c4c9SSean Wang 		 *  indicate a full H:4 frame, things can fragment. Whose length
3587237c4c9SSean Wang 		 *  recorded in STP header just shows up the most length the
3597237c4c9SSean Wang 		 *  H:4 engine can handle currently.
3607237c4c9SSean Wang 		 */
3617237c4c9SSean Wang 
3627237c4c9SSean Wang 		p_h4 = mtk_stp_split(bdev, p_left, sz_left, &sz_h4);
3637237c4c9SSean Wang 		if (!p_h4)
3647237c4c9SSean Wang 			break;
3657237c4c9SSean Wang 
3667237c4c9SSean Wang 		adv = p_h4 - p_left;
3677237c4c9SSean Wang 		sz_left -= adv;
3687237c4c9SSean Wang 		p_left += adv;
3697237c4c9SSean Wang 
3707237c4c9SSean Wang 		bdev->rx_skb = h4_recv_buf(bdev->hdev, bdev->rx_skb, p_h4,
3717237c4c9SSean Wang 					   sz_h4, mtk_recv_pkts,
372330ad75fSDan Carpenter 					   ARRAY_SIZE(mtk_recv_pkts));
3737237c4c9SSean Wang 		if (IS_ERR(bdev->rx_skb)) {
3747237c4c9SSean Wang 			err = PTR_ERR(bdev->rx_skb);
3757237c4c9SSean Wang 			bt_dev_err(bdev->hdev,
3767237c4c9SSean Wang 				   "Frame reassembly failed (%d)", err);
3777237c4c9SSean Wang 			bdev->rx_skb = NULL;
378*0f37a5c9SFrancesco Dolcini 			return;
3797237c4c9SSean Wang 		}
3807237c4c9SSean Wang 
3817237c4c9SSean Wang 		sz_left -= sz_h4;
3827237c4c9SSean Wang 		p_left += sz_h4;
3837237c4c9SSean Wang 	}
3847237c4c9SSean Wang }
3857237c4c9SSean Wang 
btmtkuart_receive_buf(struct serdev_device * serdev,const u8 * data,size_t count)3867237c4c9SSean Wang static int btmtkuart_receive_buf(struct serdev_device *serdev, const u8 *data,
3877237c4c9SSean Wang 				 size_t count)
3887237c4c9SSean Wang {
3897237c4c9SSean Wang 	struct btmtkuart_dev *bdev = serdev_device_get_drvdata(serdev);
3907237c4c9SSean Wang 
391*0f37a5c9SFrancesco Dolcini 	btmtkuart_recv(bdev->hdev, data, count);
3927237c4c9SSean Wang 
3937237c4c9SSean Wang 	bdev->hdev->stat.byte_rx += count;
3947237c4c9SSean Wang 
3957237c4c9SSean Wang 	return count;
3967237c4c9SSean Wang }
3977237c4c9SSean Wang 
btmtkuart_write_wakeup(struct serdev_device * serdev)3987237c4c9SSean Wang static void btmtkuart_write_wakeup(struct serdev_device *serdev)
3997237c4c9SSean Wang {
4007237c4c9SSean Wang 	struct btmtkuart_dev *bdev = serdev_device_get_drvdata(serdev);
4017237c4c9SSean Wang 
4027237c4c9SSean Wang 	btmtkuart_tx_wakeup(bdev);
4037237c4c9SSean Wang }
4047237c4c9SSean Wang 
4057237c4c9SSean Wang static const struct serdev_device_ops btmtkuart_client_ops = {
4067237c4c9SSean Wang 	.receive_buf = btmtkuart_receive_buf,
4077237c4c9SSean Wang 	.write_wakeup = btmtkuart_write_wakeup,
4087237c4c9SSean Wang };
4097237c4c9SSean Wang 
btmtkuart_open(struct hci_dev * hdev)4107237c4c9SSean Wang static int btmtkuart_open(struct hci_dev *hdev)
4117237c4c9SSean Wang {
4127237c4c9SSean Wang 	struct btmtkuart_dev *bdev = hci_get_drvdata(hdev);
4137237c4c9SSean Wang 	struct device *dev;
4147237c4c9SSean Wang 	int err;
4157237c4c9SSean Wang 
4167237c4c9SSean Wang 	err = serdev_device_open(bdev->serdev);
4177237c4c9SSean Wang 	if (err) {
4187237c4c9SSean Wang 		bt_dev_err(hdev, "Unable to open UART device %s",
4197237c4c9SSean Wang 			   dev_name(&bdev->serdev->dev));
4207237c4c9SSean Wang 		goto err_open;
4217237c4c9SSean Wang 	}
4227237c4c9SSean Wang 
42322eaf6c9SSean Wang 	if (btmtkuart_is_standalone(bdev)) {
42422eaf6c9SSean Wang 		if (bdev->curr_speed != bdev->desired_speed)
42522eaf6c9SSean Wang 			err = serdev_device_set_baudrate(bdev->serdev,
42622eaf6c9SSean Wang 							 115200);
42722eaf6c9SSean Wang 		else
42822eaf6c9SSean Wang 			err = serdev_device_set_baudrate(bdev->serdev,
42922eaf6c9SSean Wang 							 bdev->desired_speed);
43022eaf6c9SSean Wang 
43122eaf6c9SSean Wang 		if (err < 0) {
43222eaf6c9SSean Wang 			bt_dev_err(hdev, "Unable to set baudrate UART device %s",
43322eaf6c9SSean Wang 				   dev_name(&bdev->serdev->dev));
43422eaf6c9SSean Wang 			goto  err_serdev_close;
43522eaf6c9SSean Wang 		}
43622eaf6c9SSean Wang 
43722eaf6c9SSean Wang 		serdev_device_set_flow_control(bdev->serdev, false);
43822eaf6c9SSean Wang 	}
43922eaf6c9SSean Wang 
4407237c4c9SSean Wang 	bdev->stp_cursor = 2;
4417237c4c9SSean Wang 	bdev->stp_dlen = 0;
4427237c4c9SSean Wang 
4437237c4c9SSean Wang 	dev = &bdev->serdev->dev;
4447237c4c9SSean Wang 
4457237c4c9SSean Wang 	/* Enable the power domain and clock the device requires */
4467237c4c9SSean Wang 	pm_runtime_enable(dev);
447a1b2fdf9SZhang Qilong 	err = pm_runtime_resume_and_get(dev);
448a1b2fdf9SZhang Qilong 	if (err < 0)
4497237c4c9SSean Wang 		goto err_disable_rpm;
4507237c4c9SSean Wang 
4517237c4c9SSean Wang 	err = clk_prepare_enable(bdev->clk);
4527237c4c9SSean Wang 	if (err < 0)
4537237c4c9SSean Wang 		goto err_put_rpm;
4547237c4c9SSean Wang 
4557237c4c9SSean Wang 	return 0;
4567237c4c9SSean Wang 
4577237c4c9SSean Wang err_put_rpm:
4587237c4c9SSean Wang 	pm_runtime_put_sync(dev);
4597237c4c9SSean Wang err_disable_rpm:
4607237c4c9SSean Wang 	pm_runtime_disable(dev);
46122eaf6c9SSean Wang err_serdev_close:
46222eaf6c9SSean Wang 	serdev_device_close(bdev->serdev);
4637237c4c9SSean Wang err_open:
4647237c4c9SSean Wang 	return err;
4657237c4c9SSean Wang }
4667237c4c9SSean Wang 
btmtkuart_close(struct hci_dev * hdev)4677237c4c9SSean Wang static int btmtkuart_close(struct hci_dev *hdev)
4687237c4c9SSean Wang {
4697237c4c9SSean Wang 	struct btmtkuart_dev *bdev = hci_get_drvdata(hdev);
4707237c4c9SSean Wang 	struct device *dev = &bdev->serdev->dev;
4717237c4c9SSean Wang 
4727237c4c9SSean Wang 	/* Shutdown the clock and power domain the device requires */
4737237c4c9SSean Wang 	clk_disable_unprepare(bdev->clk);
4747237c4c9SSean Wang 	pm_runtime_put_sync(dev);
4757237c4c9SSean Wang 	pm_runtime_disable(dev);
4767237c4c9SSean Wang 
4777237c4c9SSean Wang 	serdev_device_close(bdev->serdev);
4787237c4c9SSean Wang 
4797237c4c9SSean Wang 	return 0;
4807237c4c9SSean Wang }
4817237c4c9SSean Wang 
btmtkuart_flush(struct hci_dev * hdev)4827237c4c9SSean Wang static int btmtkuart_flush(struct hci_dev *hdev)
4837237c4c9SSean Wang {
4847237c4c9SSean Wang 	struct btmtkuart_dev *bdev = hci_get_drvdata(hdev);
4857237c4c9SSean Wang 
4867237c4c9SSean Wang 	/* Flush any pending characters */
4877237c4c9SSean Wang 	serdev_device_write_flush(bdev->serdev);
4887237c4c9SSean Wang 	skb_queue_purge(&bdev->txq);
4897237c4c9SSean Wang 
4907237c4c9SSean Wang 	cancel_work_sync(&bdev->tx_work);
4917237c4c9SSean Wang 
4927237c4c9SSean Wang 	kfree_skb(bdev->rx_skb);
4937237c4c9SSean Wang 	bdev->rx_skb = NULL;
4947237c4c9SSean Wang 
4957237c4c9SSean Wang 	bdev->stp_cursor = 2;
4967237c4c9SSean Wang 	bdev->stp_dlen = 0;
4977237c4c9SSean Wang 
4987237c4c9SSean Wang 	return 0;
4997237c4c9SSean Wang }
5007237c4c9SSean Wang 
btmtkuart_func_query(struct hci_dev * hdev)501e0b67035SSean Wang static int btmtkuart_func_query(struct hci_dev *hdev)
502e0b67035SSean Wang {
503e0b67035SSean Wang 	struct btmtk_hci_wmt_params wmt_params;
504e0b67035SSean Wang 	int status, err;
505e0b67035SSean Wang 	u8 param = 0;
506e0b67035SSean Wang 
507e0b67035SSean Wang 	/* Query whether the function is enabled */
508f5c3f989SSean Wang 	wmt_params.op = BTMTK_WMT_FUNC_CTRL;
509e0b67035SSean Wang 	wmt_params.flag = 4;
510e0b67035SSean Wang 	wmt_params.dlen = sizeof(param);
511e0b67035SSean Wang 	wmt_params.data = &param;
512e0b67035SSean Wang 	wmt_params.status = &status;
513e0b67035SSean Wang 
514e0b67035SSean Wang 	err = mtk_hci_wmt_sync(hdev, &wmt_params);
515e0b67035SSean Wang 	if (err < 0) {
516e0b67035SSean Wang 		bt_dev_err(hdev, "Failed to query function status (%d)", err);
517e0b67035SSean Wang 		return err;
518e0b67035SSean Wang 	}
519e0b67035SSean Wang 
520e0b67035SSean Wang 	return status;
521e0b67035SSean Wang }
522e0b67035SSean Wang 
btmtkuart_change_baudrate(struct hci_dev * hdev)52322eaf6c9SSean Wang static int btmtkuart_change_baudrate(struct hci_dev *hdev)
52422eaf6c9SSean Wang {
52522eaf6c9SSean Wang 	struct btmtkuart_dev *bdev = hci_get_drvdata(hdev);
52622eaf6c9SSean Wang 	struct btmtk_hci_wmt_params wmt_params;
527cac63f9bSSean Wang 	__le32 baudrate;
52822eaf6c9SSean Wang 	u8 param;
52922eaf6c9SSean Wang 	int err;
53022eaf6c9SSean Wang 
53122eaf6c9SSean Wang 	/* Indicate the device to enter the probe state the host is
53222eaf6c9SSean Wang 	 * ready to change a new baudrate.
53322eaf6c9SSean Wang 	 */
53422eaf6c9SSean Wang 	baudrate = cpu_to_le32(bdev->desired_speed);
535f5c3f989SSean Wang 	wmt_params.op = BTMTK_WMT_HIF;
53622eaf6c9SSean Wang 	wmt_params.flag = 1;
53722eaf6c9SSean Wang 	wmt_params.dlen = 4;
53822eaf6c9SSean Wang 	wmt_params.data = &baudrate;
53922eaf6c9SSean Wang 	wmt_params.status = NULL;
54022eaf6c9SSean Wang 
54122eaf6c9SSean Wang 	err = mtk_hci_wmt_sync(hdev, &wmt_params);
54222eaf6c9SSean Wang 	if (err < 0) {
54322eaf6c9SSean Wang 		bt_dev_err(hdev, "Failed to device baudrate (%d)", err);
54422eaf6c9SSean Wang 		return err;
54522eaf6c9SSean Wang 	}
54622eaf6c9SSean Wang 
54722eaf6c9SSean Wang 	err = serdev_device_set_baudrate(bdev->serdev,
54822eaf6c9SSean Wang 					 bdev->desired_speed);
54922eaf6c9SSean Wang 	if (err < 0) {
55022eaf6c9SSean Wang 		bt_dev_err(hdev, "Failed to set up host baudrate (%d)",
55122eaf6c9SSean Wang 			   err);
55222eaf6c9SSean Wang 		return err;
55322eaf6c9SSean Wang 	}
55422eaf6c9SSean Wang 
55522eaf6c9SSean Wang 	serdev_device_set_flow_control(bdev->serdev, false);
55622eaf6c9SSean Wang 
55722eaf6c9SSean Wang 	/* Send a dummy byte 0xff to activate the new baudrate */
55822eaf6c9SSean Wang 	param = 0xff;
559d3a0fe6bSZijun Hu 	err = serdev_device_write_buf(bdev->serdev, &param, sizeof(param));
56022eaf6c9SSean Wang 	if (err < 0 || err < sizeof(param))
56122eaf6c9SSean Wang 		return err;
56222eaf6c9SSean Wang 
56322eaf6c9SSean Wang 	serdev_device_wait_until_sent(bdev->serdev, 0);
56422eaf6c9SSean Wang 
56522eaf6c9SSean Wang 	/* Wait some time for the device changing baudrate done */
56622eaf6c9SSean Wang 	usleep_range(20000, 22000);
56722eaf6c9SSean Wang 
56822eaf6c9SSean Wang 	/* Test the new baudrate */
569f5c3f989SSean Wang 	wmt_params.op = BTMTK_WMT_TEST;
57022eaf6c9SSean Wang 	wmt_params.flag = 7;
57122eaf6c9SSean Wang 	wmt_params.dlen = 0;
57222eaf6c9SSean Wang 	wmt_params.data = NULL;
57322eaf6c9SSean Wang 	wmt_params.status = NULL;
57422eaf6c9SSean Wang 
57522eaf6c9SSean Wang 	err = mtk_hci_wmt_sync(hdev, &wmt_params);
57622eaf6c9SSean Wang 	if (err < 0) {
57722eaf6c9SSean Wang 		bt_dev_err(hdev, "Failed to test new baudrate (%d)",
57822eaf6c9SSean Wang 			   err);
57922eaf6c9SSean Wang 		return err;
58022eaf6c9SSean Wang 	}
58122eaf6c9SSean Wang 
58222eaf6c9SSean Wang 	bdev->curr_speed = bdev->desired_speed;
58322eaf6c9SSean Wang 
58422eaf6c9SSean Wang 	return 0;
58522eaf6c9SSean Wang }
58622eaf6c9SSean Wang 
btmtkuart_setup(struct hci_dev * hdev)5877237c4c9SSean Wang static int btmtkuart_setup(struct hci_dev *hdev)
5887237c4c9SSean Wang {
58922eaf6c9SSean Wang 	struct btmtkuart_dev *bdev = hci_get_drvdata(hdev);
59088e5f366SSean Wang 	struct btmtk_hci_wmt_params wmt_params;
591e0b67035SSean Wang 	ktime_t calltime, delta, rettime;
592e0b67035SSean Wang 	struct btmtk_tci_sleep tci_sleep;
593e0b67035SSean Wang 	unsigned long long duration;
594e0b67035SSean Wang 	struct sk_buff *skb;
595e0b67035SSean Wang 	int err, status;
5967237c4c9SSean Wang 	u8 param = 0x1;
597e0b67035SSean Wang 
598e0b67035SSean Wang 	calltime = ktime_get();
599e0b67035SSean Wang 
60022eaf6c9SSean Wang 	/* Wakeup MCUSYS is required for certain devices before we start to
60122eaf6c9SSean Wang 	 * do any setups.
60222eaf6c9SSean Wang 	 */
60322eaf6c9SSean Wang 	if (test_bit(BTMTKUART_REQUIRED_WAKEUP, &bdev->tx_state)) {
604f5c3f989SSean Wang 		wmt_params.op = BTMTK_WMT_WAKEUP;
60522eaf6c9SSean Wang 		wmt_params.flag = 3;
60622eaf6c9SSean Wang 		wmt_params.dlen = 0;
60722eaf6c9SSean Wang 		wmt_params.data = NULL;
60822eaf6c9SSean Wang 		wmt_params.status = NULL;
60922eaf6c9SSean Wang 
61022eaf6c9SSean Wang 		err = mtk_hci_wmt_sync(hdev, &wmt_params);
61122eaf6c9SSean Wang 		if (err < 0) {
61222eaf6c9SSean Wang 			bt_dev_err(hdev, "Failed to wakeup the chip (%d)", err);
61322eaf6c9SSean Wang 			return err;
61422eaf6c9SSean Wang 		}
61522eaf6c9SSean Wang 
61622eaf6c9SSean Wang 		clear_bit(BTMTKUART_REQUIRED_WAKEUP, &bdev->tx_state);
61722eaf6c9SSean Wang 	}
61822eaf6c9SSean Wang 
61922eaf6c9SSean Wang 	if (btmtkuart_is_standalone(bdev))
62022eaf6c9SSean Wang 		btmtkuart_change_baudrate(hdev);
62122eaf6c9SSean Wang 
622e0b67035SSean Wang 	/* Query whether the firmware is already download */
623f5c3f989SSean Wang 	wmt_params.op = BTMTK_WMT_SEMAPHORE;
624e0b67035SSean Wang 	wmt_params.flag = 1;
625e0b67035SSean Wang 	wmt_params.dlen = 0;
626e0b67035SSean Wang 	wmt_params.data = NULL;
627e0b67035SSean Wang 	wmt_params.status = &status;
628e0b67035SSean Wang 
629e0b67035SSean Wang 	err = mtk_hci_wmt_sync(hdev, &wmt_params);
630e0b67035SSean Wang 	if (err < 0) {
631e0b67035SSean Wang 		bt_dev_err(hdev, "Failed to query firmware status (%d)", err);
632e0b67035SSean Wang 		return err;
633e0b67035SSean Wang 	}
634e0b67035SSean Wang 
635e0b67035SSean Wang 	if (status == BTMTK_WMT_PATCH_DONE) {
636e0b67035SSean Wang 		bt_dev_info(hdev, "Firmware already downloaded");
637e0b67035SSean Wang 		goto ignore_setup_fw;
638e0b67035SSean Wang 	}
6397237c4c9SSean Wang 
6407237c4c9SSean Wang 	/* Setup a firmware which the device definitely requires */
641f5c3f989SSean Wang 	err = btmtk_setup_firmware(hdev, bdev->data->fwname, mtk_hci_wmt_sync);
6427237c4c9SSean Wang 	if (err < 0)
6437237c4c9SSean Wang 		return err;
6447237c4c9SSean Wang 
645e0b67035SSean Wang ignore_setup_fw:
646e0b67035SSean Wang 	/* Query whether the device is already enabled */
647e0b67035SSean Wang 	err = readx_poll_timeout(btmtkuart_func_query, hdev, status,
648e0b67035SSean Wang 				 status < 0 || status != BTMTK_WMT_ON_PROGRESS,
649e0b67035SSean Wang 				 2000, 5000000);
650e0b67035SSean Wang 	/* -ETIMEDOUT happens */
651e0b67035SSean Wang 	if (err < 0)
6527237c4c9SSean Wang 		return err;
653e0b67035SSean Wang 
654e0b67035SSean Wang 	/* The other errors happen in btusb_mtk_func_query */
655e0b67035SSean Wang 	if (status < 0)
656e0b67035SSean Wang 		return status;
657e0b67035SSean Wang 
658e0b67035SSean Wang 	if (status == BTMTK_WMT_ON_DONE) {
659e0b67035SSean Wang 		bt_dev_info(hdev, "function already on");
660e0b67035SSean Wang 		goto ignore_func_on;
6617237c4c9SSean Wang 	}
6627237c4c9SSean Wang 
6637237c4c9SSean Wang 	/* Enable Bluetooth protocol */
664f5c3f989SSean Wang 	wmt_params.op = BTMTK_WMT_FUNC_CTRL;
66588e5f366SSean Wang 	wmt_params.flag = 0;
66688e5f366SSean Wang 	wmt_params.dlen = sizeof(param);
66788e5f366SSean Wang 	wmt_params.data = &param;
66888e5f366SSean Wang 	wmt_params.status = NULL;
66988e5f366SSean Wang 
67088e5f366SSean Wang 	err = mtk_hci_wmt_sync(hdev, &wmt_params);
6717237c4c9SSean Wang 	if (err < 0) {
6727237c4c9SSean Wang 		bt_dev_err(hdev, "Failed to send wmt func ctrl (%d)", err);
6737237c4c9SSean Wang 		return err;
6747237c4c9SSean Wang 	}
6757237c4c9SSean Wang 
676e0b67035SSean Wang ignore_func_on:
677e0b67035SSean Wang 	/* Apply the low power environment setup */
678e0b67035SSean Wang 	tci_sleep.mode = 0x5;
679e0b67035SSean Wang 	tci_sleep.duration = cpu_to_le16(0x640);
680e0b67035SSean Wang 	tci_sleep.host_duration = cpu_to_le16(0x640);
681e0b67035SSean Wang 	tci_sleep.host_wakeup_pin = 0;
682e0b67035SSean Wang 	tci_sleep.time_compensation = 0;
683e0b67035SSean Wang 
684e0b67035SSean Wang 	skb = __hci_cmd_sync(hdev, 0xfc7a, sizeof(tci_sleep), &tci_sleep,
685e0b67035SSean Wang 			     HCI_INIT_TIMEOUT);
686e0b67035SSean Wang 	if (IS_ERR(skb)) {
687e0b67035SSean Wang 		err = PTR_ERR(skb);
688e0b67035SSean Wang 		bt_dev_err(hdev, "Failed to apply low power setting (%d)", err);
689e0b67035SSean Wang 		return err;
690e0b67035SSean Wang 	}
691e0b67035SSean Wang 	kfree_skb(skb);
692e0b67035SSean Wang 
693e0b67035SSean Wang 	rettime = ktime_get();
694e0b67035SSean Wang 	delta = ktime_sub(rettime, calltime);
695e0b67035SSean Wang 	duration = (unsigned long long)ktime_to_ns(delta) >> 10;
696e0b67035SSean Wang 
697e0b67035SSean Wang 	bt_dev_info(hdev, "Device setup in %llu usecs", duration);
698e0b67035SSean Wang 
6997237c4c9SSean Wang 	return 0;
7007237c4c9SSean Wang }
7017237c4c9SSean Wang 
btmtkuart_shutdown(struct hci_dev * hdev)7027237c4c9SSean Wang static int btmtkuart_shutdown(struct hci_dev *hdev)
7037237c4c9SSean Wang {
70488e5f366SSean Wang 	struct btmtk_hci_wmt_params wmt_params;
7057237c4c9SSean Wang 	u8 param = 0x0;
7067237c4c9SSean Wang 	int err;
7077237c4c9SSean Wang 
7087237c4c9SSean Wang 	/* Disable the device */
709f5c3f989SSean Wang 	wmt_params.op = BTMTK_WMT_FUNC_CTRL;
71088e5f366SSean Wang 	wmt_params.flag = 0;
71188e5f366SSean Wang 	wmt_params.dlen = sizeof(param);
71288e5f366SSean Wang 	wmt_params.data = &param;
71388e5f366SSean Wang 	wmt_params.status = NULL;
71488e5f366SSean Wang 
71588e5f366SSean Wang 	err = mtk_hci_wmt_sync(hdev, &wmt_params);
7167237c4c9SSean Wang 	if (err < 0) {
7177237c4c9SSean Wang 		bt_dev_err(hdev, "Failed to send wmt func ctrl (%d)", err);
7187237c4c9SSean Wang 		return err;
7197237c4c9SSean Wang 	}
7207237c4c9SSean Wang 
7217237c4c9SSean Wang 	return 0;
7227237c4c9SSean Wang }
7237237c4c9SSean Wang 
btmtkuart_send_frame(struct hci_dev * hdev,struct sk_buff * skb)7247237c4c9SSean Wang static int btmtkuart_send_frame(struct hci_dev *hdev, struct sk_buff *skb)
7257237c4c9SSean Wang {
7267237c4c9SSean Wang 	struct btmtkuart_dev *bdev = hci_get_drvdata(hdev);
7277237c4c9SSean Wang 	struct mtk_stp_hdr *shdr;
7287237c4c9SSean Wang 	int err, dlen, type = 0;
7297237c4c9SSean Wang 
7307237c4c9SSean Wang 	/* Prepend skb with frame type */
7317237c4c9SSean Wang 	memcpy(skb_push(skb, 1), &hci_skb_pkt_type(skb), 1);
7327237c4c9SSean Wang 
7337237c4c9SSean Wang 	/* Make sure that there is enough rooms for STP header and trailer */
7347237c4c9SSean Wang 	if (unlikely(skb_headroom(skb) < sizeof(*shdr)) ||
7357237c4c9SSean Wang 	    (skb_tailroom(skb) < MTK_STP_TLR_SIZE)) {
7367237c4c9SSean Wang 		err = pskb_expand_head(skb, sizeof(*shdr), MTK_STP_TLR_SIZE,
7377237c4c9SSean Wang 				       GFP_ATOMIC);
7387237c4c9SSean Wang 		if (err < 0)
7397237c4c9SSean Wang 			return err;
7407237c4c9SSean Wang 	}
7417237c4c9SSean Wang 
7427237c4c9SSean Wang 	/* Add the STP header */
7437237c4c9SSean Wang 	dlen = skb->len;
7447237c4c9SSean Wang 	shdr = skb_push(skb, sizeof(*shdr));
7457237c4c9SSean Wang 	shdr->prefix = 0x80;
7467237c4c9SSean Wang 	shdr->dlen = cpu_to_be16((dlen & 0x0fff) | (type << 12));
7477237c4c9SSean Wang 	shdr->cs = 0;		/* MT7622 doesn't care about checksum value */
7487237c4c9SSean Wang 
7497237c4c9SSean Wang 	/* Add the STP trailer */
7507237c4c9SSean Wang 	skb_put_zero(skb, MTK_STP_TLR_SIZE);
7517237c4c9SSean Wang 
7527237c4c9SSean Wang 	skb_queue_tail(&bdev->txq, skb);
7537237c4c9SSean Wang 
7547237c4c9SSean Wang 	btmtkuart_tx_wakeup(bdev);
7557237c4c9SSean Wang 	return 0;
7567237c4c9SSean Wang }
7577237c4c9SSean Wang 
btmtkuart_parse_dt(struct serdev_device * serdev)75822eaf6c9SSean Wang static int btmtkuart_parse_dt(struct serdev_device *serdev)
75922eaf6c9SSean Wang {
76022eaf6c9SSean Wang 	struct btmtkuart_dev *bdev = serdev_device_get_drvdata(serdev);
76122eaf6c9SSean Wang 	struct device_node *node = serdev->dev.of_node;
76222eaf6c9SSean Wang 	u32 speed = 921600;
76322eaf6c9SSean Wang 	int err;
76422eaf6c9SSean Wang 
76522eaf6c9SSean Wang 	if (btmtkuart_is_standalone(bdev)) {
76622eaf6c9SSean Wang 		of_property_read_u32(node, "current-speed", &speed);
76722eaf6c9SSean Wang 
76822eaf6c9SSean Wang 		bdev->desired_speed = speed;
76922eaf6c9SSean Wang 
77022eaf6c9SSean Wang 		bdev->vcc = devm_regulator_get(&serdev->dev, "vcc");
77122eaf6c9SSean Wang 		if (IS_ERR(bdev->vcc)) {
77222eaf6c9SSean Wang 			err = PTR_ERR(bdev->vcc);
77322eaf6c9SSean Wang 			return err;
77422eaf6c9SSean Wang 		}
77522eaf6c9SSean Wang 
77605582561SSean Wang 		bdev->osc = devm_clk_get_optional(&serdev->dev, "osc");
77705582561SSean Wang 		if (IS_ERR(bdev->osc)) {
77805582561SSean Wang 			err = PTR_ERR(bdev->osc);
77905582561SSean Wang 			return err;
78005582561SSean Wang 		}
78105582561SSean Wang 
782a3cb6d60SSean Wang 		bdev->boot = devm_gpiod_get_optional(&serdev->dev, "boot",
783a3cb6d60SSean Wang 						     GPIOD_OUT_LOW);
784a3cb6d60SSean Wang 		if (IS_ERR(bdev->boot)) {
785a3cb6d60SSean Wang 			err = PTR_ERR(bdev->boot);
786a3cb6d60SSean Wang 			return err;
787a3cb6d60SSean Wang 		}
788a3cb6d60SSean Wang 
78922eaf6c9SSean Wang 		bdev->pinctrl = devm_pinctrl_get(&serdev->dev);
79022eaf6c9SSean Wang 		if (IS_ERR(bdev->pinctrl)) {
79122eaf6c9SSean Wang 			err = PTR_ERR(bdev->pinctrl);
79222eaf6c9SSean Wang 			return err;
79322eaf6c9SSean Wang 		}
79422eaf6c9SSean Wang 
79522eaf6c9SSean Wang 		bdev->pins_boot = pinctrl_lookup_state(bdev->pinctrl,
79622eaf6c9SSean Wang 						       "default");
797a3cb6d60SSean Wang 		if (IS_ERR(bdev->pins_boot) && !bdev->boot) {
79822eaf6c9SSean Wang 			err = PTR_ERR(bdev->pins_boot);
799a3cb6d60SSean Wang 			dev_err(&serdev->dev,
800a3cb6d60SSean Wang 				"Should assign RXD to LOW at boot stage\n");
80122eaf6c9SSean Wang 			return err;
80222eaf6c9SSean Wang 		}
80322eaf6c9SSean Wang 
80422eaf6c9SSean Wang 		bdev->pins_runtime = pinctrl_lookup_state(bdev->pinctrl,
80522eaf6c9SSean Wang 							  "runtime");
80622eaf6c9SSean Wang 		if (IS_ERR(bdev->pins_runtime)) {
80722eaf6c9SSean Wang 			err = PTR_ERR(bdev->pins_runtime);
80822eaf6c9SSean Wang 			return err;
80922eaf6c9SSean Wang 		}
81022eaf6c9SSean Wang 
81122eaf6c9SSean Wang 		bdev->reset = devm_gpiod_get_optional(&serdev->dev, "reset",
81222eaf6c9SSean Wang 						      GPIOD_OUT_LOW);
81322eaf6c9SSean Wang 		if (IS_ERR(bdev->reset)) {
81422eaf6c9SSean Wang 			err = PTR_ERR(bdev->reset);
81522eaf6c9SSean Wang 			return err;
81622eaf6c9SSean Wang 		}
81722eaf6c9SSean Wang 	} else if (btmtkuart_is_builtin_soc(bdev)) {
81822eaf6c9SSean Wang 		bdev->clk = devm_clk_get(&serdev->dev, "ref");
81922eaf6c9SSean Wang 		if (IS_ERR(bdev->clk))
82022eaf6c9SSean Wang 			return PTR_ERR(bdev->clk);
82122eaf6c9SSean Wang 	}
82222eaf6c9SSean Wang 
82322eaf6c9SSean Wang 	return 0;
82422eaf6c9SSean Wang }
82522eaf6c9SSean Wang 
btmtkuart_probe(struct serdev_device * serdev)8267237c4c9SSean Wang static int btmtkuart_probe(struct serdev_device *serdev)
8277237c4c9SSean Wang {
8287237c4c9SSean Wang 	struct btmtkuart_dev *bdev;
8297237c4c9SSean Wang 	struct hci_dev *hdev;
83022eaf6c9SSean Wang 	int err;
8317237c4c9SSean Wang 
8327237c4c9SSean Wang 	bdev = devm_kzalloc(&serdev->dev, sizeof(*bdev), GFP_KERNEL);
8337237c4c9SSean Wang 	if (!bdev)
8347237c4c9SSean Wang 		return -ENOMEM;
8357237c4c9SSean Wang 
83622eaf6c9SSean Wang 	bdev->data = of_device_get_match_data(&serdev->dev);
83722eaf6c9SSean Wang 	if (!bdev->data)
83822eaf6c9SSean Wang 		return -ENODEV;
8397237c4c9SSean Wang 
8407237c4c9SSean Wang 	bdev->serdev = serdev;
8417237c4c9SSean Wang 	serdev_device_set_drvdata(serdev, bdev);
8427237c4c9SSean Wang 
8437237c4c9SSean Wang 	serdev_device_set_client_ops(serdev, &btmtkuart_client_ops);
8447237c4c9SSean Wang 
84522eaf6c9SSean Wang 	err = btmtkuart_parse_dt(serdev);
84622eaf6c9SSean Wang 	if (err < 0)
84722eaf6c9SSean Wang 		return err;
84822eaf6c9SSean Wang 
8497237c4c9SSean Wang 	INIT_WORK(&bdev->tx_work, btmtkuart_tx_work);
8507237c4c9SSean Wang 	skb_queue_head_init(&bdev->txq);
8517237c4c9SSean Wang 
8527237c4c9SSean Wang 	/* Initialize and register HCI device */
8537237c4c9SSean Wang 	hdev = hci_alloc_dev();
8547237c4c9SSean Wang 	if (!hdev) {
8557237c4c9SSean Wang 		dev_err(&serdev->dev, "Can't allocate HCI device\n");
8567237c4c9SSean Wang 		return -ENOMEM;
8577237c4c9SSean Wang 	}
8587237c4c9SSean Wang 
8597237c4c9SSean Wang 	bdev->hdev = hdev;
8607237c4c9SSean Wang 
8617237c4c9SSean Wang 	hdev->bus = HCI_UART;
8627237c4c9SSean Wang 	hci_set_drvdata(hdev, bdev);
8637237c4c9SSean Wang 
8647237c4c9SSean Wang 	hdev->open     = btmtkuart_open;
8657237c4c9SSean Wang 	hdev->close    = btmtkuart_close;
8667237c4c9SSean Wang 	hdev->flush    = btmtkuart_flush;
8677237c4c9SSean Wang 	hdev->setup    = btmtkuart_setup;
8687237c4c9SSean Wang 	hdev->shutdown = btmtkuart_shutdown;
8697237c4c9SSean Wang 	hdev->send     = btmtkuart_send_frame;
8703640e7f4SSean Wang 	hdev->set_bdaddr = btmtk_set_bdaddr;
8717237c4c9SSean Wang 	SET_HCIDEV_DEV(hdev, &serdev->dev);
8727237c4c9SSean Wang 
8737237c4c9SSean Wang 	hdev->manufacturer = 70;
8747237c4c9SSean Wang 	set_bit(HCI_QUIRK_NON_PERSISTENT_SETUP, &hdev->quirks);
8757237c4c9SSean Wang 
87622eaf6c9SSean Wang 	if (btmtkuart_is_standalone(bdev)) {
87705582561SSean Wang 		err = clk_prepare_enable(bdev->osc);
87805582561SSean Wang 		if (err < 0)
8794803c54cSChuhong Yuan 			goto err_hci_free_dev;
88005582561SSean Wang 
881a3cb6d60SSean Wang 		if (bdev->boot) {
882a3cb6d60SSean Wang 			gpiod_set_value_cansleep(bdev->boot, 1);
883a3cb6d60SSean Wang 		} else {
884a3cb6d60SSean Wang 			/* Switch to the specific pin state for the booting
885a3cb6d60SSean Wang 			 * requires.
886a3cb6d60SSean Wang 			 */
88722eaf6c9SSean Wang 			pinctrl_select_state(bdev->pinctrl, bdev->pins_boot);
888a3cb6d60SSean Wang 		}
88922eaf6c9SSean Wang 
89022eaf6c9SSean Wang 		/* Power on */
89122eaf6c9SSean Wang 		err = regulator_enable(bdev->vcc);
8924803c54cSChuhong Yuan 		if (err < 0)
8934803c54cSChuhong Yuan 			goto err_clk_disable_unprepare;
89422eaf6c9SSean Wang 
89522eaf6c9SSean Wang 		/* Reset if the reset-gpios is available otherwise the board
89622eaf6c9SSean Wang 		 * -level design should be guaranteed.
89722eaf6c9SSean Wang 		 */
89822eaf6c9SSean Wang 		if (bdev->reset) {
89922eaf6c9SSean Wang 			gpiod_set_value_cansleep(bdev->reset, 1);
90022eaf6c9SSean Wang 			usleep_range(1000, 2000);
90122eaf6c9SSean Wang 			gpiod_set_value_cansleep(bdev->reset, 0);
90222eaf6c9SSean Wang 		}
90322eaf6c9SSean Wang 
90422eaf6c9SSean Wang 		/* Wait some time until device got ready and switch to the pin
90522eaf6c9SSean Wang 		 * mode the device requires for UART transfers.
90622eaf6c9SSean Wang 		 */
90722eaf6c9SSean Wang 		msleep(50);
908a3cb6d60SSean Wang 
909a3cb6d60SSean Wang 		if (bdev->boot)
910a3cb6d60SSean Wang 			devm_gpiod_put(&serdev->dev, bdev->boot);
911a3cb6d60SSean Wang 
91222eaf6c9SSean Wang 		pinctrl_select_state(bdev->pinctrl, bdev->pins_runtime);
91322eaf6c9SSean Wang 
91422eaf6c9SSean Wang 		/* A standalone device doesn't depends on power domain on SoC,
91522eaf6c9SSean Wang 		 * so mark it as no callbacks.
91622eaf6c9SSean Wang 		 */
91722eaf6c9SSean Wang 		pm_runtime_no_callbacks(&serdev->dev);
91822eaf6c9SSean Wang 
91922eaf6c9SSean Wang 		set_bit(BTMTKUART_REQUIRED_WAKEUP, &bdev->tx_state);
92022eaf6c9SSean Wang 	}
92122eaf6c9SSean Wang 
92222eaf6c9SSean Wang 	err = hci_register_dev(hdev);
92322eaf6c9SSean Wang 	if (err < 0) {
9247237c4c9SSean Wang 		dev_err(&serdev->dev, "Can't register HCI device\n");
92522eaf6c9SSean Wang 		goto err_regulator_disable;
9267237c4c9SSean Wang 	}
9277237c4c9SSean Wang 
9287237c4c9SSean Wang 	return 0;
92922eaf6c9SSean Wang 
93022eaf6c9SSean Wang err_regulator_disable:
931a3cb6d60SSean Wang 	if (btmtkuart_is_standalone(bdev))
93222eaf6c9SSean Wang 		regulator_disable(bdev->vcc);
9334803c54cSChuhong Yuan err_clk_disable_unprepare:
9344803c54cSChuhong Yuan 	if (btmtkuart_is_standalone(bdev))
9354803c54cSChuhong Yuan 		clk_disable_unprepare(bdev->osc);
9364803c54cSChuhong Yuan err_hci_free_dev:
9374803c54cSChuhong Yuan 	hci_free_dev(hdev);
93822eaf6c9SSean Wang 
93922eaf6c9SSean Wang 	return err;
9407237c4c9SSean Wang }
9417237c4c9SSean Wang 
btmtkuart_remove(struct serdev_device * serdev)9427237c4c9SSean Wang static void btmtkuart_remove(struct serdev_device *serdev)
9437237c4c9SSean Wang {
9447237c4c9SSean Wang 	struct btmtkuart_dev *bdev = serdev_device_get_drvdata(serdev);
9457237c4c9SSean Wang 	struct hci_dev *hdev = bdev->hdev;
9467237c4c9SSean Wang 
94705582561SSean Wang 	if (btmtkuart_is_standalone(bdev)) {
94822eaf6c9SSean Wang 		regulator_disable(bdev->vcc);
94905582561SSean Wang 		clk_disable_unprepare(bdev->osc);
95005582561SSean Wang 	}
95122eaf6c9SSean Wang 
9527237c4c9SSean Wang 	hci_unregister_dev(hdev);
9537237c4c9SSean Wang 	hci_free_dev(hdev);
9547237c4c9SSean Wang }
9557237c4c9SSean Wang 
956a88ea43bSKrzysztof Kozlowski static const struct btmtkuart_data mt7622_data __maybe_unused = {
95722eaf6c9SSean Wang 	.fwname = FIRMWARE_MT7622,
95822eaf6c9SSean Wang };
95922eaf6c9SSean Wang 
960a88ea43bSKrzysztof Kozlowski static const struct btmtkuart_data mt7663_data __maybe_unused = {
96122eaf6c9SSean Wang 	.flags = BTMTKUART_FLAG_STANDALONE_HW,
96222eaf6c9SSean Wang 	.fwname = FIRMWARE_MT7663,
96322eaf6c9SSean Wang };
96422eaf6c9SSean Wang 
965a88ea43bSKrzysztof Kozlowski static const struct btmtkuart_data mt7668_data __maybe_unused = {
96622eaf6c9SSean Wang 	.flags = BTMTKUART_FLAG_STANDALONE_HW,
96722eaf6c9SSean Wang 	.fwname = FIRMWARE_MT7668,
96822eaf6c9SSean Wang };
96922eaf6c9SSean Wang 
9707237c4c9SSean Wang #ifdef CONFIG_OF
9717237c4c9SSean Wang static const struct of_device_id mtk_of_match_table[] = {
97222eaf6c9SSean Wang 	{ .compatible = "mediatek,mt7622-bluetooth", .data = &mt7622_data},
97322eaf6c9SSean Wang 	{ .compatible = "mediatek,mt7663u-bluetooth", .data = &mt7663_data},
97422eaf6c9SSean Wang 	{ .compatible = "mediatek,mt7668u-bluetooth", .data = &mt7668_data},
9757237c4c9SSean Wang 	{ }
9767237c4c9SSean Wang };
9777237c4c9SSean Wang MODULE_DEVICE_TABLE(of, mtk_of_match_table);
9787237c4c9SSean Wang #endif
9797237c4c9SSean Wang 
9807237c4c9SSean Wang static struct serdev_device_driver btmtkuart_driver = {
9817237c4c9SSean Wang 	.probe = btmtkuart_probe,
9827237c4c9SSean Wang 	.remove = btmtkuart_remove,
9837237c4c9SSean Wang 	.driver = {
9847237c4c9SSean Wang 		.name = "btmtkuart",
9857237c4c9SSean Wang 		.of_match_table = of_match_ptr(mtk_of_match_table),
9867237c4c9SSean Wang 	},
9877237c4c9SSean Wang };
9887237c4c9SSean Wang 
9897237c4c9SSean Wang module_serdev_device_driver(btmtkuart_driver);
9907237c4c9SSean Wang 
9917237c4c9SSean Wang MODULE_AUTHOR("Sean Wang <sean.wang@mediatek.com>");
9927237c4c9SSean Wang MODULE_DESCRIPTION("MediaTek Bluetooth Serial driver ver " VERSION);
9937237c4c9SSean Wang MODULE_VERSION(VERSION);
9947237c4c9SSean Wang MODULE_LICENSE("GPL");
995