diff options
Diffstat (limited to 'baseboard/brask')
-rw-r--r-- | baseboard/brask/baseboard.c | 17 | ||||
-rw-r--r-- | baseboard/brask/baseboard.h | 248 | ||||
-rw-r--r-- | baseboard/brask/baseboard_usbc_config.h | 19 | ||||
-rw-r--r-- | baseboard/brask/battery_presence.c | 69 | ||||
-rw-r--r-- | baseboard/brask/build.mk | 14 | ||||
-rw-r--r-- | baseboard/brask/cbi.c | 52 | ||||
-rw-r--r-- | baseboard/brask/charger.c | 90 | ||||
-rw-r--r-- | baseboard/brask/usb_pd_policy.c | 204 |
8 files changed, 713 insertions, 0 deletions
diff --git a/baseboard/brask/baseboard.c b/baseboard/brask/baseboard.c new file mode 100644 index 0000000000..976831812f --- /dev/null +++ b/baseboard/brask/baseboard.c @@ -0,0 +1,17 @@ +/* Copyright 2021 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 "common.h" +#include "compile_time_macros.h" + +#include "gpio_signal.h" + +/* Wake up pins */ +const enum gpio_signal hibernate_wake_pins[] = { + GPIO_ACOK_OD, + GPIO_GSC_EC_PWR_BTN_ODL, + GPIO_LID_OPEN, +}; +const int hibernate_wake_pins_used = ARRAY_SIZE(hibernate_wake_pins); diff --git a/baseboard/brask/baseboard.h b/baseboard/brask/baseboard.h new file mode 100644 index 0000000000..6a4efe942e --- /dev/null +++ b/baseboard/brask/baseboard.h @@ -0,0 +1,248 @@ +/* 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. + */ + +/* Brya baseboard configuration */ + +#ifndef __CROS_EC_BASEBOARD_H +#define __CROS_EC_BASEBOARD_H + +/* + * By default, enable all console messages excepted HC + */ +#define CC_DEFAULT (CC_ALL & ~(BIT(CC_HOSTCMD))) + +/* NPCX9 config */ +#define NPCX9_PWM1_SEL 1 /* GPIO C2 is used as PWM1. */ +/* + * This defines which pads (GPIO10/11 or GPIO64/65) are connected to + * the "UART1" (NPCX_UART_PORT0) controller when used for + * CONSOLE_UART. + */ +#define NPCX_UART_MODULE2 1 /* 1:GPIO64/65 for UART1 */ + +/* EC Defines */ +#define CONFIG_LTO +#define CONFIG_CBI_EEPROM +#define CONFIG_BOARD_VERSION_CBI +#define CONFIG_CRC8 +#define CONFIG_DPTF +#define CONFIG_FPU + +/* Verified boot configs */ +#define CONFIG_VBOOT_EFS2 +#define CONFIG_VBOOT_HASH +#define CONFIG_VSTORE +#define CONFIG_VSTORE_SLOT_COUNT 1 + +#define CONFIG_HIBERNATE_PSL + +/* Work around double CR50 reset by waiting in initial power on. */ +#define CONFIG_BOARD_RESET_AFTER_POWER_ON + +/* Host communication */ +#define CONFIG_HOSTCMD_ESPI +#define CONFIG_HOSTCMD_ESPI_VW_SLP_S4 + +/* + * TODO(b/179648721): implement sensors + */ +#define CONFIG_TABLET_MODE +#define CONFIG_TABLET_MODE_SWITCH +#define CONFIG_GMR_TABLET_MODE + +#define CONFIG_MKBP_EVENT +#define CONFIG_MKBP_USE_HOST_EVENT + +/* LED */ +#define CONFIG_LED_COMMON + +/* Common charger defines */ +#define CONFIG_CHARGE_MANAGER +#define CONFIG_CHARGER +#define CONFIG_CHARGER_DISCHARGE_ON_AC +#define CONFIG_CHARGER_INPUT_CURRENT 512 + +#define CONFIG_CMD_CHARGER_DUMP + +#define CONFIG_USB_CHARGER +#define CONFIG_BC12_DETECT_PI3USB9201 + +/* + * Don't allow the system to boot to S0 when the battery is low and unable to + * communicate on locked systems (which haven't PD negotiated) + */ +#define CONFIG_CHARGER_MIN_POWER_MW_FOR_POWER_ON_WITH_BATT 15000 +#define CONFIG_CHARGER_MIN_POWER_MW_FOR_POWER_ON 15001 + +/* Common battery defines */ +#define CONFIG_BATTERY_SMART +#define CONFIG_BATTERY_FUEL_GAUGE +#define CONFIG_BATTERY_CUT_OFF +#define CONFIG_BATTERY_PRESENT_CUSTOM +#define CONFIG_BATTERY_HW_PRESENT_CUSTOM +#define CONFIG_BATTERY_REVIVE_DISCONNECT +#define CONFIG_CMD_BATT_MFG_ACCESS + +/* Chipset config */ +#define CONFIG_CHIPSET_ALDERLAKE_SLG4BD44540 + +#define CONFIG_CHIPSET_RESET_HOOK +#define CONFIG_CPU_PROCHOT_ACTIVE_LOW +#define CONFIG_EXTPOWER_GPIO +#define CONFIG_POWER_BUTTON +#define CONFIG_POWER_BUTTON_X86 +#define CONFIG_POWER_S0IX +#define CONFIG_POWER_SLEEP_FAILURE_DETECTION +#define CONFIG_POWER_TRACK_HOST_SLEEP_STATE +#define CONFIG_LOW_POWER_IDLE + +#define CONFIG_HOSTCMD_ESPI_RESET_SLP_SX_VW_ON_ESPI_RST + +/* + * TODO(b/191742284): When DAM enabled coreboot image is flashed on top of DAM + * disabled coreboot, S5 exit is taking more than 4 seconds, then EC triggers + * system shutdown. This WA deselects CONFIG_BOARD_HAS_RTC_RESET to prevent + * EC from system shutdown. + */ +/* #define CONFIG_BOARD_HAS_RTC_RESET */ + +#define CONFIG_CMD_AP_RESET_LOG +#define CONFIG_HOSTCMD_AP_RESET + +/* Buttons / Switches */ +#define CONFIG_VOLUME_BUTTONS +#define CONFIG_SWITCH + +/* Common Keyboard Defines */ +#define CONFIG_CMD_KEYBOARD + +#define CONFIG_KEYBOARD_COL2_INVERTED +#define CONFIG_KEYBOARD_KEYPAD +#define CONFIG_KEYBOARD_PROTOCOL_8042 +#ifdef CONFIG_KEYBOARD_VIVALDI +#define CONFIG_KEYBOARD_PWRBTN_ASSERTS_KSI2 +#else +#define CONFIG_KEYBOARD_PWRBTN_ASSERTS_KSI3 +#endif + +/* Thermal features */ +#define CONFIG_THROTTLE_AP +#define CONFIG_CHIPSET_CAN_THROTTLE + +#define CONFIG_PWM + +/* Enable I2C Support */ +#define CONFIG_I2C +#define CONFIG_I2C_CONTROLLER + +/* EDP back-light control defines */ +#define CONFIG_BACKLIGHT_LID + +/* UART COMMAND */ +#define CONFIG_CMD_CHARGEN + +/* USB Type C and USB PD defines */ +/* Enable the new USB-C PD stack */ +#define CONFIG_USB_PD_TCPMV2 +#define CONFIG_USB_DRP_ACC_TRYSRC +#define CONFIG_USB_PD_REV30 + +#define CONFIG_CMD_HCDEBUG +#define CONFIG_CMD_PPC_DUMP +#define CONFIG_CMD_TCPC_DUMP + +#define CONFIG_USB_POWER_DELIVERY +#define CONFIG_USB_PD_ALT_MODE +#define CONFIG_USB_PD_ALT_MODE_DFP +#define CONFIG_USB_PD_ALT_MODE_UFP +#define CONFIG_USB_PD_DISCHARGE_PPC +#define CONFIG_USB_PD_DUAL_ROLE +#define CONFIG_USB_PD_DUAL_ROLE_AUTO_TOGGLE +#define CONFIG_USB_PD_TCPC_LOW_POWER +#define CONFIG_USB_PD_TCPM_TCPCI +#define CONFIG_USB_PD_TCPM_NCT38XX + +#define CONFIG_USB_PD_TCPM_MUX +#define CONFIG_HOSTCMD_PD_CONTROL /* Needed for TCPC FW update */ +#define CONFIG_CMD_USB_PD_PE + +/* + * The PS8815 TCPC was found to require a 50ms delay to consistently work + * with non-PD chargers. Override the default low-power mode exit delay. + */ +#undef CONFIG_USB_PD_TCPC_LPM_EXIT_DEBOUNCE +#define CONFIG_USB_PD_TCPC_LPM_EXIT_DEBOUNCE (50*MSEC) + +/* Enable USB3.2 DRD */ +#define CONFIG_USB_PD_USB32_DRD + +#define CONFIG_USB_PD_TRY_SRC +#define CONFIG_USB_PD_VBUS_DETECT_TCPC + +#define CONFIG_USBC_PPC +/* Note - SN5S330 support automatically adds + * CONFIG_USBC_PPC_POLARITY + * CONFIG_USBC_PPC_SBU + * CONFIG_USBC_PPC_VCONN + */ +#define CONFIG_USBC_PPC_DEDICATED_INT + +#define CONFIG_USBC_SS_MUX +#define CONFIG_USB_MUX_VIRTUAL + +#define CONFIG_USBC_VCONN +#define CONFIG_USBC_VCONN_SWAP + +/* Enabling SOP* communication */ +#define CONFIG_CMD_USB_PD_CABLE +#define CONFIG_USB_PD_DECODE_SOP + +/* + * USB ID + * This is allocated specifically for Brya + * http://google3/hardware/standards/usb/ + */ +#define CONFIG_USB_PID 0x504F +/* Device version of product. */ +#define CONFIG_USB_BCD_DEV 0x0000 + +#ifndef __ASSEMBLER__ + +#include <stdbool.h> +#include <stdint.h> + +#include "common.h" +#include "baseboard_usbc_config.h" +#include "extpower.h" + +/** + * Configure run-time data structures and operation based on CBI data. This + * typically includes customization for changes in the BOARD_VERSION and + * FW_CONFIG fields in CBI. This routine is called from the baseboard after + * the CBI data has been initialized. + */ +__override_proto void board_cbi_init(void); + +/** + * Initialize the FW_CONFIG from CBI data. If the CBI data is not valid, set the + * FW_CONFIG to the board specific defaults. + */ +__override_proto void board_init_fw_config(void); + +/* + * Check battery disconnect state. + * This function will return if battery is initialized or not. + * @return true - initialized. false - not. + */ +__override_proto bool board_battery_is_initialized(void); + +/* + * Return the board revision number. + */ +uint8_t get_board_id(void); + +#endif /* !__ASSEMBLER__ */ + +#endif /* __CROS_EC_BASEBOARD_H */ diff --git a/baseboard/brask/baseboard_usbc_config.h b/baseboard/brask/baseboard_usbc_config.h new file mode 100644 index 0000000000..f8b9fab35c --- /dev/null +++ b/baseboard/brask/baseboard_usbc_config.h @@ -0,0 +1,19 @@ +/* Copyright 2021 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. + */ + +/* brya family-specific USB-C configuration */ + +#ifndef __CROS_EC_BASEBOARD_USBC_CONFIG_H +#define __CROS_EC_BASEBOARD_USBC_CONFIG_H + +#include "gpio_signal.h" + +/* Common definition for the USB PD interrupt handlers. */ +void bc12_interrupt(enum gpio_signal signal); +void ppc_interrupt(enum gpio_signal signal); +void retimer_interrupt(enum gpio_signal signal); +void tcpc_alert_event(enum gpio_signal signal); + +#endif /* __CROS_EC_BASEBOARD_USBC_CONFIG_H */ diff --git a/baseboard/brask/battery_presence.c b/baseboard/brask/battery_presence.c new file mode 100644 index 0000000000..94c9926820 --- /dev/null +++ b/baseboard/brask/battery_presence.c @@ -0,0 +1,69 @@ +/* Copyright 2021 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. + * + * Common battery presence checking for Brya family. + * Each board should implement board_battery_info[] to define the specific + * battery packs supported. + */ +#include <stdbool.h> + +#include "battery.h" +#include "battery_smart.h" +#include "common.h" + +static enum battery_present batt_pres_prev = BP_NOT_SURE; + +__overridable bool board_battery_is_initialized(void) +{ + int batt_status; + + return battery_status(&batt_status) != EC_SUCCESS ? false : + !!(batt_status & STATUS_INITIALIZED); +} + +/* + * Physical detection of battery. + */ +static enum battery_present battery_check_present_status(void) +{ + enum battery_present batt_pres; + + if (battery_is_cut_off()) + return BP_NO; + + /* Get the physical hardware status */ + batt_pres = battery_hw_present(); + + /* + * If the battery is not physically connected, then no need to perform + * any more checks. + */ + if (batt_pres == BP_NO) + return BP_NO; + + /* + * If the battery is present now and was present last time we checked, + * return early. + */ + if ((batt_pres == BP_YES) && (batt_pres == batt_pres_prev)) + return BP_YES; + + /* + * Check battery initialization. If the battery is not initialized, + * then return BP_NOT_SURE. Battery could be in ship + * mode and might require pre-charge current to wake it up. BP_NO is not + * returned here because charger state machine will not provide + * pre-charge current assuming that battery is not present. + */ + if (!board_battery_is_initialized()) + return BP_NOT_SURE; + + return BP_YES; +} + +enum battery_present battery_is_present(void) +{ + batt_pres_prev = battery_check_present_status(); + return batt_pres_prev; +} diff --git a/baseboard/brask/build.mk b/baseboard/brask/build.mk new file mode 100644 index 0000000000..e03e0a919c --- /dev/null +++ b/baseboard/brask/build.mk @@ -0,0 +1,14 @@ +# -*- makefile -*- +# 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. +# +# Brya baseboard specific files build +# + +baseboard-y= +baseboard-y+=baseboard.o +baseboard-y+=battery_presence.o +baseboard-y+=cbi.o +baseboard-y+=charger.o +baseboard-y+=usb_pd_policy.o diff --git a/baseboard/brask/cbi.c b/baseboard/brask/cbi.c new file mode 100644 index 0000000000..6d9e2b93fa --- /dev/null +++ b/baseboard/brask/cbi.c @@ -0,0 +1,52 @@ +/* Copyright 2021 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 <stdint.h> + +#include "console.h" +#include "common.h" +#include "cros_board_info.h" +#include "hooks.h" + +#define CPRINTS(format, args...) cprints(CC_CHIPSET, format, ## args) +#define CPRINTF(format, args...) cprintf(CC_CHIPSET, format, ## args) + +static uint8_t board_id; + +uint8_t get_board_id(void) +{ + return board_id; +} + +__overridable void board_cbi_init(void) +{ +} + +__overridable void board_init_fw_config(void) +{ +} + +/* + * Read CBI from I2C EEPROM and initialize variables for board variants. + */ +static void cbi_init(void) +{ + uint32_t cbi_val; + + /* Board ID */ + if (cbi_get_board_version(&cbi_val) != EC_SUCCESS || + cbi_val > UINT8_MAX) + CPRINTS("CBI: Read Board ID failed"); + else + board_id = cbi_val; + + CPRINTS("Board ID: %d", board_id); + + board_init_fw_config(); + + /* Allow the board project to make runtime changes based on CBI data */ + board_cbi_init(); +} +DECLARE_HOOK(HOOK_INIT, cbi_init, HOOK_PRIO_FIRST); diff --git a/baseboard/brask/charger.c b/baseboard/brask/charger.c new file mode 100644 index 0000000000..04be67147d --- /dev/null +++ b/baseboard/brask/charger.c @@ -0,0 +1,90 @@ +/* Copyright 2021 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 "common.h" + +#include "charge_manager.h" +#include "charge_state_v2.h" +#include "charger.h" +#include "compile_time_macros.h" +#include "console.h" +#include "driver/charger/bq25710.h" +#include "usbc_ppc.h" +#include "usb_pd.h" +#include "util.h" + + +#define CPRINTSUSB(format, args...) cprints(CC_USBCHARGE, format, ## args) +#define CPRINTFUSB(format, args...) cprintf(CC_USBCHARGE, format, ## args) + +/* Charger Chip Configuration */ +const struct charger_config_t chg_chips[] = { + { + .i2c_port = I2C_PORT_CHARGER, + .i2c_addr_flags = BQ25710_SMBUS_ADDR1_FLAGS, + .drv = &bq25710_drv, + }, +}; +BUILD_ASSERT(ARRAY_SIZE(chg_chips) == CHARGER_NUM); + +int board_set_active_charge_port(int port) +{ + int is_valid_port = board_is_usb_pd_port_present(port); + int i; + + if (port == CHARGE_PORT_NONE) { + CPRINTSUSB("Disabling all charger ports"); + + /* Disable all ports. */ + for (i = 0; i < ppc_cnt; i++) { + /* + * Do not return early if one fails otherwise we can + * get into a boot loop assertion failure. + */ + if (ppc_vbus_sink_enable(i, 0)) + CPRINTSUSB("Disabling C%d as sink failed.", i); + } + + return EC_SUCCESS; + } else if (!is_valid_port) { + return EC_ERROR_INVAL; + } + + /* Check if the port is sourcing VBUS. */ + if (ppc_is_sourcing_vbus(port)) { + CPRINTFUSB("Skip enable C%d", port); + return EC_ERROR_INVAL; + } + + CPRINTSUSB("New charge port: C%d", port); + + /* + * Turn off the other ports' sink path FETs, before enabling the + * requested charge port. + */ + for (i = 0; i < ppc_cnt; i++) { + if (i == port) + continue; + + if (ppc_vbus_sink_enable(i, 0)) + CPRINTSUSB("C%d: sink path disable failed.", i); + } + + /* Enable requested charge port. */ + if (ppc_vbus_sink_enable(port, 1)) { + CPRINTSUSB("C%d: sink path enable failed.", port); + return EC_ERROR_UNKNOWN; + } + + return EC_SUCCESS; +} + +__overridable void board_set_charge_limit(int port, int supplier, int charge_ma, + int max_ma, int charge_mv) +{ + charge_set_input_current_limit(MAX(charge_ma, + CONFIG_CHARGER_INPUT_CURRENT), + charge_mv); +} diff --git a/baseboard/brask/usb_pd_policy.c b/baseboard/brask/usb_pd_policy.c new file mode 100644 index 0000000000..1637a8bfac --- /dev/null +++ b/baseboard/brask/usb_pd_policy.c @@ -0,0 +1,204 @@ +/* Copyright 2021 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. + */ + +/* Shared USB-C policy for Brya boards */ + +#include <stddef.h> +#include <stdint.h> + +#include "charge_manager.h" +#include "chipset.h" +#include "common.h" +#include "compile_time_macros.h" +#include "console.h" +#include "ec_commands.h" +#include "gpio.h" +#include "usbc_ppc.h" +#include "usb_mux.h" +#include "usb_pd.h" +#include "usb_pd.h" +#include "usb_pd_tbt.h" +#include "usb_pd_tcpm.h" +#include "usb_pd_vdo.h" +#include "util.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) +{ + /* Only allow vconn swap after the PP5000_Z1 rail is enabled */ + return gpio_get_level(GPIO_SEQ_EC_DSW_PWROK); +} + +void pd_power_supply_reset(int port) +{ + int prev_en; + + prev_en = ppc_is_sourcing_vbus(port); + + /* Disable VBUS. */ + ppc_vbus_source_enable(port, 0); + + /* Enable discharge if we were previously sourcing 5V */ + if (prev_en) + pd_set_vbus_discharge(port, 1); + + /* Notify host of power info change. */ + pd_send_host_event(PD_EVENT_POWER_CHANGE); +} + +int pd_set_power_supply_ready(int port) +{ + int rv; + + /* Disable charging. */ + rv = ppc_vbus_sink_enable(port, 0); + if (rv) + return rv; + + pd_set_vbus_discharge(port, 0); + + /* Provide Vbus. */ + rv = ppc_vbus_source_enable(port, 1); + if (rv) + return rv; + + /* Notify host of power info change. */ + pd_send_host_event(PD_EVENT_POWER_CHANGE); + + return EC_SUCCESS; +} + +int board_vbus_source_enabled(int port) +{ + return ppc_is_sourcing_vbus(port); +} + +/* ----------------- Vendor Defined Messages ------------------ */ +/* Responses specifically for the enablement of TBT mode in the role of UFP */ + +#define OPOS_TBT 1 + +static const union tbt_mode_resp_device vdo_tbt_modes[1] = { + { + .tbt_alt_mode = 0x0001, + .tbt_adapter = TBT_ADAPTER_TBT3, + .intel_spec_b0 = 0, + .vendor_spec_b0 = 0, + .vendor_spec_b1 = 0, + } +}; + +static const uint32_t vdo_idh = VDO_IDH( + 1, /* Data caps as USB host */ + 0, /* Not a USB device */ + IDH_PTYPE_PERIPH, + 1, /* Supports alt modes */ + USB_VID_GOOGLE); + +static const uint32_t vdo_idh_rev30 = VDO_IDH_REV30( + 1, /* Data caps as USB host */ + 0, /* Not a USB device */ + IDH_PTYPE_PERIPH, + 1, /* Supports alt modes */ + IDH_PTYPE_DFP_HOST, + USB_TYPEC_RECEPTACLE, + USB_VID_GOOGLE); + +static const uint32_t vdo_product = VDO_PRODUCT(CONFIG_USB_PID, + CONFIG_USB_BCD_DEV); + +/* TODO(b/168890624): add USB4 to capability once USB4 response implemented */ +static const uint32_t vdo_ufp1 = VDO_UFP1( + (VDO_UFP1_CAPABILITY_USB20 + | VDO_UFP1_CAPABILITY_USB32), + USB_TYPEC_RECEPTACLE, + VDO_UFP1_ALT_MODE_TBT3, + USB_R30_SS_U40_GEN3); + +static const uint32_t vdo_dfp = VDO_DFP( + (VDO_DFP_HOST_CAPABILITY_USB20 + | VDO_DFP_HOST_CAPABILITY_USB32 + | VDO_DFP_HOST_CAPABILITY_USB4), + USB_TYPEC_RECEPTACLE, + 1 /* Port 1 */); + +static int svdm_tbt_compat_response_identity(int port, uint32_t *payload) +{ + /* TODO(b/154962766): Get an XID */ + payload[VDO_I(CSTAT)] = VDO_CSTAT(0); + payload[VDO_I(PRODUCT)] = vdo_product; + + if (pd_get_rev(port, TCPC_TX_SOP) == PD_REV30) { + /* PD Revision 3.0 */ + payload[VDO_I(IDH)] = vdo_idh_rev30; + payload[VDO_I(PTYPE_UFP1_VDO)] = vdo_ufp1; + /* TODO(b/181620145): Customize for brya */ + payload[VDO_I(PTYPE_UFP2_VDO)] = 0; + payload[VDO_I(PTYPE_DFP_VDO)] = vdo_dfp; + return VDO_I(PTYPE_DFP_VDO) + 1; + } + + /* PD Revision 2.0 */ + payload[VDO_I(IDH)] = vdo_idh; + return VDO_I(PRODUCT) + 1; +} + +static int svdm_tbt_compat_response_svids(int port, uint32_t *payload) +{ + payload[1] = VDO_SVID(USB_VID_INTEL, 0); + return 2; +} + +static int svdm_tbt_compat_response_modes(int port, uint32_t *payload) +{ + if (PD_VDO_VID(payload[0]) == USB_VID_INTEL) { + memcpy(payload + 1, vdo_tbt_modes, sizeof(vdo_tbt_modes)); + return ARRAY_SIZE(vdo_tbt_modes) + 1; + } else { + return 0; /* NAK */ + } +} + +static int svdm_tbt_compat_response_enter_mode( + int port, uint32_t *payload) +{ + mux_state_t mux_state = 0; + + /* Do not enter mode while CPU is off. */ + if (chipset_in_or_transitioning_to_state(CHIPSET_STATE_ANY_OFF)) + return 0; /* NAK */ + + if ((PD_VDO_VID(payload[0]) != USB_VID_INTEL) || + (PD_VDO_OPOS(payload[0]) != OPOS_TBT)) + return 0; /* NAK */ + + mux_state = usb_mux_get(port); + /* + * Ref: USB PD 3.0 Spec figure 6-21 Successful Enter Mode sequence + * UFP (responder) should be in USB mode or safe mode before sending + * Enter Mode Command response. + */ + if ((mux_state & USB_PD_MUX_USB_ENABLED) || + (mux_state & USB_PD_MUX_SAFE_MODE)) { + pd_ufp_set_enter_mode(port, payload); + set_tbt_compat_mode_ready(port); + CPRINTS("UFP Enter TBT mode"); + return 1; /* ACK */ + } + + CPRINTS("UFP failed to enter TBT mode(mux=0x%x)", mux_state); + return 0; +} + +const struct svdm_response svdm_rsp = { + .identity = &svdm_tbt_compat_response_identity, + .svids = &svdm_tbt_compat_response_svids, + .modes = &svdm_tbt_compat_response_modes, + .enter_mode = &svdm_tbt_compat_response_enter_mode, + .amode = NULL, + .exit_mode = NULL, +}; |