drivers/bluetooth/btmtkuart.c

Source file repositories/reference/linux-study-clean/drivers/bluetooth/btmtkuart.c

File Facts

System
Linux kernel
Corpus path
drivers/bluetooth/btmtkuart.c
Extension
.c
Size
24486 bytes
Lines
998
Domain
Driver Families
Bucket
drivers/bluetooth
Inferred role
Driver Families: implementation source
Status
source implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

struct mtk_stp_hdr {
	u8	prefix;
	__be16	dlen;
	u8	cs;
} __packed;

struct btmtkuart_data {
	unsigned int flags;
	const char *fwname;
};

struct btmtkuart_dev {
	struct hci_dev *hdev;
	struct serdev_device *serdev;

	struct clk *clk;
	struct clk *osc;
	struct regulator *vcc;
	struct gpio_desc *reset;
	struct gpio_desc *boot;
	struct pinctrl *pinctrl;
	struct pinctrl_state *pins_runtime;
	struct pinctrl_state *pins_boot;
	speed_t	desired_speed;
	speed_t	curr_speed;

	struct work_struct tx_work;
	unsigned long tx_state;
	struct sk_buff_head txq;

	struct sk_buff *rx_skb;
	struct sk_buff *evt_skb;

	u8	stp_pad[6];
	u8	stp_cursor;
	u16	stp_dlen;

	const struct btmtkuart_data *data;
	struct hci_uart hu;
};

#define btmtkuart_is_standalone(bdev)	\
	((bdev)->data->flags & BTMTKUART_FLAG_STANDALONE_HW)
#define btmtkuart_is_builtin_soc(bdev)	\
	!((bdev)->data->flags & BTMTKUART_FLAG_STANDALONE_HW)

static int mtk_hci_wmt_sync(struct hci_dev *hdev,
			    struct btmtk_hci_wmt_params *wmt_params)
{
	struct btmtkuart_dev *bdev = hci_get_drvdata(hdev);
	struct btmtk_hci_wmt_evt_funcc *wmt_evt_funcc;
	u32 hlen, status = BTMTK_WMT_INVALID;
	struct btmtk_hci_wmt_evt *wmt_evt;
	struct btmtk_hci_wmt_cmd *wc;
	struct btmtk_wmt_hdr *hdr;
	int err;

	/* Send the WMT command and wait until the WMT event returns */
	hlen = sizeof(*hdr) + wmt_params->dlen;
	if (hlen > 255) {
		err = -EINVAL;
		goto err_free_skb;
	}

	wc = kzalloc(hlen, GFP_KERNEL);
	if (!wc) {
		err = -ENOMEM;
		goto err_free_skb;
	}

	hdr = &wc->hdr;
	hdr->dir = 1;
	hdr->op = wmt_params->op;
	hdr->dlen = cpu_to_le16(wmt_params->dlen + 1);
	hdr->flag = wmt_params->flag;
	memcpy(wc->data, wmt_params->data, wmt_params->dlen);

	set_bit(BTMTKUART_TX_WAIT_VND_EVT, &bdev->tx_state);

	err = __hci_cmd_send(hdev, 0xfc6f, hlen, wc);
	if (err < 0) {
		clear_bit(BTMTKUART_TX_WAIT_VND_EVT, &bdev->tx_state);
		goto err_free_wc;
	}

	/* The vendor specific WMT commands are all answered by a vendor
	 * specific event and will not have the Command Status or Command
	 * Complete as with usual HCI command flow control.
	 *
	 * After sending the command, wait for BTMTKUART_TX_WAIT_VND_EVT

Annotation

Implementation Notes