diff options
-rw-r--r-- | board/firefly/usb_pd_policy.c | 10 | ||||
-rw-r--r-- | board/fruitpie/usb_pd_policy.c | 22 | ||||
-rw-r--r-- | board/plankton/usb_pd_policy.c | 10 | ||||
-rw-r--r-- | board/ryu/board.h | 2 | ||||
-rw-r--r-- | board/ryu/usb_pd_policy.c | 22 | ||||
-rw-r--r-- | board/samus/board.h | 8 | ||||
-rw-r--r-- | board/samus_pd/usb_pd_policy.c | 24 | ||||
-rw-r--r-- | common/host_command_pd.c | 17 | ||||
-rw-r--r-- | common/usb_pd_protocol.c | 17 | ||||
-rw-r--r-- | driver/battery/samus.c | 26 | ||||
-rw-r--r-- | include/ec_commands.h | 3 | ||||
-rw-r--r-- | include/usb_pd.h | 11 |
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. |