diff options
-rw-r--r-- | board/samus/board.c | 2 | ||||
-rw-r--r-- | board/samus/extpower.c | 204 | ||||
-rw-r--r-- | board/samus_pd/board.c | 167 | ||||
-rw-r--r-- | board/samus_pd/board.h | 1 | ||||
-rw-r--r-- | common/charge_state_v2.c | 3 | ||||
-rw-r--r-- | common/host_command_pd.c | 20 | ||||
-rw-r--r-- | common/usb_pd_protocol.c | 15 | ||||
-rw-r--r-- | driver/charger/bq24773.c | 13 | ||||
-rw-r--r-- | include/config.h | 15 | ||||
-rw-r--r-- | include/ec_commands.h | 10 | ||||
-rw-r--r-- | include/host_command.h | 4 | ||||
-rw-r--r-- | include/usb_pd.h | 8 |
12 files changed, 332 insertions, 130 deletions
diff --git a/board/samus/board.c b/board/samus/board.c index 7199d60c6b..7f606516b0 100644 --- a/board/samus/board.c +++ b/board/samus/board.c @@ -47,7 +47,7 @@ static void pd_mcu_interrupt(enum gpio_signal signal) { /* Exchange status with PD MCU. */ - host_command_pd_send_status(); + host_command_pd_send_status(PD_CHARGE_NO_CHANGE); } #include "gpio_list.h" diff --git a/board/samus/extpower.c b/board/samus/extpower.c index 8eb2494795..51cf5454e8 100644 --- a/board/samus/extpower.c +++ b/board/samus/extpower.c @@ -8,6 +8,8 @@ * Drive high in S5-S0 when AC_PRESENT is high, otherwise drive low. */ +#include "bq24773.h" +#include "charge_state.h" #include "charger.h" #include "chipset.h" #include "common.h" @@ -16,13 +18,32 @@ #include "gpio.h" #include "hooks.h" #include "host_command.h" +#include "i2c.h" #include "system.h" #include "task.h" #include "util.h" +/* Console output macros */ +#define CPRINTS(format, args...) cprints(CC_USBCHARGE, format, ## args) + +/* Max number of attempts to enable/disable NVDC charger */ +#define CHARGER_MODE_ATTEMPTS 3 + /* Backboost has been detected */ static int bkboost_detected; +/* Charging is disabled */ +static int charge_is_disabled; + +/* + * Charge circuit occasionally gets wedged and doesn't charge. + * This variable keeps track of the state of the circuit. + */ +static enum { + CHARGE_CIRCUIT_OK, + CHARGE_CIRCUIT_WEDGED, +} charge_circuit_state = CHARGE_CIRCUIT_OK; + int extpower_is_present(void) { return gpio_get_level(GPIO_AC_PRESENT); @@ -64,71 +85,188 @@ static void extpower_init(void) } DECLARE_HOOK(HOOK_INIT, extpower_init, HOOK_PRIO_DEFAULT); -static void extpower_board_hacks(int extpower) +/* + * Save power in S3/S5/G3 by disabling charging when the battery is + * full. Restore charging when battery is not full anymore. This saves + * power because our input AC path is inefficient. + */ + +static void check_charging_cutoff(void) { - static int extpower_prev; + /* If battery is full disable charging */ + if (charge_get_percent() == 100) { + charge_is_disabled = 1; + host_command_pd_send_status(PD_CHARGE_NONE); + } +} +DECLARE_HOOK(HOOK_CHIPSET_SUSPEND, check_charging_cutoff, HOOK_PRIO_DEFAULT); - /* - * Use discharge_on_ac() to workaround hardware backboosting - * charge circuit problems. - */ - int use_bkboost_workaround = (system_get_board_version() < 1); +static void cancel_charging_cutoff(void) +{ + /* If charging is disabled, enable it */ + if (charge_is_disabled) { + charge_is_disabled = 0; + host_command_pd_send_status(PD_CHARGE_5V); + } +} +DECLARE_HOOK(HOOK_CHIPSET_RESUME, cancel_charging_cutoff, HOOK_PRIO_DEFAULT); + +static void batt_soc_change(void) +{ + /* If in S0, leave charging alone */ + if (chipset_in_state(CHIPSET_STATE_ON)) + return; + + /* Check to disable or enable charging based on batt state of charge */ + if (!charge_is_disabled && charge_get_percent() == 100) { + host_command_pd_send_status(PD_CHARGE_NONE); + charge_is_disabled = 1; + } else if (charge_is_disabled && charge_get_percent() < 100) { + charge_is_disabled = 0; + host_command_pd_send_status(PD_CHARGE_5V); + } +} +DECLARE_HOOK(HOOK_BATTERY_SOC_CHANGE, batt_soc_change, HOOK_PRIO_DEFAULT); + +/** + * Enable/disable NVDC charger to control AC to system and battery. + */ +static void charger_disable(int disable) +{ + int i, rv; + + for (i = 0; i < CHARGER_MODE_ATTEMPTS; i++) { + rv = charger_discharge_on_ac(disable); + if (rv == EC_SUCCESS) + return; + } + + CPRINTS("Setting learn mode %d failed!", disable); +} + +static void allow_max_request(void) +{ + int prochot_status; + if (charge_circuit_state == CHARGE_CIRCUIT_WEDGED) { + /* Read PROCHOT status register to clear it */ + i2c_read8(I2C_PORT_CHARGER, BQ24773_ADDR, + BQ24773_PROCHOT_STATUS, &prochot_status); + charge_circuit_state = CHARGE_CIRCUIT_OK; + } + host_command_pd_send_status(PD_CHARGE_MAX); +} +DECLARE_DEFERRED(allow_max_request); + +static void extpower_board_hacks(int extpower, int extpower_prev) +{ + /* Cancel deferred attempt to enable max charge request */ + hook_call_deferred(allow_max_request, -1); /* + * When AC is detected, delay briefly before allowing PD + * to negotiate up to the max voltage to give charge circuit + * time to settle down. When AC goes away, set PD to only allow + * 5V charging for the next time AC is connected. + * + * Use NVDC charger learn mode (charger_disable()) when AC + * is not present to avoid backboosting when AC is plugged in. + * * When in G3, PP5000 needs to be enabled to accurately sense * CC voltage when AC is attached. When AC is disconnceted * it needs to be off to save power. */ if (extpower && !extpower_prev) { - if (use_bkboost_workaround) - charger_discharge_on_ac(0); - + /* AC connected */ + charger_disable(0); + hook_call_deferred(allow_max_request, 500*MSEC); set_pp5000_in_g3(PP5000_IN_G3_AC, 1); } else if (extpower && extpower_prev) { - if (use_bkboost_workaround) { - /* - * Glitch on AC_PRESENT, attempt to recover from - * backboost - */ - charger_discharge_on_ac(1); - charger_discharge_on_ac(0); - } + /* + * Glitch on AC_PRESENT, attempt to recover from + * backboost + */ + host_command_pd_send_status(PD_CHARGE_NONE); } else { - if (use_bkboost_workaround) - charger_discharge_on_ac(1); + /* AC disconnected */ + if (!charge_is_disabled && + charge_circuit_state == CHARGE_CIRCUIT_OK) + host_command_pd_send_status(PD_CHARGE_NONE); + + charger_disable(1); + + if (!charge_is_disabled && + charge_circuit_state == CHARGE_CIRCUIT_OK) + host_command_pd_send_status(PD_CHARGE_5V); set_pp5000_in_g3(PP5000_IN_G3_AC, 0); } extpower_prev = extpower; } +static void check_charge_wedged(void) +{ + int rv, prochot_status; + + if (charge_circuit_state == CHARGE_CIRCUIT_OK) { + /* Check PROCHOT warning */ + rv = i2c_read8(I2C_PORT_CHARGER, BQ24773_ADDR, + BQ24773_PROCHOT_STATUS, &prochot_status); + if (rv) + return; + + /* + * If PROCHOT is asserted, then charge circuit is wedged, turn + * on learn mode and notify PD to disable charging on all ports. + * Note: learn mode is critical here because when in this state + * backboosting causes >20V on boostin even after PD disables + * CHARGE_EN lines. + */ + if (prochot_status) { + host_command_pd_send_status(PD_CHARGE_NONE); + charge_circuit_state = CHARGE_CIRCUIT_WEDGED; + CPRINTS("Charge circuit wedged!"); + } + } else { + /* + * Charge circuit is wedged and we already disabled charging, + * Now start to recover from wedged state by allowing 5V. + */ + host_command_pd_send_status(PD_CHARGE_5V); + } +} + /** * Task to handle external power change */ void extpower_task(void) { int extpower = extpower_is_present(); - extpower_board_hacks(extpower); + int extpower_prev = 0; + + extpower_board_hacks(extpower, extpower_prev); /* Enable backboost detection interrupt */ gpio_enable_interrupt(GPIO_BKBOOST_DET); while (1) { - /* Wait until next extpower interrupt */ - task_wait_event(-1); - - extpower = extpower_is_present(); + if (task_wait_event(2*SECOND) == TASK_EVENT_TIMER) { + /* Periodically check if charge circuit is wedged */ + check_charge_wedged(); + } else { + /* Must have received power change interrupt */ + extpower = extpower_is_present(); - /* Various board hacks to run on extpower change */ - extpower_board_hacks(extpower); + /* Various board hacks to run on extpower change */ + extpower_board_hacks(extpower, extpower_prev); + extpower_prev = extpower; - hook_notify(HOOK_AC_CHANGE); + hook_notify(HOOK_AC_CHANGE); - /* Forward notification to host */ - if (extpower) - host_set_single_event(EC_HOST_EVENT_AC_CONNECTED); - else - host_set_single_event(EC_HOST_EVENT_AC_DISCONNECTED); + /* Forward notification to host */ + host_set_single_event(extpower ? + EC_HOST_EVENT_AC_CONNECTED : + EC_HOST_EVENT_AC_DISCONNECTED); + } } } diff --git a/board/samus_pd/board.c b/board/samus_pd/board.c index d89527dfc2..3fd3f0e219 100644 --- a/board/samus_pd/board.c +++ b/board/samus_pd/board.c @@ -37,11 +37,9 @@ static enum power_state ps; /* Battery state of charge */ static int batt_soc; -static int fake_state_of_charge = -1; /* use real soc by default */ -/* Last charge port override when charging turned off due to full battery */ -static int chg_override_port = OVERRIDE_OFF; -static int chg_is_cutoff; +/* Default to 5V charging allowed for dead battery case */ +enum pd_charge_state charge_state = PD_CHARGE_5V; /* PD MCU status and host event status for host command */ static struct ec_response_pd_status pd_status; @@ -266,31 +264,6 @@ void usb1_evt(enum gpio_signal signal) wake_usb_charger_task(1); } -/* When battery is full, cutoff charging by disabling AC input current */ -static void check_charging_cutoff(void) -{ - int port; - - /* Only check if charging needs to be turned off when not in S0 */ - if (ps == POWER_S0) - return; - - port = charge_manager_get_active_charge_port(); - - /* - * If battery is full disable charging, if battery is not full, restore - * charge port. - */ - if (!chg_is_cutoff && port != CHARGE_PORT_NONE && batt_soc == 100) { - charge_manager_set_override(OVERRIDE_DONT_CHARGE); - chg_is_cutoff = 1; - } else if (chg_is_cutoff && batt_soc < 100) { - charge_manager_set_override(chg_override_port); - chg_is_cutoff = 0; - } -} -DECLARE_HOOK(HOOK_CHIPSET_SUSPEND, check_charging_cutoff, HOOK_PRIO_DEFAULT); - static void chipset_s5_to_s3(void) { ps = POWER_S3; @@ -301,9 +274,6 @@ static void chipset_s3_to_s0(void) { /* Disable deep sleep and restore charge override port */ disable_sleep(SLEEP_MASK_AP_RUN); - charge_manager_set_override(chg_override_port); - chg_is_cutoff = 0; - ps = POWER_S0; hook_notify(HOOK_CHIPSET_RESUME); } @@ -318,8 +288,6 @@ static void chipset_s0_to_s3(void) { /* Enable deep sleep and store charge override port */ enable_sleep(SLEEP_MASK_AP_RUN); - chg_override_port = charge_manager_get_override(); - ps = POWER_S3; hook_notify(HOOK_CHIPSET_SUSPEND); } @@ -438,6 +406,9 @@ static void board_init(void) gpio_enable_interrupt(GPIO_PCH_SLP_S3_L); gpio_enable_interrupt(GPIO_PCH_SLP_S5_L); + /* Initialize active charge port to none */ + pd_status.active_charge_port = CHARGE_PORT_NONE; + /* * Do not enable PD communication in RO as a security measure. * We don't want to allow communication to outside world until @@ -596,7 +567,6 @@ void board_flip_usb_mux(int port) void board_update_battery_soc(int soc) { batt_soc = soc; - check_charging_cutoff(); } int board_get_battery_soc(void) @@ -643,26 +613,42 @@ int board_set_active_charge_port(int charge_port) return EC_ERROR_INVAL; } - pd_status.active_charge_port = charge_port; - gpio_set_level(GPIO_USB_C0_CHARGE_EN_L, !(charge_port == 0)); - gpio_set_level(GPIO_USB_C1_CHARGE_EN_L, !(charge_port == 1)); + CPRINTS("New chg p%d", charge_port); /* - * If new charge port when charge is cutoff, then user must have - * plugged in a new dedicated charger. This resets the charge - * override port and clears the charge cutoff flag. + * If charging and the active charge port is changed, then disable + * charging to guarantee charge circuit starts up cleanly. */ - if (chg_is_cutoff && is_real_port) { - chg_override_port = OVERRIDE_OFF; - chg_is_cutoff = 0; + if (pd_status.active_charge_port != CHARGE_PORT_NONE && + (charge_port == CHARGE_PORT_NONE || + charge_port != pd_status.active_charge_port)) { + gpio_set_level(GPIO_USB_C0_CHARGE_EN_L, 1); + gpio_set_level(GPIO_USB_C1_CHARGE_EN_L, 1); + charge_state = PD_CHARGE_NONE; + pd_status.active_charge_port = charge_port; + CPRINTS("Chg: None\n"); + return EC_SUCCESS; + } + + /* Save active charge port and enable charging if allowed */ + pd_status.active_charge_port = charge_port; + if (charge_state != PD_CHARGE_NONE) { + gpio_set_level(GPIO_USB_C0_CHARGE_EN_L, !(charge_port == 0)); + gpio_set_level(GPIO_USB_C1_CHARGE_EN_L, !(charge_port == 1)); } - check_charging_cutoff(); - CPRINTS("New chg p%d", charge_port); return EC_SUCCESS; } /** + * Return if max voltage charging is allowed. + */ +int pd_is_max_request_allowed(void) +{ + return charge_state == PD_CHARGE_MAX; +} + +/** * Set the charge limit based upon desired maximum. * * @param charge_ma Desired charge limit (mA). @@ -732,36 +718,6 @@ DECLARE_CONSOLE_COMMAND(pdevent, command_pd_host_event, "Send PD host event", NULL); -static int command_battfake(int argc, char **argv) -{ - char *e; - int v; - - if (argc == 2) { - v = strtoi(argv[1], &e, 0); - if (*e || v < -1 || v > 100) - return EC_ERROR_PARAM1; - - fake_state_of_charge = v; - } - - if (fake_state_of_charge < 0) { - ccprintf("Using real batt level\n"); - } else { - ccprintf("Using fake batt level %d%%\n", - fake_state_of_charge); - } - - /* Send EC int to get batt info from EC */ - pd_send_ec_int(); - - return EC_SUCCESS; -} -DECLARE_CONSOLE_COMMAND(battfake, command_battfake, - "percent (-1 = use real level)", - "Set fake battery level", - NULL); - /****************************************************************************/ /* Host commands */ static int ec_status_host_cmd(struct host_cmd_handler_args *args) @@ -769,9 +725,60 @@ static int ec_status_host_cmd(struct host_cmd_handler_args *args) const struct ec_params_pd_status *p = args->params; struct ec_response_pd_status *r = args->response; - /* if not using fake soc, then update battery soc */ - board_update_battery_soc(fake_state_of_charge < 0 ? - p->batt_soc : fake_state_of_charge); + /* update battery soc */ + board_update_battery_soc(p->batt_soc); + + if (args->version == 1) { + if (p->charge_state != charge_state) { + switch (p->charge_state) { + case PD_CHARGE_NONE: + /* + * No current allowed in, set new power request + * so that PD negotiates down to vSafe5V. + */ + charge_state = p->charge_state; + gpio_set_level(GPIO_USB_C0_CHARGE_EN_L, 1); + gpio_set_level(GPIO_USB_C1_CHARGE_EN_L, 1); + pd_set_new_power_request( + pd_status.active_charge_port); + CPRINTS("Chg: None"); + break; + case PD_CHARGE_5V: + /* Allow current on the active charge port */ + charge_state = p->charge_state; + gpio_set_level(GPIO_USB_C0_CHARGE_EN_L, + !(pd_status.active_charge_port == 0)); + gpio_set_level(GPIO_USB_C1_CHARGE_EN_L, + !(pd_status.active_charge_port == 1)); + CPRINTS("Chg: 5V"); + break; + case PD_CHARGE_MAX: + /* + * Allow negotiation above vSafe5V. Should only + * ever get this command when 5V charging is + * already allowed. + */ + if (charge_state == PD_CHARGE_5V) { + charge_state = p->charge_state; + pd_set_new_power_request( + pd_status.active_charge_port); + CPRINTS("Chg: Max"); + } + break; + default: + break; + } + } + } else { + /* + * If the EC is using this command version, then it won't ever + * set charging allowed, so we should just assume charging at + * the max is allowed. + */ + charge_state = PD_CHARGE_MAX; + pd_set_new_power_request(pd_status.active_charge_port); + CPRINTS("Chg: Max"); + } *r = pd_status; @@ -783,7 +790,7 @@ static int ec_status_host_cmd(struct host_cmd_handler_args *args) return EC_RES_SUCCESS; } DECLARE_HOST_COMMAND(EC_CMD_PD_EXCHANGE_STATUS, ec_status_host_cmd, - EC_VER_MASK(0)); + EC_VER_MASK(0) | EC_VER_MASK(1)); static int host_event_status_host_cmd(struct host_cmd_handler_args *args) { diff --git a/board/samus_pd/board.h b/board/samus_pd/board.h index 702dfcc9f5..641f78ece1 100644 --- a/board/samus_pd/board.h +++ b/board/samus_pd/board.h @@ -40,6 +40,7 @@ #define CONFIG_USB_POWER_DELIVERY #define CONFIG_USB_PD_ALT_MODE #define CONFIG_USB_PD_ALT_MODE_DFP +#define CONFIG_USB_PD_CHECK_MAX_REQUEST_ALLOWED #undef CONFIG_USB_PD_COMM_ENABLED #define CONFIG_USB_PD_COMM_ENABLED 0 #define CONFIG_USB_PD_CUSTOM_VDM diff --git a/common/charge_state_v2.c b/common/charge_state_v2.c index 2487f05fe5..445819fc4e 100644 --- a/common/charge_state_v2.c +++ b/common/charge_state_v2.c @@ -774,9 +774,6 @@ wait_for_it: show_charging_progress(); prev_charge = curr.batt.state_of_charge; hook_notify(HOOK_BATTERY_SOC_CHANGE); -#ifdef HAS_TASK_PDCMD - host_command_pd_send_status(); -#endif } prev_full = is_full; diff --git a/common/host_command_pd.c b/common/host_command_pd.c index 5e3494c46e..e9282abee4 100644 --- a/common/host_command_pd.c +++ b/common/host_command_pd.c @@ -17,8 +17,15 @@ #define TASK_EVENT_EXCHANGE_PD_STATUS TASK_EVENT_CUSTOM(1) -void host_command_pd_send_status(void) +/* By default allow 5V charging only for the dead battery case */ +static enum pd_charge_state charge_state = PD_CHARGE_5V; + +void host_command_pd_send_status(enum pd_charge_state new_chg_state) { + /* Update PD MCU charge state if necessary */ + if (new_chg_state != PD_CHARGE_NO_CHANGE) + charge_state = new_chg_state; + /* Wake PD HC task to send status */ task_set_event(TASK_ID_PDCMD, TASK_EVENT_EXCHANGE_PD_STATUS, 0); } @@ -31,13 +38,20 @@ void pd_exchange_status(int *charge_port) }; int rv = 0; - /* Send battery state of charge */ + /* Send PD charge state and battery state of charge */ + ec_status.charge_state = charge_state; if (charge_get_flags() & CHARGE_FLAG_BATT_RESPONSIVE) ec_status.batt_soc = charge_get_percent(); else ec_status.batt_soc = -1; - rv = pd_host_command(EC_CMD_PD_EXCHANGE_STATUS, 0, &ec_status, + rv = pd_host_command(EC_CMD_PD_EXCHANGE_STATUS, 1, &ec_status, + sizeof(struct ec_params_pd_status), &pd_status, + sizeof(struct ec_response_pd_status)); + + /* If PD doesn't support new command version, try old version */ + if (rv == -EC_RES_INVALID_VERSION) + rv = pd_host_command(EC_CMD_PD_EXCHANGE_STATUS, 0, &ec_status, sizeof(struct ec_params_pd_status), &pd_status, sizeof(struct ec_response_pd_status)); diff --git a/common/usb_pd_protocol.c b/common/usb_pd_protocol.c index 0bad095dd5..8d168e1f1c 100644 --- a/common/usb_pd_protocol.c +++ b/common/usb_pd_protocol.c @@ -917,14 +917,25 @@ static void pd_send_request_msg(int port, int always_send_request) #else const int charging = 1; #endif + +#ifdef CONFIG_USB_PD_CHECK_MAX_REQUEST_ALLOWED + int max_request_allowed = pd_is_max_request_allowed(); +#else + const int max_request_allowed = 1; +#endif + /* Clear new power request */ pd[port].new_power_request = 0; /* Build and send request RDO */ - /* If this port is not actively charging, select vSafe5V */ + /* + * If this port is not actively charging or we are not allowed to + * request the max voltage, then select vSafe5V + */ res = pd_build_request(pd_src_cap_cnt[port], pd_src_caps[port], &rdo, &curr_limit, &supply_voltage, - charging ? PD_REQUEST_MAX : PD_REQUEST_VSAFE5V); + charging && max_request_allowed ? + PD_REQUEST_MAX : PD_REQUEST_VSAFE5V); if (res != EC_SUCCESS) /* diff --git a/driver/charger/bq24773.c b/driver/charger/bq24773.c index fc5e7c688c..becef6d378 100644 --- a/driver/charger/bq24773.c +++ b/driver/charger/bq24773.c @@ -184,9 +184,22 @@ int charger_post_init(void) if (rv) return rv; +#ifndef BOARD_SAMUS /* Turn off PROCHOT warning */ rv = i2c_write8(I2C_PORT_CHARGER, BQ24773_ADDR, BQ24773_PROCHOT_OPTION1, 0); +#else + /* On Samus, use PROCHOT warning to detect charging problems */ + /* Turn on PROCHOT warning */ + rv = i2c_write16(I2C_PORT_CHARGER, BQ24773_ADDR, + BQ24773_PROCHOT_OPTION1, 0x8120); + /* Set PROCHOT ICRIT warning when IADP is >120% of IDPM */ + rv |= i2c_write16(I2C_PORT_CHARGER, BQ24773_ADDR, + BQ24773_PROCHOT_OPTION0, 0x1b54); +#endif + + if (rv) + return rv; #ifdef CONFIG_CHARGER_ILIM_PIN_DISABLED /* Read the external ILIM pin enabled flag. */ diff --git a/include/config.h b/include/config.h index 435a8889d0..e3983eb064 100644 --- a/include/config.h +++ b/include/config.h @@ -1157,18 +1157,18 @@ /* Include all USB Power Delivery modules */ #undef CONFIG_USB_POWER_DELIVERY -/* Alternative configuration keeping only the TX part of PHY */ -#undef CONFIG_USB_PD_TX_PHY_ONLY - -/* Default state of PD communication enabled flag */ -#define CONFIG_USB_PD_COMM_ENABLED 1 - /* Support for USB PD alternate mode */ #undef CONFIG_USB_PD_ALT_MODE /* Support for USB PD alternate mode of Downward Facing Port */ #undef CONFIG_USB_PD_ALT_MODE_DFP +/* Check if max voltage request is allowed before each request */ +#undef CONIFG_USB_PD_CHECK_MAX_REQUEST_ALLOWED + +/* Default state of PD communication enabled flag */ +#define CONFIG_USB_PD_COMM_ENABLED 1 + /* Respond to custom vendor-defined messages over PD */ #undef CONFIG_USB_PD_CUSTOM_VDM @@ -1206,6 +1206,9 @@ /* Use comparator module for PD RX interrupt */ #define CONFIG_USB_PD_RX_COMP_IRQ +/* Alternative configuration keeping only the TX part of PHY */ +#undef CONFIG_USB_PD_TX_PHY_ONLY + /* Support for USB type-c superspeed mux */ #undef CONFIG_USBC_SS_MUX diff --git a/include/ec_commands.h b/include/ec_commands.h index f42e525c4a..304cb9acda 100644 --- a/include/ec_commands.h +++ b/include/ec_commands.h @@ -2680,9 +2680,17 @@ struct ec_params_reboot_ec { /* EC to PD MCU exchange status command */ #define EC_CMD_PD_EXCHANGE_STATUS 0x100 +enum pd_charge_state { + PD_CHARGE_NO_CHANGE = 0, /* Don't change charge state */ + PD_CHARGE_NONE, /* No charging allowed */ + PD_CHARGE_5V, /* 5V charging only */ + PD_CHARGE_MAX /* Charge at max voltage */ +}; + /* Status of EC being sent to PD */ struct ec_params_pd_status { - int8_t batt_soc; /* battery state of charge */ + int8_t batt_soc; /* battery state of charge */ + uint8_t charge_state; /* charging state (from enum pd_charge_state) */ } __packed; /* Status of PD being sent back to EC */ diff --git a/include/host_command.h b/include/host_command.h index e833b96101..4661e59dd6 100644 --- a/include/host_command.h +++ b/include/host_command.h @@ -210,8 +210,10 @@ void host_throttle_cpu(int throttle); /** * Signal host command task to send status to PD MCU. + * + * @new_chg_state PD MCU charge state */ -void host_command_pd_send_status(void); +void host_command_pd_send_status(enum pd_charge_state new_chg_state); /** * Ask the PD MCU for its status, obtaining the current charge_port as a diff --git a/include/usb_pd.h b/include/usb_pd.h index 543b939682..410251775f 100644 --- a/include/usb_pd.h +++ b/include/usb_pd.h @@ -759,6 +759,14 @@ int pd_build_request(int cnt, uint32_t *src_caps, uint32_t *rdo, uint32_t *ma, uint32_t *mv, enum pd_request_type req_type); /** + * Check if max voltage request is allowed (only used if + * CONFIG_USB_PD_CHECK_MAX_REQUEST_ALLOWED is defined). + * + * @return True if max voltage request allowed, False otherwise + */ +int pd_is_max_request_allowed(void); + +/** * Process source capabilities packet * * @param port USB-C port number |