* [PATCH v5 1/2] dt-bindings: net: bluetooth: nxp: Add support for power save feature using GPIO
2024-10-08 9:11 [PATCH v5 0/2] Bluetooth: btnxpuart: Add GPIO mechanism to Neeraj Sanjay Kale
@ 2024-10-08 9:11 ` Neeraj Sanjay Kale
2024-10-08 9:11 ` [PATCH v5 2/2] Bluetooth: btnxpuart: Add GPIO support to power save feature Neeraj Sanjay Kale
2024-10-08 14:00 ` [PATCH v5 0/2] Bluetooth: btnxpuart: Add GPIO mechanism to patchwork-bot+bluetooth
2 siblings, 0 replies; 4+ messages in thread
From: Neeraj Sanjay Kale @ 2024-10-08 9:11 UTC (permalink / raw)
To: marcel, luiz.dentz, robh, krzk+dt, conor+dt
Cc: linux-bluetooth, linux-kernel, devicetree, amitkumar.karwar,
rohit.fule, neeraj.sanjaykale, sherry.sun, ziniu.wang_1,
haibo.chen, LnxRevLi
This adds a new optional device tree property device-wakeup-gpios, which
specifies the GPIO connected to BT_WAKE_IN pin of the NXP chipset.
If this property is defined, the driver will use this GPIO for driving chip
into sleep/wakeup state, else use the UART break signal by default.
Signed-off-by: Neeraj Sanjay Kale <neeraj.sanjaykale@nxp.com>
Reviewed-by: Rob Herring (Arm) <robh@kernel.org>
---
v2: Rephrase description and use "-gpios". (Krzysztof, Rob)
v3: Use device-wakeup-gpios instead of h2c-ps-gpios. (Krzysztof)
v4: Add Reviewed-by (Rob)
---
.../devicetree/bindings/net/bluetooth/nxp,88w8987-bt.yaml | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/Documentation/devicetree/bindings/net/bluetooth/nxp,88w8987-bt.yaml b/Documentation/devicetree/bindings/net/bluetooth/nxp,88w8987-bt.yaml
index 37a65badb448..0a2d7baf5db3 100644
--- a/Documentation/devicetree/bindings/net/bluetooth/nxp,88w8987-bt.yaml
+++ b/Documentation/devicetree/bindings/net/bluetooth/nxp,88w8987-bt.yaml
@@ -34,6 +34,12 @@ properties:
firmware-name:
maxItems: 1
+ device-wakeup-gpios:
+ maxItems: 1
+ description:
+ Host-To-Chip power save mechanism is driven by this GPIO
+ connected to BT_WAKE_IN pin of the NXP chipset.
+
required:
- compatible
@@ -41,10 +47,12 @@ additionalProperties: false
examples:
- |
+ #include <dt-bindings/gpio/gpio.h>
serial {
bluetooth {
compatible = "nxp,88w8987-bt";
fw-init-baudrate = <3000000>;
firmware-name = "uartuart8987_bt_v0.bin";
+ device-wakeup-gpios = <&gpio 11 GPIO_ACTIVE_HIGH>;
};
};
--
2.25.1
^ permalink raw reply related [flat|nested] 4+ messages in thread* [PATCH v5 2/2] Bluetooth: btnxpuart: Add GPIO support to power save feature
2024-10-08 9:11 [PATCH v5 0/2] Bluetooth: btnxpuart: Add GPIO mechanism to Neeraj Sanjay Kale
2024-10-08 9:11 ` [PATCH v5 1/2] dt-bindings: net: bluetooth: nxp: Add support for power save feature using GPIO Neeraj Sanjay Kale
@ 2024-10-08 9:11 ` Neeraj Sanjay Kale
2024-10-08 14:00 ` [PATCH v5 0/2] Bluetooth: btnxpuart: Add GPIO mechanism to patchwork-bot+bluetooth
2 siblings, 0 replies; 4+ messages in thread
From: Neeraj Sanjay Kale @ 2024-10-08 9:11 UTC (permalink / raw)
To: marcel, luiz.dentz, robh, krzk+dt, conor+dt
Cc: linux-bluetooth, linux-kernel, devicetree, amitkumar.karwar,
rohit.fule, neeraj.sanjaykale, sherry.sun, ziniu.wang_1,
haibo.chen, LnxRevLi
This adds support for driving the chip into sleep or wakeup with a GPIO.
If the device tree property device-wakeup-gpios is defined, the driver
utilizes this GPIO for controlling the chip's power save state, else it
uses the default UART-break method.
Signed-off-by: Neeraj Sanjay Kale <neeraj.sanjaykale@nxp.com>
---
v3: Remove GPIO toggling in ps_init(). (Shenwei Wang)
v4: Use devm_gpiod_get_optional() instead of devm_gpiod_get()
v5: Fix compile error due to copy-paste. (kernel test robot
<lkp@intel.com>)
---
drivers/bluetooth/btnxpuart.c | 57 +++++++++++++++++++++++++++++++----
1 file changed, 51 insertions(+), 6 deletions(-)
diff --git a/drivers/bluetooth/btnxpuart.c b/drivers/bluetooth/btnxpuart.c
index 2b8a07c745c9..ff4acc7347a2 100644
--- a/drivers/bluetooth/btnxpuart.c
+++ b/drivers/bluetooth/btnxpuart.c
@@ -16,6 +16,7 @@
#include <linux/crc8.h>
#include <linux/crc32.h>
#include <linux/string_helpers.h>
+#include <linux/gpio/consumer.h>
#include <net/bluetooth/bluetooth.h>
#include <net/bluetooth/hci_core.h>
@@ -82,6 +83,7 @@
#define WAKEUP_METHOD_BREAK 1
#define WAKEUP_METHOD_EXT_BREAK 2
#define WAKEUP_METHOD_RTS 3
+#define WAKEUP_METHOD_GPIO 4
#define WAKEUP_METHOD_INVALID 0xff
/* power save mode status */
@@ -135,6 +137,7 @@ struct ps_data {
bool driver_sent_cmd;
u16 h2c_ps_interval;
u16 c2h_ps_interval;
+ struct gpio_desc *h2c_ps_gpio;
struct hci_dev *hdev;
struct work_struct work;
struct timer_list ps_timer;
@@ -365,7 +368,7 @@ static void ps_control(struct hci_dev *hdev, u8 ps_state)
{
struct btnxpuart_dev *nxpdev = hci_get_drvdata(hdev);
struct ps_data *psdata = &nxpdev->psdata;
- int status;
+ int status = 0;
if (psdata->ps_state == ps_state ||
!test_bit(BTNXPUART_SERDEV_OPEN, &nxpdev->tx_state))
@@ -373,6 +376,14 @@ static void ps_control(struct hci_dev *hdev, u8 ps_state)
mutex_lock(&psdata->ps_lock);
switch (psdata->cur_h2c_wakeupmode) {
+ case WAKEUP_METHOD_GPIO:
+ if (ps_state == PS_STATE_AWAKE)
+ gpiod_set_value_cansleep(psdata->h2c_ps_gpio, 0);
+ else
+ gpiod_set_value_cansleep(psdata->h2c_ps_gpio, 1);
+ bt_dev_dbg(hdev, "Set h2c_ps_gpio: %s",
+ str_high_low(ps_state == PS_STATE_SLEEP));
+ break;
case WAKEUP_METHOD_DTR:
if (ps_state == PS_STATE_AWAKE)
status = serdev_device_set_tiocm(nxpdev->serdev, TIOCM_DTR, 0);
@@ -422,15 +433,29 @@ static void ps_timeout_func(struct timer_list *t)
}
}
-static void ps_setup(struct hci_dev *hdev)
+static int ps_setup(struct hci_dev *hdev)
{
struct btnxpuart_dev *nxpdev = hci_get_drvdata(hdev);
+ struct serdev_device *serdev = nxpdev->serdev;
struct ps_data *psdata = &nxpdev->psdata;
+ psdata->h2c_ps_gpio = devm_gpiod_get_optional(&serdev->dev, "device-wakeup",
+ GPIOD_OUT_LOW);
+ if (IS_ERR(psdata->h2c_ps_gpio)) {
+ bt_dev_err(hdev, "Error fetching device-wakeup-gpios: %ld",
+ PTR_ERR(psdata->h2c_ps_gpio));
+ return PTR_ERR(psdata->h2c_ps_gpio);
+ }
+
+ if (!psdata->h2c_ps_gpio)
+ psdata->h2c_wakeup_gpio = 0xff;
+
psdata->hdev = hdev;
INIT_WORK(&psdata->work, ps_work_func);
mutex_init(&psdata->ps_lock);
timer_setup(&psdata->ps_timer, ps_timeout_func, 0);
+
+ return 0;
}
static bool ps_wakeup(struct btnxpuart_dev *nxpdev)
@@ -516,6 +541,9 @@ static int send_wakeup_method_cmd(struct hci_dev *hdev, void *data)
pcmd.c2h_wakeupmode = psdata->c2h_wakeupmode;
pcmd.c2h_wakeup_gpio = psdata->c2h_wakeup_gpio;
switch (psdata->h2c_wakeupmode) {
+ case WAKEUP_METHOD_GPIO:
+ pcmd.h2c_wakeupmode = BT_CTRL_WAKEUP_METHOD_GPIO;
+ break;
case WAKEUP_METHOD_DTR:
pcmd.h2c_wakeupmode = BT_CTRL_WAKEUP_METHOD_DSR;
break;
@@ -550,6 +578,7 @@ static void ps_init(struct hci_dev *hdev)
{
struct btnxpuart_dev *nxpdev = hci_get_drvdata(hdev);
struct ps_data *psdata = &nxpdev->psdata;
+ u8 default_h2c_wakeup_mode = DEFAULT_H2C_WAKEUP_MODE;
serdev_device_set_tiocm(nxpdev->serdev, 0, TIOCM_RTS);
usleep_range(5000, 10000);
@@ -561,8 +590,17 @@ static void ps_init(struct hci_dev *hdev)
psdata->c2h_wakeup_gpio = 0xff;
psdata->cur_h2c_wakeupmode = WAKEUP_METHOD_INVALID;
+ if (psdata->h2c_ps_gpio)
+ default_h2c_wakeup_mode = WAKEUP_METHOD_GPIO;
+
psdata->h2c_ps_interval = PS_DEFAULT_TIMEOUT_PERIOD_MS;
- switch (DEFAULT_H2C_WAKEUP_MODE) {
+
+ switch (default_h2c_wakeup_mode) {
+ case WAKEUP_METHOD_GPIO:
+ psdata->h2c_wakeupmode = WAKEUP_METHOD_GPIO;
+ gpiod_set_value_cansleep(psdata->h2c_ps_gpio, 0);
+ usleep_range(5000, 10000);
+ break;
case WAKEUP_METHOD_DTR:
psdata->h2c_wakeupmode = WAKEUP_METHOD_DTR;
serdev_device_set_tiocm(nxpdev->serdev, 0, TIOCM_DTR);
@@ -1279,6 +1317,9 @@ static int nxp_enqueue(struct hci_dev *hdev, struct sk_buff *skb)
psdata->c2h_wakeup_gpio = wakeup_parm.c2h_wakeup_gpio;
psdata->h2c_wakeup_gpio = wakeup_parm.h2c_wakeup_gpio;
switch (wakeup_parm.h2c_wakeupmode) {
+ case BT_CTRL_WAKEUP_METHOD_GPIO:
+ psdata->h2c_wakeupmode = WAKEUP_METHOD_GPIO;
+ break;
case BT_CTRL_WAKEUP_METHOD_DSR:
psdata->h2c_wakeupmode = WAKEUP_METHOD_DTR;
break;
@@ -1509,13 +1550,17 @@ static int nxp_serdev_probe(struct serdev_device *serdev)
if (hci_register_dev(hdev) < 0) {
dev_err(&serdev->dev, "Can't register HCI device\n");
- hci_free_dev(hdev);
- return -ENODEV;
+ goto probe_fail;
}
- ps_setup(hdev);
+ if (ps_setup(hdev))
+ goto probe_fail;
return 0;
+
+probe_fail:
+ hci_free_dev(hdev);
+ return -ENODEV;
}
static void nxp_serdev_remove(struct serdev_device *serdev)
--
2.25.1
^ permalink raw reply related [flat|nested] 4+ messages in thread* Re: [PATCH v5 0/2] Bluetooth: btnxpuart: Add GPIO mechanism to
2024-10-08 9:11 [PATCH v5 0/2] Bluetooth: btnxpuart: Add GPIO mechanism to Neeraj Sanjay Kale
2024-10-08 9:11 ` [PATCH v5 1/2] dt-bindings: net: bluetooth: nxp: Add support for power save feature using GPIO Neeraj Sanjay Kale
2024-10-08 9:11 ` [PATCH v5 2/2] Bluetooth: btnxpuart: Add GPIO support to power save feature Neeraj Sanjay Kale
@ 2024-10-08 14:00 ` patchwork-bot+bluetooth
2 siblings, 0 replies; 4+ messages in thread
From: patchwork-bot+bluetooth @ 2024-10-08 14:00 UTC (permalink / raw)
To: Neeraj Sanjay Kale
Cc: marcel, luiz.dentz, robh, krzk+dt, conor+dt, linux-bluetooth,
linux-kernel, devicetree, amitkumar.karwar, rohit.fule,
sherry.sun, ziniu.wang_1, haibo.chen, LnxRevLi
Hello:
This series was applied to bluetooth/bluetooth-next.git (master)
by Luiz Augusto von Dentz <luiz.von.dentz@intel.com>:
On Tue, 8 Oct 2024 14:41:57 +0530 you wrote:
> This patch series introduces a new optional device tree property
> device-wakeup-gpios, which specifies the GPIO connected to BT_WAKE_IN pin of
> the NXP chipset.
>
> If this property is defined, the BTNXPUART driver uses this GPIO to put
> the BT controller into sleep or wake it up, instead of the default UART
> break mechanism.
>
> [...]
Here is the summary with links:
- [v5,1/2] dt-bindings: net: bluetooth: nxp: Add support for power save feature using GPIO
https://git.kernel.org/bluetooth/bluetooth-next/c/99ba211a9b71
- [v5,2/2] Bluetooth: btnxpuart: Add GPIO support to power save feature
https://git.kernel.org/bluetooth/bluetooth-next/c/039468a21912
You are awesome, thank you!
--
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html
^ permalink raw reply [flat|nested] 4+ messages in thread