summaryrefslogtreecommitdiff
path: root/common
diff options
context:
space:
mode:
authorAlec Berg <alecaberg@chromium.org>2014-08-04 17:52:53 -0700
committerchrome-internal-fetch <chrome-internal-fetch@google.com>2014-08-09 00:20:06 +0000
commit0815df9cbf1104a2c7fabdd4197358d54cdc8922 (patch)
treec0f1d79fd3e24eb6b4d10741e34565879baff3f1 /common
parent566de98ca6b0d6a579a2dae84ecaac40c703abf7 (diff)
downloadchrome-ec-0815df9cbf1104a2c7fabdd4197358d54cdc8922.tar.gz
samus: ryu: set input current limit based on PD negotiation
Set input current limit based on the max current from the PD negotiation. For samus, this information is passed to the EC as a host command. For ryu, the max current is set directly following a negotiation. CONFIG_CHARGER_INPUT_CURRENT is now just the default limit, but after a successful PD negotiation, the limit can be raised. Note, for now the input current limit for samus is set to 2/3 of the value negotiated for. This is due to hardware problems measuring input current on p2b boards. BUG=chrome-os-partner:28532, chrome-os-partner:24461 BRANCH=none TEST=tested on a samus. Verified input current limit using "charger" console command from EC. Input current limit after a reboot is 512. When zinger is plugged in, it jumps to the appropriate value (currently 1280mA), and when the negotiation is changed using the "pd 0 dev 5" command on the PD console, the input current limit is adjusted to match (2000mA). Change-Id: Iab9186a0f9814655e3240217a9baf4a38f15f84d Signed-off-by: Alec Berg <alecaberg@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/211023 Reviewed-by: Vincent Palatin <vpalatin@chromium.org>
Diffstat (limited to 'common')
-rw-r--r--common/host_command_pd.c17
-rw-r--r--common/usb_pd_protocol.c17
2 files changed, 31 insertions, 3 deletions
diff --git a/common/host_command_pd.c b/common/host_command_pd.c
index 2f27e00d3d..1216d28ae3 100644
--- a/common/host_command_pd.c
+++ b/common/host_command_pd.c
@@ -44,8 +44,23 @@ static void pd_exchange_status(void)
task_wait_event(500*MSEC);
}
- if (rv < 0)
+ if (rv < 0) {
CPRINTS("Host command to PD MCU failed");
+ return;
+ }
+
+ /* Set input current limit */
+#ifdef BOARD_SAMUS
+ /*
+ * TODO(crosbug.com/p/28532): Remove this workaround for Samus p2b
+ * boards which cannot correctly limit input current.
+ */
+ pd_status.curr_lim_ma = pd_status.curr_lim_ma * 2 / 3;
+#endif
+ rv = charger_set_input_current(MAX(pd_status.curr_lim_ma,
+ CONFIG_CHARGER_INPUT_CURRENT));
+ if (rv < 0)
+ CPRINTS("Failed to set input current limit from PD MCU");
}
void pd_command_task(void)
diff --git a/common/usb_pd_protocol.c b/common/usb_pd_protocol.c
index 202fd490ff..a591a50f94 100644
--- a/common/usb_pd_protocol.c
+++ b/common/usb_pd_protocol.c
@@ -243,6 +243,11 @@ static struct pd_protocol {
enum pd_states timeout_state;
/* Timeout for the current state. Set to 0 for no timeout. */
uint64_t timeout;
+
+#ifdef CONFIG_USB_PD_DUAL_ROLE
+ /* Current limit based on the last request message */
+ uint32_t curr_limit;
+#endif
} pd[PD_PORT_COUNT];
/*
@@ -606,6 +611,7 @@ static void pd_send_request_msg(int port)
/* we were waiting for them, let's process them */
res = pd_choose_voltage(pd_src_cap_cnt[port], pd_src_caps[port], &rdo);
if (res >= 0) {
+ pd[port].curr_limit = res;
res = send_request(port, rdo);
if (res >= 0)
set_state(port, PD_STATE_SNK_REQUESTED);
@@ -694,11 +700,13 @@ static void handle_ctrl_request(int port, uint16_t head,
case PD_CTRL_GOTO_MIN:
break;
case PD_CTRL_PS_RDY:
- if (pd[port].task_state == PD_STATE_SNK_DISCOVERY)
+ if (pd[port].task_state == PD_STATE_SNK_DISCOVERY) {
/* Don't know what power source is ready. Reset. */
set_state(port, PD_STATE_HARD_RESET);
- else if (pd[port].role == PD_ROLE_SINK)
+ } else if (pd[port].role == PD_ROLE_SINK) {
set_state(port, PD_STATE_SNK_READY);
+ pd_set_input_current_limit(pd[port].curr_limit);
+ }
break;
case PD_CTRL_REJECT:
set_state(port, PD_STATE_SNK_DISCOVERY);
@@ -915,6 +923,9 @@ static void execute_hard_reset(int port)
if (pd[port].task_state != PD_STATE_VDM_COMM)
set_state(port, pd[port].role == PD_ROLE_SINK ?
PD_STATE_SNK_DISCONNECTED : PD_STATE_SRC_DISCONNECTED);
+
+ /* Clear the input current limit */
+ pd_set_input_current_limit(0);
#else
set_state(port, PD_STATE_SRC_DISCONNECTED);
#endif
@@ -1253,6 +1264,8 @@ void pd_task(void)
if (pd[port].task_state != PD_STATE_VDM_COMM) {
/* Sink: detect disconnect by monitoring VBUS */
set_state(port, PD_STATE_SNK_DISCONNECTED);
+ /* Clear the input current limit */
+ pd_set_input_current_limit(0);
/* set timeout small to reconnect fast */
timeout = 5*MSEC;
}