From 54d44290debae98ac25416742a7534046b011125 Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Fri, 7 Oct 2022 09:50:42 +0100 Subject: [PATCH] Bluetooth: btbcm: Allow board-specific firmware names There are some devices available from multiple vendors that report the same ID. In order to load the appropriate firmware, use the board name from the FDT as a disambiguating factor, as is done for WLAN firmwares. Signed-off-by: Phil Elwell --- drivers/bluetooth/btbcm.c | 30 +++++++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/drivers/bluetooth/btbcm.c b/drivers/bluetooth/btbcm.c index a18f289..ee18cfc 100644 --- a/drivers/bluetooth/btbcm.c +++ b/drivers/bluetooth/btbcm.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #include @@ -29,7 +30,7 @@ #define BDADDR_BCM43341B (&(bdaddr_t) {{0xac, 0x1f, 0x00, 0x1b, 0x34, 0x43}}) #define BCM_FW_NAME_LEN 64 -#define BCM_FW_NAME_COUNT_MAX 2 +#define BCM_FW_NAME_COUNT_MAX 3 /* For kmalloc-ing the fw-name array instead of putting it on the stack */ typedef char bcm_fw_name[BCM_FW_NAME_LEN]; @@ -485,6 +486,8 @@ int btbcm_initialize(struct hci_dev *hdev, bool *fw_load_done) struct hci_rp_read_local_version *ver; const struct bcm_subver_table *bcm_subver_table; const char *hw_name = NULL; + struct device_node *root; + char *board_type = NULL; char postfix[16] = ""; int fw_name_count = 0; bcm_fw_name *fw_name; @@ -550,6 +553,30 @@ int btbcm_initialize(struct hci_dev *hdev, bool *fw_load_done) if (!fw_name) return -ENOMEM; + root = of_find_node_by_path("/"); + if (root) { + int i, len; + const char *tmp; + + of_property_read_string_index(root, "compatible", 0, &tmp); + + /* convert '/'s in the compatible string to '-'s */ + len = strlen(tmp) + 1; + board_type = kzalloc(len, GFP_KERNEL); + strscpy(board_type, tmp, len); + for (i = 0; i < board_type[i]; i++) { + if (board_type[i] == '/') + board_type[i] = '-'; + } + + of_node_put(root); + } + + if (hw_name && board_type && + snprintf(fw_name[fw_name_count], BCM_FW_NAME_LEN, + "brcm/%s.%s.hcd", hw_name, board_type) < BCM_FW_NAME_LEN) + fw_name_count++; + if (hw_name) { snprintf(fw_name[fw_name_count], BCM_FW_NAME_LEN, "brcm/%s%s.hcd", hw_name, postfix); @@ -583,6 +610,7 @@ int btbcm_initialize(struct hci_dev *hdev, bool *fw_load_done) } kfree(fw_name); + kfree(board_type); return 0; } EXPORT_SYMBOL_GPL(btbcm_initialize); -- 2.7.4