linux-arm-kernel.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v6 0/1] Bluetooth: mediatek: add gpio pin to reset bt
@ 2025-07-08  6:01 Zhangchao Zhang
  2025-07-08  6:01 ` [PATCH v6 1/1] " Zhangchao Zhang
  2025-07-08  6:01 ` [PATCH v6] dt-bindings: net: mediatek,mt7925-bluetooth.yaml Zhangchao Zhang
  0 siblings, 2 replies; 5+ messages in thread
From: Zhangchao Zhang @ 2025-07-08  6:01 UTC (permalink / raw)
  To: Marcel Holtmann, Matthias Brugger, Luiz Von Dentz,
	AngeloGioacchino Del Regno, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley
  Cc: Sean Wang, Jiande Lu, Deren Wu, Chris Lu, Hao Qin, Wallace Yu,
	linux-bluetooth, linux-kernel, linux-arm-kernel, linux-mediatek,
	devicetree, Zhangchao Zhang

Reset Bluetooth using hardware pin via dts

Compared with the previously submitted version, the following
information are some specific revision histories

V5-->V6 modifications:
-Add specific revisions in the changes from v4 to v5.
-Add hardware pin title and descriptions to dt-binding submission
   information.
-Modify the title descriptions in the dt-binding file.
-Add 7925 what is it.
-Wrap the descriptions of MT7925 chip uses the USB bus appropriately.
-Change the compatible string to mediatek,mt7925-bluetooth in
   the dt-binding file and driver code.
-Drop gpio-controlelr properties in the dt-binding file.
-Modify the descriptions of the reset-gpios
   properties in the dt-binding file.
-Change the node information of reset-gpios in bluetooth
   from high level valid to low level valid.

V4-->V5 modifications:
-Correct the spelling error of word provides mentioned in V1.
-Drop the xhci0 node and status property in the dt-binding file.
-Modify the bt_reset tag node to bluetooth in the dt-binding file.
-Add #gpio-cell descriptions to properties, nodes and requests.
-Make a separate patch for the changes to dt-binding.

V3-->V4 modifications:
-Modify submission information why use hardware pin to reset Bluetooth.
-Write historical commit information into the cover letter.
-Modify dt binding format information and
   the explanation text in the dt-binding file.

V2-->V3 modifications:
-Changed the capitalization of co-developer names,
   using the correct capitalization of abbreviations and full
   name, and corrected obvious spelling errors.
-Add a revision history.
-Remove the "BT Driver" in the prefix.
-Add the bt-binding document, include inforamtion related to reset
   pin and compatibility matching.
-Add a comment before the schedule_delayed_work function call,
   although schedule_delayed_work is asynchronous, there is no risk.
   Even if it is not completed within 200ms, it will only postpone
   the subsequent probe and will not have any impact.
-Add a comment before the btmtk_reset_by_gpio function call,
   if the compatibility filed or pin cannot be found in the dts
   files, it can still reset bluetooth using software reset.

V2 modifications:
-Modify gpio to GPIO, SW to software,
   and fix other obvious spelling errors.

-- 
2.46.0



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

* [PATCH v6 1/1] Bluetooth: mediatek: add gpio pin to reset bt
  2025-07-08  6:01 [PATCH v6 0/1] Bluetooth: mediatek: add gpio pin to reset bt Zhangchao Zhang
