Commit 873b6754 authored by Loic Poulain's avatar Loic Poulain Committed by Luiz Augusto von Dentz
Browse files

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: default avatarLoic Poulain <loic.poulain@linaro.org>
Reviewed-by: default avatarNeeraj Sanjay Kale <neeraj.sanjaykale@nxp.com>
Signed-off-by: default avatarLuiz Augusto von Dentz <luiz.von.dentz@intel.com>
parent 852cfdc7
Loading
Loading
Loading
Loading
+28 −4
Original line number Diff line number Diff line
@@ -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;

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