summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Marheine <pmarheine@chromium.org>2022-06-02 16:47:16 +1000
committerChromeos LUCI <chromeos-scoped@luci-project-accounts.iam.gserviceaccount.com>2022-06-03 07:00:50 +0000
commitbf09eba02420f42e7a42a5e922c0e1409c615cbd (patch)
tree8293a070f8f733c2b3e0642afae110d1bdd14316
parentc5e39056c3f2b6a607492eaaca07dae57c087f71 (diff)
downloadchrome-ec-bf09eba02420f42e7a42a5e922c0e1409c615cbd.tar.gz
nereid: bring charger out of LPM on S0 entry
This appears to fix VBUS sourcing, though we don't understand why. It may also prevent charger damage with as-yet-unexplained cause. BUG=b:231920135,b:230712704 TEST=VBUS sourcing works when AP is in S0 BRANCH=none Signed-off-by: Peter Marheine <pmarheine@chromium.org> Change-Id: Ia4d74f4211eb97b532882914d077e3dde5e59f64 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/3686012 Reviewed-by: Andrew McRae <amcrae@google.com>
-rw-r--r--zephyr/projects/nissa/src/nereid/usbc.c47
1 files changed, 47 insertions, 0 deletions
diff --git a/zephyr/projects/nissa/src/nereid/usbc.c b/zephyr/projects/nissa/src/nereid/usbc.c
index 95bb1a5fdc..5219c252e5 100644
--- a/zephyr/projects/nissa/src/nereid/usbc.c
+++ b/zephyr/projects/nissa/src/nereid/usbc.c
@@ -4,6 +4,7 @@
*/
#include <zephyr/logging/log.h>
+#include <ap_power/ap_power.h>
#include "charge_state_v2.h"
#include "chipset.h"
@@ -80,6 +81,52 @@ __override bool pd_check_vbus_level(int port, enum vbus_level level)
return false;
}
+/*
+ * Putting chargers into LPM when in suspend reduces power draw by about 8mW
+ * per charger, but also seems critical to correct operation in source mode:
+ * if chargers are not in LPM when a sink is first connected, VBUS sourcing
+ * works even if the partner is later removed (causing LPM entry) and
+ * reconnected (causing LPM exit). If in LPM initially, sourcing VBUS
+ * consistently causes the charger to report (apparently spurious) overcurrent
+ * failures.
+ *
+ * In short, this is important to making things work correctly but we don't
+ * understand why.
+ */
+static void board_chargers_suspend(struct ap_power_ev_callback *const cb,
+ const struct ap_power_ev_data data)
+{
+ void (*fn)(int chgnum);
+
+ switch (data.event) {
+ case AP_POWER_SUSPEND:
+ fn = sm5803_enable_low_power_mode;
+ break;
+ case AP_POWER_RESUME:
+ fn = sm5803_disable_low_power_mode;
+ break;
+ default:
+ LOG_WRN("%s: power event %d is not recognized",
+ __func__, data.event);
+ return;
+ }
+
+ fn(CHARGER_PRIMARY);
+ if (board_get_charger_chip_count() > 1)
+ fn(CHARGER_SECONDARY);
+}
+
+static int board_chargers_suspend_init(const struct device *unused)
+{
+ static struct ap_power_ev_callback cb = {
+ .handler = board_chargers_suspend,
+ .events = AP_POWER_SUSPEND | AP_POWER_RESUME,
+ };
+ ap_power_ev_add_callback(&cb);
+ return 0;
+}
+SYS_INIT(board_chargers_suspend_init, APPLICATION, 0);
+
int board_set_active_charge_port(int port)
{
int is_real_port = (port >= 0 && port < board_get_usb_pd_port_count());