From f5b5e93e2f246bb5eec2d20c0ffd7a064de96d50 Mon Sep 17 00:00:00 2001 From: Andrew McRae Date: Mon, 18 Jul 2022 17:13:13 +1000 Subject: pwrseq: gpio: Use output state for GPIO get on outputs When retrieving the state of an output GPIO, do not read the physical level on the pin, but instead read the configured state (by reading the GPIO configuration). Open drain outputs sometimes use low voltages, and so reading the physical level on the pin may indicate a 0 for an output that has been set to 1. The stored configuration of the GPIO does not include the GPIO_ACTIVE_LOW flag, so this is explicitly checked, and the state inverted if necessary. BUG=none TEST=zmake build nivviks; flash & run BRANCH=none Signed-off-by: Andrew McRae Change-Id: Idb2cb1c6b1b0902189e1fd1471cf9ca30c2711dc Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/3769706 Reviewed-by: Peter Marheine --- zephyr/subsys/ap_pwrseq/Kconfig | 3 +++ zephyr/subsys/ap_pwrseq/signal_gpio.c | 22 ++++++++++++++++++++++ 2 files changed, 25 insertions(+) diff --git a/zephyr/subsys/ap_pwrseq/Kconfig b/zephyr/subsys/ap_pwrseq/Kconfig index 6f39906bf2..1845baa2bd 100644 --- a/zephyr/subsys/ap_pwrseq/Kconfig +++ b/zephyr/subsys/ap_pwrseq/Kconfig @@ -5,12 +5,15 @@ menuconfig AP_PWRSEQ bool "AP Power sequencing support" select HAS_TASK_POWERBTN + select GPIO_GET_CONFIG help Enables AP power sequencing support with embedded controller. This includes normal shutdown, critical shutdown and reset handling. Enabling this automatically enables HAS_TASK_POWERBTN since this task is required to handle power button pressed/released by user. + Enabling this also enables retrieving the GPIO config feature + so that the value of output GPIOs can be determined. if AP_PWRSEQ diff --git a/zephyr/subsys/ap_pwrseq/signal_gpio.c b/zephyr/subsys/ap_pwrseq/signal_gpio.c index f4b74fd3be..4d21657624 100644 --- a/zephyr/subsys/ap_pwrseq/signal_gpio.c +++ b/zephyr/subsys/ap_pwrseq/signal_gpio.c @@ -100,6 +100,28 @@ int power_signal_gpio_get(enum pwr_sig_gpio index) if (index < 0 || index >= ARRAY_SIZE(gpio_config)) { return -EINVAL; } + /* + * Getting the current value of an output is + * done by retrieving the config and checking what the + * output state has been set to, not by reading the + * physical level of the pin (open drain outputs + * may have a low voltage). + */ + if (gpio_config[index].output) { + int rv; + gpio_flags_t flags; + + rv = gpio_pin_get_config_dt(&spec[index], &flags); + if (rv != 0) { + return rv; + } + rv = (flags & GPIO_OUTPUT_INIT_HIGH) ? 1 : 0; + /* If active low signal, invert it */ + if (spec[index].dt_flags & GPIO_ACTIVE_LOW) { + rv = !rv; + } + return rv; + } return gpio_pin_get_dt(&spec[index]); } -- cgit v1.2.1