diff options
author | Loic Poulain <loic.poulain@linaro.org> | 2025-02-19 10:15:11 +0100 |
---|---|---|
committer | Luiz Augusto von Dentz <luiz.von.dentz@intel.com> | 2025-03-25 12:41:34 -0400 |
commit | 873b6754af6869b39dc59b44fd1d957e90ae771a (patch) | |
tree | 13abf3852805c95a212493368607c5ff7b64d7c9 /drivers/bluetooth | |
parent | 852cfdc7a5a5af54358325c1e0f490cc178d9664 (diff) |
bluetooth: btnxpuart: Support for controller wakeup gpio config
When using the out-of-band WAKE_IN and WAKE_OUT pins, we have to tell
the firmware which pins to use (from controller point of view). This
allows to report remote wakeup support when WAKE_OUT(c2h) is configured.
Signed-off-by: Loic Poulain <loic.poulain@linaro.org>
Reviewed-by: Neeraj Sanjay Kale <neeraj.sanjaykale@nxp.com>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Diffstat (limited to 'drivers/bluetooth')
-rw-r--r-- | drivers/bluetooth/btnxpuart.c | 32 |
1 files changed, 28 insertions, 4 deletions
diff --git a/drivers/bluetooth/btnxpuart.c b/drivers/bluetooth/btnxpuart.c index aa5ec1d444a9..4f2f429c9800 100644 --- a/drivers/bluetooth/btnxpuart.c +++ b/drivers/bluetooth/btnxpuart.c @@ -447,8 +447,14 @@ static int ps_setup(struct hci_dev *hdev) return PTR_ERR(psdata->h2c_ps_gpio); } - if (!psdata->h2c_ps_gpio) + if (device_property_read_u8(&serdev->dev, "nxp,wakein-pin", &psdata->h2c_wakeup_gpio)) { + psdata->h2c_wakeup_gpio = 0xff; /* 0xff: use default pin/gpio */ + } else if (!psdata->h2c_ps_gpio) { + bt_dev_warn(hdev, "nxp,wakein-pin property without device-wakeup GPIO"); psdata->h2c_wakeup_gpio = 0xff; + } + + device_property_read_u8(&serdev->dev, "nxp,wakeout-pin", &psdata->c2h_wakeup_gpio); psdata->hdev = hdev; INIT_WORK(&psdata->work, ps_work_func); @@ -540,9 +546,11 @@ 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; + pcmd.h2c_wakeup_gpio = 0xff; switch (psdata->h2c_wakeupmode) { case WAKEUP_METHOD_GPIO: pcmd.h2c_wakeupmode = BT_CTRL_WAKEUP_METHOD_GPIO; + pcmd.h2c_wakeup_gpio = psdata->h2c_wakeup_gpio; break; case WAKEUP_METHOD_DTR: pcmd.h2c_wakeupmode = BT_CTRL_WAKEUP_METHOD_DSR; @@ -552,7 +560,6 @@ static int send_wakeup_method_cmd(struct hci_dev *hdev, void *data) pcmd.h2c_wakeupmode = BT_CTRL_WAKEUP_METHOD_BREAK; break; } - pcmd.h2c_wakeup_gpio = 0xff; skb = nxp_drv_send_cmd(hdev, HCI_NXP_WAKEUP_METHOD, sizeof(pcmd), &pcmd); if (IS_ERR(skb)) { @@ -586,8 +593,13 @@ static void ps_init(struct hci_dev *hdev) usleep_range(5000, 10000); psdata->ps_state = PS_STATE_AWAKE; - psdata->c2h_wakeupmode = BT_HOST_WAKEUP_METHOD_NONE; - psdata->c2h_wakeup_gpio = 0xff; + + if (psdata->c2h_wakeup_gpio) { + psdata->c2h_wakeupmode = BT_HOST_WAKEUP_METHOD_GPIO; + } else { + psdata->c2h_wakeupmode = BT_HOST_WAKEUP_METHOD_NONE; + psdata->c2h_wakeup_gpio = 0xff; + } psdata->cur_h2c_wakeupmode = WAKEUP_METHOD_INVALID; if (psdata->h2c_ps_gpio) @@ -1266,6 +1278,17 @@ static int nxp_shutdown(struct hci_dev *hdev) return 0; } +static bool nxp_wakeup(struct hci_dev *hdev) +{ + struct btnxpuart_dev *nxpdev = hci_get_drvdata(hdev); + struct ps_data *psdata = &nxpdev->psdata; + + if (psdata->c2h_wakeupmode != BT_HOST_WAKEUP_METHOD_NONE) + return true; + + return false; +} + static int btnxpuart_queue_skb(struct hci_dev *hdev, struct sk_buff *skb) { struct btnxpuart_dev *nxpdev = hci_get_drvdata(hdev); @@ -1546,6 +1569,7 @@ static int nxp_serdev_probe(struct serdev_device *serdev) hdev->send = nxp_enqueue; hdev->hw_error = nxp_hw_err; hdev->shutdown = nxp_shutdown; + hdev->wakeup = nxp_wakeup; SET_HCIDEV_DEV(hdev, &serdev->dev); if (hci_register_dev(hdev) < 0) { |