@ 2025-07-08  6:01 ` Zhangchao Zhang
  2025-07-08  6:07   ` Krzysztof Kozlowski
  2025-07-08  6:01 ` [PATCH v6] dt-bindings: net: mediatek,mt7925-bluetooth.yaml Zhangchao Zhang
  1 sibling, 1 reply; 5+ messages in thread
From: Zhangchao Zhang @ 2025-07-08  6:01 UTC (permalink / raw)
  To: Marcel Holtmann, Matthias Brugger, Luiz Von Dentz,
	AngeloGioacchino Del Regno, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley
  Cc: Sean Wang, Jiande Lu, Deren Wu, Chris Lu, Hao Qin, Wallace Yu,
	linux-bluetooth, linux-kernel, linux-arm-kernel, linux-mediatek,
	devicetree, Zhangchao Zhang

Makes the platform Bluetooth to be reset by hardware pin,
it provides two methods to do it for mediatek controller,
and it has been tested locally many times and can reset normally.

When an exception occurs, resetting Bluetooth by hardware pin
is more stable than resetting Bluetooth by software.
If the corresponding pin is not found in dts,
bluetooth can also be reset successfully.

Co-developed: Hao Qin <hao.qin@mediatek.com>
Co-developed: Chris Lu <chris.lu@mediatek.com>
Co-developed: Jiande Lu <jiande.lu@mediatek.com>
Signed-off-by: Zhangchao Zhang <ot_zhangchao.zhang@mediatek.com>
---
 drivers/bluetooth/btmtk.c | 69 +++++++++++++++++++++++++++++++++++++++
 drivers/bluetooth/btmtk.h |  5 +++
 2 files changed, 74 insertions(+)

diff --git a/drivers/bluetooth/btmtk.c b/drivers/bluetooth/btmtk.c
index 4390fd571dbd..cdb90143be61 100644
--- a/drivers/bluetooth/btmtk.c
+++ b/drivers/bluetooth/btmtk.c
@@ -6,6 +6,8 @@
 #include <linux/firmware.h>
 #include <linux/usb.h>
 #include <linux/iopoll.h>
+#include <linux/of.h>
+#include <linux/of_gpio.h>
 #include <linux/unaligned.h>
 
 #include <net/bluetooth/bluetooth.h>
@@ -109,6 +111,65 @@ static void btmtk_coredump_notify(struct hci_dev *hdev, int state)
 	}
 }
 
+static void btmtk_reset_by_gpio_work(struct work_struct *work)
+{
+	struct btmtk_reset_gpio *reset_gpio_data =
+			container_of(work, struct btmtk_reset_gpio, reset_work.work);
+
+	gpio_direction_output(reset_gpio_data->gpio_number, 1);
+	kfree(reset_gpio_data);
+}
+
+static int btmtk_reset_by_gpio(struct hci_dev *hdev)
+{
+	struct btmtk_data *data = hci_get_priv(hdev);
+	struct btmtk_reset_gpio *reset_gpio_data;
+	struct device_node *node;
+	int reset_gpio_number;
+
+	node = of_find_compatible_node(NULL, NULL, "mediatek,mt7925-bluetooth");
+	if (node) {
+		reset_gpio_number = of_get_named_gpio(node, "reset-gpios", 0);
+		if (!gpio_is_valid(reset_gpio_number)) {
+			bt_dev_warn(hdev, "invalid reset GPIO, use software reset");
+			return -EINVAL;
+		}
+	} else {
+		bt_dev_warn(hdev, "no reset GPIO, use software reset");
+		return -ENODEV;
+	}
+
+	/* Toggle the hard reset line. The Mediatek device is going to
+	 * yank itself off the USB and then replug. The cleanup is handled
+	 * correctly on the way out (standard USB disconnect), and the new
+	 * device is detected cleanly and bound to the driver again like
+	 * it should be.
+	 */
+
+	if (test_and_set_bit(BTMTK_HW_RESET_ACTIVE, &data->flags)) {
+		bt_dev_err(hdev, "last reset failed? Not resetting again");
+		return 0;
+	}
+
+	reset_gpio_data = kzalloc(sizeof(*reset_gpio_data), GFP_KERNEL);
+	if (!reset_gpio_data)
+		return -ENOMEM;
+
+	INIT_DELAYED_WORK(&reset_gpio_data->reset_work, btmtk_reset_by_gpio_work);
+	reset_gpio_data->gpio_number = reset_gpio_number;
+
+	gpio_direction_output(reset_gpio_number, 0);
+
+	/* It requires 200ms for mtk bt chip to do reset,
+	 * although Schedule_delayed_work is asynchronous,
+	 * it is risk-free. If it is not completed in 200ms,
+	 * it will only postpone the next probe, which will
+	 * only make the probe run later. There is no other risk.
+	 */
+	schedule_delayed_work(&reset_gpio_data->reset_work, msecs_to_jiffies(200));
+	return 0;
+}
+
 void btmtk_fw_get_filename(char *buf, size_t size, u32 dev_id, u32 fw_ver,
 			   u32 fw_flavor)
 {
@@ -364,6 +425,14 @@ void btmtk_reset_sync(struct hci_dev *hdev)
 	struct btmtk_data *reset_work = hci_get_priv(hdev);
 	int err;
 
+	/* Toggle reset gpio if the platform provides one,
+	 * if the compatibility field or pin cannot be found
+	 * in the dts files, it can still reset bluetooth using
+	 * software reset.
+	 */
+	err = btmtk_reset_by_gpio(hdev);
+	if (!err)
+		return;
 	hci_dev_lock(hdev);
 
 	err = hci_cmd_sync_queue(hdev, reset_work->reset_sync, NULL, NULL);
diff --git a/drivers/bluetooth/btmtk.h b/drivers/bluetooth/btmtk.h
index 5df7c3296624..8a265ce367d1 100644
--- a/drivers/bluetooth/btmtk.h
+++ b/drivers/bluetooth/btmtk.h
@@ -179,6 +179,11 @@ struct btmtk_data {
 	spinlock_t isorxlock;
 };
 
+struct btmtk_reset_gpio {
+	struct delayed_work reset_work;
+	int gpio_number;
+};
+
 typedef int (*wmt_cmd_sync_func_t)(struct hci_dev *,
 				   struct btmtk_hci_wmt_params *);
 
-- 
2.46.0



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

* [PATCH v6] dt-bindings: net: mediatek,mt7925-bluetooth.yaml
  2025-07-08  6:01 [PATCH v6 0/1] Bluetooth: mediatek: add gpio pin to reset bt Zhangchao Zhang
  2025-07-08  6:01 ` [PATCH v6 1/1] " Zhangchao Zhang
