Skip to content

Commit

Permalink
bluetooth: btnxpuart: Support for controller wakeup gpio config
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Loic Poulain authored and Luiz Augusto von Dentz committed Mar 25, 2025
1 parent 852cfdc commit 873b675
Showing 1 changed file with 28 additions and 4 deletions.
32 changes: 28 additions & 4 deletions drivers/bluetooth/btnxpuart.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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;
Expand All @@ -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)) {
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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) {
Expand Down

0 comments on commit 873b675

Please sign in to comment.