diff options
-rw-r--r-- | board/samus_pd/board.h | 1 | ||||
-rw-r--r-- | common/charge_manager.c | 33 | ||||
-rw-r--r-- | common/charge_ramp.c | 73 | ||||
-rw-r--r-- | include/charge_ramp.h | 14 | ||||
-rw-r--r-- | include/config.h | 3 | ||||
-rw-r--r-- | util/ectool.c | 8 |
6 files changed, 112 insertions, 20 deletions
diff --git a/board/samus_pd/board.h b/board/samus_pd/board.h index ea5a7ef290..5e48b5e53a 100644 --- a/board/samus_pd/board.h +++ b/board/samus_pd/board.h @@ -53,6 +53,7 @@ #define CONFIG_USB_PD_CUSTOM_VDM #define CONFIG_USB_PD_DUAL_ROLE #define CONFIG_USB_PD_FLASH_ERASE_CHECK +#define CONFIG_USB_PD_HOST_EVENT_ON_POWER_CHANGE #define CONFIG_USB_PD_INTERNAL_COMP #define CONFIG_USB_PD_LOGGING #define CONFIG_USB_PD_LOG_SIZE 512 diff --git a/common/charge_manager.c b/common/charge_manager.c index 83b0582ddd..7e0600d8d9 100644 --- a/common/charge_manager.c +++ b/common/charge_manager.c @@ -192,11 +192,40 @@ static void charge_manager_fill_power_info(int port, r->meas.voltage_max = available_charge[sup][port].voltage; if (use_ramp_current) { - r->meas.current_max = chg_ramp_get_current_limit(); + /* + * If charge_ramp has not detected charger yet, + * then charger type is unknown. + */ + if (!chg_ramp_is_detected()) + r->type = USB_CHG_TYPE_UNKNOWN; + + /* Current limit is output of ramp module */ + r->meas.current_lim = chg_ramp_get_current_limit(); + + /* + * If ramp is allowed, then the max current depends + * on if ramp is stable. If ramp is stable, then + * max current is same as input current limit. If + * ramp is not stable, then we report the maximum + * current we could ramp up to for this supplier. + * If ramp is not allowed, max current is just the + * available charge current. + */ + if (board_is_ramp_allowed(sup)) { + r->meas.current_max = chg_ramp_is_stable() ? + r->meas.current_lim : + board_get_ramp_current_limit( + sup, + available_charge[sup][port].current); + } else { + r->meas.current_max = + available_charge[sup][port].current; + } + r->max_power = r->meas.current_max * r->meas.voltage_max; } else { - r->meas.current_max = + r->meas.current_max = r->meas.current_lim = available_charge[sup][port].current; r->max_power = POWER(available_charge[sup][port]); } diff --git a/common/charge_ramp.c b/common/charge_ramp.c index dbe14e11d4..f2a2c8bf51 100644 --- a/common/charge_ramp.c +++ b/common/charge_ramp.c @@ -9,6 +9,7 @@ #include "charge_ramp.h" #include "common.h" #include "console.h" +#include "ec_commands.h" #include "task.h" #include "timer.h" #include "usb_pd.h" @@ -48,7 +49,7 @@ enum chg_ramp_state { CHG_RAMP_DISCONNECTED, - CHG_RAMP_CHARGE_DETECT, + CHG_RAMP_CHARGE_DETECT_DELAY, CHG_RAMP_OVERCURRENT_DETECT, CHG_RAMP_RAMP, CHG_RAMP_STABILIZE, @@ -115,8 +116,8 @@ void chg_ramp_charge_supplier_change(int port, int supplier, int current, reg_time = registration_time; if (ramp_st != CHG_RAMP_STABILIZE) { ramp_st = (active_port == CHARGE_PORT_NONE) ? - CHG_RAMP_DISCONNECTED : CHG_RAMP_CHARGE_DETECT; - CPRINTS("Ramp reset: st%d\n", ramp_st); + CHG_RAMP_DISCONNECTED : CHG_RAMP_CHARGE_DETECT_DELAY; + CPRINTS("Ramp reset: st%d", ramp_st); task_wake(TASK_ID_CHG_RAMP); } } @@ -138,10 +139,24 @@ int chg_ramp_get_current_limit(void) } } +int chg_ramp_is_detected(void) +{ + /* Charger detected (charge detect delay has passed) */ + return ramp_st > CHG_RAMP_CHARGE_DETECT_DELAY; +} + +int chg_ramp_is_stable(void) +{ + return ramp_st == CHG_RAMP_STABLE; +} + void chg_ramp_task(void) { int task_wait_time = -1; int i; + uint64_t detect_end_time_us = 0, time_us; + int last_active_port = CHARGE_PORT_NONE; + /* * Static initializer so that we don't clobber early calls to this * module. @@ -162,25 +177,37 @@ void chg_ramp_task(void) /* Do nothing */ task_wait_time = -1; break; - case CHG_RAMP_CHARGE_DETECT: + case CHG_RAMP_CHARGE_DETECT_DELAY: /* Delay for charge_manager to determine supplier */ - /* On entry to state, store the OC recovery time */ - if (ramp_st_prev != ramp_st) + /* + * On entry to state, or if port changes, store the + * OC recovery time, and calculate the detect end + * time to exit this state. + */ + if (ramp_st_prev != ramp_st || + active_port != last_active_port) { + last_active_port = active_port; ACTIVE_OC_INFO.recover = reg_time.val - ACTIVE_OC_INFO.ts.val; + detect_end_time_us = get_time().val + + CHARGE_DETECT_DELAY; + task_wait_time = CHARGE_DETECT_DELAY; + break; + } - /* - * If we are not drawing full charge, then don't ramp, - * just wait in this state, until we are. - */ - if (!board_is_consuming_full_charge()) { - task_wait_time = CURRENT_DRAW_DELAY; + /* If detect delay has not passed, set wait time */ + time_us = get_time().val; + if (time_us < detect_end_time_us) { + task_wait_time = detect_end_time_us - time_us; break; } + /* Detect delay is over, fall through to next state */ ramp_st_new = CHG_RAMP_OVERCURRENT_DETECT; - task_wait_time = CHARGE_DETECT_DELAY; - break; +#ifdef CONFIG_USB_PD_HOST_EVENT_ON_POWER_CHANGE + /* notify host of power info change */ + pd_send_host_event(PD_EVENT_POWER_CHANGE); +#endif case CHG_RAMP_OVERCURRENT_DETECT: /* Check if we should ramp or go straight to stable */ task_wait_time = SECOND; @@ -193,6 +220,15 @@ void chg_ramp_task(void) } /* + * If we are not drawing full charge, then don't ramp, + * just wait in this state, until we are. + */ + if (!board_is_consuming_full_charge()) { + task_wait_time = CURRENT_DRAW_DELAY; + break; + } + + /* * Compare recent OCP events, if all info matches, * then we don't need to ramp anymore. */ @@ -259,15 +295,20 @@ void chg_ramp_task(void) ramp_st_new = active_port == CHARGE_PORT_NONE ? CHG_RAMP_DISCONNECTED : - CHG_RAMP_CHARGE_DETECT; + CHG_RAMP_CHARGE_DETECT_DELAY; break; case CHG_RAMP_STABLE: /* Maintain input current limit */ /* On entry log charging stats */ + if (ramp_st_prev != ramp_st) { #ifdef CONFIG_USB_PD_LOGGING - if (ramp_st_prev != ramp_st) charge_manager_save_log(active_port); #endif +#ifdef CONFIG_USB_PD_HOST_EVENT_ON_POWER_CHANGE + /* notify host of power info change */ + pd_send_host_event(PD_EVENT_POWER_CHANGE); +#endif + } /* Keep an eye on VBUS and restart ramping if it dips */ if (board_is_ramp_allowed(active_sup) && diff --git a/include/charge_ramp.h b/include/charge_ramp.h index c6e0531496..5779200026 100644 --- a/include/charge_ramp.h +++ b/include/charge_ramp.h @@ -58,6 +58,20 @@ int board_is_vbus_too_low(enum chg_ramp_vbus_state ramp_state); */ int chg_ramp_get_current_limit(void); +/** + * Return if charge ramping has reached stable state + * + * @return 1 if stable, 0 otherwise + */ +int chg_ramp_is_stable(void); + +/** + * Return if charge ramping has reached detected state + * + * @return 1 if detected, 0 otherwise + */ +int chg_ramp_is_detected(void); + #ifdef HAS_TASK_CHG_RAMP /** * Notify charge ramp module of supplier type change on a port. If port diff --git a/include/config.h b/include/config.h index 88337a2b29..6e63cec8cd 100644 --- a/include/config.h +++ b/include/config.h @@ -1279,6 +1279,9 @@ /* Check whether PD is the sole power source before flash erase operation */ #undef CONFIG_USB_PD_FLASH_ERASE_CHECK +/* Send host event when power changes */ +#undef CONFIG_USB_PD_HOST_EVENT_ON_POWER_CHANGE + /* HW & SW version for alternate mode discover identity response (4bits each) */ #undef CONFIG_USB_PD_IDENTITY_HW_ID #undef CONFIG_USB_PD_IDENTITY_SW_ID diff --git a/util/ectool.c b/util/ectool.c index 92b663e534..c809464d92 100644 --- a/util/ectool.c +++ b/util/ectool.c @@ -3771,9 +3771,13 @@ static void print_pd_power_info(struct ec_response_usb_pd_power_info *r) case USB_CHG_TYPE_VBUS: printf(" VBUS"); break; + case USB_CHG_TYPE_UNKNOWN: + printf(" Unknown"); + break; } - printf(" %dmV max %dmV / %dmA", - r->meas.voltage_now, r->meas.voltage_max, r->meas.current_max); + printf(" %dmV / %dmA, max %dmV / %dmA", + r->meas.voltage_now, r->meas.current_lim, r->meas.voltage_max, + r->meas.current_max); if (r->max_power) printf(" / %dmW", r->max_power / 1000); printf("\n"); |