diff options
Diffstat (limited to 'common/dps.c')
-rw-r--r-- | common/dps.c | 63 |
1 files changed, 40 insertions, 23 deletions
diff --git a/common/dps.c b/common/dps.c index 13f551a95d..c5a8ba4045 100644 --- a/common/dps.c +++ b/common/dps.c @@ -16,6 +16,7 @@ #include "charge_manager.h" #include "charge_state.h" #include "ec_commands.h" +#include "hooks.h" #include "math_util.h" #include "task.h" #include "timer.h" @@ -30,13 +31,8 @@ #define T_REQUEST_STABLE_TIME (10 * SECOND) #define T_NEXT_CHECK_TIME (5 * SECOND) -#define DPS_FLAG_DISABLED BIT(0) -#define DPS_FLAG_NO_SRCCAP BIT(1) -#define DPS_FLAG_WAITING BIT(2) -#define DPS_FLAG_SAMPLED BIT(3) -#define DPS_FLAG_NEED_MORE_PWR BIT(4) - -#define DPS_FLAG_STOP_EVENTS (DPS_FLAG_DISABLED | DPS_FLAG_NO_SRCCAP) +#define DPS_FLAG_STOP_EVENTS \ + (DPS_FLAG_DISABLED | DPS_FLAG_NO_SRCCAP | DPS_FLAG_NO_BATTERY) #define DPS_FLAG_ALL GENMASK(31, 0) #define MAX_MOVING_AVG_WINDOW 5 @@ -52,7 +48,7 @@ static bool fake_enabled; static int fake_mv, fake_ma; static int dynamic_mv; static int dps_port = CHARGE_PORT_NONE; -static uint32_t flag; +static atomic_t flag; #define CPRINTF(format, args...) cprintf(CC_USBPD, "DPS " format, ##args) #define CPRINTS(format, args...) cprints(CC_USBPD, "DPS " format, ##args) @@ -370,18 +366,18 @@ __maybe_unused static bool has_new_power_request(struct pdo_candidate *cand) */ if (is_near_limit(input_pwr_avg, req_pwr) || is_near_limit(input_curr_avg, MIN(req_ma, input_curr_limit))) { - flag |= DPS_FLAG_NEED_MORE_PWR; + atomic_or(&flag, DPS_FLAG_NEED_MORE_PWR); if (!fake_enabled) input_pwr_avg = req_pwr + 1; } else { - flag &= ~DPS_FLAG_NEED_MORE_PWR; + atomic_clear_bits(&flag, DPS_FLAG_NEED_MORE_PWR); } if (debug_level) CPRINTS("C%d 0x%x last (%dmW %dmV) input (%dmW %dmV %dmA) " "avg (%dmW, %dmA)", - active_port, flag, req_pwr, req_mv, input_pwr, vbus, - input_curr, input_pwr_avg, input_curr_avg); + active_port, (int)flag, req_pwr, req_mv, input_pwr, + vbus, input_curr, input_pwr_avg, input_curr_avg); for (int i = 0; i < board_get_usb_pd_port_count(); ++i) { const uint32_t *const src_caps = pd_get_src_caps(i); @@ -498,29 +494,34 @@ void dps_task(void *u) dps_reset(); task_wait_event(-1); /* clear flags after wake up. */ - flag = 0; + atomic_clear(&flag); update_timeout(dps_config.t_check); continue; } else if (now.val < timeout.val) { - flag |= DPS_FLAG_WAITING; + atomic_or(&flag, DPS_FLAG_WAITING); task_wait_event(timeout.val - now.val); - flag &= ~DPS_FLAG_WAITING; + atomic_clear_bits(&flag, DPS_FLAG_WAITING); continue; } if (!is_enabled) { - flag |= DPS_FLAG_DISABLED; + atomic_or(&flag, DPS_FLAG_DISABLED); continue; } if (!has_srccap()) { - flag |= DPS_FLAG_NO_SRCCAP; + atomic_or(&flag, DPS_FLAG_NO_SRCCAP); + continue; + } + + if (battery_is_present() != BP_YES) { + atomic_or(&flag, DPS_FLAG_NO_BATTERY); continue; } if (!has_new_power_request(&curr_cand)) { sample_count = 0; - flag &= ~DPS_FLAG_SAMPLED; + atomic_clear_bits(&flag, DPS_FLAG_SAMPLED); } else { if (last_cand.port == curr_cand.port && last_cand.mv == curr_cand.mv && @@ -528,7 +529,7 @@ void dps_task(void *u) sample_count++; else sample_count = 1; - flag |= DPS_FLAG_SAMPLED; + atomic_or(&flag, DPS_FLAG_SAMPLED); } if (sample_count == dps_config.k_sample) { @@ -536,17 +537,28 @@ void dps_task(void *u) dps_port = curr_cand.port; pd_dpm_request(dps_port, DPM_REQUEST_NEW_POWER_LEVEL); sample_count = 0; - flag &= ~(DPS_FLAG_SAMPLED | DPS_FLAG_NEED_MORE_PWR); + atomic_clear_bits(&flag, (DPS_FLAG_SAMPLED | + DPS_FLAG_NEED_MORE_PWR)); } last_cand.port = curr_cand.port; last_cand.mv = curr_cand.mv; last_cand.mw = curr_cand.mw; - update_timeout(dps_config.t_check); } } +void check_battery_present(void) +{ + const struct batt_params *batt = charger_current_battery_params(); + + if (batt->is_present == BP_YES && (flag & DPS_FLAG_NO_BATTERY)) { + atomic_clear_bits(&flag, DPS_FLAG_NO_BATTERY); + task_wake(TASK_ID_DPS); + } +} +DECLARE_HOOK(HOOK_BATTERY_SOC_CHANGE, check_battery_present, HOOK_PRIO_DEFAULT); + static int command_dps(int argc, const char **argv) { int port = charge_manager_get_active_charge_port(); @@ -558,8 +570,9 @@ static int command_dps(int argc, const char **argv) int batt_mv; ccprintf("flag=0x%x k_more=%d k_less=%d k_sample=%d k_win=%d\n", - flag, dps_config.k_more_pwr, dps_config.k_less_pwr, - dps_config.k_sample, dps_config.k_window); + (int)flag, dps_config.k_more_pwr, + dps_config.k_less_pwr, dps_config.k_sample, + dps_config.k_window); ccprintf("t_stable=%d t_check=%d\n", dps_config.t_stable / SECOND, dps_config.t_check / SECOND); @@ -703,4 +716,8 @@ __test_only int *dps_get_debug_level(void) { return &debug_level; } +__test_only int dps_get_flag(void) +{ + return flag; +} #endif /* TEST_BUILD */ |