@ 2025-07-08  6:01 ` Zhangchao Zhang
  2025-07-08  6:05   ` Krzysztof Kozlowski
  1 sibling, 1 reply; 5+ messages in thread
From: Zhangchao Zhang @ 2025-07-08  6:01 UTC (permalink / raw)
  To: Marcel Holtmann, Matthias Brugger, Luiz Von Dentz,
	AngeloGioacchino Del Regno, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley
  Cc: Sean Wang, Jiande Lu, Deren Wu, Chris Lu, Hao Qin, Wallace Yu,
	linux-bluetooth, linux-kernel, linux-arm-kernel, linux-mediatek,
	devicetree, Zhangchao Zhang

Reset BT via BT_KILL_1V2_L hardware pin.

On the M.2 standard hardware pin interface, the MTK chip
has a pin called BT_KILL_1V2_L or W_DISABLE#2, it uses
function-level device reset (FLDR) to reset Bluetooth.
When it is pulled low, it can external shut down the BT
function, it is defined as 5 on the MT7925 chip, and is
defined as 248 on the device tree pio controller.

Signed-off-by: Zhangchao Zhang <ot_zhangchao.zhang@mediatek.com>
---
 .../bluetooth/mediatek,mt7925-bluetooth.yaml  | 55 +++++++++++++++++++
 MAINTAINERS                                   |  1 +
 2 files changed, 56 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/net/bluetooth/mediatek,mt7925-bluetooth.yaml

diff --git a/Documentation/devicetree/bindings/net/bluetooth/mediatek,mt7925-bluetooth.yaml b/Documentation/devicetree/bindings/net/bluetooth/mediatek,mt7925-bluetooth.yaml
new file mode 100644
index 000000000000..636b8b3d6a14
--- /dev/null
+++ b/Documentation/devicetree/bindings/net/bluetooth/mediatek,mt7925-bluetooth.yaml
@@ -0,0 +1,55 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/net/bluetooth/mediatek,mt7925-bluetooth.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Bluetooth mediatek use BT_KILL_1V2_L hardware pin to reset BT
+
+maintainers:
+  - Sean Wang <sean.wang@mediatek.com>
+
+description:
+  MT7925 chip uses the USB bus to communicate with the host.
+  Two methods are used to reset Bluetooth. It provide hardware
+  pin, when an exception occurs, resetting Bluetooth by hardware
+  pin is more stable than resetting Bluetooth by software. If the
+  corresponding pin is not found in dts, bluetooth can also be
+  reset successfully.
+
+allOf:
+  - $ref: bluetooth-controller.yaml#
+
+properties:
+  compatible:
+    enum:
+      - mediatek,mt7925-bluetooth
+
+  "#gpio-cells":
+    const: 2
+
+  reset-gpios:
+    maxItems: 1
+    description:
+      Default high level, this pin can external shut down the BT function
+      when this pin is pull low, at the same time, USB interface will be also
+      disabled. When this function is not required, external pull high is not
+      required. After 200ms, it is pulled high to 3.3v and the next probe is
+      performed. On typical M.2 key E modules this is the W_DISABLE2# pin.
+
+required:
+  - compatible
+  - "#gpio-cells"
+  - reset-gpios
+
+unevaluatedProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/gpio/gpio.h>
+
+    bluetooth {
+      compatible = "mediatek,mt7925-bluetooth";
+      #gpio-cells = <2>;
+      reset-gpios = <&pio 248 GPIO_ACTIVE_LOW>;
+    };
diff --git a/MAINTAINERS b/MAINTAINERS
index 5959513a7359..d104a5821f20 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -14676,6 +14676,7 @@ L:	linux-mediatek@lists.infradead.org (moderated for non-subscribers)
 S:	Maintained
 F:	Documentation/devicetree/bindings/net/bluetooth/mediatek,bluetooth.txt
 F:	Documentation/devicetree/bindings/net/bluetooth/mediatek,mt7921s-bluetooth.yaml
