summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--board/samus_pd/board.h1
-rw-r--r--common/charge_manager.c33
-rw-r--r--common/charge_ramp.c73
-rw-r--r--include/charge_ramp.h14
-rw-r--r--include/config.h3
-rw-r--r--util/ectool.c8
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");