summaryrefslogtreecommitdiff
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
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>
-rw-r--r--board/firefly/usb_pd_policy.c10
-rw-r--r--board/fruitpie/usb_pd_policy.c22
-rw-r--r--board/plankton/usb_pd_policy.c10
-rw-r--r--board/ryu/board.h2
-rw-r--r--board/ryu/usb_pd_policy.c22
-rw-r--r--board/samus/board.h8
-rw-r--r--board/samus_pd/usb_pd_policy.c24
-rw-r--r--common/host_command_pd.c17
-rw-r--r--common/usb_pd_protocol.c17
-rw-r--r--driver/battery/samus.c26
-rw-r--r--include/ec_commands.h3
-rw-r--r--include/usb_pd.h11
12 files changed, 114 insertions, 58 deletions
diff --git a/board/firefly/usb_pd_policy.c b/board/firefly/usb_pd_policy.c
index 7ddf6f65ed..dab977fc29 100644
--- a/board/firefly/usb_pd_policy.c
+++ b/board/firefly/usb_pd_policy.c
@@ -60,8 +60,14 @@ int pd_choose_voltage(int cnt, uint32_t *src_caps, uint32_t *rdo)
/* request all the power ... */
ma = 10 * (src_caps[i] & 0x3FF);
*rdo = RDO_FIXED(i + 1, ma, ma, 0);
- ccprintf("Request [%d] %d V %d mA\n", i, set_mv/1000, ma);
- return EC_SUCCESS;
+ ccprintf("Request [%d] %dV %dmA\n", i, set_mv/1000, ma);
+ return ma;
+}
+
+void pd_set_input_current_limit(uint32_t max_ma)
+{
+ /* No battery, nothing to do */
+ return;
}
void pd_set_max_voltage(unsigned mv)
diff --git a/board/fruitpie/usb_pd_policy.c b/board/fruitpie/usb_pd_policy.c
index e8886aabe8..3292a80a77 100644
--- a/board/fruitpie/usb_pd_policy.c
+++ b/board/fruitpie/usb_pd_policy.c
@@ -3,6 +3,7 @@
* found in the LICENSE file.
*/
+#include "charger.h"
#include "common.h"
#include "console.h"
#include "gpio.h"
@@ -37,6 +38,7 @@ int pd_choose_voltage(int cnt, uint32_t *src_caps, uint32_t *rdo)
int i;
int sel_mv;
int max_uw = 0;
+ int max_ma;
int max_i = -1;
/* Get max power */
@@ -61,16 +63,26 @@ int pd_choose_voltage(int cnt, uint32_t *src_caps, uint32_t *rdo)
/* request all the power ... */
if ((src_caps[max_i] & PDO_TYPE_MASK) == PDO_TYPE_BATTERY) {
int uw = 250000 * (src_caps[max_i] & 0x3FF);
+ max_ma = uw / sel_mv;
*rdo = RDO_BATT(max_i + 1, uw/2, uw, 0);
- ccprintf("Request [%d] %dV %d/%d mW\n",
- max_i, sel_mv/1000, uw/1000, uw/1000);
+ ccprintf("Request [%d] %dV %dmW\n",
+ max_i, sel_mv/1000, uw/1000);
} else {
int ma = 10 * (src_caps[max_i] & 0x3FF);
+ max_ma = ma;
*rdo = RDO_FIXED(max_i + 1, ma / 2, ma, 0);
- ccprintf("Request [%d] %dV %d/%d mA\n",
- max_i, sel_mv/1000, max_i, ma/2, ma);
+ ccprintf("Request [%d] %dV %dmA\n",
+ max_i, sel_mv/1000, ma);
}
- return EC_SUCCESS;
+ return max_ma;
+}
+
+void pd_set_input_current_limit(uint32_t max_ma)
+{
+ int rv = charger_set_input_current(MAX(max_ma,
+ CONFIG_CHARGER_INPUT_CURRENT));
+ if (rv < 0)
+ CPRINTS("Failed to set input current limit for PD");
}
void pd_set_max_voltage(unsigned mv)
diff --git a/board/plankton/usb_pd_policy.c b/board/plankton/usb_pd_policy.c
index c0d58e236b..c2ac2fd155 100644
--- a/board/plankton/usb_pd_policy.c
+++ b/board/plankton/usb_pd_policy.c
@@ -77,8 +77,14 @@ int pd_choose_voltage(int cnt, uint32_t *src_caps, uint32_t *rdo)
/* request all the power ... */
ma = 10 * (src_caps[i] & 0x3FF);
*rdo = RDO_FIXED(i + 1, ma, ma, 0);
- ccprintf("Request [%d] %d V %d mA\n", i, set_mv/1000, ma);
- return EC_SUCCESS;
+ ccprintf("Request [%d] %dV %dmA\n", i, set_mv/1000, ma);
+ return ma;
+}
+
+void pd_set_input_current_limit(uint32_t max_ma)
+{
+ /* No battery, nothing to do */
+ return;
}
void pd_set_max_voltage(unsigned mv)
diff --git a/board/ryu/board.h b/board/ryu/board.h
index 2d837fa3f8..a59db2f93f 100644
--- a/board/ryu/board.h
+++ b/board/ryu/board.h
@@ -44,7 +44,7 @@
#define CONFIG_CHARGER_ILIM_PIN_DISABLED
#define CONFIG_CHARGER_SENSE_RESISTOR 5
#define CONFIG_CHARGER_SENSE_RESISTOR_AC 10
-#define CONFIG_CHARGER_INPUT_CURRENT 1024
+#define CONFIG_CHARGER_INPUT_CURRENT 512
#define CONFIG_CHARGER_DISCHARGE_ON_AC
#define CONFIG_CHIPSET_TEGRA
#define CONFIG_PMIC_FW_LONG_PRESS_TIMER
diff --git a/board/ryu/usb_pd_policy.c b/board/ryu/usb_pd_policy.c
index fe8247de8d..f202b31e24 100644
--- a/board/ryu/usb_pd_policy.c
+++ b/board/ryu/usb_pd_policy.c
@@ -3,6 +3,7 @@
* found in the LICENSE file.
*/
+#include "charger.h"
#include "common.h"
#include "console.h"
#include "gpio.h"
@@ -38,6 +39,7 @@ int pd_choose_voltage(int cnt, uint32_t *src_caps, uint32_t *rdo)
int i;
int sel_mv;
int max_uw = 0;
+ int max_ma;
int max_i = -1;
/* Get max power */
@@ -62,16 +64,26 @@ int pd_choose_voltage(int cnt, uint32_t *src_caps, uint32_t *rdo)
/* request all the power ... */
if ((src_caps[max_i] & PDO_TYPE_MASK) == PDO_TYPE_BATTERY) {
int uw = 250000 * (src_caps[max_i] & 0x3FF);
+ max_ma = uw / sel_mv;
*rdo = RDO_BATT(max_i + 1, uw/2, uw, 0);
- ccprintf("Request [%d] %dV %d/%d mW\n",
- max_i, sel_mv/1000, uw/1000, uw/1000);
+ ccprintf("Request [%d] %dV %dmW\n",
+ max_i, sel_mv/1000, uw/1000);
} else {
int ma = 10 * (src_caps[max_i] & 0x3FF);
+ max_ma = ma;
*rdo = RDO_FIXED(max_i + 1, ma / 2, ma, 0);
- ccprintf("Request [%d] %dV %d/%d mA\n",
- max_i, sel_mv/1000, max_i, ma/2, ma);
+ ccprintf("Request [%d] %dV %dmA\n",
+ max_i, sel_mv/1000, ma);
}
- return EC_SUCCESS;
+ return max_ma;
+}
+
+void pd_set_input_current_limit(uint32_t max_ma)
+{
+ int rv = charger_set_input_current(MAX(max_ma,
+ CONFIG_CHARGER_INPUT_CURRENT));
+ if (rv < 0)
+ CPRINTS("Failed to set input current limit for PD");
}
void pd_set_max_voltage(unsigned mv)
diff --git a/board/samus/board.h b/board/samus/board.h
index d6b41f408e..eb13854008 100644
--- a/board/samus/board.h
+++ b/board/samus/board.h
@@ -38,11 +38,9 @@
#define CONFIG_CHARGER_V2
#define CONFIG_CHARGER_BQ24773
#define CONFIG_CHARGER_ILIM_PIN_DISABLED
-/* FIXME(crosbug.com/p/28721): determine correct values for these */
-#define CONFIG_CHARGER_SENSE_RESISTOR 5
-#define CONFIG_CHARGER_SENSE_RESISTOR_AC 10
-/* FIXME(crosbug.com/p/24461): determine correct values for this */
-#define CONFIG_CHARGER_INPUT_CURRENT 2048
+#define CONFIG_CHARGER_SENSE_RESISTOR 5
+#define CONFIG_CHARGER_SENSE_RESISTOR_AC 10
+#define CONFIG_CHARGER_INPUT_CURRENT 512
#define CONFIG_CHARGER_DISCHARGE_ON_AC
#define CONFIG_FANS 2
#define CONFIG_PECI_TJMAX 100
diff --git a/board/samus_pd/usb_pd_policy.c b/board/samus_pd/usb_pd_policy.c
index 115a7812a8..4edbed4f79 100644
--- a/board/samus_pd/usb_pd_policy.c
+++ b/board/samus_pd/usb_pd_policy.c
@@ -36,11 +36,15 @@ static unsigned max_mv = -1; /* no cap */
/* Battery state of charge percentage */
static int batt_soc;
+/* PD MCU status for host response */
+static struct ec_response_pd_status pd_status;
+
int pd_choose_voltage(int cnt, uint32_t *src_caps, uint32_t *rdo)
{
int i;
int sel_mv;
int max_uw = 0;
+ int max_ma;
int max_i = -1;
/* Get max power */
@@ -65,16 +69,18 @@ int pd_choose_voltage(int cnt, uint32_t *src_caps, uint32_t *rdo)
/* request all the power ... */
if ((src_caps[max_i] & PDO_TYPE_MASK) == PDO_TYPE_BATTERY) {
int uw = 250000 * (src_caps[max_i] & 0x3FF);
+ max_ma = uw / sel_mv;
*rdo = RDO_BATT(max_i + 1, uw/2, uw, 0);
- ccprintf("Request [%d] %dV %d/%d mW\n",
- max_i, sel_mv/1000, uw/1000, uw/1000);
+ ccprintf("Request [%d] %dV %dmW\n",
+ max_i, sel_mv/1000, uw/1000);
} else {
int ma = 10 * (src_caps[max_i] & 0x3FF);
+ max_ma = ma;
*rdo = RDO_FIXED(max_i + 1, ma / 2, ma, 0);
- ccprintf("Request [%d] %dV %d/%d mA\n",
- max_i, sel_mv/1000, max_i, ma/2, ma);
+ ccprintf("Request [%d] %dV %dmA\n",
+ max_i, sel_mv/1000, ma);
}
- return EC_SUCCESS;
+ return max_ma;
}
void pd_set_max_voltage(unsigned mv)
@@ -136,6 +142,12 @@ static void pd_send_ec_int(void)
gpio_set_level(GPIO_EC_INT_L, 1);
}
+void pd_set_input_current_limit(uint32_t max_ma)
+{
+ pd_status.curr_lim_ma = max_ma;
+ pd_send_ec_int();
+}
+
int pd_board_checks(void)
{
return EC_SUCCESS;
@@ -214,7 +226,7 @@ static int ec_status_host_cmd(struct host_cmd_handler_args *args)
batt_soc = p->batt_soc;
- r->status = 0;
+ *r = pd_status;
args->response_size = sizeof(*r);
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;
}
diff --git a/driver/battery/samus.c b/driver/battery/samus.c
index 4c4f3480c4..951130867e 100644
--- a/driver/battery/samus.c
+++ b/driver/battery/samus.c
@@ -46,17 +46,6 @@ const struct battery_info *battery_get_info(void)
#ifdef CONFIG_CHARGER_PROFILE_OVERRIDE
-/*
- * For Samus, we'd like to set the CONFIG_CHARGER_INPUT_CURRENT to a higher
- * value, but the AC adapters freak out if we do. So instead we set it to a
- * low value, and it gets reset to that point every time AC is applied. Then we
- * bump it up a little bit every time through the loop until it's where we
- * wanted it in the first place.
- */
-/* FIXME(crosbug.com/p/24461): determine correct values for this */
-#define MAX_INPUT_CURRENT 2048
-#define INPUT_CURRENT_INCR 64
-
static int fast_charging_allowed;
/*
@@ -69,25 +58,10 @@ static int fast_charging_allowed;
*/
int charger_profile_override(struct charge_state_data *curr)
{
- int rv;
-
/* We only want to override how we charge, nothing else. */
if (curr->state != ST_CHARGE)
return 0;
- /* Bump the input current up a little at a time if needed. */
- if (curr->chg.input_current < MAX_INPUT_CURRENT) {
- rv = charger_set_input_current(curr->chg.input_current +
- INPUT_CURRENT_INCR);
- /*
- * If we can't set the input current, indicate the error
- * (negative, since positive changes the poll period) and
- * don't override the default behavior.
- */
- if (rv)
- return -rv;
- }
-
/* Do we want to mess with the charge profile too? */
if (!fast_charging_allowed)
return 0;
diff --git a/include/ec_commands.h b/include/ec_commands.h
index 1756a11247..d5d5590269 100644
--- a/include/ec_commands.h
+++ b/include/ec_commands.h
@@ -2497,7 +2497,8 @@ struct ec_params_pd_status {
/* Status of PD being sent back to EC */
struct ec_response_pd_status {
- int8_t status; /* currently empty */
+ int8_t status; /* PD MCU status */
+ uint32_t curr_lim_ma; /* input current limit */
} __packed;
/* Set USB type-C port role and muxes */
diff --git a/include/usb_pd.h b/include/usb_pd.h
index a20664ba8a..96bacba78e 100644
--- a/include/usb_pd.h
+++ b/include/usb_pd.h
@@ -159,7 +159,7 @@ void pd_set_dual_role(enum pd_dual_role_states state);
* @param cnt the number of Power Data Objects.
* @param src_caps Power Data Objects representing the source capabilities.
* @param rdo requested Request Data Object.
- * @return EC_SUCCESS if the RDO is filled with valid data, <0 else.
+ * @return <0 if invalid, else value is the current limit of the RDO data
*/
int pd_choose_voltage(int cnt, uint32_t *src_caps, uint32_t *rdo);
@@ -201,7 +201,14 @@ int pd_set_power_supply_ready(int port);
*/
void pd_request_source_voltage(int port, int mv);
-/*
+/**
+ * Set the input current limit.
+ *
+ * @max_ma Maximum current limit
+ */
+void pd_set_input_current_limit(uint32_t max_ma);
+
+/**
* Verify board specific health status : current, voltages...
*
* @return EC_SUCCESS if the board is good, <0 else.