+F:	Documentation/devicetree/bindings/net/bluetooth/mediatek,mt7925-bluetooth.yaml
 F:	drivers/bluetooth/btmtkuart.c
 
 MEDIATEK BOARD LEVEL SHUTDOWN DRIVERS
-- 
2.46.0



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

* Re: [PATCH v6] dt-bindings: net: mediatek,mt7925-bluetooth.yaml
  2025-07-08  6:01 ` [PATCH v6] dt-bindings: net: mediatek,mt7925-bluetooth.yaml Zhangchao Zhang
@ 2025-07-08  6:05   ` Krzysztof Kozlowski
  0 siblings, 0 replies; 5+ messages in thread
From: Krzysztof Kozlowski @ 2025-07-08  6:05 UTC (permalink / raw)
  To: Zhangchao Zhang, Marcel Holtmann, Matthias Brugger,
	Luiz Von Dentz, AngeloGioacchino Del Regno, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley
  Cc: Sean Wang, Jiande Lu, Deren Wu, Chris Lu, Hao Qin, Wallace Yu,
	linux-bluetooth, linux-kernel, linux-arm-kernel, linux-mediatek,
	devicetree

On 08/07/2025 08:01, Zhangchao Zhang wrote:
> Reset BT via BT_KILL_1V2_L hardware pin.
> 
> On the M.2 standard hardware pin interface, the MTK chip
> has a pin called BT_KILL_1V2_L or W_DISABLE#2, it uses
> function-level device reset (FLDR) to reset Bluetooth.
> When it is pulled low, it can external shut down the BT
> function, it is defined as 5 on the MT7925 chip, and is
> defined as 248 on the device tree pio controller.
> 
> Signed-off-by: Zhangchao Zhang <ot_zhangchao.zhang@mediatek.com>
> ---
>  .../bluetooth/mediatek,mt7925-bluetooth.yaml  | 55 +++++++++++++++++++
>  MAINTAINERS                                   |  1 +
>  2 files changed, 56 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/net/bluetooth/mediatek,mt7925-bluetooth.yaml
> 
> diff --git a/Documentation/devicetree/bindings/net/bluetooth/mediatek,mt7925-bluetooth.yaml b/Documentation/devicetree/bindings/net/bluetooth/mediatek,mt7925-bluetooth.yaml
> new file mode 100644
> index 000000000000..636b8b3d6a14
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/net/bluetooth/mediatek,mt7925-bluetooth.yaml
> @@ -0,0 +1,55 @@
> +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/net/bluetooth/mediatek,mt7925-bluetooth.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Bluetooth mediatek use BT_KILL_1V2_L hardware pin to reset BT
> +
> +maintainers:
> +  - Sean Wang <sean.wang@mediatek.com>
> +
> +description:
> +  MT7925 chip uses the USB bus to communicate with the host.
> +  Two methods are used to reset Bluetooth. It provide hardware
> +  pin, when an exception occurs, resetting Bluetooth by hardware
> +  pin is more stable than resetting Bluetooth by software. If the
> +  corresponding pin is not found in dts, bluetooth can also be
> +  reset successfully.

Don't describe DTS, but the hardware.

> +
> +allOf:
> +  - $ref: bluetooth-controller.yaml#
> +
> +properties:
> +  compatible:
> +    enum:
> +      - mediatek,mt7925-bluetooth
> +
> +  "#gpio-cells":
> +    const: 2

You did not say this is a GPIO controller.

> +
> +  reset-gpios:
> +    maxItems: 1
> +    description:
> +      Default high level, this pin can external shut down the BT function

How defaults matter?

> +      when this pin is pull low, at the same time, USB interface will be also
> +      disabled. When this function is not required, external pull high is not

So active low?

