All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v5 0/4] Bluetooth: hci_bcm: Additional changes for BCM4354 support
@ 2019-11-15  2:10 Abhishek Pandit-Subedi
  2019-11-15  2:10 ` [PATCH v5 1/4] Bluetooth: hci_bcm: Disallow set_baudrate for BCM4354 Abhishek Pandit-Subedi
                   ` (3 more replies)
  0 siblings, 4 replies; 9+ messages in thread
From: Abhishek Pandit-Subedi @ 2019-11-15  2:10 UTC (permalink / raw)
  To: Marcel Holtmann, Johan Hedberg, Rob Herring
  Cc: linux-bluetooth, dianders, Abhishek Pandit-Subedi, devicetree,
	David S. Miller, netdev, linux-kernel, Ondrej Jirman,
	Mark Rutland, Chen-Yu Tsai


While adding support for the BCM4354, I discovered a few more things
that weren't working as they should have.

First, we disallow serdev from setting the baudrate on BCM4354. Serdev
sets the oper_speed first before calling hu->setup() in
hci_uart_setup(). On the BCM4354, this results in bcm_setup() failing
when the hci reset times out.

Next, we add support for setting the PCM parameters, which consists of
a pair of vendor specific opcodes to set the pcm parameters. The
documentation for these params are available in the brcm_patchram_plus
package (i.e. https://github.com/balena-os/brcm_patchram_plus). This is
necessary for PCM to work properly.

All changes were tested with rk3288-veyron-minnie.dts.


Changes in v5:
- Rename parameters to bt-* and read as integer instead of bytestring
- Update documentation with defaults and put values in header
- Changed patch order

Changes in v4:
- Fix incorrect function name in hci_bcm

Changes in v3:
- Change disallow baudrate setting to return -EBUSY if called before
  ready. bcm_proto is no longer modified and is back to being const.
- Changed btbcm_set_pcm_params to btbcm_set_pcm_int_params
- Changed brcm,sco-routing to brcm,bt-sco-routing

Changes in v2:
- Use match data to disallow baudrate setting
- Parse pcm parameters by name instead of as a byte string
- Fix prefix for dt-bindings commit

Abhishek Pandit-Subedi (4):
  Bluetooth: hci_bcm: Disallow set_baudrate for BCM4354
  Bluetooth: btbcm: Support pcm configuration
  dt-bindings: net: broadcom-bluetooth: Add pcm config
  Bluetooth: hci_bcm: Support pcm params in dts

 .../bindings/net/broadcom-bluetooth.txt       | 20 ++++-
 drivers/bluetooth/btbcm.c                     | 19 +++++
 drivers/bluetooth/btbcm.h                     |  8 ++
 drivers/bluetooth/hci_bcm.c                   | 78 ++++++++++++++++++-
 include/dt-bindings/bluetooth/brcm.h          | 32 ++++++++
 5 files changed, 154 insertions(+), 3 deletions(-)
 create mode 100644 include/dt-bindings/bluetooth/brcm.h

-- 
2.24.0.432.g9d3f5f5b63-goog


^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH v5 1/4] Bluetooth: hci_bcm: Disallow set_baudrate for BCM4354
  2019-11-15  2:10 [PATCH v5 0/4] Bluetooth: hci_bcm: Additional changes for BCM4354 support Abhishek Pandit-Subedi
