diff options
-rw-r--r-- | baseboard/dedede/baseboard.h | 69 | ||||
-rw-r--r-- | board/waddledoo/battery.c | 86 | ||||
-rw-r--r-- | board/waddledoo/board.c | 236 | ||||
-rw-r--r-- | board/waddledoo/board.h | 20 | ||||
-rw-r--r-- | board/waddledoo/build.mk | 2 | ||||
-rw-r--r-- | board/waddledoo/ec.tasklist | 10 | ||||
-rw-r--r-- | board/waddledoo/gpio.inc | 5 | ||||
-rw-r--r-- | board/waddledoo/usb_pd_policy.c | 66 |
8 files changed, 490 insertions, 4 deletions
diff --git a/baseboard/dedede/baseboard.h b/baseboard/dedede/baseboard.h index a1e85abf1a..b2683c8df9 100644 --- a/baseboard/dedede/baseboard.h +++ b/baseboard/dedede/baseboard.h @@ -57,6 +57,8 @@ #define GPIO_POWER_BUTTON_L GPIO_H1_EC_PWR_BTN_ODL #define GPIO_RSMRST_L_PGOOD GPIO_RSMRST_PWRGD_L #define GPIO_SYS_RESET_L GPIO_SYS_RST_ODL +#define GPIO_USB_C0_DP_HPD GPIO_EC_AP_USB_C0_HPD +#define GPIO_USB_C1_DP_HPD GPIO_EC_AP_USB_C1_HDMI_HPD #define GPIO_VOLUME_UP_L GPIO_VOLUP_BTN_ODL #define GPIO_VOLUME_DOWN_L GPIO_VOLDN_BTN_ODL #define GPIO_WP GPIO_EC_WP_OD @@ -76,6 +78,12 @@ #define CONFIG_VSTORE #define CONFIG_VSTORE_SLOT_COUNT 1 +/* Battery */ +#define CONFIG_BATTERY_CUT_OFF +#define CONFIG_BATTERY_PRESENT_GPIO GPIO_EC_BATTERY_PRES_ODL +#define CONFIG_BATTERY_REVIVE_DISCONNECT +#define CONFIG_BATTERY_SMART + /* Buttons / Switches */ #define CONFIG_SWITCH #define CONFIG_VOLUME_BUTTONS @@ -85,6 +93,17 @@ #define CONFIG_CROS_BOARD_INFO #define CONFIG_BOARD_VERSION_CBI +/* Charger */ +#define CONFIG_CHARGE_MANAGER +#define CONFIG_CHARGER +#define CONFIG_CHARGER_INPUT_CURRENT 256 +#define CONFIG_USB_CHARGER +#define CONFIG_USB_PD_5V_EN_CUSTOM +#define CONFIG_TRICKLE_CHARGING + +/* /\* PWM *\/ */ +/* #define CONFIG_PWM */ + /* SoC */ #define CONFIG_BOARD_HAS_RTC_RESET #define CONFIG_CHIPSET_JASPERLAKE @@ -93,10 +112,60 @@ #define CONFIG_POWER_BUTTON_X86 #define CONFIG_POWER_COMMON +/* USB Type-C */ +#define CONFIG_USB_MUX_PI3USB31532 +#define CONFIG_USBC_SS_MUX +#define CONFIG_USBC_SS_MUX_DFP_ONLY +#define CONFIG_USBC_VCONN +#define CONFIG_USBC_VCONN_SWAP + +/* USB PD */ +#define CONFIG_USB_PD_ALT_MODE +#define CONFIG_USB_PD_ALT_MODE_DFP +#define CONFIG_USB_PD_DISCHARGE_TCPC +#define CONFIG_USB_PD_DP_HPD_GPIO +#define CONFIG_USB_PD_DUAL_ROLE +#define CONFIG_USB_PD_DUAL_ROLE_AUTO_TOGGLE +#define CONFIG_USB_PD_LOGGING +#define CONFIG_USB_PD_PORT_MAX_COUNT 2 +/* #define CONFIG_USB_PD_TCPC_LOW_POWER */ +#define CONFIG_USB_PD_TCPM_MUX +#define CONFIG_USB_PD_TCPM_TCPCI +#define CONFIG_USB_PD_TRY_SRC +/* + * Don't attempt Try.Src if the battery is too low. Even batteries which report + * 1% state of charge can sometimes disable their discharge FET if the load is + * too much. Therefore, set this threshold a bit higher. 5% should leave + * plenty of margin. + */ +#undef CONFIG_USB_PD_TRY_SRC_MIN_BATT_SOC +#define CONFIG_USB_PD_TRY_SRC_MIN_BATT_SOC 5 +/* #define CONFIG_USB_PD_VBUS_DETECT_CHARGER */ +#define CONFIG_USB_PD_VBUS_DETECT_TCPC +#define CONFIG_USB_PD_VBUS_MEASURE_CHARGER +#define CONFIG_USB_PD_DECODE_SOP +#define CONFIG_USB_PID 0x5042 +#define CONFIG_USB_POWER_DELIVERY +#define CONFIG_USB_SM_FRAMEWORK +#define CONFIG_USB_TYPEC_DRP_ACC_TRYSRC + +/* Define typical operating power and max power. */ +#define PD_MAX_VOLTAGE_MV 20000 +#define PD_MAX_CURRENT_MA 3000 +#define PD_MAX_POWER_MW 45000 +#define PD_OPERATING_POWER_MW 15000 + +/* TODO(b:147314141): Verify these timings */ +#define PD_POWER_SUPPLY_TURN_ON_DELAY 30000 /* us */ +#define PD_POWER_SUPPLY_TURN_OFF_DELAY 250000 /* us */ +#define PD_VCONN_SWAP_DELAY 5000 /* us */ #ifndef __ASSEMBLER__ #include "gpio_signal.h" +/* Reset all TCPCs */ +void board_reset_pd_mcu(void); + #endif /* !__ASSEMBLER__ */ #endif /* __CROS_EC_BASEBOARD_H */ diff --git a/board/waddledoo/battery.c b/board/waddledoo/battery.c new file mode 100644 index 0000000000..7f82bcb95f --- /dev/null +++ b/board/waddledoo/battery.c @@ -0,0 +1,86 @@ +/* Copyright 2020 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + * + * Battery pack information + */ + +#include "battery.h" +#include "battery_smart.h" +#include "common.h" +#include "ec_commands.h" +#include "extpower.h" + +/* Shutdown mode parameter to write to manufacturer access register */ +#define SB_SHUTDOWN_DATA 0x0010 + +/* Battery info */ +static const struct battery_info info = { + .voltage_max = 8880, + .voltage_normal = 7700, + .voltage_min = 6000, + .precharge_current = 160, + .start_charging_min_c = 0, + .start_charging_max_c = 45, + .charging_min_c = 0, + .charging_max_c = 45, + .discharging_min_c = -20, + .discharging_max_c = 60, +}; + +const struct battery_info *battery_get_info(void) +{ + return &info; +} + +int board_cut_off_battery(void) +{ + int rv; + + /* Ship mode command must be sent twice to take effect */ + rv = sb_write(SB_MANUFACTURER_ACCESS, SB_SHUTDOWN_DATA); + if (rv != EC_SUCCESS) + return EC_RES_ERROR; + + rv = sb_write(SB_MANUFACTURER_ACCESS, SB_SHUTDOWN_DATA); + return rv ? EC_RES_ERROR : EC_RES_SUCCESS; +} + +enum battery_disconnect_state battery_get_disconnect_state(void) +{ + uint8_t data[6]; + int rv; + + /* + * Take note if we find that the battery isn't in disconnect state, + * and always return NOT_DISCONNECTED without probing the battery. + * This assumes the battery will not go to disconnect state during + * runtime. + */ + static int not_disconnected; + + if (not_disconnected) + return BATTERY_NOT_DISCONNECTED; + + /* Check if battery discharge FET is disabled. */ + rv = sb_read_mfgacc(PARAM_OPERATION_STATUS, + SB_ALT_MANUFACTURER_ACCESS, data, sizeof(data)); + if (rv) + return BATTERY_DISCONNECT_ERROR; + if (~data[3] & (BATTERY_DISCHARGING_DISABLED)) { + not_disconnected = 1; + return BATTERY_NOT_DISCONNECTED; + } + + /* + * Battery discharge FET is disabled. Verify that we didn't enter this + * state due to a safety fault. + */ + rv = sb_read_mfgacc(PARAM_SAFETY_STATUS, + SB_ALT_MANUFACTURER_ACCESS, data, sizeof(data)); + if (rv || data[2] || data[3] || data[4] || data[5]) + return BATTERY_DISCONNECT_ERROR; + + /* No safety fault, battery is disconnected */ + return BATTERY_DISCONNECTED; +} diff --git a/board/waddledoo/board.c b/board/waddledoo/board.c index 8ef3330887..a9303be923 100644 --- a/board/waddledoo/board.c +++ b/board/waddledoo/board.c @@ -7,24 +7,165 @@ #include "adc_chip.h" #include "button.h" +#include "charge_manager.h" +#include "charge_state_v2.h" +#include "charger.h" #include "common.h" #include "compile_time_macros.h" #include "driver/accel_bma2x2.h" #include "driver/accelgyro_bmi160.h" +#include "driver/bc12/pi3usb9201.h" #include "driver/sync.h" +#include "driver/tcpm/raa489000.h" +#include "driver/tcpm/tcpci.h" +#include "driver/usb_mux/pi3usb3x532.h" #include "extpower.h" #include "gpio.h" +#include "hooks.h" #include "i2c.h" #include "lid_switch.h" #include "motion_sense.h" #include "power.h" #include "power_button.h" +#include "stdbool.h" #include "switch.h" #include "tablet_mode.h" #include "task.h" +#include "usb_mux.h" +#include "usb_pd.h" +#include "usb_pd_tcpm.h" + +#define CPRINTS(format, args...) cprints(CC_USBCHARGE, format, ## args) +#define CPRINTF(format, args...) cprintf(CC_USBCHARGE, format, ## args) + +static void tcpc_alert_event(enum gpio_signal s) +{ + int port = (s == GPIO_USB_C0_INT_ODL) ? 0 : 1; + + schedule_deferred_pd_interrupt(port); +} + +static void usb_c0_interrupt(enum gpio_signal s) +{ + /* + * The interrupt line is shared between the TCPC and BC 1.2 detection + * chip. Therefore we'll need to check both ICs. + */ + tcpc_alert_event(s); + task_set_event(TASK_ID_USB_CHG_P0, USB_CHG_EVENT_BC12, 0); +} + +static void sub_usb_c1_interrupt(enum gpio_signal s) +{ + /* + * The interrupt line is shared between the TCPC and BC 1.2 detection + * chip. Therefore we'll need to check both ICs. + */ + tcpc_alert_event(s); + task_set_event(TASK_ID_USB_CHG_P1, USB_CHG_EVENT_BC12, 0); +} #include "gpio_list.h" +void board_init(void) +{ + gpio_enable_interrupt(GPIO_USB_C0_INT_ODL); + gpio_enable_interrupt(GPIO_SUB_USB_C1_INT_ODL); +} +DECLARE_HOOK(HOOK_INIT, board_init, HOOK_PRIO_DEFAULT); + +void board_reset_pd_mcu(void) +{ + /* + * TODO(b:147316511): Here we could issue a digital reset to the IC, + * unsure if we actually want to do that or not yet. + */ +} + +int board_is_sourcing_vbus(int port) +{ + int regval; + + tcpc_read(port, TCPC_REG_POWER_STATUS, ®val); + return !!(regval & TCPC_REG_POWER_STATUS_SOURCING_VBUS); + +} + +int board_set_active_charge_port(int port) +{ + int is_real_port = (port >= 0 && + port < CONFIG_USB_PD_PORT_MAX_COUNT); + int i; + int old_port; + + if (!is_real_port && port != CHARGE_PORT_NONE) + return EC_ERROR_INVAL; + + old_port = charge_manager_get_active_charge_port(); + + CPRINTS("New chg p%d", port); + + /* Disable all ports. */ + if (port == CHARGE_PORT_NONE) { + for (i = 0; i < CONFIG_USB_PD_PORT_MAX_COUNT; i++) + tcpc_write(i, TCPC_REG_COMMAND, + TCPC_REG_COMMAND_SNK_CTRL_LOW); + + return EC_SUCCESS; + } + + /* Check if port is sourcing VBUS. */ + if (board_is_sourcing_vbus(port)) { + CPRINTS("Skip enable p%d", port); + return EC_ERROR_INVAL; + } + + /* + * Turn off the other ports' sink path FETs, before enabling the + * requested charge port. + */ + for (i = 0; i < CONFIG_USB_PD_PORT_MAX_COUNT; i++) { + if (i == port) + continue; + + if (tcpc_write(i, TCPC_REG_COMMAND, + TCPC_REG_COMMAND_SNK_CTRL_LOW)) + CPRINTS("p%d: sink path disable failed.", i); + } + + /* + * Stop the charger IC from switching while changing ports. Otherwise, + * we can overcurrent the adapter we're switching to. (crbug.com/926056) + */ + if (old_port != CHARGE_PORT_NONE) + charger_discharge_on_ac(1); + + /* Enable requested charge port. */ + if (tcpc_write(port, TCPC_REG_COMMAND, + TCPC_REG_COMMAND_SNK_CTRL_HIGH)) { + CPRINTS("p%d: sink path enable failed.", port); + charger_discharge_on_ac(0); + return EC_ERROR_UNKNOWN; + } + + /* Allow the charger IC to begin/continue switching. */ + charger_discharge_on_ac(0); + + return EC_SUCCESS; +} + +void board_set_charge_limit(int port, int supplier, int charge_ma, + int max_ma, int charge_mv) +{ + int icl = MAX(charge_ma, CONFIG_CHARGER_INPUT_CURRENT); + + /* + * TODO(b:147463641): Characterize the input current limit in case that + * a scaling needs to be applied here. + */ + charge_set_input_current_limit(icl, charge_mv); +} + /* Sensors */ static struct mutex g_lid_mutex; static struct mutex g_base_mutex; @@ -114,14 +255,105 @@ struct motion_sensor_t motion_sensors[] = { const unsigned int motion_sensor_count = ARRAY_SIZE(motion_sensors); - int extpower_is_present(void) { /* * TODO(b:146651593) We can likely use the charger IC to determine VBUS * presence. */ - return 1; + return pd_snk_is_vbus_provided(0) || pd_snk_is_vbus_provided(1); +} + +int pd_snk_is_vbus_provided(int port) +{ + int regval = 0; + + tcpc_read(port, TCPC_REG_POWER_STATUS, ®val); + return regval & TCPC_REG_POWER_STATUS_VBUS_PRES; +} + +const struct pi3usb9201_config_t pi3usb9201_bc12_chips[] = { + { + .i2c_port = I2C_PORT_USB_C0, + .i2c_addr_flags = PI3USB9201_I2C_ADDR_3_FLAGS, + }, + + { + .i2c_port = I2C_PORT_SUB_USB_C1, + .i2c_addr_flags = PI3USB9201_I2C_ADDR_3_FLAGS, + }, +}; + +const struct tcpc_config_t tcpc_config[CONFIG_USB_PD_PORT_MAX_COUNT] = { + { + .bus_type = EC_BUS_TYPE_I2C, + .i2c_info = { + .port = I2C_PORT_USB_C0, + .addr_flags = RAA489000_TCPC0_I2C_FLAGS, + }, + .drv = &raa489000_tcpm_drv, + }, + + { + .bus_type = EC_BUS_TYPE_I2C, + .i2c_info = { + .port = I2C_PORT_SUB_USB_C1, + .addr_flags = RAA489000_TCPC0_I2C_FLAGS, + }, + .drv = &raa489000_tcpm_drv, + }, +}; + +struct usb_mux usb_muxes[CONFIG_USB_PD_PORT_MAX_COUNT] = { + { + .port_addr = MUX_PORT_AND_ADDR(I2C_PORT_USB_C0, 0x54), + .driver = &pi3usb3x532_usb_mux_driver, + }, + { + .port_addr = MUX_PORT_AND_ADDR(I2C_PORT_SUB_USB_C1, 0x54), + .driver = &pi3usb3x532_usb_mux_driver, + } +}; + +uint16_t tcpc_get_alert_status(void) +{ + uint16_t status = 0; + int regval; + + /* + * The interrupt line is shared between the TCPC and BC1.2 detector IC. + * Therefore, go out and actually read the alert registers to report the + * alert status. + */ + if (!gpio_get_level(GPIO_USB_C0_INT_ODL)) { + /* + * TODO(b:147716486) If we decide to handle TCPCIv2.0, we cannot + * ignore bits 14:12 any longer. + */ + if (!tcpc_read16(0, TCPC_REG_ALERT, ®val)) { + /* The TCPCI v1.0 spec says to ignore bits 14:12. */ + regval &= ~((1 << 14) | (1 << 13) | (1 << 12)); + + if (regval) + status |= PD_STATUS_TCPC_ALERT_0; + } + } + + if (!gpio_get_level(GPIO_SUB_USB_C1_INT_ODL)) { + /* + * TODO(b:147716486) If we decide to handle TCPCIv2.0, we cannot + * ignore bits 14:12 any longer. + */ + if (!tcpc_read16(1, TCPC_REG_ALERT, ®val)) { + /* TCPCI spec v1.0 says to ignore bits 14:12. */ + regval &= ~((1 << 14) | (1 << 13) | (1 << 12)); + + if (regval) + status |= PD_STATUS_TCPC_ALERT_1; + } + } + + return status; } #ifndef TEST_BUILD diff --git a/board/waddledoo/board.h b/board/waddledoo/board.h index f19f92133e..582bcd1495 100644 --- a/board/waddledoo/board.h +++ b/board/waddledoo/board.h @@ -11,12 +11,30 @@ #define VARIANT_DEDEDE_EC_NPCX796FC #include "baseboard.h" +/* Charger */ +#define CONFIG_CHARGER_DISCHARGE_ON_AC +#define CONFIG_CHARGER_RAA489000 +#define CONFIG_CHARGER_SENSE_RESISTOR_AC 10 +#define CONFIG_CHARGER_SENSE_RESISTOR 10 + +/* EC console commands */ +#define CONFIG_CMD_TCPCI_DUMP + +/* USB */ +#define CONFIG_BC12_DETECT_PI3USB9201 + +/* USB PD */ +#define CONFIG_USB_PD_TCPM_RAA489000 + /* I2C configuration */ #define I2C_PORT_EEPROM NPCX_I2C_PORT7_0 #define I2C_PORT_BATTERY NPCX_I2C_PORT5_0 #define I2C_PORT_SENSOR NPCX_I2C_PORT0_0 #define I2C_PORT_USB_C0 NPCX_I2C_PORT1_0 #define I2C_PORT_SUB_USB_C1 NPCX_I2C_PORT2_0 +#define I2C_PORT_USB_MUX I2C_PORT_USB_C0 +/* TODO(b:147440290): Need to handle multiple charger ICs */ +#define I2C_PORT_CHARGER I2C_PORT_USB_C0 #define I2C_PORT_ACCEL I2C_PORT_SENSOR @@ -75,5 +93,7 @@ enum sensor_id { SENSOR_COUNT }; +int board_is_sourcing_vbus(int port); + #endif /* !__ASSEMBLER__ */ #endif /* __CROS_EC_BOARD_H */ diff --git a/board/waddledoo/build.mk b/board/waddledoo/build.mk index 620016f814..aeaa29b2a4 100644 --- a/board/waddledoo/build.mk +++ b/board/waddledoo/build.mk @@ -11,4 +11,4 @@ CHIP_FAMILY:=npcx7 CHIP_VARIANT:=npcx7m6fc BASEBOARD:=dedede -board-y=board.o +board-y=board.o battery.o usb_pd_policy.o diff --git a/board/waddledoo/ec.tasklist b/board/waddledoo/ec.tasklist index 2bc06ded0c..1b0823ccdd 100644 --- a/board/waddledoo/ec.tasklist +++ b/board/waddledoo/ec.tasklist @@ -10,8 +10,16 @@ #define CONFIG_TASK_LIST \ TASK_ALWAYS(HOOKS, hook_task, NULL, VENTI_TASK_STACK_SIZE) \ TASK_ALWAYS(MOTIONSENSE, motion_sense_task, NULL, VENTI_TASK_STACK_SIZE) \ + TASK_ALWAYS(USB_CHG_P0, usb_charger_task, 0, LARGER_TASK_STACK_SIZE) \ + TASK_ALWAYS(USB_CHG_P1, usb_charger_task, 1, LARGER_TASK_STACK_SIZE) \ + TASK_ALWAYS(CHARGER, charger_task, NULL, VENTI_TASK_STACK_SIZE) \ TASK_NOTEST(CHIPSET, chipset_task, NULL, VENTI_TASK_STACK_SIZE) \ TASK_NOTEST(KEYPROTO, keyboard_protocol_task, NULL, TASK_STACK_SIZE) \ TASK_ALWAYS(CONSOLE, console_task, NULL, VENTI_TASK_STACK_SIZE) \ + TASK_NOTEST(PDCMD, pd_command_task, NULL, VENTI_TASK_STACK_SIZE) \ TASK_ALWAYS(HOSTCMD, host_command_task, NULL, VENTI_TASK_STACK_SIZE) \ - TASK_ALWAYS(POWERBTN, power_button_task, NULL, VENTI_TASK_STACK_SIZE) + TASK_ALWAYS(POWERBTN, power_button_task, NULL, VENTI_TASK_STACK_SIZE) \ + TASK_ALWAYS(PD_C0, pd_task, NULL, VENTI_TASK_STACK_SIZE) \ + TASK_ALWAYS(PD_C1, pd_task, NULL, VENTI_TASK_STACK_SIZE) \ + TASK_ALWAYS(PD_INT_C0, pd_interrupt_handler_task, 0, VENTI_TASK_STACK_SIZE) \ + TASK_ALWAYS(PD_INT_C1, pd_interrupt_handler_task, 1, VENTI_TASK_STACK_SIZE) diff --git a/board/waddledoo/gpio.inc b/board/waddledoo/gpio.inc index ccf041cb44..dd1931e23a 100644 --- a/board/waddledoo/gpio.inc +++ b/board/waddledoo/gpio.inc @@ -23,6 +23,10 @@ GPIO_INT(PG_VCCIO_EXT_OD, PIN(B, 0), GPIO_INT_BOTH, power_signal_interrupt) GPIO_INT(PG_PP5000_U_OD, PIN(E, 2), GPIO_INT_BOTH, power_signal_interrupt) GPIO_INT(PG_DRAM_OD, PIN(E, 4), GPIO_INT_BOTH, power_signal_interrupt) +/* USB-C interrupts */ +GPIO_INT(USB_C0_INT_ODL, PIN(6, 2), GPIO_INT_FALLING | GPIO_PULL_UP, usb_c0_interrupt) +GPIO_INT(SUB_USB_C1_INT_ODL, PIN(F, 5), GPIO_INT_FALLING | GPIO_PULL_UP, sub_usb_c1_interrupt) + /* Button interrupts */ GPIO_INT(H1_EC_PWR_BTN_ODL, PIN(0, 1), GPIO_INT_BOTH | GPIO_PULL_UP, power_button_interrupt) GPIO_INT(VOLDN_BTN_ODL, PIN(4, 0), GPIO_INT_BOTH | GPIO_PULL_UP | GPIO_SEL_1P8V, button_interrupt) @@ -84,6 +88,7 @@ GPIO(USB_C0_RST_ODL, PIN(9, 7), GPIO_OUT_HIGH) /* currently unused */ GPIO(EC_AP_USB_C1_HDMI_HPD, PIN(9, 6), GPIO_OUT_LOW) GPIO(EC_AP_USB_C0_HPD, PIN(9, 3), GPIO_OUT_LOW) GPIO(HDMI_SEL_L, PIN(7, 2), GPIO_OUT_HIGH) +GPIO(EC_BATTERY_PRES_ODL, PIN(E, 1), GPIO_INPUT) /* * Waddledoo doesn't have these physical pins coming to the EC but uses other diff --git a/board/waddledoo/usb_pd_policy.c b/board/waddledoo/usb_pd_policy.c new file mode 100644 index 0000000000..bcdf8300c5 --- /dev/null +++ b/board/waddledoo/usb_pd_policy.c @@ -0,0 +1,66 @@ +/* Copyright 2020 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "charge_manager.h" +#include "chipset.h" +#include "common.h" +#include "console.h" +#include "driver/tcpm/tcpci.h" +#include "usb_pd.h" + +#define CPRINTF(format, args...) cprintf(CC_USBPD, format, ## args) +#define CPRINTS(format, args...) cprints(CC_USBPD, format, ## args) + +int pd_check_vconn_swap(int port) +{ + /* Allow VCONN swaps if the AP is on. */ + return chipset_in_state(CHIPSET_STATE_ANY_SUSPEND | CHIPSET_STATE_ON); +} + +void pd_power_supply_reset(int port) +{ + /* Disable VBUS */ + tcpc_write(port, TCPC_REG_COMMAND, TCPC_REG_COMMAND_SRC_CTRL_LOW); + +#ifdef CONFIG_USB_PD_MAX_SINGLE_SOURCE_CURRENT + /* Give back the current quota we are no longer using */ + charge_manager_source_port(port, 0); +#endif /* defined(CONFIG_USB_PD_MAX_SINGLE_SOURCE_CURRENT) */ + + /* Notify host of power info change. */ + pd_send_host_event(PD_EVENT_POWER_CHANGE); +} + +int pd_set_power_supply_ready(int port) +{ + int rv; + + if (port >= CONFIG_USB_PD_PORT_MAX_COUNT) + return EC_ERROR_INVAL; + + /* Disable charging. */ + rv = tcpc_write(port, TCPC_REG_COMMAND, TCPC_REG_COMMAND_SNK_CTRL_LOW); + if (rv) + return rv; + + /* Our policy is not to source VBUS when the AP is off. */ + if (chipset_in_state(CHIPSET_STATE_ANY_OFF)) + return EC_ERROR_NOT_POWERED; + + /* Provide Vbus. */ + rv = tcpc_write(port, TCPC_REG_COMMAND, TCPC_REG_COMMAND_SRC_CTRL_HIGH); + if (rv) + return rv; + +#ifdef CONFIG_USB_PD_MAX_SINGLE_SOURCE_CURRENT + /* Ensure we advertise the proper available current quota */ + charge_manager_source_port(port, 1); +#endif /* defined(CONFIG_USB_PD_MAX_SINGLE_SOURCE_CURRENT) */ + + /* Notify host of power info change. */ + pd_send_host_event(PD_EVENT_POWER_CHANGE); + + return EC_SUCCESS; +} |