> +      required. After 200ms, it is pulled high to 3.3v and the next probe is
> +      performed. On typical M.2 key E modules this is the W_DISABLE2# pin.

So that's part of PCI slot? Sorry, but this does not fit here at all.


Best regards,
Krzysztof


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

* Re: [PATCH v6 1/1] Bluetooth: mediatek: add gpio pin to reset bt
  2025-07-08  6:01 ` [PATCH v6 1/1] " Zhangchao Zhang
@ 2025-07-08  6:07   ` Krzysztof Kozlowski
  0 siblings, 0 replies; 5+ messages in thread
From: Krzysztof Kozlowski @ 2025-07-08  6:07 UTC (permalink / raw)
  To: Zhangchao Zhang, Marcel Holtmann, Matthias Brugger,
	Luiz Von Dentz, AngeloGioacchino Del Regno, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley
  Cc: Sean Wang, Jiande Lu, Deren Wu, Chris Lu, Hao Qin, Wallace Yu,
	linux-bluetooth, linux-kernel, linux-arm-kernel, linux-mediatek,
	devicetree

On 08/07/2025 08:01, Zhangchao Zhang wrote:
> Makes the platform Bluetooth to be reset by hardware pin,
> it provides two methods to do it for mediatek controller,
> and it has been tested locally many times and can reset normally.
> 
> When an exception occurs, resetting Bluetooth by hardware pin
> is more stable than resetting Bluetooth by software.
> If the corresponding pin is not found in dts,
> bluetooth can also be reset successfully.
> 
> Co-developed: Hao Qin <hao.qin@mediatek.com>
> Co-developed: Chris Lu <chris.lu@mediatek.com>
> Co-developed: Jiande Lu <jiande.lu@mediatek.com>
> Signed-off-by: Zhangchao Zhang <ot_zhangchao.zhang@mediatek.com>
> ---
>  drivers/bluetooth/btmtk.c | 69 +++++++++++++++++++++++++++++++++++++++
>  drivers/bluetooth/btmtk.h |  5 +++
>  2 files changed, 74 insertions(+)
> 
> diff --git a/drivers/bluetooth/btmtk.c b/drivers/bluetooth/btmtk.c
> index 4390fd571dbd..cdb90143be61 100644
> --- a/drivers/bluetooth/btmtk.c
> +++ b/drivers/bluetooth/btmtk.c
> @@ -6,6 +6,8 @@
>  #include <linux/firmware.h>
>  #include <linux/usb.h>
>  #include <linux/iopoll.h>
> +#include <linux/of.h>
> +#include <linux/of_gpio.h>
>  #include <linux/unaligned.h>
>  
>  #include <net/bluetooth/bluetooth.h>
> @@ -109,6 +111,65 @@ static void btmtk_coredump_notify(struct hci_dev *hdev, int state)
>  	}
>  }
>  
> +static void btmtk_reset_by_gpio_work(struct work_struct *work)
> +{
> +	struct btmtk_reset_gpio *reset_gpio_data =
> +			container_of(work, struct btmtk_reset_gpio, reset_work.work);
> +
> +	gpio_direction_output(reset_gpio_data->gpio_number, 1);
> +	kfree(reset_gpio_data);
> +}
> +
> +static int btmtk_reset_by_gpio(struct hci_dev *hdev)
> +{
> +	struct btmtk_data *data = hci_get_priv(hdev);
> +	struct btmtk_reset_gpio *reset_gpio_data;
> +	struct device_node *node;
> +	int reset_gpio_number;
> +
> +	node = of_find_compatible_node(NULL, NULL, "mediatek,mt7925-bluetooth");

No. You don't take GPIOs from random node. You take them from your
device with proper API, instead of:

> +	if (node) {
> +		reset_gpio_number = of_get_named_gpio(node, "reset-gpios", 0);

legacy OF API. This only points that your driver model is broken or your
hardware description is wrong.


Best regards,
Krzysztof


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

end of thread, other threads:[~2025-07-08  6:14 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-07-08  6:01 [PATCH v6 0/1] Bluetooth: mediatek: add gpio pin to reset bt Zhangchao Zhang
2025-07-08  6:01 ` [PATCH v6 1/1] " Zhangchao Zhang
2025-07-08  6:07   ` Krzysztof Kozlowski
2025-07-08  6:01 ` [PATCH v6] dt-bindings: net: mediatek,mt7925-bluetooth.yaml Zhangchao Zhang
2025-07-08  6:05   ` Krzysztof Kozlowski

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).