0001
0002
0003
0004
0005 #include <linux/module.h>
0006 #include <linux/firmware.h>
0007
0008 #include <net/bluetooth/bluetooth.h>
0009 #include <net/bluetooth/hci_core.h>
0010
0011 #include "btmtk.h"
0012
0013 #define VERSION "0.1"
0014
0015
0016 #define MTK_FW_ROM_PATCH_HEADER_SIZE 32
0017 #define MTK_FW_ROM_PATCH_GD_SIZE 64
0018 #define MTK_FW_ROM_PATCH_SEC_MAP_SIZE 64
0019 #define MTK_SEC_MAP_COMMON_SIZE 12
0020 #define MTK_SEC_MAP_NEED_SEND_SIZE 52
0021
0022 struct btmtk_patch_header {
0023 u8 datetime[16];
0024 u8 platform[4];
0025 __le16 hwver;
0026 __le16 swver;
0027 __le32 magicnum;
0028 } __packed;
0029
0030 struct btmtk_global_desc {
0031 __le32 patch_ver;
0032 __le32 sub_sys;
0033 __le32 feature_opt;
0034 __le32 section_num;
0035 } __packed;
0036
0037 struct btmtk_section_map {
0038 __le32 sectype;
0039 __le32 secoffset;
0040 __le32 secsize;
0041 union {
0042 __le32 u4SecSpec[13];
0043 struct {
0044 __le32 dlAddr;
0045 __le32 dlsize;
0046 __le32 seckeyidx;
0047 __le32 alignlen;
0048 __le32 sectype;
0049 __le32 dlmodecrctype;
0050 __le32 crc;
0051 __le32 reserved[6];
0052 } bin_info_spec;
0053 };
0054 } __packed;
0055
0056 int btmtk_setup_firmware_79xx(struct hci_dev *hdev, const char *fwname,
0057 wmt_cmd_sync_func_t wmt_cmd_sync)
0058 {
0059 struct btmtk_hci_wmt_params wmt_params;
0060 struct btmtk_global_desc *globaldesc = NULL;
0061 struct btmtk_section_map *sectionmap;
0062 const struct firmware *fw;
0063 const u8 *fw_ptr;
0064 const u8 *fw_bin_ptr;
0065 int err, dlen, i, status;
0066 u8 flag, first_block, retry;
0067 u32 section_num, dl_size, section_offset;
0068 u8 cmd[64];
0069
0070 err = request_firmware(&fw, fwname, &hdev->dev);
0071 if (err < 0) {
0072 bt_dev_err(hdev, "Failed to load firmware file (%d)", err);
0073 return err;
0074 }
0075
0076 fw_ptr = fw->data;
0077 fw_bin_ptr = fw_ptr;
0078 globaldesc = (struct btmtk_global_desc *)(fw_ptr + MTK_FW_ROM_PATCH_HEADER_SIZE);
0079 section_num = le32_to_cpu(globaldesc->section_num);
0080
0081 for (i = 0; i < section_num; i++) {
0082 first_block = 1;
0083 fw_ptr = fw_bin_ptr;
0084 sectionmap = (struct btmtk_section_map *)(fw_ptr + MTK_FW_ROM_PATCH_HEADER_SIZE +
0085 MTK_FW_ROM_PATCH_GD_SIZE + MTK_FW_ROM_PATCH_SEC_MAP_SIZE * i);
0086
0087 section_offset = le32_to_cpu(sectionmap->secoffset);
0088 dl_size = le32_to_cpu(sectionmap->bin_info_spec.dlsize);
0089
0090 if (dl_size > 0) {
0091 retry = 20;
0092 while (retry > 0) {
0093 cmd[0] = 0;
0094 memcpy(cmd + 1,
0095 fw_ptr + MTK_FW_ROM_PATCH_HEADER_SIZE +
0096 MTK_FW_ROM_PATCH_GD_SIZE +
0097 MTK_FW_ROM_PATCH_SEC_MAP_SIZE * i +
0098 MTK_SEC_MAP_COMMON_SIZE,
0099 MTK_SEC_MAP_NEED_SEND_SIZE + 1);
0100
0101 wmt_params.op = BTMTK_WMT_PATCH_DWNLD;
0102 wmt_params.status = &status;
0103 wmt_params.flag = 0;
0104 wmt_params.dlen = MTK_SEC_MAP_NEED_SEND_SIZE + 1;
0105 wmt_params.data = &cmd;
0106
0107 err = wmt_cmd_sync(hdev, &wmt_params);
0108 if (err < 0) {
0109 bt_dev_err(hdev, "Failed to send wmt patch dwnld (%d)",
0110 err);
0111 goto err_release_fw;
0112 }
0113
0114 if (status == BTMTK_WMT_PATCH_UNDONE) {
0115 break;
0116 } else if (status == BTMTK_WMT_PATCH_PROGRESS) {
0117 msleep(100);
0118 retry--;
0119 } else if (status == BTMTK_WMT_PATCH_DONE) {
0120 goto next_section;
0121 } else {
0122 bt_dev_err(hdev, "Failed wmt patch dwnld status (%d)",
0123 status);
0124 err = -EIO;
0125 goto err_release_fw;
0126 }
0127 }
0128
0129 fw_ptr += section_offset;
0130 wmt_params.op = BTMTK_WMT_PATCH_DWNLD;
0131 wmt_params.status = NULL;
0132
0133 while (dl_size > 0) {
0134 dlen = min_t(int, 250, dl_size);
0135 if (first_block == 1) {
0136 flag = 1;
0137 first_block = 0;
0138 } else if (dl_size - dlen <= 0) {
0139 flag = 3;
0140 } else {
0141 flag = 2;
0142 }
0143
0144 wmt_params.flag = flag;
0145 wmt_params.dlen = dlen;
0146 wmt_params.data = fw_ptr;
0147
0148 err = wmt_cmd_sync(hdev, &wmt_params);
0149 if (err < 0) {
0150 bt_dev_err(hdev, "Failed to send wmt patch dwnld (%d)",
0151 err);
0152 goto err_release_fw;
0153 }
0154
0155 dl_size -= dlen;
0156 fw_ptr += dlen;
0157 }
0158 }
0159 next_section:
0160 continue;
0161 }
0162
0163 usleep_range(100000, 120000);
0164
0165 err_release_fw:
0166 release_firmware(fw);
0167
0168 return err;
0169 }
0170 EXPORT_SYMBOL_GPL(btmtk_setup_firmware_79xx);
0171
0172 int btmtk_setup_firmware(struct hci_dev *hdev, const char *fwname,
0173 wmt_cmd_sync_func_t wmt_cmd_sync)
0174 {
0175 struct btmtk_hci_wmt_params wmt_params;
0176 const struct firmware *fw;
0177 const u8 *fw_ptr;
0178 size_t fw_size;
0179 int err, dlen;
0180 u8 flag, param;
0181
0182 err = request_firmware(&fw, fwname, &hdev->dev);
0183 if (err < 0) {
0184 bt_dev_err(hdev, "Failed to load firmware file (%d)", err);
0185 return err;
0186 }
0187
0188
0189 param = 1;
0190 wmt_params.op = BTMTK_WMT_FUNC_CTRL;
0191 wmt_params.flag = 3;
0192 wmt_params.dlen = sizeof(param);
0193 wmt_params.data = ¶m;
0194 wmt_params.status = NULL;
0195
0196 err = wmt_cmd_sync(hdev, &wmt_params);
0197 if (err < 0) {
0198 bt_dev_err(hdev, "Failed to power on data RAM (%d)", err);
0199 goto err_release_fw;
0200 }
0201
0202 fw_ptr = fw->data;
0203 fw_size = fw->size;
0204
0205
0206 if (fw_size < 30) {
0207 err = -EINVAL;
0208 goto err_release_fw;
0209 }
0210
0211 fw_size -= 30;
0212 fw_ptr += 30;
0213 flag = 1;
0214
0215 wmt_params.op = BTMTK_WMT_PATCH_DWNLD;
0216 wmt_params.status = NULL;
0217
0218 while (fw_size > 0) {
0219 dlen = min_t(int, 250, fw_size);
0220
0221
0222 if (fw_size - dlen <= 0)
0223 flag = 3;
0224 else if (fw_size < fw->size - 30)
0225 flag = 2;
0226
0227 wmt_params.flag = flag;
0228 wmt_params.dlen = dlen;
0229 wmt_params.data = fw_ptr;
0230
0231 err = wmt_cmd_sync(hdev, &wmt_params);
0232 if (err < 0) {
0233 bt_dev_err(hdev, "Failed to send wmt patch dwnld (%d)",
0234 err);
0235 goto err_release_fw;
0236 }
0237
0238 fw_size -= dlen;
0239 fw_ptr += dlen;
0240 }
0241
0242 wmt_params.op = BTMTK_WMT_RST;
0243 wmt_params.flag = 4;
0244 wmt_params.dlen = 0;
0245 wmt_params.data = NULL;
0246 wmt_params.status = NULL;
0247
0248
0249 err = wmt_cmd_sync(hdev, &wmt_params);
0250 if (err < 0) {
0251 bt_dev_err(hdev, "Failed to send wmt rst (%d)", err);
0252 goto err_release_fw;
0253 }
0254
0255
0256 usleep_range(10000, 12000);
0257
0258 err_release_fw:
0259 release_firmware(fw);
0260
0261 return err;
0262 }
0263 EXPORT_SYMBOL_GPL(btmtk_setup_firmware);
0264
0265 int btmtk_set_bdaddr(struct hci_dev *hdev, const bdaddr_t *bdaddr)
0266 {
0267 struct sk_buff *skb;
0268 long ret;
0269
0270 skb = __hci_cmd_sync(hdev, 0xfc1a, 6, bdaddr, HCI_INIT_TIMEOUT);
0271 if (IS_ERR(skb)) {
0272 ret = PTR_ERR(skb);
0273 bt_dev_err(hdev, "changing Mediatek device address failed (%ld)",
0274 ret);
0275 return ret;
0276 }
0277 kfree_skb(skb);
0278
0279 return 0;
0280 }
0281 EXPORT_SYMBOL_GPL(btmtk_set_bdaddr);
0282
0283 MODULE_AUTHOR("Sean Wang <sean.wang@mediatek.com>");
0284 MODULE_AUTHOR("Mark Chen <mark-yw.chen@mediatek.com>");
0285 MODULE_DESCRIPTION("Bluetooth support for MediaTek devices ver " VERSION);
0286 MODULE_VERSION(VERSION);
0287 MODULE_LICENSE("GPL");
0288 MODULE_FIRMWARE(FIRMWARE_MT7622);
0289 MODULE_FIRMWARE(FIRMWARE_MT7663);
0290 MODULE_FIRMWARE(FIRMWARE_MT7668);
0291 MODULE_FIRMWARE(FIRMWARE_MT7961);