@ 2019-11-15  2:10 ` Abhishek Pandit-Subedi
  2019-11-15  7:59   ` Marcel Holtmann
  2019-11-15  2:10 ` [PATCH v5 2/4] Bluetooth: btbcm: Support pcm configuration Abhishek Pandit-Subedi
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 9+ messages in thread
From: Abhishek Pandit-Subedi @ 2019-11-15  2:10 UTC (permalink / raw)
  To: Marcel Holtmann, Johan Hedberg, Rob Herring
  Cc: linux-bluetooth, dianders, Abhishek Pandit-Subedi, linux-kernel

Without updating the patchram, the BCM4354 does not support a higher
operating speed. The normal bcm_setup follows the correct order
(init_speed, patchram and then oper_speed) but the serdev driver will
set the operating speed before calling the hu->setup function. Thus,
for the BCM4354, don't set the operating speed before patchram.

Signed-off-by: Abhishek Pandit-Subedi <abhishekpandit@chromium.org>
---

Changes in v5: None
Changes in v4: None
Changes in v3: None
Changes in v2: None

 drivers/bluetooth/hci_bcm.c | 31 +++++++++++++++++++++++++++++--
 1 file changed, 29 insertions(+), 2 deletions(-)

diff --git a/drivers/bluetooth/hci_bcm.c b/drivers/bluetooth/hci_bcm.c
index 0f851c0dde7f..ee40003008d8 100644
--- a/drivers/bluetooth/hci_bcm.c
+++ b/drivers/bluetooth/hci_bcm.c
@@ -47,6 +47,14 @@
 
 #define BCM_NUM_SUPPLIES 2
 
+/**
+ * struct bcm_device_data - device specific data
+ * @no_early_set_baudrate: Disallow set baudrate before driver setup()
+ */
+struct bcm_device_data {
+	bool	no_early_set_baudrate;
+};
+
 /**
  * struct bcm_device - device driver resources
  * @serdev_hu: HCI UART controller struct
@@ -79,6 +87,7 @@
  * @hu: pointer to HCI UART controller struct,
  *	used to disable flow control during runtime suspend and system sleep
  * @is_suspended: whether flow control is currently disabled
+ * @no_early_set_baudrate: don't set_baudrate before setup()
  */
 struct bcm_device {
 	/* Must be the first member, hci_serdev.c expects this. */
@@ -112,6 +121,7 @@ struct bcm_device {
 	struct hci_uart		*hu;
 	bool			is_suspended;
 #endif
+	bool			no_early_set_baudrate;
 };
 
 /* generic bcm uart resources */
@@ -447,7 +457,13 @@ static int bcm_open(struct hci_uart *hu)
 	if (bcm->dev) {
 		hci_uart_set_flow_control(hu, true);
 		hu->init_speed = bcm->dev->init_speed;
-		hu->oper_speed = bcm->dev->oper_speed;
+
+		/* If oper_speed is set, ldisc/serdev will set the baudrate
+		 * before calling setup()
+		 */
+		if (!bcm->dev->no_early_set_baudrate)
+			hu->oper_speed = bcm->dev->oper_speed;
+
 		err = bcm_gpio_set_power(bcm->dev, true);
 		hci_uart_set_flow_control(hu, false);
 		if (err)
@@ -565,6 +581,8 @@ static int bcm_setup(struct hci_uart *hu)
 	/* Operational speed if any */
 	if (hu->oper_speed)
 		speed = hu->oper_speed;
+	else if (bcm->dev && bcm->dev->oper_speed)
+		speed = bcm->dev->oper_speed;
 	else if (hu->proto->oper_speed)
 		speed = hu->proto->oper_speed;
 	else
@@ -1374,6 +1392,7 @@ static struct platform_driver bcm_driver = {
 static int bcm_serdev_probe(struct serdev_device *serdev)
 {
 	struct bcm_device *bcmdev;
+	const struct bcm_device_data *data;
 	int err;
 
 	bcmdev = devm_kzalloc(&serdev->dev, sizeof(*bcmdev), GFP_KERNEL);
@@ -1408,6 +1427,10 @@ static int bcm_serdev_probe(struct serdev_device *serdev)
 	if (err)
 		dev_err(&serdev->dev, "Failed to power down\n");
 
+	data = device_get_match_data(bcmdev->dev);
+	if (data)
+		bcmdev->no_early_set_baudrate = data->no_early_set_baudrate;
+
 	return hci_uart_register_device(&bcmdev->serdev_hu, &bcm_proto);
 }
 
@@ -1419,12 +1442,16 @@ static void bcm_serdev_remove(struct serdev_device *serdev)
 }
 
 #ifdef CONFIG_OF
+struct bcm_device_data bcm4354_device_data = {
+	.no_early_set_baudrate = true,
+};
+
 static const struct of_device_id bcm_bluetooth_of_match[] = {
 	{ .compatible = "brcm,bcm20702a1" },
 	{ .compatible = "brcm,bcm4345c5" },
 	{ .compatible = "brcm,bcm4330-bt" },
 	{ .compatible = "brcm,bcm43438-bt" },
-	{ .compatible = "brcm,bcm43540-bt" },
+	{ .compatible = "brcm,bcm43540-bt", .data = &bcm4354_device_data },
 	{ },
 };
 MODULE_DEVICE_TABLE(of, bcm_bluetooth_of_match);
-- 
2.24.0.432.g9d3f5f5b63-goog


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH v5 2/4] Bluetooth: btbcm: Support pcm configuration
  2019-11-15  2:10 [PATCH v5 0/4] Bluetooth: hci_bcm: Additional changes for BCM4354 support Abhishek Pandit-Subedi
  2019-11-15  2:10 ` [PATCH v5 1/4] Bluetooth: hci_bcm: Disallow set_baudrate for BCM4354 Abhishek Pandit-Subedi
@ 2019-11-15  2:10 ` Abhishek Pandit-Subedi
  2019-11-15  7:54   ` Marcel Holtmann
  2019-11-15  2:10 ` [PATCH v5 3/4] dt-bindings: net: broadcom-bluetooth: Add pcm config Abhishek Pandit-Subedi
  2019-11-15  2:10 ` [PATCH v5 4/4] Bluetooth: hci_bcm: Support pcm params in dts Abhishek Pandit-Subedi
  3 siblings, 1 reply; 9+ messages in thread
From: Abhishek Pandit-Subedi @ 2019-11-15  2:10 UTC (permalink / raw)
  To: Marcel Holtmann, Johan Hedberg, Rob Herring
  Cc: linux-bluetooth, dianders, Abhishek Pandit-Subedi, linux-kernel

Add BCM vendor specific command to configure PCM parameters. The new
vendor opcode allows us to set the sco routing, the pcm interface rate,
and a few other pcm specific options (frame sync, sync mode, and clock
mode). See broadcom-bluetooth.txt in Documentation for more information
about valid values for those settings.

Here is an example trace where this opcode was used to configure
a BCM4354:

        < HCI Command: Vendor (0x3f|0x001c) plen 5
                01 02 00 01 01
        > HCI Event: Command Complete (0x0e) plen 4
        Vendor (0x3f|0x001c) ncmd 1
                Status: Success (0x00)

