summaryrefslogtreecommitdiff
path: root/drivers/bluetooth/btbcm.c
diff options
context:
space:
mode:
authorHakan Jansson <hakan.jansson@infineon.com>2022-05-30 17:02:18 +0200
committerLuiz Augusto von Dentz <luiz.von.dentz@intel.com>2022-07-21 17:04:38 -0700
commitaf35e28f0fea877832fa27802bc862b2a912f32a (patch)
treead726766d10991dcb4a10157f421cdda59c10d0f /drivers/bluetooth/btbcm.c
parent0b4de2523f281b0492de3427da82495bfca6f263 (diff)
Bluetooth: hci_bcm: Add support for FW loading in autobaud mode
Use the presence of a DT property, "brcm,requires-autobaud-mode", to enable startup in autobaud mode. If the property is present, the device is started in autobaud mode by asserting RTS (BT_UART_CTS_N) prior to powering on the device. Also prevent the use of unsupported commands for devices started in autobaud mode. Only a limited subset of HCI commands are supported in autobaud mode. Some devices (e.g. CYW5557x) require autobaud mode to enable FW loading. Autobaud mode can also be required on some boards where the controller device is using a non-standard baud rate in normal mode when first powered on. Signed-off-by: Hakan Jansson <hakan.jansson@infineon.com> Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
Diffstat (limited to 'drivers/bluetooth/btbcm.c')
-rw-r--r--drivers/bluetooth/btbcm.c31
1 files changed, 23 insertions, 8 deletions
diff --git a/drivers/bluetooth/btbcm.c b/drivers/bluetooth/btbcm.c
index 76fbb046bdbe..cfe018a6c1fc 100644
--- a/drivers/bluetooth/btbcm.c
+++ b/drivers/bluetooth/btbcm.c
@@ -403,6 +403,13 @@ static int btbcm_read_info(struct hci_dev *hdev)
bt_dev_info(hdev, "BCM: chip id %u", skb->data[1]);
kfree_skb(skb);
+ return 0;
+}
+
+static int btbcm_print_controller_features(struct hci_dev *hdev)
+{
+ struct sk_buff *skb;
+
/* Read Controller Features */
skb = btbcm_read_controller_features(hdev);
if (IS_ERR(skb))
@@ -514,7 +521,7 @@ static const char *btbcm_get_board_name(struct device *dev)
#endif
}
-int btbcm_initialize(struct hci_dev *hdev, bool *fw_load_done)
+int btbcm_initialize(struct hci_dev *hdev, bool *fw_load_done, bool use_autobaud_mode)
{
u16 subver, rev, pid, vid;
struct sk_buff *skb;
@@ -551,9 +558,16 @@ int btbcm_initialize(struct hci_dev *hdev, bool *fw_load_done)
if (err)
return err;
}
- err = btbcm_print_local_name(hdev);
- if (err)
- return err;
+
+ if (!use_autobaud_mode) {
+ err = btbcm_print_controller_features(hdev);
+ if (err)
+ return err;
+
+ err = btbcm_print_local_name(hdev);
+ if (err)
+ return err;
+ }
bcm_subver_table = (hdev->bus == HCI_USB) ? bcm_usb_subver_table :
bcm_uart_subver_table;
@@ -636,13 +650,13 @@ int btbcm_initialize(struct hci_dev *hdev, bool *fw_load_done)
}
EXPORT_SYMBOL_GPL(btbcm_initialize);
-int btbcm_finalize(struct hci_dev *hdev, bool *fw_load_done)
+int btbcm_finalize(struct hci_dev *hdev, bool *fw_load_done, bool use_autobaud_mode)
{
int err;
/* Re-initialize if necessary */
if (*fw_load_done) {
- err = btbcm_initialize(hdev, fw_load_done);
+ err = btbcm_initialize(hdev, fw_load_done, use_autobaud_mode);
if (err)
return err;
}
@@ -658,15 +672,16 @@ EXPORT_SYMBOL_GPL(btbcm_finalize);
int btbcm_setup_patchram(struct hci_dev *hdev)
{
bool fw_load_done = false;
+ bool use_autobaud_mode = false;
int err;
/* Initialize */
- err = btbcm_initialize(hdev, &fw_load_done);
+ err = btbcm_initialize(hdev, &fw_load_done, use_autobaud_mode);
if (err)
return err;
/* Re-initialize after loading Patch */
- return btbcm_finalize(hdev, &fw_load_done);
+ return btbcm_finalize(hdev, &fw_load_done, use_autobaud_mode);
}
EXPORT_SYMBOL_GPL(btbcm_setup_patchram);