Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Bluetooth: btmtkuart: rely on BT_MTK module

Rely on btmtk module to reduce duplicated code

Signed-off-by: Sean Wang <sean.wang@mediatek.com>
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>

authored by

Sean Wang and committed by
Marcel Holtmann
f5c3f989 cc68a041

+29 -158
+1
drivers/bluetooth/Kconfig
··· 400 400 config BT_MTKUART 401 401 tristate "MediaTek HCI UART driver" 402 402 depends on SERIAL_DEV_BUS 403 + select BT_MTK 403 404 help 404 405 MediaTek Bluetooth HCI UART driver. 405 406 This driver is required if you want to use MediaTek Bluetooth
+1
drivers/bluetooth/btmtk.c
··· 285 285 MODULE_DESCRIPTION("Bluetooth support for MediaTek devices ver " VERSION); 286 286 MODULE_VERSION(VERSION); 287 287 MODULE_LICENSE("GPL"); 288 + MODULE_FIRMWARE(FIRMWARE_MT7622); 288 289 MODULE_FIRMWARE(FIRMWARE_MT7663); 289 290 MODULE_FIRMWARE(FIRMWARE_MT7668); 290 291 MODULE_FIRMWARE(FIRMWARE_MT7961);
+1
drivers/bluetooth/btmtk.h
··· 1 1 /* SPDX-License-Identifier: ISC */ 2 2 /* Copyright (C) 2021 MediaTek Inc. */ 3 3 4 + #define FIRMWARE_MT7622 "mediatek/mt7622pr2h.bin" 4 5 #define FIRMWARE_MT7663 "mediatek/mt7663pr2h.bin" 5 6 #define FIRMWARE_MT7668 "mediatek/mt7668pr2h.bin" 6 7 #define FIRMWARE_MT7961 "mediatek/BT_RAM_CODE_MT7961_1_2_hdr.bin"
+26 -158
drivers/bluetooth/btmtkuart.c
··· 28 28 #include <net/bluetooth/hci_core.h> 29 29 30 30 #include "h4_recv.h" 31 + #include "btmtk.h" 31 32 32 33 #define VERSION "0.2" 33 - 34 - #define FIRMWARE_MT7622 "mediatek/mt7622pr2h.bin" 35 - #define FIRMWARE_MT7663 "mediatek/mt7663pr2h.bin" 36 - #define FIRMWARE_MT7668 "mediatek/mt7668pr2h.bin" 37 34 38 35 #define MTK_STP_TLR_SIZE 2 39 36 ··· 41 44 42 45 #define BTMTKUART_FLAG_STANDALONE_HW BIT(0) 43 46 44 - enum { 45 - MTK_WMT_PATCH_DWNLD = 0x1, 46 - MTK_WMT_TEST = 0x2, 47 - MTK_WMT_WAKEUP = 0x3, 48 - MTK_WMT_HIF = 0x4, 49 - MTK_WMT_FUNC_CTRL = 0x6, 50 - MTK_WMT_RST = 0x7, 51 - MTK_WMT_SEMAPHORE = 0x17, 52 - }; 53 - 54 - enum { 55 - BTMTK_WMT_INVALID, 56 - BTMTK_WMT_PATCH_UNDONE, 57 - BTMTK_WMT_PATCH_DONE, 58 - BTMTK_WMT_ON_UNDONE, 59 - BTMTK_WMT_ON_DONE, 60 - BTMTK_WMT_ON_PROGRESS, 61 - }; 62 - 63 47 struct mtk_stp_hdr { 64 48 u8 prefix; 65 49 __be16 dlen; ··· 50 72 struct btmtkuart_data { 51 73 unsigned int flags; 52 74 const char *fwname; 53 - }; 54 - 55 - struct mtk_wmt_hdr { 56 - u8 dir; 57 - u8 op; 58 - __le16 dlen; 59 - u8 flag; 60 - } __packed; 61 - 62 - struct mtk_hci_wmt_cmd { 63 - struct mtk_wmt_hdr hdr; 64 - u8 data[256]; 65 - } __packed; 66 - 67 - struct btmtk_hci_wmt_evt { 68 - struct hci_event_hdr hhdr; 69 - struct mtk_wmt_hdr whdr; 70 - } __packed; 71 - 72 - struct btmtk_hci_wmt_evt_funcc { 73 - struct btmtk_hci_wmt_evt hwhdr; 74 - __be16 status; 75 - } __packed; 76 - 77 - struct btmtk_tci_sleep { 78 - u8 mode; 79 - __le16 duration; 80 - __le16 host_duration; 81 - u8 host_wakeup_pin; 82 - u8 time_compensation; 83 - } __packed; 84 - 85 - struct btmtk_hci_wmt_params { 86 - u8 op; 87 - u8 flag; 88 - u16 dlen; 89 - const void *data; 90 - u32 *status; 91 75 }; 92 76 93 77 struct btmtkuart_dev { ··· 93 153 struct btmtk_hci_wmt_evt_funcc *wmt_evt_funcc; 94 154 u32 hlen, status = BTMTK_WMT_INVALID; 95 155 struct btmtk_hci_wmt_evt *wmt_evt; 96 - struct mtk_hci_wmt_cmd wc; 97 - struct mtk_wmt_hdr *hdr; 156 + struct btmtk_hci_wmt_cmd *wc; 157 + struct btmtk_wmt_hdr *hdr; 98 158 int err; 99 159 160 + /* Send the WMT command and wait until the WMT event returns */ 100 161 hlen = sizeof(*hdr) + wmt_params->dlen; 101 162 if (hlen > 255) { 102 163 err = -EINVAL; 103 164 goto err_free_skb; 104 165 } 105 166 106 - hdr = (struct mtk_wmt_hdr *)&wc; 167 + wc = kzalloc(hlen, GFP_KERNEL); 168 + if (!wc) 169 + return -ENOMEM; 170 + 171 + hdr = &wc->hdr; 107 172 hdr->dir = 1; 108 173 hdr->op = wmt_params->op; 109 174 hdr->dlen = cpu_to_le16(wmt_params->dlen + 1); 110 175 hdr->flag = wmt_params->flag; 111 - memcpy(wc.data, wmt_params->data, wmt_params->dlen); 176 + memcpy(wc->data, wmt_params->data, wmt_params->dlen); 112 177 113 178 set_bit(BTMTKUART_TX_WAIT_VND_EVT, &bdev->tx_state); 114 179 115 - err = __hci_cmd_send(hdev, 0xfc6f, hlen, &wc); 180 + err = __hci_cmd_send(hdev, 0xfc6f, hlen, wc); 116 181 if (err < 0) { 117 182 clear_bit(BTMTKUART_TX_WAIT_VND_EVT, &bdev->tx_state); 118 - goto err_free_skb; 183 + goto err_free_wc; 119 184 } 120 185 121 186 /* The vendor specific WMT commands are all answered by a vendor ··· 137 192 if (err == -EINTR) { 138 193 bt_dev_err(hdev, "Execution of wmt command interrupted"); 139 194 clear_bit(BTMTKUART_TX_WAIT_VND_EVT, &bdev->tx_state); 140 - goto err_free_skb; 195 + goto err_free_wc; 141 196 } 142 197 143 198 if (err) { 144 199 bt_dev_err(hdev, "Execution of wmt command timed out"); 145 200 clear_bit(BTMTKUART_TX_WAIT_VND_EVT, &bdev->tx_state); 146 201 err = -ETIMEDOUT; 147 - goto err_free_skb; 202 + goto err_free_wc; 148 203 } 149 204 150 205 /* Parse and handle the return WMT event */ ··· 157 212 } 158 213 159 214 switch (wmt_evt->whdr.op) { 160 - case MTK_WMT_SEMAPHORE: 215 + case BTMTK_WMT_SEMAPHORE: 161 216 if (wmt_evt->whdr.flag == 2) 162 217 status = BTMTK_WMT_PATCH_UNDONE; 163 218 else 164 219 status = BTMTK_WMT_PATCH_DONE; 165 220 break; 166 - case MTK_WMT_FUNC_CTRL: 221 + case BTMTK_WMT_FUNC_CTRL: 167 222 wmt_evt_funcc = (struct btmtk_hci_wmt_evt_funcc *)wmt_evt; 168 223 if (be16_to_cpu(wmt_evt_funcc->status) == 0x404) 169 224 status = BTMTK_WMT_ON_DONE; ··· 180 235 err_free_skb: 181 236 kfree_skb(bdev->evt_skb); 182 237 bdev->evt_skb = NULL; 238 + err_free_wc: 239 + kfree(wc); 183 240 184 - return err; 185 - } 186 - 187 - static int mtk_setup_firmware(struct hci_dev *hdev, const char *fwname) 188 - { 189 - struct btmtk_hci_wmt_params wmt_params; 190 - const struct firmware *fw; 191 - const u8 *fw_ptr; 192 - size_t fw_size; 193 - int err, dlen; 194 - u8 flag; 195 - 196 - err = request_firmware(&fw, fwname, &hdev->dev); 197 - if (err < 0) { 198 - bt_dev_err(hdev, "Failed to load firmware file (%d)", err); 199 - return err; 200 - } 201 - 202 - fw_ptr = fw->data; 203 - fw_size = fw->size; 204 - 205 - /* The size of patch header is 30 bytes, should be skip */ 206 - if (fw_size < 30) { 207 - err = -EINVAL; 208 - goto free_fw; 209 - } 210 - 211 - fw_size -= 30; 212 - fw_ptr += 30; 213 - flag = 1; 214 - 215 - wmt_params.op = MTK_WMT_PATCH_DWNLD; 216 - wmt_params.status = NULL; 217 - 218 - while (fw_size > 0) { 219 - dlen = min_t(int, 250, fw_size); 220 - 221 - /* Tell device the position in sequence */ 222 - if (fw_size - dlen <= 0) 223 - flag = 3; 224 - else if (fw_size < fw->size - 30) 225 - flag = 2; 226 - 227 - wmt_params.flag = flag; 228 - wmt_params.dlen = dlen; 229 - wmt_params.data = fw_ptr; 230 - 231 - err = mtk_hci_wmt_sync(hdev, &wmt_params); 232 - if (err < 0) { 233 - bt_dev_err(hdev, "Failed to send wmt patch dwnld (%d)", 234 - err); 235 - goto free_fw; 236 - } 237 - 238 - fw_size -= dlen; 239 - fw_ptr += dlen; 240 - } 241 - 242 - wmt_params.op = MTK_WMT_RST; 243 - wmt_params.flag = 4; 244 - wmt_params.dlen = 0; 245 - wmt_params.data = NULL; 246 - wmt_params.status = NULL; 247 - 248 - /* Activate funciton the firmware providing to */ 249 - err = mtk_hci_wmt_sync(hdev, &wmt_params); 250 - if (err < 0) { 251 - bt_dev_err(hdev, "Failed to send wmt rst (%d)", err); 252 - goto free_fw; 253 - } 254 - 255 - /* Wait a few moments for firmware activation done */ 256 - usleep_range(10000, 12000); 257 - 258 - free_fw: 259 - release_firmware(fw); 260 241 return err; 261 242 } 262 243 ··· 516 645 u8 param = 0; 517 646 518 647 /* Query whether the function is enabled */ 519 - wmt_params.op = MTK_WMT_FUNC_CTRL; 648 + wmt_params.op = BTMTK_WMT_FUNC_CTRL; 520 649 wmt_params.flag = 4; 521 650 wmt_params.dlen = sizeof(param); 522 651 wmt_params.data = &param; ··· 543 672 * ready to change a new baudrate. 544 673 */ 545 674 baudrate = cpu_to_le32(bdev->desired_speed); 546 - wmt_params.op = MTK_WMT_HIF; 675 + wmt_params.op = BTMTK_WMT_HIF; 547 676 wmt_params.flag = 1; 548 677 wmt_params.dlen = 4; 549 678 wmt_params.data = &baudrate; ··· 577 706 usleep_range(20000, 22000); 578 707 579 708 /* Test the new baudrate */ 580 - wmt_params.op = MTK_WMT_TEST; 709 + wmt_params.op = BTMTK_WMT_TEST; 581 710 wmt_params.flag = 7; 582 711 wmt_params.dlen = 0; 583 712 wmt_params.data = NULL; ··· 612 741 * do any setups. 613 742 */ 614 743 if (test_bit(BTMTKUART_REQUIRED_WAKEUP, &bdev->tx_state)) { 615 - wmt_params.op = MTK_WMT_WAKEUP; 744 + wmt_params.op = BTMTK_WMT_WAKEUP; 616 745 wmt_params.flag = 3; 617 746 wmt_params.dlen = 0; 618 747 wmt_params.data = NULL; ··· 631 760 btmtkuart_change_baudrate(hdev); 632 761 633 762 /* Query whether the firmware is already download */ 634 - wmt_params.op = MTK_WMT_SEMAPHORE; 763 + wmt_params.op = BTMTK_WMT_SEMAPHORE; 635 764 wmt_params.flag = 1; 636 765 wmt_params.dlen = 0; 637 766 wmt_params.data = NULL; ··· 649 778 } 650 779 651 780 /* Setup a firmware which the device definitely requires */ 652 - err = mtk_setup_firmware(hdev, bdev->data->fwname); 781 + err = btmtk_setup_firmware(hdev, bdev->data->fwname, mtk_hci_wmt_sync); 653 782 if (err < 0) 654 783 return err; 655 784 ··· 672 801 } 673 802 674 803 /* Enable Bluetooth protocol */ 675 - wmt_params.op = MTK_WMT_FUNC_CTRL; 804 + wmt_params.op = BTMTK_WMT_FUNC_CTRL; 676 805 wmt_params.flag = 0; 677 806 wmt_params.dlen = sizeof(param); 678 807 wmt_params.data = &param; ··· 717 846 int err; 718 847 719 848 /* Disable the device */ 720 - wmt_params.op = MTK_WMT_FUNC_CTRL; 849 + wmt_params.op = BTMTK_WMT_FUNC_CTRL; 721 850 wmt_params.flag = 0; 722 851 wmt_params.dlen = sizeof(param); 723 852 wmt_params.data = &param; ··· 1002 1131 MODULE_DESCRIPTION("MediaTek Bluetooth Serial driver ver " VERSION); 1003 1132 MODULE_VERSION(VERSION); 1004 1133 MODULE_LICENSE("GPL"); 1005 - MODULE_FIRMWARE(FIRMWARE_MT7622); 1006 - MODULE_FIRMWARE(FIRMWARE_MT7663); 1007 - MODULE_FIRMWARE(FIRMWARE_MT7668);