From: Hans de Goede <hdegoede@redhat.com>
To: Marcel Holtmann <marcel@holtmann.org>,
Johan Hedberg <johan.hedberg@gmail.com>,
Martin Blumenstingl <martin.blumenstingl@googlemail.com>
Cc: Hans de Goede <hdegoede@redhat.com>,
robh@kernel.org, Jeremy Cline <jeremy@jcline.org>,
linux-bluetooth@vger.kernel.org, linux-serial@vger.kernel.org,
linux-acpi@vger.kernel.org, devicetree@vger.kernel.org
Subject: [PATCH 04/13] Bluetooth: btrtl: add support for retrieving the UART settings
Date: Sun, 27 May 2018 21:04:48 +0200 [thread overview]
Message-ID: <20180527190457.2632-5-hdegoede@redhat.com> (raw)
In-Reply-To: <20180527190457.2632-1-hdegoede@redhat.com>
From: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
The UART settings are embedded in the config blob. This has to be parsed
to successfully initialize the Bluetooth part of the RTL8723BS (which is
an SDIO chip, but the Bluetooth part is connected via UART).
The Realtek "rtl8723bs_bt" and "rtl8723ds_bt" userspace Bluetooth UART
initialization tools (rtk_hciattach) use the following sequence:
- send H5 sync pattern (already supported by hci_h5)
- get LMP version (already supported by btrtl)
- get ROM version (already supported by btrtl)
- load the firmware and config for the current chipset (already
supported by btrtl)
- read UART settings from the config blob (part of this patch)
- send UART settings via a vendor command to the device (which changes
the baudrate of the device and enables or disables flow control
depending on the config)
- change the baudrate and flow control settings on the host
- send the firmware and config blob to the device (already supported by
btrtl)
Sending the last firmware and config blob download command
(rtl_download_cmd) fails if the UART settings are not updated
beforehand. This is presumably because the device applies the config
right after the firmware and config blob download - which means that at
this point the host is using different UART settings than the device
(which will obviously result in non-working communication).
Signed-off-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
Signed-off-by: Jeremy Cline <jeremy@jcline.org>
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
drivers/bluetooth/btrtl.c | 112 ++++++++++++++++++++++++++++++++++++++
drivers/bluetooth/btrtl.h | 25 +++++++++
2 files changed, 137 insertions(+)
diff --git a/drivers/bluetooth/btrtl.c b/drivers/bluetooth/btrtl.c
index d7b44338cc8a..bc56ef7fcac3 100644
--- a/drivers/bluetooth/btrtl.c
+++ b/drivers/bluetooth/btrtl.c
@@ -34,6 +34,7 @@
#define RTL_ROM_LMP_8821A 0x8821
#define RTL_ROM_LMP_8761A 0x8761
#define RTL_ROM_LMP_8822B 0x8822
+#define RTL_CONFIG_MAGIC 0x8723ab55
#define IC_MATCH_FL_LMPSUBV (1 << 0)
#define IC_MATCH_FL_HCIREV (1 << 1)
@@ -590,6 +591,117 @@ int btrtl_setup_realtek(struct hci_dev *hdev)
}
EXPORT_SYMBOL_GPL(btrtl_setup_realtek);
+unsigned int btrtl_convert_baudrate(u32 device_baudrate)
+{
+ switch (device_baudrate) {
+ case 0x0252a00a:
+ return 230400;
+
+ case 0x05f75004:
+ return 921600;
+
+ case 0x00005004:
+ return 1000000;
+
+ case 0x04928002:
+ case 0x01128002:
+ return 1500000;
+
+ case 0x00005002:
+ return 2000000;
+
+ case 0x0000b001:
+ return 2500000;
+
+ case 0x04928001:
+ return 3000000;
+
+ case 0x052a6001:
+ return 3500000;
+
+ case 0x00005001:
+ return 4000000;
+
+ case 0x0252c014:
+ default:
+ return 115200;
+ }
+}
+
+int btrtl_get_uart_settings(struct hci_dev *hdev,
+ struct btrtl_device_info *btrtl_dev,
+ unsigned int *controller_baudrate,
+ u32 *device_baudrate, bool *flow_control)
+{
+ struct rtl_vendor_config *config;
+ struct rtl_vendor_config_entry *entry;
+ int i, total_data_len;
+ bool found = false;
+
+ total_data_len = btrtl_dev->cfg_len - sizeof(*config);
+ if (total_data_len <= 0) {
+ bt_dev_warn(hdev, "rtl: no config loaded");
+ return -EINVAL;
+ }
+
+ config = (struct rtl_vendor_config *)btrtl_dev->cfg_data;
+ if (le32_to_cpu(config->signature) != RTL_CONFIG_MAGIC) {
+ bt_dev_err(hdev, "rtl: invalid config magic");
+ return -EINVAL;
+ }
+
+ if (total_data_len < le16_to_cpu(config->total_len)) {
+ bt_dev_err(hdev, "rtl: config is too short");
+ return -EINVAL;
+ }
+
+ for (i = 0; i < total_data_len; ) {
+ entry = ((void *)config->entry) + i;
+
+ switch (le16_to_cpu(entry->offset)) {
+ case 0xc:
+ if (entry->len < sizeof(*device_baudrate)) {
+ bt_dev_err(hdev,
+ "rtl: invalid UART config entry");
+ return -EINVAL;
+ }
+
+ *device_baudrate = get_unaligned_le32(entry->data);
+ *controller_baudrate = btrtl_convert_baudrate(
+ *device_baudrate);
+
+ if (entry->len >= 13)
+ *flow_control = !!(entry->data[12] & BIT(2));
+ else
+ *flow_control = false;
+
+ found = true;
+ break;
+
+ default:
+ bt_dev_dbg(hdev,
+ "rtl: skipping config entry 0x%x (len %u)",
+ le16_to_cpu(entry->offset), entry->len);
+ break;
+ };
+
+ i += sizeof(*entry) + entry->len;
+ }
+
+ if (!found) {
+ bt_dev_err(hdev, "rtl: no UART config entry found");
+ return -ENOENT;
+ }
+
+ bt_dev_dbg(hdev, "rtl: device baudrate = 0x%08x", *device_baudrate);
+ bt_dev_dbg(hdev, "rtl: controller baudrate = %u",
+ *controller_baudrate);
+ bt_dev_dbg(hdev, "rtl: flow control %d", *flow_control);
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(btrtl_get_uart_settings);
+
MODULE_AUTHOR("Daniel Drake <drake@endlessm.com>");
MODULE_DESCRIPTION("Bluetooth support for Realtek devices ver " VERSION);
MODULE_VERSION(VERSION);
diff --git a/drivers/bluetooth/btrtl.h b/drivers/bluetooth/btrtl.h
index 21c28dcbe5e0..2e7856fa5ac7 100644
--- a/drivers/bluetooth/btrtl.h
+++ b/drivers/bluetooth/btrtl.h
@@ -40,6 +40,18 @@ struct rtl_epatch_header {
__le16 num_patches;
} __packed;
+struct rtl_vendor_config_entry {
+ __le16 offset;
+ __u8 len;
+ __u8 data[0];
+} __packed;
+
+struct rtl_vendor_config {
+ __le32 signature;
+ __le16 total_len;
+ struct rtl_vendor_config_entry entry[0];
+} __packed;
+
#if IS_ENABLED(CONFIG_BT_RTL)
struct btrtl_device_info *btrtl_initialize(struct hci_dev *hdev);
@@ -47,6 +59,10 @@ void btrtl_free(struct btrtl_device_info *btrtl_dev);
int btrtl_download_firmware(struct hci_dev *hdev,
struct btrtl_device_info *btrtl_dev);
int btrtl_setup_realtek(struct hci_dev *hdev);
+int btrtl_get_uart_settings(struct hci_dev *hdev,
+ struct btrtl_device_info *btrtl_dev,
+ unsigned int *controller_baudrate,
+ u32 *device_baudrate, bool *flow_control);
#else
@@ -70,4 +86,13 @@ static inline int btrtl_setup_realtek(struct hci_dev *hdev)
return -EOPNOTSUPP;
}
+static inline int btrtl_get_uart_settings(struct hci_dev *hdev,
+ struct btrtl_device_info *btrtl_dev,
+ unsigned int *controller_baudrate,
+ u32 *device_baudrate,
+ bool *flow_control)
+{
+ return -ENOENT;
+}
+
#endif
--
2.17.0
next prev parent reply other threads:[~2018-05-27 19:04 UTC|newest]
Thread overview: 32+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-05-27 19:04 [PATCH 00/13] Bluetooth: Add RTL8723BS support Hans de Goede
2018-05-27 19:04 ` [PATCH 01/13] dt-bindings: net: bluetooth: add support for Realtek Bluetooth chips Hans de Goede
2018-05-30 6:42 ` Marcel Holtmann
2018-05-30 8:04 ` Hans de Goede
2018-05-31 16:42 ` Rob Herring
2018-05-31 20:50 ` Hans de Goede
2018-06-04 10:17 ` Marcel Holtmann
2018-06-04 13:58 ` Hans de Goede
2018-06-04 19:11 ` Marcel Holtmann
2018-06-09 11:29 ` Hans de Goede
2018-06-11 13:32 ` Marcel Holtmann
2018-05-27 19:04 ` [PATCH 02/13] Bluetooth: btrtl: add MODULE_FIRMWARE declarations Hans de Goede
2018-05-27 19:04 ` [PATCH 03/13] Bluetooth: btrtl: split the device initialization into smaller parts Hans de Goede
2018-05-27 19:04 ` Hans de Goede [this message]
2018-05-30 12:14 ` [PATCH 04/13] Bluetooth: btrtl: add support for retrieving the UART settings kbuild test robot
2018-05-30 12:14 ` [RFC PATCH] Bluetooth: btrtl: btrtl_convert_baudrate() can be static kbuild test robot
2018-05-27 19:04 ` [PATCH 05/13] Bluetooth: btrtl: add support for the RTL8723BS and RTL8723DS chips Hans de Goede
2018-05-27 19:04 ` [PATCH 06/13] Bluetooth: btrtl: load the config blob from devicetree when available Hans de Goede
2018-05-27 19:04 ` [PATCH 07/13] Bluetooth: hci_uart: Restore hci_dev->flush callback on open() Hans de Goede
2018-05-30 6:47 ` Marcel Holtmann
2018-05-27 19:04 ` [PATCH 08/13] Bluetooth: hci_serdev: Move serdev_device_close/open into common hci_serdev code Hans de Goede
2018-05-30 6:48 ` Marcel Holtmann
2018-05-27 19:04 ` [PATCH 09/13] Bluetooth: hci_serdev: Fix HCI_UART_INIT_PENDING not working Hans de Goede
2018-05-30 6:49 ` Marcel Holtmann
2018-05-30 13:25 ` Rob Herring
2018-05-30 17:31 ` Hans de Goede
2018-05-27 19:04 ` [PATCH 10/13] Bluetooth: hci_h5: Add support for serdev enumerated devices Hans de Goede
2018-05-27 19:04 ` [PATCH 11/13] Bluetooth: hci_h5: Add vendor setup, open, and close callbacks Hans de Goede
2018-05-27 19:04 ` [PATCH 12/13] Bluetooth: hci_h5: Add support for the RTL8723BS Hans de Goede
2018-05-30 7:40 ` kbuild test robot
2018-05-27 19:04 ` [PATCH 13/13] Bluetooth: hci_h5: Add support for enable and device-wake GPIOs Hans de Goede
2018-05-29 12:34 ` [PATCH 00/13] Bluetooth: Add RTL8723BS support Ian W MORRISON
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20180527190457.2632-5-hdegoede@redhat.com \
--to=hdegoede@redhat.com \
--cc=devicetree@vger.kernel.org \
--cc=jeremy@jcline.org \
--cc=johan.hedberg@gmail.com \
--cc=linux-acpi@vger.kernel.org \
--cc=linux-bluetooth@vger.kernel.org \
--cc=linux-serial@vger.kernel.org \
--cc=marcel@holtmann.org \
--cc=martin.blumenstingl@googlemail.com \
--cc=robh@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).