diff options
author | Yang Qi <yangqs@google.com> | 2022-10-10 23:02:25 +0000 |
---|---|---|
committer | Yang Qi <yangqs@google.com> | 2022-11-11 05:11:59 +0000 |
commit | ab28ff91f6c6cbafadccf9d93b73f1b6e0d1437a (patch) | |
tree | 087ed5e2e6191b24a3062f58aebd514301940995 | |
parent | aded81bcbe571931844d80cc34a384e14651c0bd (diff) | |
download | uwb-ab28ff91f6c6cbafadccf9d93b73f1b6e0d1437a.tar.gz |
Modify dw3000 driver to insulate UWB from Aoc
Description: Given the hardware setup, both AP and AoC are directly
connected to the uwb_rst_L pin, AoC will give an inevitable pull down by
hardware default during its reset or crash. Thus, we try to drive uwb_rst_L pin high directly from AP to compensate, with permission from Qorvo that wait until the chip finishes cold boot (when uwb_rst_L goes high on boot).
Bug: 240205717
Test: see b/253540544
Change-Id: I723e8af9a7ffb30693a97c0bd990bb0a96f6cf70
-rw-r--r-- | kernel/drivers/net/ieee802154/dw3000_core.c | 17 |
1 files changed, 15 insertions, 2 deletions
diff --git a/kernel/drivers/net/ieee802154/dw3000_core.c b/kernel/drivers/net/ieee802154/dw3000_core.c index 4b384b9..42119c9 100644 --- a/kernel/drivers/net/ieee802154/dw3000_core.c +++ b/kernel/drivers/net/ieee802154/dw3000_core.c @@ -1823,6 +1823,7 @@ static int dw3000_power_supply(struct dw3000 *dw, int onoff) static int dw3000_reset_assert(struct dw3000 *dw, bool reset) { int rc; + int value; if (!gpio_is_valid(dw->reset_gpio)) { dev_err(dw->dev, "invalid reset gpio\n"); @@ -1838,10 +1839,22 @@ static int dw3000_reset_assert(struct dw3000 *dw, bool reset) } else { /* Release RESET GPIO. * Reset should be open drain, or switched to input whenever not driven - * low. It should not be driven high. */ + * low. It should not be driven high during chip cold boot process. */ rc = gpio_direction_input(dw->reset_gpio); - if (rc) + if (rc) { dev_err(dw->dev, "Could not set reset gpio as input\n"); + return rc; + } + /* check if dw3000 finishes cold boot */ + value = gpio_get_value(dw->reset_gpio); + if (!value) { + return -EPROBE_DEFER; + } + + /* set pin to output and drive high */ + rc = gpio_direction_output(dw->reset_gpio, 1); + if (rc) + dev_err(dw->dev, "Could not set reset gpio as output\n"); } return rc; } |