summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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.