From 61d912b9378172b5857183acd47831a7c443c176 Mon Sep 17 00:00:00 2001 From: Umesh Vats Date: Mon, 15 Mar 2021 18:57:33 -0700 Subject: [PATCH] Bluetooth: Assert XO GPIO before asserting BT_EN Make change in sequence to assert XO GPIO before BT_EN GPIO is asserted for valid latch in HW. Change-Id: Ibe3bd668adb284c861619d3b195006b7e9b106eb Signed-off-by: Umesh Vats --- drivers/bluetooth/btpower.c | 81 ++++++++++++++++++++----------------- 1 file changed, 44 insertions(+), 37 deletions(-) diff --git a/drivers/bluetooth/btpower.c b/drivers/bluetooth/btpower.c index a50493a9c5fa..40b42fce539e 100644 --- a/drivers/bluetooth/btpower.c +++ b/drivers/bluetooth/btpower.c @@ -353,6 +353,45 @@ static int bt_clk_disable(struct bt_power_clk_data *clk) return rc; } +static void btpower_set_xo_reset_gpio_state(bool enable) +{ + int xo_reset_gpio = bt_power_pdata->xo_gpio_sys_rst; + int retry = 0; + int rc = 0; + + if (xo_reset_gpio < 0) + return; + +retry_gpio_req: + rc = gpio_request(xo_reset_gpio, "xo_reset_gpio_n"); + if (rc) { + if (retry++ < XO_RESET_RETRY_COUNT_MAX) { + /* wait for ~(10 - 20) ms */ + usleep_range(10000, 20000); + goto retry_gpio_req; + } + } + + if (rc) { + pr_err("%s: unable to request XO reset gpio %d (%d)\n", + __func__, xo_reset_gpio, rc); + return; + } + + if (enable) { + gpio_direction_output(xo_reset_gpio, 1); + /*XO CLK must be asserted for some time before BT_EN */ + usleep_range(100, 200); + } else { + /* Assert XO CLK ~(2-5)ms before off for valid latch in HW */ + usleep_range(2000, 5000); + gpio_direction_output(xo_reset_gpio, 0); + } + + gpio_free(xo_reset_gpio); +} + + static int bt_configure_gpios(int on) { int rc = 0; @@ -360,9 +399,7 @@ static int bt_configure_gpios(int on) int wl_reset_gpio = bt_power_pdata->wl_gpio_sys_rst; int bt_sw_ctrl_gpio = bt_power_pdata->bt_gpio_sw_ctrl; int bt_debug_gpio = bt_power_pdata->bt_gpio_debug; - int xo_reset_gpio = bt_power_pdata->xo_gpio_sys_rst; int assert_dbg_gpio = 0; - int retry = 0; if (on) { rc = gpio_request(bt_reset_gpio, "bt_sys_rst_n"); @@ -396,6 +433,8 @@ static int bt_configure_gpios(int on) if ((wl_reset_gpio < 0) || ((wl_reset_gpio >= 0) && gpio_get_value(wl_reset_gpio))) { + + btpower_set_xo_reset_gpio_state(true); pr_info("%s: BTON: Asserting BT_EN\n", __func__); rc = gpio_direction_output(bt_reset_gpio, 1); if (rc) { @@ -404,6 +443,7 @@ static int bt_configure_gpios(int on) } PWR_SRC_STATUS_SET(BT_RESET_GPIO, gpio_get_value(bt_reset_gpio)); + btpower_set_xo_reset_gpio_state(false); } if ((wl_reset_gpio >= 0) && (gpio_get_value(wl_reset_gpio) == 0)) { if (gpio_get_value(bt_reset_gpio)) { @@ -420,6 +460,7 @@ static int bt_configure_gpios(int on) pr_info("%s:add 100ms delay for AON output to fully discharge\n", __func__); msleep(100); + btpower_set_xo_reset_gpio_state(true); rc = gpio_direction_output(bt_reset_gpio, 1); if (rc) { pr_err("%s: Unable to set direction\n", __func__); @@ -427,43 +468,9 @@ static int bt_configure_gpios(int on) } bt_power_src_status[BT_RESET_GPIO] = gpio_get_value(bt_reset_gpio); + btpower_set_xo_reset_gpio_state(false); } - pr_info("xo_reset_gpio(%d)\n", xo_reset_gpio); - - if (xo_reset_gpio > 0) { -retry_gpio_req: - rc = gpio_request(xo_reset_gpio, "xo_reset_gpio_n"); - if (rc) { - if (retry++ < XO_RESET_RETRY_COUNT_MAX) { - /* wait for ~(10 - 20) ms */ - usleep_range(10000, 20000); - goto retry_gpio_req; - } - } - - if (rc) { - pr_err("%s: unable to request XO reset gpio %d (%d)\n", - __func__, xo_reset_gpio, rc); - } else { - pr_info("%s: gpio_request for xo_reset_gpio succeed\n", - __func__); - // XO clk GPIO must be asserted for some time - rc = gpio_direction_output(xo_reset_gpio, 1); - if (rc) { - pr_err("%s: Unable to set direction of xo_reset_gpio\n", - __func__); - } - usleep_range(2000, 5000); - // pull XO clk GPIO low after 2 ms delay - rc = gpio_direction_output(xo_reset_gpio, 0); - if (rc) { - pr_err("%s: Unable to set direction of xo_reset_gpio\n", - __func__); - } - gpio_free(xo_reset_gpio); - } - } msleep(50); /* Check if SW_CTRL is asserted */ if (bt_sw_ctrl_gpio >= 0) {