0001
0002
0003
0004
0005
0006
0007
0008
0009 #include <linux/module.h>
0010 #include <linux/firmware.h>
0011 #include <linux/dmi.h>
0012 #include <linux/of.h>
0013 #include <asm/unaligned.h>
0014
0015 #include <net/bluetooth/bluetooth.h>
0016 #include <net/bluetooth/hci_core.h>
0017
0018 #include "btbcm.h"
0019
0020 #define VERSION "0.1"
0021
0022 #define BDADDR_BCM20702A0 (&(bdaddr_t) {{0x00, 0xa0, 0x02, 0x70, 0x20, 0x00}})
0023 #define BDADDR_BCM20702A1 (&(bdaddr_t) {{0x00, 0x00, 0xa0, 0x02, 0x70, 0x20}})
0024 #define BDADDR_BCM2076B1 (&(bdaddr_t) {{0x79, 0x56, 0x00, 0xa0, 0x76, 0x20}})
0025 #define BDADDR_BCM43430A0 (&(bdaddr_t) {{0xac, 0x1f, 0x12, 0xa0, 0x43, 0x43}})
0026 #define BDADDR_BCM4324B3 (&(bdaddr_t) {{0x00, 0x00, 0x00, 0xb3, 0x24, 0x43}})
0027 #define BDADDR_BCM4330B1 (&(bdaddr_t) {{0x00, 0x00, 0x00, 0xb1, 0x30, 0x43}})
0028 #define BDADDR_BCM4334B0 (&(bdaddr_t) {{0x00, 0x00, 0x00, 0xb0, 0x34, 0x43}})
0029 #define BDADDR_BCM4345C5 (&(bdaddr_t) {{0xac, 0x1f, 0x00, 0xc5, 0x45, 0x43}})
0030 #define BDADDR_BCM43341B (&(bdaddr_t) {{0xac, 0x1f, 0x00, 0x1b, 0x34, 0x43}})
0031
0032 #define BCM_FW_NAME_LEN 64
0033 #define BCM_FW_NAME_COUNT_MAX 4
0034
0035 typedef char bcm_fw_name[BCM_FW_NAME_LEN];
0036
0037 int btbcm_check_bdaddr(struct hci_dev *hdev)
0038 {
0039 struct hci_rp_read_bd_addr *bda;
0040 struct sk_buff *skb;
0041
0042 skb = __hci_cmd_sync(hdev, HCI_OP_READ_BD_ADDR, 0, NULL,
0043 HCI_INIT_TIMEOUT);
0044 if (IS_ERR(skb)) {
0045 int err = PTR_ERR(skb);
0046
0047 bt_dev_err(hdev, "BCM: Reading device address failed (%d)", err);
0048 return err;
0049 }
0050
0051 if (skb->len != sizeof(*bda)) {
0052 bt_dev_err(hdev, "BCM: Device address length mismatch");
0053 kfree_skb(skb);
0054 return -EIO;
0055 }
0056
0057 bda = (struct hci_rp_read_bd_addr *)skb->data;
0058
0059
0060
0061
0062
0063
0064
0065
0066
0067
0068
0069
0070
0071
0072
0073
0074
0075
0076
0077
0078
0079
0080
0081 if (!bacmp(&bda->bdaddr, BDADDR_BCM20702A0) ||
0082 !bacmp(&bda->bdaddr, BDADDR_BCM20702A1) ||
0083 !bacmp(&bda->bdaddr, BDADDR_BCM2076B1) ||
0084 !bacmp(&bda->bdaddr, BDADDR_BCM4324B3) ||
0085 !bacmp(&bda->bdaddr, BDADDR_BCM4330B1) ||
0086 !bacmp(&bda->bdaddr, BDADDR_BCM4334B0) ||
0087 !bacmp(&bda->bdaddr, BDADDR_BCM4345C5) ||
0088 !bacmp(&bda->bdaddr, BDADDR_BCM43430A0) ||
0089 !bacmp(&bda->bdaddr, BDADDR_BCM43341B)) {
0090 bt_dev_info(hdev, "BCM: Using default device address (%pMR)",
0091 &bda->bdaddr);
0092 set_bit(HCI_QUIRK_INVALID_BDADDR, &hdev->quirks);
0093 }
0094
0095 kfree_skb(skb);
0096
0097 return 0;
0098 }
0099 EXPORT_SYMBOL_GPL(btbcm_check_bdaddr);
0100
0101 int btbcm_set_bdaddr(struct hci_dev *hdev, const bdaddr_t *bdaddr)
0102 {
0103 struct sk_buff *skb;
0104 int err;
0105
0106 skb = __hci_cmd_sync(hdev, 0xfc01, 6, bdaddr, HCI_INIT_TIMEOUT);
0107 if (IS_ERR(skb)) {
0108 err = PTR_ERR(skb);
0109 bt_dev_err(hdev, "BCM: Change address command failed (%d)", err);
0110 return err;
0111 }
0112 kfree_skb(skb);
0113
0114 return 0;
0115 }
0116 EXPORT_SYMBOL_GPL(btbcm_set_bdaddr);
0117
0118 int btbcm_read_pcm_int_params(struct hci_dev *hdev,
0119 struct bcm_set_pcm_int_params *params)
0120 {
0121 struct sk_buff *skb;
0122 int err = 0;
0123
0124 skb = __hci_cmd_sync(hdev, 0xfc1d, 0, NULL, HCI_INIT_TIMEOUT);
0125 if (IS_ERR(skb)) {
0126 err = PTR_ERR(skb);
0127 bt_dev_err(hdev, "BCM: Read PCM int params failed (%d)", err);
0128 return err;
0129 }
0130
0131 if (skb->len != 6 || skb->data[0]) {
0132 bt_dev_err(hdev, "BCM: Read PCM int params length mismatch");
0133 kfree_skb(skb);
0134 return -EIO;
0135 }
0136
0137 if (params)
0138 memcpy(params, skb->data + 1, 5);
0139
0140 kfree_skb(skb);
0141
0142 return 0;
0143 }
0144 EXPORT_SYMBOL_GPL(btbcm_read_pcm_int_params);
0145
0146 int btbcm_write_pcm_int_params(struct hci_dev *hdev,
0147 const struct bcm_set_pcm_int_params *params)
0148 {
0149 struct sk_buff *skb;
0150 int err;
0151
0152 skb = __hci_cmd_sync(hdev, 0xfc1c, 5, params, HCI_INIT_TIMEOUT);
0153 if (IS_ERR(skb)) {
0154 err = PTR_ERR(skb);
0155 bt_dev_err(hdev, "BCM: Write PCM int params failed (%d)", err);
0156 return err;
0157 }
0158 kfree_skb(skb);
0159
0160 return 0;
0161 }
0162 EXPORT_SYMBOL_GPL(btbcm_write_pcm_int_params);
0163
0164 int btbcm_patchram(struct hci_dev *hdev, const struct firmware *fw)
0165 {
0166 const struct hci_command_hdr *cmd;
0167 const u8 *fw_ptr;
0168 size_t fw_size;
0169 struct sk_buff *skb;
0170 u16 opcode;
0171 int err = 0;
0172
0173
0174 skb = __hci_cmd_sync(hdev, 0xfc2e, 0, NULL, HCI_INIT_TIMEOUT);
0175 if (IS_ERR(skb)) {
0176 err = PTR_ERR(skb);
0177 bt_dev_err(hdev, "BCM: Download Minidrv command failed (%d)",
0178 err);
0179 goto done;
0180 }
0181 kfree_skb(skb);
0182
0183
0184 msleep(50);
0185
0186 fw_ptr = fw->data;
0187 fw_size = fw->size;
0188
0189 while (fw_size >= sizeof(*cmd)) {
0190 const u8 *cmd_param;
0191
0192 cmd = (struct hci_command_hdr *)fw_ptr;
0193 fw_ptr += sizeof(*cmd);
0194 fw_size -= sizeof(*cmd);
0195
0196 if (fw_size < cmd->plen) {
0197 bt_dev_err(hdev, "BCM: Patch is corrupted");
0198 err = -EINVAL;
0199 goto done;
0200 }
0201
0202 cmd_param = fw_ptr;
0203 fw_ptr += cmd->plen;
0204 fw_size -= cmd->plen;
0205
0206 opcode = le16_to_cpu(cmd->opcode);
0207
0208 skb = __hci_cmd_sync(hdev, opcode, cmd->plen, cmd_param,
0209 HCI_INIT_TIMEOUT);
0210 if (IS_ERR(skb)) {
0211 err = PTR_ERR(skb);
0212 bt_dev_err(hdev, "BCM: Patch command %04x failed (%d)",
0213 opcode, err);
0214 goto done;
0215 }
0216 kfree_skb(skb);
0217 }
0218
0219
0220 msleep(250);
0221
0222 done:
0223 return err;
0224 }
0225 EXPORT_SYMBOL(btbcm_patchram);
0226
0227 static int btbcm_reset(struct hci_dev *hdev)
0228 {
0229 struct sk_buff *skb;
0230
0231 skb = __hci_cmd_sync(hdev, HCI_OP_RESET, 0, NULL, HCI_INIT_TIMEOUT);
0232 if (IS_ERR(skb)) {
0233 int err = PTR_ERR(skb);
0234
0235 bt_dev_err(hdev, "BCM: Reset failed (%d)", err);
0236 return err;
0237 }
0238 kfree_skb(skb);
0239
0240
0241 msleep(100);
0242
0243 return 0;
0244 }
0245
0246 static struct sk_buff *btbcm_read_local_name(struct hci_dev *hdev)
0247 {
0248 struct sk_buff *skb;
0249
0250 skb = __hci_cmd_sync(hdev, HCI_OP_READ_LOCAL_NAME, 0, NULL,
0251 HCI_INIT_TIMEOUT);
0252 if (IS_ERR(skb)) {
0253 bt_dev_err(hdev, "BCM: Reading local name failed (%ld)",
0254 PTR_ERR(skb));
0255 return skb;
0256 }
0257
0258 if (skb->len != sizeof(struct hci_rp_read_local_name)) {
0259 bt_dev_err(hdev, "BCM: Local name length mismatch");
0260 kfree_skb(skb);
0261 return ERR_PTR(-EIO);
0262 }
0263
0264 return skb;
0265 }
0266
0267 static struct sk_buff *btbcm_read_local_version(struct hci_dev *hdev)
0268 {
0269 struct sk_buff *skb;
0270
0271 skb = __hci_cmd_sync(hdev, HCI_OP_READ_LOCAL_VERSION, 0, NULL,
0272 HCI_INIT_TIMEOUT);
0273 if (IS_ERR(skb)) {
0274 bt_dev_err(hdev, "BCM: Reading local version info failed (%ld)",
0275 PTR_ERR(skb));
0276 return skb;
0277 }
0278
0279 if (skb->len != sizeof(struct hci_rp_read_local_version)) {
0280 bt_dev_err(hdev, "BCM: Local version length mismatch");
0281 kfree_skb(skb);
0282 return ERR_PTR(-EIO);
0283 }
0284
0285 return skb;
0286 }
0287
0288 static struct sk_buff *btbcm_read_verbose_config(struct hci_dev *hdev)
0289 {
0290 struct sk_buff *skb;
0291
0292 skb = __hci_cmd_sync(hdev, 0xfc79, 0, NULL, HCI_INIT_TIMEOUT);
0293 if (IS_ERR(skb)) {
0294 bt_dev_err(hdev, "BCM: Read verbose config info failed (%ld)",
0295 PTR_ERR(skb));
0296 return skb;
0297 }
0298
0299 if (skb->len != 7) {
0300 bt_dev_err(hdev, "BCM: Verbose config length mismatch");
0301 kfree_skb(skb);
0302 return ERR_PTR(-EIO);
0303 }
0304
0305 return skb;
0306 }
0307
0308 static struct sk_buff *btbcm_read_controller_features(struct hci_dev *hdev)
0309 {
0310 struct sk_buff *skb;
0311
0312 skb = __hci_cmd_sync(hdev, 0xfc6e, 0, NULL, HCI_INIT_TIMEOUT);
0313 if (IS_ERR(skb)) {
0314 bt_dev_err(hdev, "BCM: Read controller features failed (%ld)",
0315 PTR_ERR(skb));
0316 return skb;
0317 }
0318
0319 if (skb->len != 9) {
0320 bt_dev_err(hdev, "BCM: Controller features length mismatch");
0321 kfree_skb(skb);
0322 return ERR_PTR(-EIO);
0323 }
0324
0325 return skb;
0326 }
0327
0328 static struct sk_buff *btbcm_read_usb_product(struct hci_dev *hdev)
0329 {
0330 struct sk_buff *skb;
0331
0332 skb = __hci_cmd_sync(hdev, 0xfc5a, 0, NULL, HCI_INIT_TIMEOUT);
0333 if (IS_ERR(skb)) {
0334 bt_dev_err(hdev, "BCM: Read USB product info failed (%ld)",
0335 PTR_ERR(skb));
0336 return skb;
0337 }
0338
0339 if (skb->len != 5) {
0340 bt_dev_err(hdev, "BCM: USB product length mismatch");
0341 kfree_skb(skb);
0342 return ERR_PTR(-EIO);
0343 }
0344
0345 return skb;
0346 }
0347
0348 static const struct dmi_system_id disable_broken_read_transmit_power[] = {
0349 {
0350 .matches = {
0351 DMI_MATCH(DMI_BOARD_VENDOR, "Apple Inc."),
0352 DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro16,1"),
0353 },
0354 },
0355 {
0356 .matches = {
0357 DMI_MATCH(DMI_BOARD_VENDOR, "Apple Inc."),
0358 DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro16,2"),
0359 },
0360 },
0361 {
0362 .matches = {
0363 DMI_MATCH(DMI_BOARD_VENDOR, "Apple Inc."),
0364 DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro16,4"),
0365 },
0366 },
0367 {
0368 .matches = {
0369 DMI_MATCH(DMI_BOARD_VENDOR, "Apple Inc."),
0370 DMI_MATCH(DMI_PRODUCT_NAME, "MacBookAir8,1"),
0371 },
0372 },
0373 {
0374 .matches = {
0375 DMI_MATCH(DMI_BOARD_VENDOR, "Apple Inc."),
0376 DMI_MATCH(DMI_PRODUCT_NAME, "MacBookAir8,2"),
0377 },
0378 },
0379 {
0380 .matches = {
0381 DMI_MATCH(DMI_BOARD_VENDOR, "Apple Inc."),
0382 DMI_MATCH(DMI_PRODUCT_NAME, "iMac20,1"),
0383 },
0384 },
0385 {
0386 .matches = {
0387 DMI_MATCH(DMI_BOARD_VENDOR, "Apple Inc."),
0388 DMI_MATCH(DMI_PRODUCT_NAME, "iMac20,2"),
0389 },
0390 },
0391 { }
0392 };
0393
0394 static int btbcm_read_info(struct hci_dev *hdev)
0395 {
0396 struct sk_buff *skb;
0397
0398
0399 skb = btbcm_read_verbose_config(hdev);
0400 if (IS_ERR(skb))
0401 return PTR_ERR(skb);
0402
0403 bt_dev_info(hdev, "BCM: chip id %u", skb->data[1]);
0404 kfree_skb(skb);
0405
0406 return 0;
0407 }
0408
0409 static int btbcm_print_controller_features(struct hci_dev *hdev)
0410 {
0411 struct sk_buff *skb;
0412
0413
0414 skb = btbcm_read_controller_features(hdev);
0415 if (IS_ERR(skb))
0416 return PTR_ERR(skb);
0417
0418 bt_dev_info(hdev, "BCM: features 0x%2.2x", skb->data[1]);
0419 kfree_skb(skb);
0420
0421
0422 if (dmi_first_match(disable_broken_read_transmit_power))
0423 set_bit(HCI_QUIRK_BROKEN_READ_TRANSMIT_POWER, &hdev->quirks);
0424
0425 return 0;
0426 }
0427
0428 static int btbcm_print_local_name(struct hci_dev *hdev)
0429 {
0430 struct sk_buff *skb;
0431
0432
0433 skb = btbcm_read_local_name(hdev);
0434 if (IS_ERR(skb))
0435 return PTR_ERR(skb);
0436
0437 bt_dev_info(hdev, "%s", (char *)(skb->data + 1));
0438 kfree_skb(skb);
0439
0440 return 0;
0441 }
0442
0443 struct bcm_subver_table {
0444 u16 subver;
0445 const char *name;
0446 };
0447
0448 static const struct bcm_subver_table bcm_uart_subver_table[] = {
0449 { 0x1111, "BCM4362A2" },
0450 { 0x4103, "BCM4330B1" },
0451 { 0x410d, "BCM4334B0" },
0452 { 0x410e, "BCM43341B0" },
0453 { 0x4204, "BCM2076B1" },
0454 { 0x4406, "BCM4324B3" },
0455 { 0x4606, "BCM4324B5" },
0456 { 0x6109, "BCM4335C0" },
0457 { 0x610c, "BCM4354" },
0458 { 0x2122, "BCM4343A0" },
0459 { 0x2209, "BCM43430A1" },
0460 { 0x6119, "BCM4345C0" },
0461 { 0x6606, "BCM4345C5" },
0462 { 0x230f, "BCM4356A2" },
0463 { 0x220e, "BCM20702A1" },
0464 { 0x420d, "BCM4349B1" },
0465 { 0x420e, "BCM4349B1" },
0466 { 0x4217, "BCM4329B1" },
0467 { 0x6106, "BCM4359C0" },
0468 { 0x4106, "BCM4335A0" },
0469 { 0x410c, "BCM43430B0" },
0470 { 0x2119, "BCM4373A0" },
0471 { }
0472 };
0473
0474 static const struct bcm_subver_table bcm_usb_subver_table[] = {
0475 { 0x2105, "BCM20703A1" },
0476 { 0x210b, "BCM43142A0" },
0477 { 0x2112, "BCM4314A0" },
0478 { 0x2118, "BCM20702A0" },
0479 { 0x2126, "BCM4335A0" },
0480 { 0x220e, "BCM20702A1" },
0481 { 0x230f, "BCM4356A2" },
0482 { 0x4106, "BCM4335B0" },
0483 { 0x410e, "BCM20702B0" },
0484 { 0x6109, "BCM4335C0" },
0485 { 0x610c, "BCM4354" },
0486 { 0x6607, "BCM4350C5" },
0487 { }
0488 };
0489
0490
0491
0492
0493
0494 static const char *btbcm_get_board_name(struct device *dev)
0495 {
0496 #ifdef CONFIG_OF
0497 struct device_node *root;
0498 char *board_type;
0499 const char *tmp;
0500 int len;
0501 int i;
0502
0503 root = of_find_node_by_path("/");
0504 if (!root)
0505 return NULL;
0506
0507 if (of_property_read_string_index(root, "compatible", 0, &tmp))
0508 return NULL;
0509
0510
0511 len = strlen(tmp) + 1;
0512 board_type = devm_kzalloc(dev, len, GFP_KERNEL);
0513 strscpy(board_type, tmp, len);
0514 for (i = 0; i < board_type[i]; i++) {
0515 if (board_type[i] == '/')
0516 board_type[i] = '-';
0517 }
0518 of_node_put(root);
0519
0520 return board_type;
0521 #else
0522 return NULL;
0523 #endif
0524 }
0525
0526 int btbcm_initialize(struct hci_dev *hdev, bool *fw_load_done, bool use_autobaud_mode)
0527 {
0528 u16 subver, rev, pid, vid;
0529 struct sk_buff *skb;
0530 struct hci_rp_read_local_version *ver;
0531 const struct bcm_subver_table *bcm_subver_table;
0532 const char *hw_name = NULL;
0533 const char *board_name;
0534 char postfix[16] = "";
0535 int fw_name_count = 0;
0536 bcm_fw_name *fw_name;
0537 const struct firmware *fw;
0538 int i, err;
0539
0540 board_name = btbcm_get_board_name(&hdev->dev);
0541
0542
0543 err = btbcm_reset(hdev);
0544 if (err)
0545 return err;
0546
0547
0548 skb = btbcm_read_local_version(hdev);
0549 if (IS_ERR(skb))
0550 return PTR_ERR(skb);
0551
0552 ver = (struct hci_rp_read_local_version *)skb->data;
0553 rev = le16_to_cpu(ver->hci_rev);
0554 subver = le16_to_cpu(ver->lmp_subver);
0555 kfree_skb(skb);
0556
0557
0558 if (!(*fw_load_done)) {
0559 err = btbcm_read_info(hdev);
0560 if (err)
0561 return err;
0562 }
0563
0564 if (!use_autobaud_mode) {
0565 err = btbcm_print_controller_features(hdev);
0566 if (err)
0567 return err;
0568
0569 err = btbcm_print_local_name(hdev);
0570 if (err)
0571 return err;
0572 }
0573
0574 bcm_subver_table = (hdev->bus == HCI_USB) ? bcm_usb_subver_table :
0575 bcm_uart_subver_table;
0576
0577 for (i = 0; bcm_subver_table[i].name; i++) {
0578 if (subver == bcm_subver_table[i].subver) {
0579 hw_name = bcm_subver_table[i].name;
0580 break;
0581 }
0582 }
0583
0584 bt_dev_info(hdev, "%s (%3.3u.%3.3u.%3.3u) build %4.4u",
0585 hw_name ? hw_name : "BCM", (subver & 0xe000) >> 13,
0586 (subver & 0x1f00) >> 8, (subver & 0x00ff), rev & 0x0fff);
0587
0588 if (*fw_load_done)
0589 return 0;
0590
0591 if (hdev->bus == HCI_USB) {
0592
0593 skb = btbcm_read_usb_product(hdev);
0594 if (IS_ERR(skb))
0595 return PTR_ERR(skb);
0596
0597 vid = get_unaligned_le16(skb->data + 1);
0598 pid = get_unaligned_le16(skb->data + 3);
0599 kfree_skb(skb);
0600
0601 snprintf(postfix, sizeof(postfix), "-%4.4x-%4.4x", vid, pid);
0602 }
0603
0604 fw_name = kmalloc(BCM_FW_NAME_COUNT_MAX * BCM_FW_NAME_LEN, GFP_KERNEL);
0605 if (!fw_name)
0606 return -ENOMEM;
0607
0608 if (hw_name) {
0609 if (board_name) {
0610 snprintf(fw_name[fw_name_count], BCM_FW_NAME_LEN,
0611 "brcm/%s%s.%s.hcd", hw_name, postfix, board_name);
0612 fw_name_count++;
0613 }
0614 snprintf(fw_name[fw_name_count], BCM_FW_NAME_LEN,
0615 "brcm/%s%s.hcd", hw_name, postfix);
0616 fw_name_count++;
0617 }
0618
0619 if (board_name) {
0620 snprintf(fw_name[fw_name_count], BCM_FW_NAME_LEN,
0621 "brcm/BCM%s.%s.hcd", postfix, board_name);
0622 fw_name_count++;
0623 }
0624 snprintf(fw_name[fw_name_count], BCM_FW_NAME_LEN,
0625 "brcm/BCM%s.hcd", postfix);
0626 fw_name_count++;
0627
0628 for (i = 0; i < fw_name_count; i++) {
0629 err = firmware_request_nowarn(&fw, fw_name[i], &hdev->dev);
0630 if (err == 0) {
0631 bt_dev_info(hdev, "%s '%s' Patch",
0632 hw_name ? hw_name : "BCM", fw_name[i]);
0633 *fw_load_done = true;
0634 break;
0635 }
0636 }
0637
0638 if (*fw_load_done) {
0639 err = btbcm_patchram(hdev, fw);
0640 if (err)
0641 bt_dev_info(hdev, "BCM: Patch failed (%d)", err);
0642
0643 release_firmware(fw);
0644 } else {
0645 bt_dev_err(hdev, "BCM: firmware Patch file not found, tried:");
0646 for (i = 0; i < fw_name_count; i++)
0647 bt_dev_err(hdev, "BCM: '%s'", fw_name[i]);
0648 }
0649
0650 kfree(fw_name);
0651 return 0;
0652 }
0653 EXPORT_SYMBOL_GPL(btbcm_initialize);
0654
0655 int btbcm_finalize(struct hci_dev *hdev, bool *fw_load_done, bool use_autobaud_mode)
0656 {
0657 int err;
0658
0659
0660 if (*fw_load_done) {
0661 err = btbcm_initialize(hdev, fw_load_done, use_autobaud_mode);
0662 if (err)
0663 return err;
0664 }
0665
0666 btbcm_check_bdaddr(hdev);
0667
0668 set_bit(HCI_QUIRK_STRICT_DUPLICATE_FILTER, &hdev->quirks);
0669
0670 return 0;
0671 }
0672 EXPORT_SYMBOL_GPL(btbcm_finalize);
0673
0674 int btbcm_setup_patchram(struct hci_dev *hdev)
0675 {
0676 bool fw_load_done = false;
0677 bool use_autobaud_mode = false;
0678 int err;
0679
0680
0681 err = btbcm_initialize(hdev, &fw_load_done, use_autobaud_mode);
0682 if (err)
0683 return err;
0684
0685
0686 return btbcm_finalize(hdev, &fw_load_done, use_autobaud_mode);
0687 }
0688 EXPORT_SYMBOL_GPL(btbcm_setup_patchram);
0689
0690 int btbcm_setup_apple(struct hci_dev *hdev)
0691 {
0692 struct sk_buff *skb;
0693 int err;
0694
0695
0696 err = btbcm_reset(hdev);
0697 if (err)
0698 return err;
0699
0700
0701 skb = btbcm_read_verbose_config(hdev);
0702 if (!IS_ERR(skb)) {
0703 bt_dev_info(hdev, "BCM: chip id %u build %4.4u",
0704 skb->data[1], get_unaligned_le16(skb->data + 5));
0705 kfree_skb(skb);
0706 }
0707
0708
0709 skb = btbcm_read_usb_product(hdev);
0710 if (!IS_ERR(skb)) {
0711 bt_dev_info(hdev, "BCM: product %4.4x:%4.4x",
0712 get_unaligned_le16(skb->data + 1),
0713 get_unaligned_le16(skb->data + 3));
0714 kfree_skb(skb);
0715 }
0716
0717
0718 skb = btbcm_read_controller_features(hdev);
0719 if (!IS_ERR(skb)) {
0720 bt_dev_info(hdev, "BCM: features 0x%2.2x", skb->data[1]);
0721 kfree_skb(skb);
0722 }
0723
0724
0725 skb = btbcm_read_local_name(hdev);
0726 if (!IS_ERR(skb)) {
0727 bt_dev_info(hdev, "%s", (char *)(skb->data + 1));
0728 kfree_skb(skb);
0729 }
0730
0731 set_bit(HCI_QUIRK_STRICT_DUPLICATE_FILTER, &hdev->quirks);
0732
0733 return 0;
0734 }
0735 EXPORT_SYMBOL_GPL(btbcm_setup_apple);
0736
0737 MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>");
0738 MODULE_DESCRIPTION("Bluetooth support for Broadcom devices ver " VERSION);
0739 MODULE_VERSION(VERSION);
0740 MODULE_LICENSE("GPL");