summaryrefslogtreecommitdiff
path: root/zephyr/projects/nissa/src/nereid/usbc.c
diff options
context:
space:
mode:
Diffstat (limited to 'zephyr/projects/nissa/src/nereid/usbc.c')
-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());