]> www.infradead.org Git - users/hch/misc.git/commitdiff
bluetooth: btnxpuart: Support for controller wakeup gpio config
authorLoic Poulain <loic.poulain@linaro.org>
Wed, 19 Feb 2025 09:15:11 +0000 (10:15 +0100)
committerLuiz Augusto von Dentz <luiz.von.dentz@intel.com>
Tue, 25 Mar 2025 16:41:34 +0000 (12:41 -0400)
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>
drivers/bluetooth/btnxpuart.c

index aa5ec1d444a9d91b584cfaae53affd78fe269c52..4f2f429c9800b13b4dd0b8ec642fb4f3a6772311 100644 (file)
@@ -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) {