We can read back the values as well with ocf 0x001d to confirm the
values that were set:
        $ hcitool cmd 0x3f 0x001d
        < HCI Command: ogf 0x3f, ocf 0x001d, plen 0
        > HCI Event: 0x0e plen 9
        01 1D FC 00 01 02 00 01 01

Signed-off-by: Abhishek Pandit-Subedi <abhishekpandit@chromium.org>
---

Changes in v5: None
Changes in v4: None
Changes in v3: None
Changes in v2: None

 drivers/bluetooth/btbcm.c | 19 +++++++++++++++++++
 drivers/bluetooth/btbcm.h |  8 ++++++++
 2 files changed, 27 insertions(+)

diff --git a/drivers/bluetooth/btbcm.c b/drivers/bluetooth/btbcm.c
index 2d2e6d862068..53fd66a96e69 100644
--- a/drivers/bluetooth/btbcm.c
+++ b/drivers/bluetooth/btbcm.c
@@ -105,6 +105,25 @@ int btbcm_set_bdaddr(struct hci_dev *hdev, const bdaddr_t *bdaddr)
 }
 EXPORT_SYMBOL_GPL(btbcm_set_bdaddr);
 
+int btbcm_set_pcm_int_params(struct hci_dev *hdev,
+			     const struct bcm_set_pcm_int_params *int_params)
+{
+	struct sk_buff *skb;
+	int err;
+
+	/* Vendor ocf 0x001c sets the pcm parameters and 0x001d reads it */
+	skb = __hci_cmd_sync(hdev, 0xfc1c, 5, int_params, HCI_INIT_TIMEOUT);
+	if (IS_ERR(skb)) {
+		err = PTR_ERR(skb);
+		bt_dev_err(hdev, "BCM: Set PCM int params failed (%d)", err);
+		return err;
+	}
+	kfree_skb(skb);
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(btbcm_set_pcm_int_params);
+
 int btbcm_patchram(struct hci_dev *hdev, const struct firmware *fw)
 {
 	const struct hci_command_hdr *cmd;
diff --git a/drivers/bluetooth/btbcm.h b/drivers/bluetooth/btbcm.h
index d204be8a84bf..bf9d86924787 100644
--- a/drivers/bluetooth/btbcm.h
+++ b/drivers/bluetooth/btbcm.h
@@ -54,6 +54,8 @@ struct bcm_set_pcm_format_params {
 int btbcm_check_bdaddr(struct hci_dev *hdev);
 int btbcm_set_bdaddr(struct hci_dev *hdev, const bdaddr_t *bdaddr);
 int btbcm_patchram(struct hci_dev *hdev, const struct firmware *fw);
+int btbcm_set_pcm_int_params(struct hci_dev *hdev,
+			     const struct bcm_set_pcm_int_params *int_params);
 
 int btbcm_setup_patchram(struct hci_dev *hdev);
 int btbcm_setup_apple(struct hci_dev *hdev);
@@ -74,6 +76,12 @@ static inline int btbcm_set_bdaddr(struct hci_dev *hdev, const bdaddr_t *bdaddr)
 	return -EOPNOTSUPP;
 }
 
+int btbcm_set_pcm_int_params(struct hci_dev *hdev,
+			     const struct bcm_set_pcm_int_params *int_params)
+{
+	return -EOPNOTSUPP;
+}
+
 static inline int btbcm_patchram(struct hci_dev *hdev, const struct firmware *fw)
 {
 	return -EOPNOTSUPP;
-- 
2.24.0.432.g9d3f5f5b63-goog


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH v5 3/4] dt-bindings: net: broadcom-bluetooth: Add pcm config
  2019-11-15  2:10 [PATCH v5 0/4] Bluetooth: hci_bcm: Additional changes for BCM4354 support Abhishek Pandit-Subedi
  2019-11-15  2:10 ` [PATCH v5 1/4] Bluetooth: hci_bcm: Disallow set_baudrate for BCM4354 Abhishek Pandit-Subedi
  2019-11-15  2:10 ` [PATCH v5 2/4] Bluetooth: btbcm: Support pcm configuration Abhishek Pandit-Subedi
@ 2019-11-15  2:10 ` Abhishek Pandit-Subedi
  2019-11-15  8:01   ` Marcel Holtmann
  2019-11-15  2:10 ` [PATCH v5 4/4] Bluetooth: hci_bcm: Support pcm params in dts Abhishek Pandit-Subedi
  3 siblings, 1 reply; 9+ messages in thread
From: Abhishek Pandit-Subedi @ 2019-11-15  2:10 UTC (permalink / raw)
  To: Marcel Holtmann, Johan Hedberg, Rob Herring
  Cc: linux-bluetooth, dianders, Abhishek Pandit-Subedi, devicetree,
	David S. Miller, netdev, linux-kernel, Ondrej Jirman,
	Mark Rutland, Chen-Yu Tsai

Add documentation for pcm parameters.

Signed-off-by: Abhishek Pandit-Subedi <abhishekpandit@chromium.org>
---

Changes in v5: None
Changes in v4: None
Changes in v3: None
Changes in v2: None

 .../bindings/net/broadcom-bluetooth.txt       | 20 +++++++++++-
 include/dt-bindings/bluetooth/brcm.h          | 32 +++++++++++++++++++
 2 files changed, 51 insertions(+), 1 deletion(-)
 create mode 100644 include/dt-bindings/bluetooth/brcm.h

diff --git a/Documentation/devicetree/bindings/net/broadcom-bluetooth.txt b/Documentation/devicetree/bindings/net/broadcom-bluetooth.txt
index c749dc297624..a92da31daa79 100644
--- a/Documentation/devicetree/bindings/net/broadcom-bluetooth.txt
+++ b/Documentation/devicetree/bindings/net/broadcom-bluetooth.txt
@@ -29,10 +29,22 @@ Optional properties:
    - "lpo": external low power 32.768 kHz clock
  - vbat-supply: phandle to regulator supply for VBAT
  - vddio-supply: phandle to regulator supply for VDDIO
-
+ - brcm,bt-sco-routing: PCM, Transport, Codec, I2S
+                        This value must be set in order for the latter
+                        properties to take effect.
+ - brcm,bt-pcm-interface-rate: 128KBps, 256KBps, 512KBps, 1024KBps, 2048KBps
+ - brcm,bt-pcm-frame-type: short, long
+ - brcm,bt-pcm-sync-mode: slave, master
+ - brcm,bt-pcm-clock-mode: slave, master
+
+See include/dt-bindings/bluetooth/brcm.h for SCO/PCM parameters. The default
+value for all these values are 0 (except for brcm,bt-sco-routing which requires
+a value) if you choose to leave it out.
 
 Example:
 
+#include <dt-bindings/bluetooth/brcm.h>
+
 &uart2 {
        pinctrl-names = "default";
        pinctrl-0 = <&uart2_pins>;
@@ -40,5 +52,11 @@ Example:
        bluetooth {
                compatible = "brcm,bcm43438-bt";
                max-speed = <921600>;
+
+               brcm,bt-sco-routing        = <BRCM_SCO_ROUTING_TRANSPORT>;
+               brcm,bt-pcm-interface-rate = <BRCM_PCM_IF_RATE_512KBPS>;
+               brcm,bt-pcm-frame-type     = <BRCM_PCM_FRAME_TYPE_SHORT>;
+               brcm,bt-pcm-sync-mode      = <BRCM_PCM_SYNC_MODE_MASTER>;
+               brcm,bt-pcm-clock-mode     = <BRCM_PCM_CLOCK_MODE_MASTER>;
        };
 };
diff --git a/include/dt-bindings/bluetooth/brcm.h b/include/dt-bindings/bluetooth/brcm.h
new file mode 100644
index 000000000000..8b86f90d7dd2
--- /dev/null
+++ b/include/dt-bindings/bluetooth/brcm.h
@@ -0,0 +1,32 @@
+/* SPDX-License-Identifier: (GPL-2.0+ OR MIT) */
+/*
+ * This header provides constants for Broadcom bluetooth dt-bindings.
+ */
+#ifndef _DT_BINDINGS_BLUETOOTH_BRCM_H
+#define _DT_BINDINGS_BLUETOOTH_BRCM_H
+
+#define BRCM_BT_SCO_ROUTING_PCM			0
+#define BRCM_BT_SCO_ROUTING_TRANSPORT		1
+#define BRCM_BT_SCO_ROUTING_CODEC		2
+#define BRCM_BT_SCO_ROUTING_I2S			3
+
+/* Default is 128KBPs */
+#define BRCM_BT_PCM_INTERFACE_RATE_128KBPS	0
+#define BRCM_BT_PCM_INTERFACE_RATE_256KBPS	1
+#define BRCM_BT_PCM_INTERFACE_RATE_512KBPS	2
+#define BRCM_BT_PCM_INTERFACE_RATE_1024KBPS	3
+#define BRCM_BT_PCM_INTERFACE_RATE_2048KBPS	4
+
+/* Default should be short */
+#define BRCM_BT_PCM_FRAME_TYPE_SHORT		0
+#define BRCM_BT_PCM_FRAME_TYPE_LONG		1
+
+/* Default should be master */
+#define BRCM_BT_PCM_SYNC_MODE_SLAVE		0
+#define BRCM_BT_PCM_SYNC_MODE_MASTER		1
+
+/* Default should be master */
+#define BRCM_BT_PCM_CLOCK_MODE_SLAVE		0
+#define BRCM_BT_PCM_CLOCK_MODE_MASTER		1
+
+#endif /* _DT_BINDINGS_BLUETOOTH_BRCM_H */
-- 
2.24.0.432.g9d3f5f5b63-goog


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH v5 4/4] Bluetooth: hci_bcm: Support pcm params in dts
  2019-11-15  2:10 [PATCH v5 0/4] Bluetooth: hci_bcm: Additional changes for BCM4354 support Abhishek Pandit-Subedi
                   ` (2 preceding siblings ...)
  2019-11-15  2:10 ` [PATCH v5 3/4] dt-bindings: net: broadcom-bluetooth: Add pcm config Abhishek Pandit-Subedi
@ 2019-11-15  2:10 ` Abhishek Pandit-Subedi
  2019-11-15  8:04   ` Marcel Holtmann
  3 siblings, 1 reply; 9+ messages in thread
From: Abhishek Pandit-Subedi @ 2019-11-15  2:10 UTC (permalink / raw)
  To: Marcel Holtmann, Johan Hedberg, Rob Herring
  Cc: linux-bluetooth, dianders, Abhishek Pandit-Subedi, linux-kernel

BCM chips may require configuration of PCM to operate correctly and
there is a vendor specific HCI command to do this. Add support in the
hci_bcm driver to parse this from devicetree and configure the chip.

Signed-off-by: Abhishek Pandit-Subedi <abhishekpandit@chromium.org>
---
Looks like hcitool cmd 0x3f 0x001d will read back the PCM parameters so
I experimented with different values for sco_routing, interface_rate and
other values.

The hardware doesn't care about frame_type, sync_mode or clock_mode (I
put them all as 0, all as 1, etc). Only the sco_routing seems to have
a discernable effect on the hardware.

To avoid complicating this, I opted not to read PCM settings and then
write back to it. Let the user decide what to write themselves. I've
opted to add a comment explaining that 0x001d is the read opcode if they
want to verify it themselves.

Changes in v5:
- Rename parameters to bt-* and read as integer instead of bytestring
- Update documentation with defaults and put values in header
- Changed patch order

Changes in v4:
- Fix incorrect function name in hci_bcm

Changes in v3:
- Change disallow baudrate setting to return -EBUSY if called before
  ready. bcm_proto is no longer modified and is back to being const.
- Changed btbcm_set_pcm_params to btbcm_set_pcm_int_params
- Changed brcm,sco-routing to brcm,bt-sco-routing

Changes in v2:
- Use match data to disallow baudrate setting
- Parse pcm parameters by name instead of as a byte string
- Fix prefix for dt-bindings commit

 drivers/bluetooth/hci_bcm.c | 47 +++++++++++++++++++++++++++++++++++++
 1 file changed, 47 insertions(+)

diff --git a/drivers/bluetooth/hci_bcm.c b/drivers/bluetooth/hci_bcm.c
index ee40003008d8..ad694b0436c9 100644
--- a/drivers/bluetooth/hci_bcm.c
+++ b/drivers/bluetooth/hci_bcm.c
@@ -25,6 +25,7 @@
 #include <linux/pm_runtime.h>
 #include <linux/serdev.h>
 
+#include <dt-bindings/bluetooth/brcm.h>
 #include <net/bluetooth/bluetooth.h>
 #include <net/bluetooth/hci_core.h>
 
@@ -88,6 +89,8 @@ struct bcm_device_data {
  *	used to disable flow control during runtime suspend and system sleep
  * @is_suspended: whether flow control is currently disabled
  * @no_early_set_baudrate: don't set_baudrate before setup()
+ * @has_pcm_params: whether PCM parameters need to be configured
+ * @pcm_params: PCM and routing parameters
  */
 struct bcm_device {
 	/* Must be the first member, hci_serdev.c expects this. */
@@ -122,6 +125,9 @@ struct bcm_device {
 	bool			is_suspended;
 #endif
 	bool			no_early_set_baudrate;
+
+	bool				has_pcm_params;
+	struct bcm_set_pcm_int_params	pcm_params;
 };
 
 /* generic bcm uart resources */
@@ -594,6 +600,16 @@ static int bcm_setup(struct hci_uart *hu)
 			host_set_baudrate(hu, speed);
 	}
 
+	/* PCM parameters if any*/
+	if (bcm->dev && bcm->dev->has_pcm_params) {
+		err = btbcm_set_pcm_int_params(hu->hdev, &bcm->dev->pcm_params);
+
+		if (err) {
+			bt_dev_info(hu->hdev, "BCM: Set pcm params failed (%d)",
+				    err);
+		}
+	}
+
 finalize:
 	release_firmware(fw);
 
@@ -1128,9 +1144,40 @@ static int bcm_acpi_probe(struct bcm_device *dev)
 }
 #endif /* CONFIG_ACPI */
 
+static int property_read_u8(struct device *dev, const char *prop, u8 *value)
+{
+	int err;
+	u32 tmp;
+
+	err = device_property_read_u32(dev, prop, &tmp);
+
+	if (!err)
+		*value = (u8)tmp;
+
+	return err;
+}
+
 static int bcm_of_probe(struct bcm_device *bdev)
 {
+	int err;
+
 	device_property_read_u32(bdev->dev, "max-speed", &bdev->oper_speed);
+
+	err = property_read_u8(bdev->dev, "brcm,bt-sco-routing",
+			       &bdev->pcm_params.routing);
+
+	if (!err)
+		bdev->has_pcm_params = true;
+
+	property_read_u8(bdev->dev, "brcm,bt-pcm-interface-rate",
+			 &bdev->pcm_params.rate);
+	property_read_u8(bdev->dev, "brcm,bt-pcm-frame-type",
+			 &bdev->pcm_params.frame_sync);
+	property_read_u8(bdev->dev, "brcm,bt-pcm-sync-mode",
+			 &bdev->pcm_params.sync_mode);
+	property_read_u8(bdev->dev, "brcm,bt-pcm-clock-mode",
+			 &bdev->pcm_params.clock_mode);
+
 	return 0;
 }
 
-- 
2.24.0.432.g9d3f5f5b63-goog


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* Re: [PATCH v5 2/4] Bluetooth: btbcm: Support pcm configuration
  2019-11-15  2:10 ` [PATCH v5 2/4] Bluetooth: btbcm: Support pcm configuration Abhishek Pandit-Subedi
@ 2019-11-15  7:54   ` Marcel Holtmann
  0 siblings, 0 replies; 9+ messages in thread
From: Marcel Holtmann @ 2019-11-15  7:54 UTC (permalink / raw)
  To: Abhishek Pandit-Subedi
  Cc: Johan Hedberg, Rob Herring, Bluez mailing list, dianders, linux-kernel

Hi Abhishek,

> Add BCM vendor specific command to configure PCM parameters. The new
> vendor opcode allows us to set the sco routing, the pcm interface rate,
> and a few other pcm specific options (frame sync, sync mode, and clock
> mode). See broadcom-bluetooth.txt in Documentation for more information
> about valid values for those settings.
> 
> Here is an example trace where this opcode was used to configure
> a BCM4354:
> 
>        < HCI Command: Vendor (0x3f|0x001c) plen 5
>                01 02 00 01 01
>> HCI Event: Command Complete (0x0e) plen 4
>        Vendor (0x3f|0x001c) ncmd 1
>                Status: Success (0x00)
> 
> We can read back the values as well with ocf 0x001d to confirm the
> values that were set:
>        $ hcitool cmd 0x3f 0x001d
>        < HCI Command: ogf 0x3f, ocf 0x001d, plen 0
>> HCI Event: 0x0e plen 9
>        01 1D FC 00 01 02 00 01 01
> 
> Signed-off-by: Abhishek Pandit-Subedi <abhishekpandit@chromium.org>
> ---
> 
> Changes in v5: None
> Changes in v4: None
> Changes in v3: None
> Changes in v2: None
> 
> drivers/bluetooth/btbcm.c | 19 +++++++++++++++++++
> drivers/bluetooth/btbcm.h |  8 ++++++++
> 2 files changed, 27 insertions(+)
> 
> diff --git a/drivers/bluetooth/btbcm.c b/drivers/bluetooth/btbcm.c
> index 2d2e6d862068..53fd66a96e69 100644
> --- a/drivers/bluetooth/btbcm.c
> +++ b/drivers/bluetooth/btbcm.c
> @@ -105,6 +105,25 @@ int btbcm_set_bdaddr(struct hci_dev *hdev, const bdaddr_t *bdaddr)
> }
> EXPORT_SYMBOL_GPL(btbcm_set_bdaddr);
> 
> +int btbcm_set_pcm_int_params(struct hci_dev *hdev,
> +			     const struct bcm_set_pcm_int_params *int_params)
> +{
> +	struct sk_buff *skb;
> +	int err;
> +
> +	/* Vendor ocf 0x001c sets the pcm parameters and 0x001d reads it */

drop this comment.

> +	skb = __hci_cmd_sync(hdev, 0xfc1c, 5, int_params, HCI_INIT_TIMEOUT);
> +	if (IS_ERR(skb)) {
> +		err = PTR_ERR(skb);
> +		bt_dev_err(hdev, "BCM: Set PCM int params failed (%d)", err);
> +		return err;
> +	}
> +	kfree_skb(skb);
> +
> +	return 0;
> +}
> +EXPORT_SYMBOL_GPL(btbcm_set_pcm_int_params);
> +

Lets introduce two function here. btbcm_write_pcm_int_param and btbcm_read_pcm_int_param.

Regards

Marcel


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH v5 1/4] Bluetooth: hci_bcm: Disallow set_baudrate for BCM4354
  2019-11-15  2:10 ` [PATCH v5 1/4] Bluetooth: hci_bcm: Disallow set_baudrate for BCM4354 Abhishek Pandit-Subedi
@ 2019-11-15  7:59   ` Marcel Holtmann
  0 siblings, 0 replies; 9+ messages in thread
From: Marcel Holtmann @ 2019-11-15  7:59 UTC (permalink / raw)
  To: Abhishek Pandit-Subedi
  Cc: Johan Hedberg, Rob Herring, linux-bluetooth, dianders, linux-kernel

Hi Abhishek,

> Without updating the patchram, the BCM4354 does not support a higher
> operating speed. The normal bcm_setup follows the correct order
> (init_speed, patchram and then oper_speed) but the serdev driver will
> set the operating speed before calling the hu->setup function. Thus,
> for the BCM4354, don't set the operating speed before patchram.
> 
> Signed-off-by: Abhishek Pandit-Subedi <abhishekpandit@chromium.org>
> ---
> 
> Changes in v5: None
> Changes in v4: None
> Changes in v3: None
> Changes in v2: None
> 
> drivers/bluetooth/hci_bcm.c | 31 +++++++++++++++++++++++++++++--
> 1 file changed, 29 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/bluetooth/hci_bcm.c b/drivers/bluetooth/hci_bcm.c
> index 0f851c0dde7f..ee40003008d8 100644
> --- a/drivers/bluetooth/hci_bcm.c
> +++ b/drivers/bluetooth/hci_bcm.c
> @@ -47,6 +47,14 @@
> 
> #define BCM_NUM_SUPPLIES 2
> 
> +/**
> + * struct bcm_device_data - device specific data
> + * @no_early_set_baudrate: Disallow set baudrate before driver setup()
> + */
> +struct bcm_device_data {
> +	bool	no_early_set_baudrate;
> +};
> +
> /**
>  * struct bcm_device - device driver resources
>  * @serdev_hu: HCI UART controller struct
> @@ -79,6 +87,7 @@
>  * @hu: pointer to HCI UART controller struct,
>  *	used to disable flow control during runtime suspend and system sleep
>  * @is_suspended: whether flow control is currently disabled
> + * @no_early_set_baudrate: don't set_baudrate before setup()
>  */
> struct bcm_device {
> 	/* Must be the first member, hci_serdev.c expects this. */
> @@ -112,6 +121,7 @@ struct bcm_device {
> 	struct hci_uart		*hu;
> 	bool			is_suspended;
> #endif
> +	bool			no_early_set_baudrate;
> };
> 
> /* generic bcm uart resources */
> @@ -447,7 +457,13 @@ static int bcm_open(struct hci_uart *hu)
> 	if (bcm->dev) {
> 		hci_uart_set_flow_control(hu, true);
> 		hu->init_speed = bcm->dev->init_speed;
> -		hu->oper_speed = bcm->dev->oper_speed;
> +
> +		/* If oper_speed is set, ldisc/serdev will set the baudrate
> +		 * before calling setup()
> +		 */
> +		if (!bcm->dev->no_early_set_baudrate)
> +			hu->oper_speed = bcm->dev->oper_speed;
> +
> 		err = bcm_gpio_set_power(bcm->dev, true);
> 		hci_uart_set_flow_control(hu, false);
> 		if (err)
> @@ -565,6 +581,8 @@ static int bcm_setup(struct hci_uart *hu)
> 	/* Operational speed if any */
> 	if (hu->oper_speed)
> 		speed = hu->oper_speed;
> +	else if (bcm->dev && bcm->dev->oper_speed)
> +		speed = bcm->dev->oper_speed;
> 	else if (hu->proto->oper_speed)
> 		speed = hu->proto->oper_speed;
> 	else
> @@ -1374,6 +1392,7 @@ static struct platform_driver bcm_driver = {
> static int bcm_serdev_probe(struct serdev_device *serdev)
> {
> 	struct bcm_device *bcmdev;
> +	const struct bcm_device_data *data;
> 	int err;
> 
> 	bcmdev = devm_kzalloc(&serdev->dev, sizeof(*bcmdev), GFP_KERNEL);
> @@ -1408,6 +1427,10 @@ static int bcm_serdev_probe(struct serdev_device *serdev)
> 	if (err)
> 		dev_err(&serdev->dev, "Failed to power down\n");
> 
> +	data = device_get_match_data(bcmdev->dev);
> +	if (data)
> +		bcmdev->no_early_set_baudrate = data->no_early_set_baudrate;
> +
> 	return hci_uart_register_device(&bcmdev->serdev_hu, &bcm_proto);
> }
> 
> @@ -1419,12 +1442,16 @@ static void bcm_serdev_remove(struct serdev_device *serdev)
> }
> 
> #ifdef CONFIG_OF
> +struct bcm_device_data bcm4354_device_data = {
> +	.no_early_set_baudrate = true,
> +};
> +
> static const struct of_device_id bcm_bluetooth_of_match[] = {
> 	{ .compatible = "brcm,bcm20702a1" },
> 	{ .compatible = "brcm,bcm4345c5" },
> 	{ .compatible = "brcm,bcm4330-bt" },
> 	{ .compatible = "brcm,bcm43438-bt" },
> -	{ .compatible = "brcm,bcm43540-bt" },
> +	{ .compatible = "brcm,bcm43540-bt", .data = &bcm4354_device_data },

this looks good to me. Can some users of the other devices test this patch so we ensure that it won’t break other devices.

Regards

Marcel


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH v5 3/4] dt-bindings: net: broadcom-bluetooth: Add pcm config
  2019-11-15  2:10 ` [PATCH v5 3/4] dt-bindings: net: broadcom-bluetooth: Add pcm config Abhishek Pandit-Subedi
@ 2019-11-15  8:01   ` Marcel Holtmann
  0 siblings, 0 replies; 9+ messages in thread
From: Marcel Holtmann @ 2019-11-15  8:01 UTC (permalink / raw)
  To: Abhishek Pandit-Subedi
  Cc: Johan Hedberg, Rob Herring, Bluez mailing list, dianders,
	devicetree, David S. Miller, netdev, lkml, Ondrej Jirman,
	Mark Rutland, Chen-Yu Tsai

Hi Abhishek,

> Add documentation for pcm parameters.
> 
> Signed-off-by: Abhishek Pandit-Subedi <abhishekpandit@chromium.org>
> ---
> 
> Changes in v5: None
> Changes in v4: None
> Changes in v3: None
> Changes in v2: None
> 
> .../bindings/net/broadcom-bluetooth.txt       | 20 +++++++++++-
> include/dt-bindings/bluetooth/brcm.h          | 32 +++++++++++++++++++
> 2 files changed, 51 insertions(+), 1 deletion(-)
> create mode 100644 include/dt-bindings/bluetooth/brcm.h
> 
> diff --git a/Documentation/devicetree/bindings/net/broadcom-bluetooth.txt b/Documentation/devicetree/bindings/net/broadcom-bluetooth.txt
> index c749dc297624..a92da31daa79 100644
> --- a/Documentation/devicetree/bindings/net/broadcom-bluetooth.txt
> +++ b/Documentation/devicetree/bindings/net/broadcom-bluetooth.txt
> @@ -29,10 +29,22 @@ Optional properties:
>    - "lpo": external low power 32.768 kHz clock
>  - vbat-supply: phandle to regulator supply for VBAT
>  - vddio-supply: phandle to regulator supply for VDDIO
> -
> + - brcm,bt-sco-routing: PCM, Transport, Codec, I2S
> +                        This value must be set in order for the latter
> +                        properties to take effect.
> + - brcm,bt-pcm-interface-rate: 128KBps, 256KBps, 512KBps, 1024KBps, 2048KBps
> + - brcm,bt-pcm-frame-type: short, long
> + - brcm,bt-pcm-sync-mode: slave, master
> + - brcm,bt-pcm-clock-mode: slave, master
> +
> +See include/dt-bindings/bluetooth/brcm.h for SCO/PCM parameters. The default
> +value for all these values are 0 (except for brcm,bt-sco-routing which requires
> +a value) if you choose to leave it out.
> 
> Example:
> 
> +#include <dt-bindings/bluetooth/brcm.h>
> +
> &uart2 {
>        pinctrl-names = "default";
>        pinctrl-0 = <&uart2_pins>;
> @@ -40,5 +52,11 @@ Example:
>        bluetooth {
>                compatible = "brcm,bcm43438-bt";
>                max-speed = <921600>;
> +
> +               brcm,bt-sco-routing        = <BRCM_SCO_ROUTING_TRANSPORT>;
> +               brcm,bt-pcm-interface-rate = <BRCM_PCM_IF_RATE_512KBPS>;
> +               brcm,bt-pcm-frame-type     = <BRCM_PCM_FRAME_TYPE_SHORT>;
> +               brcm,bt-pcm-sync-mode      = <BRCM_PCM_SYNC_MODE_MASTER>;
> +               brcm,bt-pcm-clock-mode     = <BRCM_PCM_CLOCK_MODE_MASTER>;
>        };

I am not sure this makes this all that much more readable. I would have been fine with using actual integer values with a comment behind it. Especially since in the driver itself we will never compare against the constants, we set whatever the DT gives us.

Anyway, for the names, I like Rob to ack them before applying them.

Regards

Marcel


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH v5 4/4] Bluetooth: hci_bcm: Support pcm params in dts
  2019-11-15  2:10 ` [PATCH v5 4/4] Bluetooth: hci_bcm: Support pcm params in dts Abhishek Pandit-Subedi
@ 2019-11-15  8:04   ` Marcel Holtmann
  0 siblings, 0 replies; 9+ messages in thread
From: Marcel Holtmann @ 2019-11-15  8:04 UTC (permalink / raw)
  To: Abhishek Pandit-Subedi
  Cc: Johan Hedberg, Rob Herring, linux-bluetooth, dianders, linux-kernel

Hi Abhishek,

> BCM chips may require configuration of PCM to operate correctly and
> there is a vendor specific HCI command to do this. Add support in the
> hci_bcm driver to parse this from devicetree and configure the chip.
> 
> Signed-off-by: Abhishek Pandit-Subedi <abhishekpandit@chromium.org>
> ---
> Looks like hcitool cmd 0x3f 0x001d will read back the PCM parameters so
> I experimented with different values for sco_routing, interface_rate and
> other values.
> 
> The hardware doesn't care about frame_type, sync_mode or clock_mode (I
> put them all as 0, all as 1, etc). Only the sco_routing seems to have
> a discernable effect on the hardware.
> 
> To avoid complicating this, I opted not to read PCM settings and then
> write back to it. Let the user decide what to write themselves. I've
> opted to add a comment explaining that 0x001d is the read opcode if they
> want to verify it themselves.

actually I would really do it like this:

	1) read params
	2) overwrite values from DT
	2) write params (if transport mode is different)

The advantage with this is that when you have to debug things, then the btmon trace will contain the default values the firmware has. So it is in all trace files all the time. We do that with other parameters as for exactly that reason.

That also means you can drop has_pcm_params variable.

Regards

Marcel


^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2019-11-15  8:04 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-11-15  2:10 [PATCH v5 0/4] Bluetooth: hci_bcm: Additional changes for BCM4354 support Abhishek Pandit-Subedi
2019-11-15  2:10 ` [PATCH v5 1/4] Bluetooth: hci_bcm: Disallow set_baudrate for BCM4354 Abhishek Pandit-Subedi
2019-11-15  7:59   ` Marcel Holtmann
2019-11-15  2:10 ` [PATCH v5 2/4] Bluetooth: btbcm: Support pcm configuration Abhishek Pandit-Subedi
2019-11-15  7:54   ` Marcel Holtmann
2019-11-15  2:10 ` [PATCH v5 3/4] dt-bindings: net: broadcom-bluetooth: Add pcm config Abhishek Pandit-Subedi
2019-11-15  8:01   ` Marcel Holtmann
2019-11-15  2:10 ` [PATCH v5 4/4] Bluetooth: hci_bcm: Support pcm params in dts Abhishek Pandit-Subedi
2019-11-15  8:04   ` Marcel Holtmann

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.